/
pos.go
132 lines (116 loc) · 3.06 KB
/
pos.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package cube
import (
"github.com/go-gl/mathgl/mgl64"
"math"
)
const (
MaxY = 255
MinY = 0
)
// Pos holds the position of a block. The position is represented of an array with an x, y and z value,
// where the y value is positive.
type Pos [3]int
// X returns the X coordinate of the block position.
func (p Pos) X() int {
return p[0]
}
// Y returns the Y coordinate of the block position.
func (p Pos) Y() int {
return p[1]
}
// Z returns the Z coordinate of the block position.
func (p Pos) Z() int {
return p[2]
}
// OutOfBounds checks if the Y value is either bigger than 255 or smaller than 0.
func (p Pos) OutOfBounds() bool {
y := p[1]
return y > MaxY || y < MinY
}
// Add adds two block positions together and returns a new one with the combined values.
func (p Pos) Add(pos Pos) Pos {
return Pos{p[0] + pos[0], p[1] + pos[1], p[2] + pos[2]}
}
// Subtract subtracts two block positions together and returns a new one with the combined values.
func (p Pos) Subtract(pos Pos) Pos {
return Pos{p[0] - pos[0], p[1] - pos[1], p[2] - pos[2]}
}
// Vec3 returns a vec3 holding the same coordinates as the block position.
func (p Pos) Vec3() mgl64.Vec3 {
return mgl64.Vec3{float64(p[0]), float64(p[1]), float64(p[2])}
}
// Vec3Middle returns a Vec3 holding the coordinates of the block position with 0.5 added on both horizontal
// axes.
func (p Pos) Vec3Middle() mgl64.Vec3 {
return mgl64.Vec3{float64(p[0]) + 0.5, float64(p[1]), float64(p[2]) + 0.5}
}
// Vec3Centre returns a Vec3 holding the coordinates of the block position with 0.5 added on all axes.
func (p Pos) Vec3Centre() mgl64.Vec3 {
return mgl64.Vec3{float64(p[0]) + 0.5, float64(p[1]) + 0.5, float64(p[2]) + 0.5}
}
// Side returns the position on the side of this block position, at a specific face.
func (p Pos) Side(face Face) Pos {
switch face {
case FaceUp:
p[1]++
case FaceDown:
p[1]--
case FaceNorth:
p[2]--
case FaceSouth:
p[2]++
case FaceWest:
p[0]--
case FaceEast:
p[0]++
}
return p
}
// Face returns the face that the other Pos was on compared to the current Pos. The other Pos
// is assumed to be a direct neighbour of the current Pos.
func (p Pos) Face(other Pos) Face {
switch other {
case p.Add(Pos{0, 1}):
return FaceUp
case p.Add(Pos{0, -1}):
return FaceDown
case p.Add(Pos{0, 0, -1}):
return FaceNorth
case p.Add(Pos{0, 0, 1}):
return FaceSouth
case p.Add(Pos{-1, 0, 0}):
return FaceWest
case p.Add(Pos{1, 0, 0}):
return FaceEast
}
return FaceUp
}
// Neighbours calls the function passed for each of the block position's neighbours. If the Y value is out of
// bounds, the function will not be called for that position.
func (p Pos) Neighbours(f func(neighbour Pos)) {
if p.OutOfBounds() {
return
}
p[0]++
f(p)
p[0] -= 2
f(p)
p[0]++
p[1]++
if p[1] <= MaxY {
f(p)
}
p[1] -= 2
if p[1] >= MinY {
f(p)
}
p[1]++
p[2]++
f(p)
p[2] -= 2
f(p)
}
// PosFromVec3 returns a block position by a Vec3, rounding the values down adequately.
func PosFromVec3(vec3 mgl64.Vec3) Pos {
return Pos{int(math.Floor(vec3[0])), int(math.Floor(vec3[1])), int(math.Floor(vec3[2]))}
}