206 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			206 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package vec3
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"zworld/plugin/math"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"zworld/plugin/math/vec2"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var (
							 | 
						||
| 
								 | 
							
									// Zero is the zero vector
							 | 
						||
| 
								 | 
							
									Zero = T{0, 0, 0}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// One is the unit vector
							 | 
						||
| 
								 | 
							
									One = T{1, 1, 1}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// UnitX is the unit vector in the X direction (right)
							 | 
						||
| 
								 | 
							
									UnitX = T{1, 0, 0}
							 | 
						||
| 
								 | 
							
									Right = T{1, 0, 0}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// UnitXN is the unit vector in the negative X direction (left)
							 | 
						||
| 
								 | 
							
									UnitXN = T{-1, 0, 0}
							 | 
						||
| 
								 | 
							
									Left   = T{-1, 0, 0}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// UnitY is the unit vector in the Y direction (up)
							 | 
						||
| 
								 | 
							
									UnitY = T{0, 1, 0}
							 | 
						||
| 
								 | 
							
									Up    = T{0, 1, 0}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// UnitYN is the unit vector in the negative Y direction (down)
							 | 
						||
| 
								 | 
							
									UnitYN = T{0, -1, 0}
							 | 
						||
| 
								 | 
							
									Down   = T{0, -1, 0}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// UnitZ is the unit vector in the Z direction (forward)
							 | 
						||
| 
								 | 
							
									UnitZ   = T{0, 0, 1}
							 | 
						||
| 
								 | 
							
									Forward = T{0, 0, 1}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// UnitZN is the unit vector in the negative Z direction (backward)
							 | 
						||
| 
								 | 
							
									UnitZN   = T{0, 0, -1}
							 | 
						||
| 
								 | 
							
									Backward = T{0, 0, 1}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									InfPos = T{math.InfPos, math.InfPos, math.InfPos}
							 | 
						||
| 
								 | 
							
									InfNeg = T{math.InfNeg, math.InfNeg, math.InfNeg}
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// T holds a 3-component vector of 32-bit floats
							 | 
						||
| 
								 | 
							
								type T struct {
							 | 
						||
| 
								 | 
							
									X, Y, Z float32
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Slice converts the vector into a 3-element slice of float32
							 | 
						||
| 
								 | 
							
								func (v T) Slice() [3]float32 {
							 | 
						||
| 
								 | 
							
									return [3]float32{v.X, v.Y, v.Z}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Length returns the length of the vector.
							 | 
						||
| 
								 | 
							
								// See also LengthSqr and Normalize.
							 | 
						||
| 
								 | 
							
								func (v T) Length() float32 {
							 | 
						||
| 
								 | 
							
									return math.Sqrt(v.LengthSqr())
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// LengthSqr returns the squared length of the vector.
							 | 
						||
| 
								 | 
							
								// See also Length and Normalize.
							 | 
						||
| 
								 | 
							
								func (v T) LengthSqr() float32 {
							 | 
						||
| 
								 | 
							
									return v.X*v.X + v.Y*v.Y + v.Z*v.Z
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Abs returns a copy containing the absolute values of the vector components.
							 | 
						||
| 
								 | 
							
								func (v T) Abs() T {
							 | 
						||
| 
								 | 
							
									return T{math.Abs(v.X), math.Abs(v.Y), math.Abs(v.Z)}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Normalize normalizes the vector to unit length.
							 | 
						||
| 
								 | 
							
								func (v *T) Normalize() {
							 | 
						||
| 
								 | 
							
									sl := v.LengthSqr()
							 | 
						||
| 
								 | 
							
									if sl == 0 || sl == 1 {
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									s := 1 / math.Sqrt(sl)
							 | 
						||
| 
								 | 
							
									v.X *= s
							 | 
						||
| 
								 | 
							
									v.Y *= s
							 | 
						||
| 
								 | 
							
									v.Z *= s
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Normalized returns a unit length normalized copy of the vector.
							 | 
						||
| 
								 | 
							
								func (v T) Normalized() T {
							 | 
						||
| 
								 | 
							
									v.Normalize()
							 | 
						||
| 
								 | 
							
									return v
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Scale the vector by a constant (in-place)
							 | 
						||
| 
								 | 
							
								func (v *T) Scale(f float32) {
							 | 
						||
| 
								 | 
							
									v.X *= f
							 | 
						||
| 
								 | 
							
									v.Y *= f
							 | 
						||
| 
								 | 
							
									v.Z *= f
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Scaled returns a scaled vector
							 | 
						||
| 
								 | 
							
								func (v T) Scaled(f float32) T {
							 | 
						||
| 
								 | 
							
									return T{v.X * f, v.Y * f, v.Z * f}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// ScaleI returns a vector scaled by an integer factor
							 | 
						||
| 
								 | 
							
								func (v T) ScaleI(i int) T {
							 | 
						||
| 
								 | 
							
									return v.Scaled(float32(i))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Invert the vector components
							 | 
						||
| 
								 | 
							
								func (v *T) Invert() {
							 | 
						||
| 
								 | 
							
									v.X = -v.X
							 | 
						||
| 
								 | 
							
									v.Y = -v.Y
							 | 
						||
| 
								 | 
							
									v.Z = -v.Z
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Inverted returns an inverted vector
							 | 
						||
| 
								 | 
							
								func (v *T) Inverted() T {
							 | 
						||
| 
								 | 
							
									i := *v
							 | 
						||
| 
								 | 
							
									i.Invert()
							 | 
						||
| 
								 | 
							
									return i
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Floor each components of the vector
							 | 
						||
| 
								 | 
							
								func (v T) Floor() T {
							 | 
						||
| 
								 | 
							
									return T{math.Floor(v.X), math.Floor(v.Y), math.Floor(v.Z)}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Ceil each component of the vector
							 | 
						||
| 
								 | 
							
								func (v T) Ceil() T {
							 | 
						||
| 
								 | 
							
									return T{math.Ceil(v.X), math.Ceil(v.Y), math.Ceil(v.Z)}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Round each component of the vector
							 | 
						||
| 
								 | 
							
								func (v T) Round() T {
							 | 
						||
| 
								 | 
							
									return T{math.Round(v.X), math.Round(v.Y), math.Round(v.Z)}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Add each element of the vector with the corresponding element of another vector
							 | 
						||
| 
								 | 
							
								func (v T) Add(v2 T) T {
							 | 
						||
| 
								 | 
							
									return T{
							 | 
						||
| 
								 | 
							
										v.X + v2.X,
							 | 
						||
| 
								 | 
							
										v.Y + v2.Y,
							 | 
						||
| 
								 | 
							
										v.Z + v2.Z,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Sub subtracts each element of the vector with the corresponding element of another vector
							 | 
						||
| 
								 | 
							
								func (v T) Sub(v2 T) T {
							 | 
						||
| 
								 | 
							
									return T{
							 | 
						||
| 
								 | 
							
										v.X - v2.X,
							 | 
						||
| 
								 | 
							
										v.Y - v2.Y,
							 | 
						||
| 
								 | 
							
										v.Z - v2.Z,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Mul multiplies each element of the vector with the corresponding element of another vector
							 | 
						||
| 
								 | 
							
								func (v T) Mul(v2 T) T {
							 | 
						||
| 
								 | 
							
									return T{
							 | 
						||
| 
								 | 
							
										v.X * v2.X,
							 | 
						||
| 
								 | 
							
										v.Y * v2.Y,
							 | 
						||
| 
								 | 
							
										v.Z * v2.Z,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// XY returns a 2-component vector with the X, Y components of this vector
							 | 
						||
| 
								 | 
							
								func (v T) XY() vec2.T {
							 | 
						||
| 
								 | 
							
									return vec2.T{X: v.X, Y: v.Y}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// XZ returns a 2-component vector with the X, Z components of this vector
							 | 
						||
| 
								 | 
							
								func (v T) XZ() vec2.T {
							 | 
						||
| 
								 | 
							
									return vec2.T{X: v.X, Y: v.Z}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// YZ returns a 2-component vector with the Y, Z components of this vector
							 | 
						||
| 
								 | 
							
								func (v T) YZ() vec2.T {
							 | 
						||
| 
								 | 
							
									return vec2.T{X: v.Y, Y: v.Z}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Div divides each element of the vector with the corresponding element of another vector
							 | 
						||
| 
								 | 
							
								func (v T) Div(v2 T) T {
							 | 
						||
| 
								 | 
							
									return T{v.X / v2.X, v.Y / v2.Y, v.Z / v2.Z}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// WithX returns a new vector with the X component set to a given value
							 | 
						||
| 
								 | 
							
								func (v T) WithX(x float32) T {
							 | 
						||
| 
								 | 
							
									return T{x, v.Y, v.Z}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// WithY returns a new vector with the Y component set to a given value
							 | 
						||
| 
								 | 
							
								func (v T) WithY(y float32) T {
							 | 
						||
| 
								 | 
							
									return T{v.X, y, v.Z}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// WithZ returns a new vector with the Z component set to a given value
							 | 
						||
| 
								 | 
							
								func (v T) WithZ(z float32) T {
							 | 
						||
| 
								 | 
							
									return T{v.X, v.Y, z}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (v T) ApproxEqual(v2 T) bool {
							 | 
						||
| 
								 | 
							
									epsilon := float32(0.0001)
							 | 
						||
| 
								 | 
							
									return Distance(v, v2) < epsilon
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (v T) String() string {
							 | 
						||
| 
								 | 
							
									return fmt.Sprintf("%.3f,%.3f,%.3f", v.X, v.Y, v.Z)
							 | 
						||
| 
								 | 
							
								}
							 |