Selaa lähdekoodia

quaternion changed to public components

leonsal 8 vuotta sitten
vanhempi
commit
25a7b81610
4 muutettua tiedostoa jossa 205 lisäystä ja 203 poistoa
  1. 4 4
      math32/matrix4.go
  2. 192 190
      math32/quaternion.go
  3. 4 4
      math32/vector3.go
  4. 5 5
      math32/vector4.go

+ 4 - 4
math32/matrix4.go

@@ -164,10 +164,10 @@ func (m *Matrix4) MakeRotationFromEuler(euler *Vector3) *Matrix4 {
 // Returns pointer to this updated matrix.
 func (m *Matrix4) MakeRotationFromQuaternion(q *Quaternion) *Matrix4 {
 
-	x := q.x
-	y := q.y
-	z := q.z
-	w := q.w
+	x := q.X
+	y := q.Y
+	z := q.Z
+	w := q.W
 	x2 := x + x
 	y2 := y + y
 	z2 := z + z

+ 192 - 190
math32/quaternion.go

@@ -4,120 +4,98 @@
 
 package math32
 
+// Quaternion is quaternion with X,Y,Z and W components.
 type Quaternion struct {
-	x float32
-	y float32
-	z float32
-	w float32
+	X float32
+	Y float32
+	Z float32
+	W float32
 }
 
+// NewQuaternion creates and returns a pointer to a new quaternion
+// from the specified components.
 func NewQuaternion(x, y, z, w float32) *Quaternion {
 
 	return &Quaternion{
-		x: x, y: y, z: z, w: w,
+		X: x, Y: y, Z: z, W: w,
 	}
 }
 
-func (this *Quaternion) X() float32 {
+// SetX sets this quaternion's X component.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) SetX(val float32) *Quaternion {
 
-	return this.x
-}
-
-func (this *Quaternion) SetX(val float32) *Quaternion {
-
-	this.x = val
-	return this
-}
-
-func (this *Quaternion) Y() float32 {
-
-	return this.y
-}
-
-func (this *Quaternion) SetY(val float32) *Quaternion {
-
-	this.y = val
-	return this
-}
-
-func (this *Quaternion) Z() float32 {
-
-	return this.z
+	q.X = val
+	return q
 }
 
-func (this *Quaternion) SetZ(val float32) *Quaternion {
+// SetY sets this quaternion's Y component.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) SetY(val float32) *Quaternion {
 
-	this.z = val
-	return this
+	q.Y = val
+	return q
 }
 
-func (this *Quaternion) W() float32 {
+// SetZ sets this quaternion's Z component.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) SetZ(val float32) *Quaternion {
 
-	return this.w
+	q.Z = val
+	return q
 }
 
-func (this *Quaternion) SetW(val float32) *Quaternion {
+// SetW sets this quaternion's W component.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) SetW(val float32) *Quaternion {
 
-	this.w = val
-	return this
+	q.W = val
+	return q
 }
 
-func (this *Quaternion) Set(x, y, z, w float32) *Quaternion {
+// Set sets this quaternion's components.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) Set(x, y, z, w float32) *Quaternion {
 
-	this.x = x
-	this.y = y
-	this.z = z
-	this.w = w
-	return this
+	q.X = x
+	q.Y = y
+	q.Z = z
+	q.W = w
+	return q
 }
 
-func (this *Quaternion) SetIdentity() *Quaternion {
+// SetIdentity sets this quanternion to the identity quaternion.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) SetIdentity() *Quaternion {
 
-	this.x = 0
-	this.y = 0
-	this.z = 0
-	this.w = 1
-	return this
+	q.X = 0
+	q.Y = 0
+	q.Z = 0
+	q.W = 1
+	return q
 }
 
+// IsIdentity returns it this is an identity quaternion.
 func (q *Quaternion) IsIdentity() bool {
 
-	if q.x == 0 && q.y == 0 && q.z == 0 && q.w == 1 {
+	if q.X == 0 && q.Y == 0 && q.Z == 0 && q.W == 1 {
 		return true
 	}
 	return false
 }
 
-// Copy copies the specified quaternion into this one.
-func (this *Quaternion) Copy(quaternion *Quaternion) *Quaternion {
+// Copy copies the other quaternion into this one.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) Copy(other *Quaternion) *Quaternion {
 
-	*this = *quaternion
-	return this
+	*q = *other
+	return q
 }
 
-//func (this *Quaternion) SetFromEuler2(euler *Euler) *Quaternion {
-//
-//	c1 := Cos(euler.X / 2)
-//	c2 := Cos(euler.Y / 2)
-//	c3 := Cos(euler.Z / 2)
-//	s1 := Sin(euler.X / 2)
-//	s2 := Sin(euler.Y / 2)
-//	s3 := Sin(euler.Z / 2)
-//
-//	if euler.Order == XYZ {
-//		this.x = s1*c2*c3 + c1*s2*s3
-//		this.y = c1*s2*c3 - s1*c2*s3
-//		this.z = c1*c2*s3 + s1*s2*c3
-//		this.w = c1*c2*c3 - s1*s2*s3
-//	} else {
-//		panic("Unsupported Euler Order")
-//	}
-//	return this
-//}
-
 // SetFromEuler sets this quaternion from the specified vector with
 // euler angles for each axis. It is assumed that the Euler angles
 // are in XYZ order.
+// Returns pointer to this updated quaternion.
 func (q *Quaternion) SetFromEuler(euler *Vector3) *Quaternion {
 
 	c1 := Cos(euler.X / 2)
@@ -127,28 +105,31 @@ func (q *Quaternion) SetFromEuler(euler *Vector3) *Quaternion {
 	s2 := Sin(euler.Y / 2)
 	s3 := Sin(euler.Z / 2)
 
-	q.x = s1*c2*c3 - c1*s2*s3
-	q.y = c1*s2*c3 + s1*c2*s3
-	q.z = c1*c2*s3 - s1*s2*c3
-	q.w = c1*c2*c3 + s1*s2*s3
+	q.X = s1*c2*c3 - c1*s2*s3
+	q.Y = c1*s2*c3 + s1*c2*s3
+	q.Z = c1*c2*s3 - s1*s2*c3
+	q.W = c1*c2*c3 + s1*s2*s3
 
 	return q
 }
 
 // SetFromAxisAngle sets this quaternion with the rotation
 // specified by the given axis and angle.
+// Returns pointer to this updated quaternion.
 func (q *Quaternion) SetFromAxisAngle(axis *Vector3, angle float32) *Quaternion {
 
 	halfAngle := angle / 2
 	s := Sin(halfAngle)
-	q.x = axis.X * s
-	q.y = axis.Y * s
-	q.z = axis.Z * s
-	q.w = Cos(halfAngle)
+	q.X = axis.X * s
+	q.Y = axis.Y * s
+	q.Z = axis.Z * s
+	q.W = Cos(halfAngle)
 	return q
 }
 
-func (this *Quaternion) SetFromRotationMatrix(m *Matrix4) *Quaternion {
+// SetFromRotationMatrix sets this quaternion from the specified rotation matrix.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) SetFromRotationMatrix(m *Matrix4) *Quaternion {
 
 	m11 := m[0]
 	m12 := m[4]
@@ -164,33 +145,36 @@ func (this *Quaternion) SetFromRotationMatrix(m *Matrix4) *Quaternion {
 	var s float32
 	if trace > 0 {
 		s = 0.5 / Sqrt(trace+1.0)
-		this.w = 0.25 / s
-		this.x = (m32 - m23) * s
-		this.y = (m13 - m31) * s
-		this.z = (m21 - m12) * s
+		q.W = 0.25 / s
+		q.X = (m32 - m23) * s
+		q.Y = (m13 - m31) * s
+		q.Z = (m21 - m12) * s
 	} else if m11 > m22 && m11 > m33 {
 		s = 2.0 * Sqrt(1.0+m11-m22-m33)
-		this.w = (m32 - m23) / s
-		this.x = 0.25 * s
-		this.y = (m12 + m21) / s
-		this.z = (m13 + m31) / s
+		q.W = (m32 - m23) / s
+		q.X = 0.25 * s
+		q.Y = (m12 + m21) / s
+		q.Z = (m13 + m31) / s
 	} else if m22 > m33 {
 		s = 2.0 * Sqrt(1.0+m22-m11-m33)
-		this.w = (m13 - m31) / s
-		this.x = (m12 + m21) / s
-		this.y = 0.25 * s
-		this.z = (m23 + m32) / s
+		q.W = (m13 - m31) / s
+		q.X = (m12 + m21) / s
+		q.Y = 0.25 * s
+		q.Z = (m23 + m32) / s
 	} else {
 		s = 2.0 * Sqrt(1.0+m33-m11-m22)
-		this.w = (m21 - m12) / s
-		this.x = (m13 + m31) / s
-		this.y = (m23 + m32) / s
-		this.z = 0.25 * s
+		q.W = (m21 - m12) / s
+		q.X = (m13 + m31) / s
+		q.Y = (m23 + m32) / s
+		q.Z = 0.25 * s
 	}
-	return this
+	return q
 }
 
-func (this *Quaternion) SetFromUnitVectors(vFrom, vTo *Vector3) *Quaternion {
+// SetFromUnitVectors sets this quaternion to the rotation from vector vFrom to vTo.
+// The vectors must be normalized.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) SetFromUnitVectors(vFrom, vTo *Vector3) *Quaternion {
 
 	var v1 Vector3
 	var EPS float32 = 0.000001
@@ -210,132 +194,148 @@ func (this *Quaternion) SetFromUnitVectors(vFrom, vTo *Vector3) *Quaternion {
 		v1.CrossVectors(vFrom, vTo)
 
 	}
-	this.x = v1.X
-	this.y = v1.Y
-	this.z = v1.Z
-	this.w = r
+	q.X = v1.X
+	q.Y = v1.Y
+	q.Z = v1.Z
+	q.W = r
 
-	this.Normalize()
+	q.Normalize()
 
-	return this
+	return q
 }
 
+// Inverse sets this quaternion to its inverse.
+// Returns pointer to this updated quaternion.
 func (q *Quaternion) Inverse() *Quaternion {
 
 	q.Conjugate().Normalize()
 	return q
 }
 
-func (this *Quaternion) Conjugate() *Quaternion {
+// Conjugate sets this quaternion to its conjugate.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) Conjugate() *Quaternion {
 
-	this.x *= -1
-	this.y *= -1
-	this.z *= -1
-	return this
+	q.X *= -1
+	q.Y *= -1
+	q.Z *= -1
+	return q
 }
 
-func (this *Quaternion) Dot(v *Quaternion) float32 {
+// Dot returns the dot products of this quaternion with other.
+func (q *Quaternion) Dot(other *Quaternion) float32 {
 
-	return this.x*v.x + this.y*v.y + this.z*v.z + this.w*v.w
+	return q.X*other.X + q.Y*other.Y + q.Z*other.Z + q.W*other.W
 }
 
-func (this *Quaternion) lengthSq() float32 {
+// LengthSq returns this quanternion's lenght squared
+func (q *Quaternion) lengthSq() float32 {
 
-	return this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w
+	return q.X*q.X + q.Y*q.Y + q.Z*q.Z + q.W*q.W
 }
 
-func (this *Quaternion) Length() float32 {
+// Length returns the length of this quaternion
+func (q *Quaternion) Length() float32 {
 
-	return Sqrt(this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w)
+	return Sqrt(q.X*q.X + q.Y*q.Y + q.Z*q.Z + q.W*q.W)
 }
 
-func (this *Quaternion) Normalize() *Quaternion {
+// Normalize normalizes this quaternion.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) Normalize() *Quaternion {
 
-	l := this.Length()
+	l := q.Length()
 
 	if l == 0 {
 
-		this.x = 0
-		this.y = 0
-		this.z = 0
-		this.w = 1
+		q.X = 0
+		q.Y = 0
+		q.Z = 0
+		q.W = 1
 
 	} else {
 
 		l = 1 / l
 
-		this.x = this.x * l
-		this.y = this.y * l
-		this.z = this.z * l
-		this.w = this.w * l
+		q.X = q.X * l
+		q.Y = q.Y * l
+		q.Z = q.Z * l
+		q.W = q.W * l
 
 	}
-	return this
+	return q
 }
 
-func (this *Quaternion) Multiply(q *Quaternion) *Quaternion {
+// Multiply sets this quaternion to the multiplication of itself by other.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) Multiply(other *Quaternion) *Quaternion {
 
-	return this.MultiplyQuaternions(this, q)
+	return q.MultiplyQuaternions(q, other)
 }
 
-func (this *Quaternion) MultiplyQuaternions(a, b *Quaternion) *Quaternion {
+// MultiplyQuaternions set this quaternion to the multiplication of a by b.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) MultiplyQuaternions(a, b *Quaternion) *Quaternion {
 
 	// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
 
-	qax := a.x
-	qay := a.y
-	qaz := a.z
-	qaw := a.w
-	qbx := b.x
-	qby := b.y
-	qbz := b.z
-	qbw := b.w
-
-	this.x = qax*qbw + qaw*qbx + qay*qbz - qaz*qby
-	this.y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz
-	this.z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx
-	this.w = qaw*qbw - qax*qbx - qay*qby - qaz*qbz
-	return this
+	qax := a.X
+	qay := a.Y
+	qaz := a.Z
+	qaw := a.W
+	qbx := b.X
+	qby := b.Y
+	qbz := b.Z
+	qbw := b.W
+
+	q.X = qax*qbw + qaw*qbx + qay*qbz - qaz*qby
+	q.Y = qay*qbw + qaw*qby + qaz*qbx - qax*qbz
+	q.Z = qaz*qbw + qaw*qbz + qax*qby - qay*qbx
+	q.W = qaw*qbw - qax*qbx - qay*qby - qaz*qbz
+	return q
 }
 
-func (this *Quaternion) Slerp(qb *Quaternion, t float32) *Quaternion {
+// Slerp sets this quaternion to another quaternion which is the spherically linear interpolation
+// from this quaternion to other using t.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) Slerp(other *Quaternion, t float32) *Quaternion {
 
 	if t == 0 {
-		return this
+		return q
 	}
 	if t == 1 {
-		return this.Copy(qb)
+		return q.Copy(other)
 	}
 
-	x := this.x
-	y := this.y
-	z := this.z
-	w := this.w
+	x := q.X
+	y := q.Y
+	z := q.Z
+	w := q.W
 
-	cosHalfTheta := w*qb.w + x*qb.x + y*qb.y + z*qb.z
+	cosHalfTheta := w*other.W + x*other.X + y*other.Y + z*other.Z
 
 	if cosHalfTheta < 0 {
 
-		this.w = -qb.w
-		this.x = -qb.x
-		this.y = -qb.y
-		this.z = -qb.z
+		q.W = -other.W
+		q.X = -other.X
+		q.Y = -other.Y
+		q.Z = -other.Z
 
 		cosHalfTheta = -cosHalfTheta
 
 	} else {
 
-		this.Copy(qb)
+		q.Copy(other)
 	}
 
 	if cosHalfTheta >= 1.0 {
 
-		this.w = w
-		this.x = x
-		this.y = y
-		this.z = z
+		q.W = w
+		q.X = x
+		q.Y = y
+		q.Z = z
 
-		return this
+		return q
 
 	}
 
@@ -344,48 +344,50 @@ func (this *Quaternion) Slerp(qb *Quaternion, t float32) *Quaternion {
 
 	if Abs(sinHalfTheta) < 0.001 {
 
-		this.w = 0.5 * (w + this.w)
-		this.x = 0.5 * (x + this.x)
-		this.y = 0.5 * (y + this.y)
-		this.z = 0.5 * (z + this.z)
+		q.W = 0.5 * (w + q.W)
+		q.X = 0.5 * (x + q.X)
+		q.Y = 0.5 * (y + q.Y)
+		q.Z = 0.5 * (z + q.Z)
 
-		return this
+		return q
 	}
 
 	ratioA := Sin((1-t)*halfTheta) / sinHalfTheta
 	ratioB := Sin(t*halfTheta) / sinHalfTheta
 
-	this.w = (w*ratioA + this.w*ratioB)
-	this.x = (x*ratioA + this.x*ratioB)
-	this.y = (y*ratioA + this.y*ratioB)
-	this.z = (z*ratioA + this.z*ratioB)
+	q.W = (w*ratioA + q.W*ratioB)
+	q.X = (x*ratioA + q.X*ratioB)
+	q.Y = (y*ratioA + q.Y*ratioB)
+	q.Z = (z*ratioA + q.Z*ratioB)
 
-	return this
+	return q
 }
 
-func (this *Quaternion) Equals(quaternion *Quaternion) bool {
+// Equals returns if this quaternion is equal to other.
+func (q *Quaternion) Equals(other *Quaternion) bool {
 
-	return (quaternion.x == this.x) && (quaternion.y == this.y) && (quaternion.z == this.z) && (quaternion.w == this.w)
+	return (other.X == q.X) && (other.Y == q.Y) && (other.Z == q.Z) && (other.W == q.W)
 }
 
-func (this *Quaternion) FromArray(array []float32, offset int) *Quaternion {
+// FromArray sets this quaternion's components from array starting at offset.
+// Returns pointer to this updated quaternion.
+func (q *Quaternion) FromArray(array []float32, offset int) *Quaternion {
 
-	this.x = array[offset]
-	this.y = array[offset+1]
-	this.z = array[offset+2]
-	this.w = array[offset+3]
-	return this
+	q.X = array[offset]
+	q.Y = array[offset+1]
+	q.Z = array[offset+2]
+	q.W = array[offset+3]
+	return q
 }
 
-func (this *Quaternion) ToArray(array []float32, offset int) []float32 {
+// ToArray copies this quaternions's components to array starting at offset.
+// Returns pointer to this updated array.
+func (q *Quaternion) ToArray(array []float32, offset int) []float32 {
 
-	if array == nil {
-		array = make([]float32, 4)
-	}
-	array[offset] = this.x
-	array[offset+1] = this.y
-	array[offset+2] = this.z
-	array[offset+3] = this.w
+	array[offset] = q.X
+	array[offset+1] = q.Y
+	array[offset+2] = q.Z
+	array[offset+3] = q.W
 
 	return array
 }

+ 4 - 4
math32/vector3.go

@@ -482,10 +482,10 @@ func (v *Vector3) ApplyQuaternion(q *Quaternion) *Vector3 {
 	y := v.Y
 	z := v.Z
 
-	qx := q.x
-	qy := q.y
-	qz := q.z
-	qw := q.w
+	qx := q.X
+	qy := q.Y
+	qz := q.Z
+	qw := q.W
 
 	// calculate quat * vector
 	ix := qw*x + qy*z - qz*y

+ 5 - 5
math32/vector4.go

@@ -475,16 +475,16 @@ func (v *Vector4) ApplyMatrix4(m *Matrix4) *Vector4 {
 func (v *Vector4) SetAxisAngleFromQuaternion(q *Quaternion) *Vector4 {
 
 	// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
-	v.W = 2 * Acos(q.W())
-	s := Sqrt(1 - q.W()*q.W())
+	v.W = 2 * Acos(q.W)
+	s := Sqrt(1 - q.W*q.W)
 	if s < 0.0001 {
 		v.X = 1
 		v.Y = 0
 		v.Z = 0
 	} else {
-		v.X = q.X() / s
-		v.Y = q.Y() / s
-		v.Z = q.Z() / s
+		v.X = q.X / s
+		v.Y = q.Y / s
+		v.Z = q.Z / s
 	}
 	return v
 }