Browse Source

changed matrix*.GetInverse() to return error

leonsal 8 years ago
parent
commit
e8b4c7b0c3
5 changed files with 51 additions and 37 deletions
  1. 6 6
      camera/camera.go
  2. 24 9
      camera/perspective.go
  3. 11 14
      math32/matrix3.go
  4. 7 6
      math32/matrix4.go
  5. 3 2
      math32/plane.go

+ 6 - 6
camera/camera.go

@@ -15,9 +15,9 @@ type ICamera interface {
 	GetCamera() *Camera
 	ViewMatrix(*math32.Matrix4)
 	ProjMatrix(*math32.Matrix4)
-	Project(*math32.Vector3) *math32.Vector3
-	Unproject(*math32.Vector3) *math32.Vector3
-	SetRaycaster(rc *core.Raycaster, x, y float32)
+	Project(*math32.Vector3) (*math32.Vector3, error)
+	Unproject(*math32.Vector3) (*math32.Vector3, error)
+	SetRaycaster(rc *core.Raycaster, x, y float32) error
 }
 
 // Camera is the base camera which is normally embedded in other camera types
@@ -150,21 +150,21 @@ func (cam *Camera) updateQuaternion() {
 
 // Project satisfies the ICamera interface and must
 // be implemented for specific camera types.
-func (cam *Camera) Project(v *math32.Vector3) *math32.Vector3 {
+func (cam *Camera) Project(v *math32.Vector3) (*math32.Vector3, error) {
 
 	panic("Not implemented")
 }
 
 // Unproject satisfies the ICamera interface and must
 // be implemented for specific camera types.
-func (cam *Camera) Unproject(v *math32.Vector3) *math32.Vector3 {
+func (cam *Camera) Unproject(v *math32.Vector3) (*math32.Vector3, error) {
 
 	panic("Not implemented")
 }
 
 // SetRaycaster satisfies the ICamera interface and must
 // be implemented for specific camera types.
-func (cam *Camera) SetRaycaster(rc *core.Raycaster, x, y float32) {
+func (cam *Camera) SetRaycaster(rc *core.Raycaster, x, y float32) error {
 
 	panic("Not implemented")
 }

+ 24 - 9
camera/perspective.go

@@ -79,29 +79,39 @@ func (cam *Perspective) ProjMatrix(m *math32.Matrix4) {
 }
 
 // Project transforms the specified position from world coordinates to this camera projected coordinates.
-func (cam *Perspective) Project(v *math32.Vector3) *math32.Vector3 {
+func (cam *Perspective) Project(v *math32.Vector3) (*math32.Vector3, error) {
 
 	cam.updateProjMatrix()
 	var matrix math32.Matrix4
 	matrixWorld := cam.MatrixWorld()
-	matrix.MultiplyMatrices(&cam.projMatrix, matrix.GetInverse(&matrixWorld))
+	err := matrix.GetInverse(&matrixWorld)
+	if err != nil {
+		return nil, err
+	}
+	matrix.MultiplyMatrices(&cam.projMatrix, &matrix)
 	v.ApplyProjection(&matrix)
-	return v
+	return v, nil
 }
 
 // Unproject transforms the specified position from camera projected coordinates to world coordinates.
-func (cam *Perspective) Unproject(v *math32.Vector3) *math32.Vector3 {
+func (cam *Perspective) Unproject(v *math32.Vector3) (*math32.Vector3, error) {
 
 	// Get inverted camera view matrix
 	var viewMatrix math32.Matrix4
 	cam.ViewMatrix(&viewMatrix)
 	var invertedViewMatrix math32.Matrix4
-	invertedViewMatrix.GetInverse(&viewMatrix)
+	err := invertedViewMatrix.GetInverse(&viewMatrix)
+	if err != nil {
+		return nil, err
+	}
 
 	// Get inverted camera projection matrix
 	cam.updateProjMatrix()
 	var invertedProjMatrix math32.Matrix4
-	invertedProjMatrix.GetInverse(&cam.projMatrix)
+	err = invertedProjMatrix.GetInverse(&cam.projMatrix)
+	if err != nil {
+		return nil, err
+	}
 
 	// Multiply invertedViewMatrix by invertedProjMatrix
 	// to get transformation from camera projected coordinates to world coordinates
@@ -109,21 +119,26 @@ func (cam *Perspective) Unproject(v *math32.Vector3) *math32.Vector3 {
 	var matrix math32.Matrix4
 	matrix.MultiplyMatrices(&invertedViewMatrix, &invertedProjMatrix)
 	v.ApplyProjection(&matrix)
-	return v
+	return v, nil
 }
 
 // SetRaycaster sets the specified raycaster with this camera position in world coordinates
 // pointing to the direction defined by the specified coordinates unprojected using this camera.
-func (cam *Perspective) SetRaycaster(rc *core.Raycaster, sx, sy float32) {
+func (cam *Perspective) SetRaycaster(rc *core.Raycaster, sx, sy float32) error {
 
 	var origin, direction math32.Vector3
 	matrixWorld := cam.MatrixWorld()
 	origin.SetFromMatrixPosition(&matrixWorld)
 	direction.Set(sx, sy, 0.5)
-	cam.Unproject(&direction).Sub(&origin).Normalize()
+	unproj, err := cam.Unproject(&direction)
+	if err != nil {
+		return err
+	}
+	unproj.Sub(&origin).Normalize()
 	rc.Set(&origin, &direction)
 	// Updates the view matrix of the raycaster
 	cam.ViewMatrix(&rc.ViewMatrix)
+	return nil
 }
 
 // updateProjMatrix updates this camera projection matrix if necessary

+ 11 - 14
math32/matrix3.go

@@ -4,6 +4,8 @@
 
 package math32
 
+import "errors"
+
 // Matrix3 is 3x3 matrix organized internally as column matrix
 type Matrix3 [9]float32
 
@@ -99,11 +101,10 @@ func (m *Matrix3) Determinant() float32 {
 		m[2]*m[4]*m[6]
 }
 
-// GetInverse sets this matrix to the inverse of the src matrix and
-// returns pointer to this updated matrix.
-// If the src matrix cannot be inverted returns nil and
+// GetInverse sets this matrix to the inverse of the src matrix.
+// If the src matrix cannot be inverted returns error and
 // sets this matrix to the identity matrix.
-func (m *Matrix3) GetInverse(src *Matrix4) *Matrix3 {
+func (m *Matrix3) GetInverse(src *Matrix4) error {
 
 	m[0] = src[10]*src[5] - src[6]*src[9]
 	m[1] = -src[10]*src[1] + src[2]*src[9]
@@ -120,10 +121,10 @@ func (m *Matrix3) GetInverse(src *Matrix4) *Matrix3 {
 	// no inverse
 	if det == 0 {
 		m.Identity()
-		return nil
+		return errors.New("Cannot inverse matrix")
 	}
 	m.MultiplyScalar(1.0 / det)
-	return m
+	return nil
 }
 
 // Transpose transposes this matrix.
@@ -145,16 +146,12 @@ func (m *Matrix3) Transpose() *Matrix3 {
 
 // GetNormalMatrix set this matrix to the matrix to transform the normal vectors
 // from the src matrix to transform the vertices.
-// If the src matrix cannot be inverted, returns nil
-// otherwise returns pointer to this updated matrix.
-func (m *Matrix3) GetNormalMatrix(src *Matrix4) *Matrix3 {
+// If the src matrix cannot be inverted returns error.
+func (m *Matrix3) GetNormalMatrix(src *Matrix4) error {
 
-	inv := m.GetInverse(src)
+	err := m.GetInverse(src)
 	m.Transpose()
-	if inv == nil {
-		return nil
-	}
-	return m
+	return err
 }
 
 // FromArray set this matrix array starting at offset.

+ 7 - 6
math32/matrix4.go

@@ -4,6 +4,8 @@
 
 package math32
 
+import "errors"
+
 // Matrix4 is 4x4 matrix organized internally as column matrix.
 type Matrix4 [16]float32
 
@@ -413,11 +415,10 @@ func (m *Matrix4) SetPosition(v *Vector3) *Matrix4 {
 	return m
 }
 
-// GetInverse sets this matrix to the inverse of the src matrix and
-// returns pointer to this updated matrix.
-// If the src matrix cannot be inverted returns nil and
+// GetInverse sets this matrix to the inverse of the src matrix.
+// If the src matrix cannot be inverted returns error and
 // sets this matrix to the identity matrix.
-func (m *Matrix4) GetInverse(src *Matrix4) *Matrix4 {
+func (m *Matrix4) GetInverse(src *Matrix4) error {
 
 	n11 := src[0]
 	n12 := src[4]
@@ -457,10 +458,10 @@ func (m *Matrix4) GetInverse(src *Matrix4) *Matrix4 {
 
 	if det == 0 {
 		m.Identity()
-		return nil
+		return errors.New("Cannot inverse matrix")
 	}
 	m.MultiplyScalar(1.0 / det)
-	return m
+	return nil
 }
 
 // Scale multiply the first column of this matrix by the vector X component,

+ 3 - 2
math32/plane.go

@@ -164,10 +164,11 @@ func (this *Plane) ApplyMatrix4(matrix *Matrix4, optionalNormalMatrix *Matrix3)
 	if optionalNormalMatrix != nil {
 		normalMatrix = optionalNormalMatrix
 	} else {
-		normalMatrix = m1.GetNormalMatrix(matrix)
-		if normalMatrix == nil {
+		err := m1.GetNormalMatrix(matrix)
+		if err != nil {
 			return nil
 		}
+		normalMatrix = m1
 	}
 
 	newNormal := v1.Copy(&this.normal).ApplyMatrix3(normalMatrix)