github.com/df-mc/dragonfly@v0.9.13/server/block/cube/rotation.go (about) 1 package cube 2 3 import ( 4 "github.com/go-gl/mathgl/mgl64" 5 "math" 6 ) 7 8 // Rotation describes the rotation of an object in the world. It holds a yaw 9 // (r[0]) and pitch value (r[1]). Yaw is in the range (-180, 180) while pitch is 10 // in the range (-90, 90). A positive pitch implies an entity is looking 11 // downwards, while a negative pitch implies it is looking upwards. 12 type Rotation [2]float64 13 14 // Yaw returns the yaw of r (r[0]). 15 func (r Rotation) Yaw() float64 { 16 return r[0] 17 } 18 19 // Pitch returns the pitch of r (r[1]). 20 func (r Rotation) Pitch() float64 { 21 return r[1] 22 } 23 24 // Elem extracts the elements of the Rotation for direct value assignment. 25 func (r Rotation) Elem() (yaw, pitch float64) { 26 return r[0], r[1] 27 } 28 29 // Add adds the values of two Rotations element-wise and returns a new Rotation. 30 // If the yaw or pitch would otherwise exceed their respective range as 31 // described, they are 'overflown' to the other end of the allowed range. 32 func (r Rotation) Add(r2 Rotation) Rotation { 33 return Rotation{r[0] + r2[0], r[1] + r2[1]}.fix() 34 } 35 36 // Opposite returns the Rotation opposite r, so that 37 // r.Vec3().Add(r.Opposite().Vec3()).Len() is equal to 0. 38 func (r Rotation) Opposite() Rotation { 39 return Rotation{r[0] + 180, -r[1]}.fix() 40 } 41 42 // Direction returns the horizontal Direction that r points towards based on the 43 // yaw of r. 44 func (r Rotation) Direction() Direction { 45 yaw := r.fix().Yaw() 46 switch { 47 case yaw > 45 && yaw <= 135: 48 return West 49 case yaw > -45 && yaw <= 45: 50 return South 51 case yaw > -135 && yaw <= -45: 52 return East 53 case yaw <= -135 || yaw > 135: 54 return North 55 } 56 return 0 57 } 58 59 // Orientation returns an Orientation value that most closely matches the yaw 60 // of r. 61 func (r Rotation) Orientation() Orientation { 62 const step = 360 / 16.0 63 64 yaw := r.fix().Yaw() 65 if yaw < -step/2 { 66 yaw += 360 67 } 68 return Orientation(math.Round(yaw / step)) 69 } 70 71 // Vec3 returns the direction vector of r. The length of the mgl64.Vec3 returned 72 // is always 1. 73 func (r Rotation) Vec3() mgl64.Vec3 { 74 yaw, pitch := r.fix().Elem() 75 yawRad, pitchRad := mgl64.DegToRad(yaw), mgl64.DegToRad(pitch) 76 77 m := math.Cos(pitchRad) 78 return mgl64.Vec3{ 79 -m * math.Sin(yawRad), 80 -math.Sin(pitchRad), 81 m * math.Cos(yawRad), 82 } 83 } 84 85 // fix 'overflows' the Rotation's values to make sure they are within the range 86 // as described above. 87 func (r Rotation) fix() Rotation { 88 return Rotation{ 89 math.Mod(r[0]+180, 360) - 180, 90 math.Mod(r[1]+90, 180) - 90, 91 } 92 }