You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
5.4 KiB
178 lines
5.4 KiB
//==== 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
|
|
|