github.com/df-mc/dragonfly@v0.9.13/server/block/cube/pos.go (about)

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