aboutsummaryrefslogtreecommitdiff
path: root/tool_src/BspLib/Transform3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tool_src/BspLib/Transform3.cpp')
-rw-r--r--tool_src/BspLib/Transform3.cpp312
1 files changed, 312 insertions, 0 deletions
diff --git a/tool_src/BspLib/Transform3.cpp b/tool_src/BspLib/Transform3.cpp
new file mode 100644
index 0000000..7f8b54d
--- /dev/null
+++ b/tool_src/BspLib/Transform3.cpp
@@ -0,0 +1,312 @@
+//-----------------------------------------------------------------------------
+// BSPLIB MODULE: Transform3.cpp
+//
+// Copyright (c) 1997-1998 by Markus Hadwiger
+// All Rights Reserved.
+//-----------------------------------------------------------------------------
+
+// bsplib headers
+#include "Transform3.h"
+
+
+BSPLIB_NAMESPACE_BEGIN
+
+
+// multiply two 4x4 matrices --------------------------------------------------
+//
+PRIVATE
+void mat4x4_mul( double dest_matrix[][4], const double matrix1[][4], const double matrix2[][4] )
+{
+ //NOTE:
+ // full homogeneous multiplication is performed. (that is, all 16
+ // elements are calculated.) normally this isn't necessary as
+ // most matrices are affine. but since this is no real-time
+ // application more flexibility seems better.
+/*
+ for ( int i = 0; i < 4; i++ ) {
+ for ( int j = 0; j < 4; j++ ) {
+ dest_matrix[ i ][ j ] = 0.0;
+ for ( int k = 0; k < 4; k++ )
+ dest_matrix[ i ][ j ] += matrix1[ i ][ k ] * matrix2[ k ][ j ];
+ }
+ }
+*/
+ dest_matrix[ 0 ][ 0 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 0 ][ 1 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 0 ][ 2 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 0 ][ 3 ] = matrix1[ 0 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 0 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 0 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 0 ][ 3 ] * matrix2[ 3 ][ 3 ];
+
+ dest_matrix[ 1 ][ 0 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 1 ][ 1 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 1 ][ 2 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 1 ][ 3 ] = matrix1[ 1 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 1 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 1 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 1 ][ 3 ] * matrix2[ 3 ][ 3 ];
+
+ dest_matrix[ 2 ][ 0 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 2 ][ 1 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 2 ][ 2 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 2 ][ 3 ] = matrix1[ 2 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 2 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 2 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 2 ][ 3 ] * matrix2[ 3 ][ 3 ];
+
+ dest_matrix[ 3 ][ 0 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 0 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 0 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 0 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 0 ];
+ dest_matrix[ 3 ][ 1 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 1 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 1 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 1 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 1 ];
+ dest_matrix[ 3 ][ 2 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 2 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 2 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 2 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 2 ];
+ dest_matrix[ 3 ][ 3 ] = matrix1[ 3 ][ 0 ] * matrix2[ 0 ][ 3 ] +
+ matrix1[ 3 ][ 1 ] * matrix2[ 1 ][ 3 ] +
+ matrix1[ 3 ][ 2 ] * matrix2[ 2 ][ 3 ] +
+ matrix1[ 3 ][ 3 ] * matrix2[ 3 ][ 3 ];
+}
+
+
+// calculate concatenation; don't overwrite object matrix ---------------------
+//
+Transform3 operator *( const Transform3& trafo1, const Transform3& trafo2 )
+{
+ Transform3 temp;
+ mat4x4_mul( temp.m_matrix, trafo1.m_matrix, trafo2.m_matrix );
+ return temp;
+}
+
+
+// calculate concatenation as new object matrix -------------------------------
+//
+Transform3& Transform3::Concat( const Transform3& cattrafo )
+{
+ Transform3 temp;
+ mat4x4_mul( temp.m_matrix, (const double(*)[4]) m_matrix, cattrafo.m_matrix );
+ memcpy( m_matrix, temp.m_matrix, sizeof( m_matrix ) );
+ return *this;
+}
+
+
+// reversed concatenation -----------------------------------------------------
+//
+Transform3& Transform3::ConcatR( const Transform3& cattrafo )
+{
+ Transform3 temp;
+ mat4x4_mul( temp.m_matrix, cattrafo.m_matrix, (const double(*)[4]) m_matrix );
+ memcpy( m_matrix, temp.m_matrix, sizeof( m_matrix ) );
+ return *this;
+}
+
+
+// transform Vector3 by matrix (homogeneous component is also evaluated!) -----
+//
+Vector3 Transform3::TransformVector3( const Vector3& vec ) const
+{
+ Vector3 temp;
+ temp.setX( m_matrix[ 0 ][ 0 ] * vec.getX() + m_matrix[ 1 ][ 0 ] * vec.getY() + m_matrix[ 2 ][ 0 ] * vec.getZ() + m_matrix[ 3 ][ 0 ] * vec.getW() );
+ temp.setY( m_matrix[ 0 ][ 1 ] * vec.getX() + m_matrix[ 1 ][ 1 ] * vec.getY() + m_matrix[ 2 ][ 1 ] * vec.getZ() + m_matrix[ 3 ][ 1 ] * vec.getW() );
+ temp.setZ( m_matrix[ 0 ][ 2 ] * vec.getX() + m_matrix[ 1 ][ 2 ] * vec.getY() + m_matrix[ 2 ][ 2 ] * vec.getZ() + m_matrix[ 3 ][ 2 ] * vec.getW() );
+ temp.setW( m_matrix[ 0 ][ 3 ] * vec.getX() + m_matrix[ 1 ][ 3 ] * vec.getY() + m_matrix[ 2 ][ 3 ] * vec.getZ() + m_matrix[ 3 ][ 3 ] * vec.getW() );
+ return temp;
+}
+
+
+// fetch translation part of matrix -------------------------------------------
+//
+Vector3 Transform3::FetchTranslation() const
+{
+ // return translation vector
+ return Vector3( m_matrix[ 3 ][ 0 ], m_matrix[ 3 ][ 1 ], m_matrix[ 3 ][ 2 ] );
+}
+
+
+// extract translation part of matrix; set to NULL translation afterwards -----
+//
+Vector3 Transform3::ExtractTranslation()
+{
+ // create translation vector
+ Vector3 temp( m_matrix[ 3 ][ 0 ], m_matrix[ 3 ][ 1 ], m_matrix[ 3 ][ 2 ] );
+ // zero translation part of matrix
+ m_matrix[ 3 ][ 0 ] = 0.0;
+ m_matrix[ 3 ][ 1 ] = 0.0;
+ m_matrix[ 3 ][ 2 ] = 0.0;
+ return temp;
+}
+
+
+// create rotation matrix -----------------------------------------------------
+//
+Transform3& Transform3::LoadRotation( double angle, double x, double y, double z )
+{
+ // init matrix
+ LoadIdentity();
+
+ // normalize axis of rotation
+ Vector3 axis( x, y, z );
+ if ( !axis.Normalize() ) {
+ // NULL vector: return identity matrix
+ return *this;
+ }
+
+ // calculate unit quaternion corresponding to rotation
+ double phi2 = -angle / 2;
+ double sinphi2 = sin( phi2 );
+ double W = cos( phi2 );
+ double X = sinphi2 * axis.getX();
+ double Y = sinphi2 * axis.getY();
+ double Z = sinphi2 * axis.getZ();
+
+ // calculate intermediate terms
+ double X2 = X * X;
+ double Y2 = Y * Y;
+ double Z2 = Z * Z;
+ double XY = X * Y;
+ double XZ = X * Z;
+ double YZ = Y * Z;
+ double WX = W * X;
+ double WY = W * Y;
+ double WZ = W * Z;
+
+ // convert quaternion into rotation matrix
+ m_matrix[ 0 ][ 0 ] = 1 - ( Y2 + Z2 ) * 2;
+ m_matrix[ 0 ][ 1 ] = ( XY - WZ ) * 2;
+ m_matrix[ 0 ][ 2 ] = ( XZ + WY ) * 2;
+ m_matrix[ 1 ][ 0 ] = ( XY + WZ ) * 2;
+ m_matrix[ 1 ][ 1 ] = 1 - ( X2 + Z2 ) * 2;
+ m_matrix[ 1 ][ 2 ] = ( YZ - WX ) * 2;
+ m_matrix[ 2 ][ 0 ] = ( XZ - WY ) * 2;
+ m_matrix[ 2 ][ 1 ] = ( YZ + WX ) * 2;
+ m_matrix[ 2 ][ 2 ] = 1 - ( X2 + Y2 ) * 2;
+
+ return *this;
+}
+
+
+// create scale matrix --------------------------------------------------------
+//
+Transform3& Transform3::LoadScale( double x, double y, double z )
+{
+ LoadIdentity();
+ m_matrix[ 0 ][ 0 ] = x;
+ m_matrix[ 1 ][ 1 ] = y;
+ m_matrix[ 2 ][ 2 ] = z;
+ return *this;
+}
+
+
+// create translation matrix --------------------------------------------------
+//
+Transform3& Transform3::LoadTranslation( double x, double y, double z )
+{
+ LoadIdentity();
+ m_matrix[ 3 ][ 0 ] = x;
+ m_matrix[ 3 ][ 1 ] = y;
+ m_matrix[ 3 ][ 2 ] = z;
+ return *this;
+}
+
+
+// rotate around arbitrary axis -----------------------------------------------
+//
+Transform3& Transform3::Rotate( double angle, double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadRotation( angle, x, y, z );
+ Concat( temp );
+ return *this;
+}
+
+
+// rotate around arbitrary axis (reversed) ------------------------------------
+//
+Transform3& Transform3::RotateR( double angle, double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadRotation( angle, x, y, z );
+ ConcatR( temp );
+ return *this;
+}
+
+
+// apply scale factors --------------------------------------------------------
+//
+Transform3& Transform3::Scale( double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadScale( x, y, z );
+ Concat( temp );
+ return *this;
+}
+
+
+// apply scale factors (reversed) ---------------------------------------------
+//
+Transform3& Transform3::ScaleR( double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadScale( x, y, z );
+ ConcatR( temp );
+ return *this;
+}
+
+
+// apply translation ----------------------------------------------------------
+//
+Transform3& Transform3::Translate( double x, double y, double z )
+{
+ m_matrix[ 3 ][ 0 ] += x;
+ m_matrix[ 3 ][ 1 ] += y;
+ m_matrix[ 3 ][ 2 ] += z;
+ return *this;
+}
+
+
+// apply translation (reversed) -----------------------------------------------
+//
+Transform3& Transform3::TranslateR( double x, double y, double z )
+{
+ Transform3 temp;
+ temp.LoadTranslation( x, y, z );
+ ConcatR( temp );
+ return *this;
+}
+
+
+BSPLIB_NAMESPACE_END
+
+//-----------------------------------------------------------------------------