|
|
//==== Copyright (c) 1996-2011, Valve Corporation, All rights reserved. =====//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#if !defined(_STATIC_LINKED) || defined(_SHARED_LIB)
#include "mathlib/transform.h"
#include "mathlib/mathlib.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
const CTransform g_TransformIdentity( Vector( 0.0f, 0.0f, 0.0f ), Quaternion( 0.0f, 0.0f, 0.0f, 1.0f ) );
void SetIdentityTransform( CTransform &out ) { out.m_vPosition = vec3_origin; out.m_orientation = quat_identity; }
void ConcatTransforms( const CTransform &in1, const CTransform &in2, CTransform &out ) { // Store in temp to avoid problems if out == in1 or out == in2
CTransform result; QuaternionMult( in1.m_orientation, in2.m_orientation, result.m_orientation ); QuaternionMultiply( in1.m_orientation, in2.m_vPosition, result.m_vPosition ); result.m_vPosition += in1.m_vPosition; out = result; }
void VectorIRotate( const Vector &v, const CTransform &t, Vector &out ) { // FIXME: Make work directly with the transform
matrix3x4_t m; TransformMatrix( t, m ); VectorIRotate( v, m, out ); }
void VectorITransform( const Vector &v, const CTransform &t, Vector &out ) { // FIXME: Make work directly with the transform
matrix3x4_t m; TransformMatrix( t, m ); VectorITransform( v, m, out ); }
void TransformSlerp( const CTransform &p, const CTransform &q, float t, CTransform &qt ) { QuaternionSlerp( p.m_orientation, q.m_orientation, t, qt.m_orientation ); VectorLerp( p.m_vPosition, q.m_vPosition, t, qt.m_vPosition ); }
void TransformLerp( const CTransform &p, const CTransform &q, float t, CTransform &qt ) { QuaternionBlend( p.m_orientation, q.m_orientation, t, qt.m_orientation ); VectorLerp( p.m_vPosition, q.m_vPosition, t, qt.m_vPosition ); }
void TransformMatrix( const CTransform &in, matrix3x4_t &out ) { QuaternionMatrix( in.m_orientation, in.m_vPosition, out ); }
void TransformMatrix( const CTransformUnaligned &in, matrix3x4_t &out ) { QuaternionMatrix( in.m_orientation, in.m_vPosition, out ); }
void TransformMatrix( const CTransform &in, const Vector &vScaleIn, matrix3x4_t &out ) { QuaternionMatrix( in.m_orientation, in.m_vPosition, vScaleIn, out ); }
void MatrixTransform( const matrix3x4_t &in, CTransformUnaligned &out ) { MatrixQuaternion( in, out.m_orientation ); MatrixGetColumn( in, ORIGIN, out.m_vPosition ); }
void MatrixTransform( const matrix3x4_t &in, CTransform &out ) { MatrixQuaternion( in, out.m_orientation ); MatrixGetColumn( in, ORIGIN, out.m_vPosition ); }
void MatrixTransform( const matrix3x4_t &in, CTransform &out, Vector &vScaleOut ) { matrix3x4_t norm; vScaleOut = MatrixNormalize( in, norm ); MatrixTransform( norm, out ); }
void AngleTransform( const QAngle &angles, const Vector &origin, CTransform &out ) { AngleQuaternion( angles, out.m_orientation ); out.m_vPosition = origin; }
void TransformInvert( const CTransform &in, CTransform &out ) { QuaternionInvert( in.m_orientation, out.m_orientation ); QuaternionMultiply( out.m_orientation, in.m_vPosition, out.m_vPosition ); out.m_vPosition *= -1.0f; }
void AxisAngleTransform( const Vector &vecAxis, float flAngleDegrees, CTransform &out ) { AxisAngleQuaternion( vecAxis, flAngleDegrees, out.m_orientation ); out.m_vPosition = vec3_origin; }
void TransformVectorsFLU( const CTransform &in, Vector* pForward, Vector *pLeft, Vector *pUp ) { QuaternionVectorsFLU( in.m_orientation, pForward, pLeft, pUp ); }
void TransformVectorsForward( const CTransform &in, Vector* pForward ) { QuaternionVectorsForward( in.m_orientation, pForward ); }
bool TransformsAreEqual( const CTransform &src1, const CTransform &src2, float flPosTolerance, float flRotTolerance ) { if ( !VectorsAreEqual( src1.m_vPosition, src2.m_vPosition, flPosTolerance ) ) return false; return QuaternionsAreEqual( src1.m_orientation, src2.m_orientation, flRotTolerance ); }
// FIXME: optimize this with simd goodness
void TransformToWorldSpace( int nRootTransformCount, int nTransformCount, const int *pParentIndices, CTransform *pTransforms ) { #ifdef _DEBUG
for ( int i = 0; i < nRootTransformCount; ++i ) { Assert( pParentIndices[i] < 0 ); } #endif
for ( int i = nRootTransformCount; i < nTransformCount; ++i ) { int nParentBone = pParentIndices[i]; Assert( nParentBone >= 0 && nParentBone < i ); ConcatTransforms( pTransforms[ nParentBone ], pTransforms[ i ], pTransforms[ i ] ); } }
// FIXME: optimize this with simd goodness
void TransformToParentSpace( int nRootTransformCount, int nTransformCount, const int *pParentIndices, CTransform *pTransforms ) { #ifdef _DEBUG
for ( int i = 0; i < nRootTransformCount; ++i ) { Assert( pParentIndices[i] < 0 ); } #endif
bool *pComputedParentTransform = (bool*)stackalloc( nTransformCount * sizeof(bool) ); memset( pComputedParentTransform, 0, nTransformCount * sizeof(bool) ); CTransform *pWorldToParentTransforms = (CTransform*)stackalloc( nTransformCount * sizeof(CTransform) );
for ( int b = nTransformCount; --b >= nRootTransformCount; ) { int nParentBone = pParentIndices[ b ]; if ( !pComputedParentTransform[ nParentBone ] ) { TransformInvert( pTransforms[ nParentBone ], pWorldToParentTransforms[ nParentBone ] ); pComputedParentTransform[ nParentBone ] = true; } ConcatTransforms( pWorldToParentTransforms[ nParentBone ], pTransforms[ b ], pTransforms[ b ] ); } }
#endif // !_STATIC_LINKED || _SHARED_LIB
|