352 lines
20 KiB
C++
352 lines
20 KiB
C++
//========= Copyright © Valve Corporation, All rights reserved. ============//
|
|
#include "mathlib/femodeldesc.h"
|
|
#include "mathlib/femodel.h"
|
|
#include "tier1/heapsort.h"
|
|
#include "tier1/fmtstr.h"
|
|
|
|
template < typename T >
|
|
inline CLockedResource< T > CloneArrayWithMarkers( CResourceStream *pStream, const T *pArray, uint nCount, const char *pName )
|
|
{
|
|
// create the marker for the start of the array
|
|
CFmtStr beginMsg( "Begin of %s, %d byte aligned, here: <", pName, VALIGNOF( T ) );
|
|
// align the marker so that it ends aligned, right before the array data
|
|
int nBeginMsgLength = beginMsg.Length( );
|
|
int nPreAlign = ( -int( pStream->GetTotalSize() + nBeginMsgLength ) ) & ( VALIGNOF( T ) - 1 );
|
|
V_memset( pStream->AllocateBytes( nPreAlign ), '-', nPreAlign );
|
|
void *pPrefixData = pStream->AllocateBytes( nBeginMsgLength );
|
|
Assert( !( ( uintp( pPrefixData ) + nBeginMsgLength ) & ( VALIGNOF( T ) - 1 ) ) );
|
|
V_memcpy( pPrefixData, beginMsg.Get(), nBeginMsgLength );
|
|
// write out the array
|
|
CLockedResource< T > result = CloneArray( pStream, pArray, nCount );
|
|
// add the end marker
|
|
pStream->WriteString( CFmtStr( "> End of %s, %d bytes total.", pName, nCount * sizeof( T ) ) );
|
|
return result;
|
|
}
|
|
|
|
#if 0//def _DEBUG
|
|
#define CloneArray( STREAM, ARRAY, COUNT ) CloneArrayWithMarkers( (STREAM), (ARRAY), (COUNT), #ARRAY );
|
|
#endif
|
|
|
|
|
|
|
|
CLockedResource< PhysFeModelDesc_t > Clone( CFeModel *pFeModel, CResourceStream *pStream )
|
|
{
|
|
CLockedResource< PhysFeModelDesc_t > pFx = pStream->Allocate< PhysFeModelDesc_t >( );
|
|
uint nDynamicNodes = pFeModel->m_nNodeCount - pFeModel->m_nStaticNodes;
|
|
|
|
pFx->m_flLocalForce = pFeModel->m_flLocalForce;
|
|
pFx->m_flLocalRotation = pFeModel->m_flLocalRotation;
|
|
|
|
pFx->m_nStaticNodeFlags = pFeModel->m_nStaticNodeFlags;
|
|
pFx->m_nDynamicNodeFlags = pFeModel->m_nDynamicNodeFlags;
|
|
pFx->m_nNodeCount = pFeModel->m_nNodeCount;
|
|
pFx->m_nStaticNodes = pFeModel->m_nStaticNodes;
|
|
pFx->m_nRotLockStaticNodes = pFeModel->m_nRotLockStaticNodes;
|
|
pFx->m_nSimdTriCount1 = pFeModel->m_nSimdTriCount[ 1 ];
|
|
pFx->m_nSimdTriCount2 = pFeModel->m_nSimdTriCount[ 2 ];
|
|
pFx->m_nSimdQuadCount1 = pFeModel->m_nSimdQuadCount[ 1 ];
|
|
pFx->m_nSimdQuadCount2 = pFeModel->m_nSimdQuadCount[ 2 ];
|
|
pFx->m_nQuadCount1 = pFeModel->m_nQuadCount[ 1 ];
|
|
pFx->m_nQuadCount2 = pFeModel->m_nQuadCount[ 2 ];
|
|
pFx->m_nFitMatrixCount1 = pFeModel->m_nFitMatrixCount[ 1 ];
|
|
pFx->m_nFitMatrixCount2 = pFeModel->m_nFitMatrixCount[ 2 ];
|
|
pFx->m_nSimdFitMatrixCount1 = pFeModel->m_nSimdFitMatrixCount[ 1 ];
|
|
pFx->m_nSimdFitMatrixCount2 = pFeModel->m_nSimdFitMatrixCount[ 2 ];
|
|
pFx->m_nRopeCount = pFeModel->m_nRopeCount;
|
|
pFx->m_nTreeDepth = pFeModel->m_nTreeDepth;
|
|
pFx->m_flDefaultSurfaceStretch = pFeModel->m_flDefaultSurfaceStretch;
|
|
pFx->m_flDefaultThreadStretch = pFeModel->m_flDefaultThreadStretch;
|
|
|
|
pFx->m_flDefaultGravityScale = pFeModel->m_flDefaultGravityScale;
|
|
pFx->m_flDefaultVelAirDrag = pFeModel->m_flDefaultVelAirDrag;
|
|
pFx->m_flDefaultExpAirDrag = pFeModel->m_flDefaultExpAirDrag;
|
|
pFx->m_flDefaultVelQuadAirDrag = pFeModel->m_flDefaultVelQuadAirDrag;
|
|
pFx->m_flDefaultExpQuadAirDrag = pFeModel->m_flDefaultExpQuadAirDrag;
|
|
pFx->m_flDefaultVelRodAirDrag = pFeModel->m_flDefaultVelRodAirDrag;
|
|
pFx->m_flDefaultExpRodAirDrag = pFeModel->m_flDefaultExpRodAirDrag;
|
|
pFx->m_flQuadVelocitySmoothRate = pFeModel->m_flQuadVelocitySmoothRate;
|
|
pFx->m_flRodVelocitySmoothRate = pFeModel->m_flRodVelocitySmoothRate;
|
|
pFx->m_flAddWorldCollisionRadius = pFeModel->m_flAddWorldCollisionRadius;
|
|
pFx->m_nQuadVelocitySmoothIterations = pFeModel->m_nQuadVelocitySmoothIterations;
|
|
pFx->m_nRodVelocitySmoothIterations = pFeModel->m_nRodVelocitySmoothIterations;
|
|
pFx->m_flDefaultVolumetricSolveAmount = pFeModel->m_flDefaultVolumetricSolveAmount;
|
|
pFx->m_flWindage = pFeModel->m_flWindage;
|
|
pFx->m_flWindDrag = pFeModel->m_flWindDrag;
|
|
|
|
pFx->m_SimdQuads = CloneArray( pStream, pFeModel->m_pSimdQuads, pFeModel->m_nSimdQuadCount[ 0 ] );
|
|
pFx->m_SimdTris = CloneArray( pStream, pFeModel->m_pSimdTris, pFeModel->m_nSimdTriCount[ 0 ] );
|
|
pFx->m_SimdRods = CloneArray( pStream, pFeModel->m_pSimdRods, pFeModel->m_nSimdRodCount );
|
|
pFx->m_SimdNodeBases = CloneArray( pStream, pFeModel->m_pSimdNodeBases, pFeModel->m_nSimdNodeBaseCount );
|
|
pFx->m_SimdFitMatrices = CloneArray( pStream, pFeModel->m_pSimdFitMatrices, pFeModel->m_nSimdFitMatrixCount[ 0 ] );
|
|
pFx->m_FitMatrices = CloneArray( pStream, pFeModel->m_pFitMatrices, pFeModel->m_nFitMatrixCount[ 0 ] );
|
|
pFx->m_Quads = CloneArray( pStream, pFeModel->m_pQuads, pFeModel->m_nQuadCount[ 0 ] );
|
|
pFx->m_CtrlOffsets = CloneArray( pStream, pFeModel->m_pCtrlOffsets, pFeModel->m_nCtrlOffsets );
|
|
pFx->m_CtrlOsOffsets = CloneArray( pStream, pFeModel->m_pCtrlOsOffsets, pFeModel->m_nCtrlOsOffsets );
|
|
pFx->m_Rods = CloneArray( pStream, pFeModel->m_pRods, pFeModel->m_nRodCount );
|
|
pFx->m_AxialEdges = CloneArray( pStream, pFeModel->m_pAxialEdges, pFeModel->m_nAxialEdgeCount );
|
|
pFx->m_Ropes = CloneArray( pStream, pFeModel->m_pRopes, pFeModel->m_nRopeIndexCount );
|
|
pFx->m_NodeBases = CloneArray( pStream, pFeModel->m_pNodeBases, pFeModel->m_nNodeBaseCount );
|
|
pFx->m_SpringIntegrator = CloneArray( pStream, pFeModel->m_pSpringIntegrator, pFeModel->m_nSpringIntegratorCount );
|
|
pFx->m_SimdSpringIntegrator = CloneArray( pStream, pFeModel->m_pSimdSpringIntegrator, pFeModel->m_nSimdSpringIntegratorCount );
|
|
pFx->m_InitPose = CloneArray( pStream, pFeModel->m_pInitPose, pFeModel->m_nCtrlCount );
|
|
pFx->m_FollowNodes = CloneArray( pStream, pFeModel->m_pFollowNodes, pFeModel->m_nFollowNodeCount );
|
|
pFx->m_CollisionSpheres = CloneArray( pStream, pFeModel->m_pCollisionSpheres, pFeModel->m_nCollisionSpheres[ 0 ] );
|
|
pFx->m_CollisionPlanes = CloneArray( pStream, pFeModel->m_pCollisionPlanes, pFeModel->m_nCollisionPlanes );
|
|
pFx->m_NodeCollisionRadii = CloneArray( pStream, pFeModel->m_pNodeCollisionRadii, nDynamicNodes );
|
|
pFx->m_LocalRotation = CloneArray( pStream, pFeModel->m_pLocalRotation, nDynamicNodes );
|
|
pFx->m_LocalForce = CloneArray( pStream, pFeModel->m_pLocalForce, nDynamicNodes );
|
|
pFx->m_FitWeights = CloneArray( pStream, pFeModel->m_pFitWeights, pFeModel->m_nFitWeightCount );
|
|
pFx->m_nCollisionSphereInclusiveCount = pFeModel->m_nCollisionSpheres[ 1 ];
|
|
pFx->m_WorldCollisionParams = CloneArray( pStream, pFeModel->m_pWorldCollisionParams, pFeModel->m_nWorldCollisionParamCount );
|
|
pFx->m_TaperedCapsuleStretches = CloneArray( pStream, pFeModel->m_pTaperedCapsuleStretches, pFeModel->m_nTaperedCapsuleStretchCount );
|
|
pFx->m_TaperedCapsuleRigids = CloneArray( pStream, pFeModel->m_pTaperedCapsuleRigids, pFeModel->m_nTaperedCapsuleRigidCount );
|
|
pFx->m_SphereRigids = CloneArray( pStream, pFeModel->m_pSphereRigids, pFeModel->m_nSphereRigidCount );
|
|
pFx->m_TreeChildren = CloneArray( pStream, pFeModel->m_pTreeChildren, nDynamicNodes - 1 );
|
|
pFx->m_TreeParents = CloneArray( pStream, pFeModel->m_pTreeParents, nDynamicNodes + nDynamicNodes - 1 );
|
|
pFx->m_TreeCollisionMasks = CloneArray( pStream, pFeModel->m_pTreeCollisionMasks, nDynamicNodes + nDynamicNodes - 1 );
|
|
pFx->m_WorldCollisionNodes = CloneArray( pStream, pFeModel->m_pWorldCollisionNodes, pFeModel->m_nWorldCollisionNodeCount );
|
|
pFx->m_FreeNodes = CloneArray( pStream, pFeModel->m_pFreeNodes, pFeModel->m_nFreeNodeCount );
|
|
pFx->m_ReverseOffsets = CloneArray( pStream, pFeModel->m_pReverseOffsets, pFeModel->m_nReverseOffsetCount );
|
|
|
|
if ( pFeModel->m_pLegacyStretchForce )
|
|
{
|
|
pFx->m_LegacyStretchForce = CloneArray( pStream, pFeModel->m_pLegacyStretchForce, pFeModel->m_nNodeCount );
|
|
}
|
|
if ( pFeModel->m_pNodeIntegrator )
|
|
{
|
|
pFx->m_NodeIntegrator = CloneArray( pStream, pFeModel->m_pNodeIntegrator, pFeModel->m_nNodeCount );
|
|
}
|
|
pFx->m_NodeInvMasses = CloneArray( pStream, pFeModel->m_pNodeInvMasses, pFeModel->m_nNodeCount );
|
|
|
|
if ( pFeModel->m_pCtrlHash )
|
|
{
|
|
pFx->m_CtrlHash = CloneArray( pStream, pFeModel->m_pCtrlHash, pFeModel->m_nCtrlCount );
|
|
}
|
|
if ( pFeModel->m_pCtrlName )
|
|
{
|
|
pFx->m_CtrlName = pStream->Allocate< CResourceString >( pFeModel->m_nCtrlCount );
|
|
for ( uint i = 0; i < pFeModel->m_nCtrlCount; ++i )
|
|
{
|
|
pFx->m_CtrlName[ i ] = pStream->WriteString( pFeModel->m_pCtrlName[ i ] );
|
|
}
|
|
}
|
|
|
|
return pFx;
|
|
}
|
|
|
|
|
|
|
|
|
|
void Clone( const PhysFeModelDesc_t *pFeDesc, intp nOffsetBytes, char **pCtrlNames, CFeModel *pFeModel )
|
|
{
|
|
pFeModel->m_nDynamicNodeFlags = pFeDesc->m_nDynamicNodeFlags;
|
|
pFeModel->m_nStaticNodeFlags = pFeDesc->m_nStaticNodeFlags;
|
|
pFeModel->m_flLocalForce = pFeDesc->m_flLocalForce;
|
|
pFeModel->m_flLocalRotation = pFeDesc->m_flLocalRotation;
|
|
|
|
pFeModel->m_nAxialEdgeCount = pFeDesc->m_AxialEdges.Count();
|
|
pFeModel->m_nCtrlCount = pFeDesc->m_CtrlHash.Count();
|
|
pFeModel->m_nNodeCount = pFeDesc->m_nNodeCount;
|
|
pFeModel->m_nStaticNodes = pFeDesc->m_nStaticNodes;
|
|
pFeModel->m_nRotLockStaticNodes = pFeDesc->m_nRotLockStaticNodes;
|
|
AssertDbg( pFeModel->m_nRotLockStaticNodes <= pFeModel->m_nStaticNodes );
|
|
pFeModel->m_nTreeDepth = pFeDesc->m_nTreeDepth;
|
|
// no scalar data
|
|
pFeModel->m_nQuadCount[ 0 ] = 0;
|
|
pFeModel->m_nQuadCount[ 1 ] = 0;
|
|
pFeModel->m_nQuadCount[ 2 ] = 0;
|
|
pFeModel->m_nTriCount[ 0 ] = 0;
|
|
pFeModel->m_nTriCount[ 1 ] = 0;
|
|
pFeModel->m_nTriCount[ 2 ] = 0;
|
|
pFeModel->m_nSimdQuadCount[ 0 ] = pFeDesc->m_SimdQuads.Count();
|
|
pFeModel->m_nSimdQuadCount[ 1 ] = pFeDesc->m_nSimdQuadCount1;
|
|
pFeModel->m_nSimdQuadCount[ 2 ] = pFeDesc->m_nSimdQuadCount2;
|
|
pFeModel->m_nSimdTriCount[ 0 ] = pFeDesc->m_SimdTris.Count();
|
|
pFeModel->m_nSimdTriCount[ 1 ] = pFeDesc->m_nSimdTriCount1;
|
|
pFeModel->m_nSimdTriCount[ 2 ] = pFeDesc->m_nSimdTriCount2;
|
|
pFeModel->m_nQuadCount[ 0 ] = pFeDesc->m_Quads.Count();
|
|
pFeModel->m_nQuadCount[ 1 ] = pFeDesc->m_nQuadCount1;
|
|
pFeModel->m_nQuadCount[ 2 ] = pFeDesc->m_nQuadCount2;
|
|
pFeModel->m_nFitMatrixCount[ 0 ] = pFeDesc->m_FitMatrices.Count();
|
|
pFeModel->m_nFitMatrixCount[ 1 ] = pFeDesc->m_nFitMatrixCount1;
|
|
pFeModel->m_nFitMatrixCount[ 2 ] = pFeDesc->m_nFitMatrixCount2;
|
|
pFeModel->m_nSimdFitMatrixCount[ 0 ] = pFeDesc->m_SimdFitMatrices.Count();
|
|
pFeModel->m_nSimdFitMatrixCount[ 1 ] = pFeDesc->m_nSimdFitMatrixCount1;
|
|
pFeModel->m_nSimdFitMatrixCount[ 2 ] = pFeDesc->m_nSimdFitMatrixCount2;
|
|
pFeModel->m_flDefaultSurfaceStretch = pFeDesc->m_flDefaultSurfaceStretch;
|
|
pFeModel->m_flDefaultThreadStretch = pFeDesc->m_flDefaultThreadStretch;
|
|
pFeModel->m_flDefaultGravityScale = pFeDesc->m_flDefaultGravityScale;
|
|
pFeModel->m_flDefaultVelAirDrag = pFeDesc->m_flDefaultVelAirDrag;
|
|
pFeModel->m_flDefaultExpAirDrag = pFeDesc->m_flDefaultExpAirDrag;
|
|
pFeModel->m_flDefaultVelQuadAirDrag = pFeDesc->m_flDefaultVelQuadAirDrag;
|
|
pFeModel->m_flDefaultExpQuadAirDrag = pFeDesc->m_flDefaultExpQuadAirDrag;
|
|
pFeModel->m_flDefaultVelRodAirDrag = pFeDesc->m_flDefaultVelRodAirDrag;
|
|
pFeModel->m_flDefaultExpRodAirDrag = pFeDesc->m_flDefaultExpRodAirDrag;
|
|
pFeModel->m_flQuadVelocitySmoothRate = pFeDesc->m_flQuadVelocitySmoothRate;
|
|
pFeModel->m_flRodVelocitySmoothRate = pFeDesc->m_flRodVelocitySmoothRate;
|
|
pFeModel->m_nQuadVelocitySmoothIterations = pFeDesc->m_nQuadVelocitySmoothIterations;
|
|
pFeModel->m_nRodVelocitySmoothIterations = pFeDesc->m_nRodVelocitySmoothIterations;
|
|
pFeModel->m_flAddWorldCollisionRadius = pFeDesc->m_flAddWorldCollisionRadius;
|
|
pFeModel->m_flDefaultVolumetricSolveAmount = pFeDesc->m_flDefaultVolumetricSolveAmount;
|
|
pFeModel->m_nFitWeightCount = pFeDesc->m_FitWeights.Count();
|
|
pFeModel->m_nReverseOffsetCount = pFeDesc->m_ReverseOffsets.Count();
|
|
pFeModel->m_flWindage = pFeDesc->m_flWindage;
|
|
pFeModel->m_flWindDrag = pFeDesc->m_flWindDrag;
|
|
|
|
pFeModel->m_nRodCount = pFeDesc->m_Rods.Count();
|
|
pFeModel->m_nSimdRodCount = pFeDesc->m_SimdRods.Count();
|
|
pFeModel->m_nFollowNodeCount = pFeDesc->m_FollowNodes.Count();
|
|
pFeModel->m_nCtrlOffsets = pFeDesc->m_CtrlOffsets.Count();
|
|
pFeModel->m_nCtrlOsOffsets = pFeDesc->m_CtrlOsOffsets.Count();
|
|
pFeModel->m_nSpringIntegratorCount = pFeDesc->m_SpringIntegrator.Count();
|
|
pFeModel->m_nSimdSpringIntegratorCount = pFeDesc->m_SimdSpringIntegrator.Count();
|
|
pFeModel->m_nWorldCollisionParamCount = pFeDesc->m_WorldCollisionParams.Count();
|
|
pFeModel->m_nWorldCollisionNodeCount = pFeDesc->m_WorldCollisionNodes.Count();
|
|
pFeModel->m_nFreeNodeCount = pFeDesc->m_FreeNodes.Count();
|
|
pFeModel->m_nTaperedCapsuleStretchCount = pFeDesc->m_TaperedCapsuleStretches.Count();
|
|
pFeModel->m_nTaperedCapsuleRigidCount = pFeDesc->m_TaperedCapsuleRigids.Count();
|
|
pFeModel->m_nSphereRigidCount = pFeDesc->m_SphereRigids.Count();
|
|
pFeModel->m_pSimdQuads = ConstCastOffsetPointer( pFeDesc->m_SimdQuads.Base(), nOffsetBytes );
|
|
pFeModel->m_pQuads = ConstCastOffsetPointer( pFeDesc->m_Quads.Base(), nOffsetBytes );
|
|
pFeModel->m_pSimdTris = ConstCastOffsetPointer( pFeDesc->m_SimdTris.Base(), nOffsetBytes );
|
|
pFeModel->m_pTris = NULL;
|
|
pFeModel->m_pRods = ConstCastOffsetPointer( pFeDesc->m_Rods.Base(), nOffsetBytes );;
|
|
pFeModel->m_pSimdRods = ConstCastOffsetPointer( pFeDesc->m_SimdRods.Base(), nOffsetBytes );
|
|
pFeModel->m_pAxialEdges = ConstCastOffsetPointer( pFeDesc->m_AxialEdges.Base(), nOffsetBytes );
|
|
pFeModel->m_pNodeToCtrl = NULL;
|
|
pFeModel->m_pCtrlToNode = NULL;
|
|
pFeModel->m_pCtrlHash = ConstCastOffsetPointer( pFeDesc->m_CtrlHash.Base(), nOffsetBytes );
|
|
pFeModel->m_pRopes = ConstCastOffsetPointer( pFeDesc->m_Ropes.Base(), nOffsetBytes );
|
|
pFeModel->m_pNodeBases = ConstCastOffsetPointer( pFeDesc->m_NodeBases.Base(), nOffsetBytes );
|
|
pFeModel->m_pSimdNodeBases = ConstCastOffsetPointer( pFeDesc->m_SimdNodeBases.Base(), nOffsetBytes );
|
|
pFeModel->m_pNodeIntegrator = ConstCastOffsetPointer( pFeDesc->m_NodeIntegrator.Base(), nOffsetBytes );
|
|
pFeModel->m_pSpringIntegrator = ConstCastOffsetPointer( pFeDesc->m_SpringIntegrator.Base(), nOffsetBytes );
|
|
pFeModel->m_pSimdSpringIntegrator = ConstCastOffsetPointer( pFeDesc->m_SimdSpringIntegrator.Base(), nOffsetBytes );
|
|
pFeModel->m_pCtrlOffsets = ConstCastOffsetPointer( pFeDesc->m_CtrlOffsets.Base(), nOffsetBytes );
|
|
pFeModel->m_pCtrlOsOffsets = ConstCastOffsetPointer( pFeDesc->m_CtrlOsOffsets.Base(), nOffsetBytes );
|
|
pFeModel->m_pFollowNodes = ConstCastOffsetPointer( pFeDesc->m_FollowNodes.Base(), nOffsetBytes );
|
|
pFeModel->m_pNodeCollisionRadii = ConstCastOffsetPointer( pFeDesc->m_NodeCollisionRadii.Base(), nOffsetBytes );
|
|
pFeModel->m_pLocalRotation = ConstCastOffsetPointer( pFeDesc->m_LocalRotation.Base(), nOffsetBytes );
|
|
pFeModel->m_pLocalForce = ConstCastOffsetPointer( pFeDesc->m_LocalForce.Base(), nOffsetBytes );
|
|
pFeModel->m_pCollisionSpheres = ConstCastOffsetPointer( pFeDesc->m_CollisionSpheres.Base(), nOffsetBytes );
|
|
pFeModel->m_pCollisionPlanes = ConstCastOffsetPointer( pFeDesc->m_CollisionPlanes.Base(), nOffsetBytes );
|
|
pFeModel->m_pWorldCollisionNodes = ConstCastOffsetPointer( pFeDesc->m_WorldCollisionNodes.Base(), nOffsetBytes );
|
|
pFeModel->m_pWorldCollisionParams = ConstCastOffsetPointer( pFeDesc->m_WorldCollisionParams.Base(), nOffsetBytes );
|
|
pFeModel->m_pLegacyStretchForce = ConstCastOffsetPointer( pFeDesc->m_LegacyStretchForce.Base(), nOffsetBytes );
|
|
pFeModel->m_pTaperedCapsuleStretches = ConstCastOffsetPointer( pFeDesc->m_TaperedCapsuleStretches.Base(), nOffsetBytes );
|
|
pFeModel->m_pTaperedCapsuleRigids = ConstCastOffsetPointer( pFeDesc->m_TaperedCapsuleRigids.Base(), nOffsetBytes );
|
|
pFeModel->m_pSphereRigids = ConstCastOffsetPointer( pFeDesc->m_SphereRigids.Base(), nOffsetBytes );
|
|
pFeModel->m_pFreeNodes = ConstCastOffsetPointer( pFeDesc->m_FreeNodes.Base(), nOffsetBytes );
|
|
pFeModel->m_pFitMatrices = ConstCastOffsetPointer( pFeDesc->m_FitMatrices.Base(), nOffsetBytes );
|
|
pFeModel->m_pSimdFitMatrices = ConstCastOffsetPointer( pFeDesc->m_SimdFitMatrices.Base(), nOffsetBytes );
|
|
pFeModel->m_pFitWeights = ConstCastOffsetPointer( pFeDesc->m_FitWeights.Base(), nOffsetBytes );
|
|
pFeModel->m_pReverseOffsets = ConstCastOffsetPointer( pFeDesc->m_ReverseOffsets.Base(), nOffsetBytes );
|
|
AssertDbg( pFeModel->m_pWorldCollisionParams ? pFeModel->m_pWorldCollisionParams[ pFeModel->m_nWorldCollisionParamCount - 1 ].nListEnd == pFeModel->m_nWorldCollisionNodeCount : !pFeModel->m_pWorldCollisionNodes && !pFeModel->m_nWorldCollisionParamCount && !pFeModel->m_nWorldCollisionNodeCount );
|
|
pFeModel->m_nRopeCount = pFeDesc->m_nRopeCount;
|
|
pFeModel->m_nRopeIndexCount = pFeDesc->m_Ropes.Count();
|
|
pFeModel->m_nNodeBaseCount = pFeDesc->m_NodeBases.Count();
|
|
pFeModel->m_nSimdNodeBaseCount = pFeDesc->m_SimdNodeBases.Count();
|
|
pFeModel->m_nCollisionSpheres[ 0 ] = pFeDesc->m_CollisionSpheres.Count();
|
|
pFeModel->m_nCollisionSpheres[ 1 ] = pFeDesc->m_nCollisionSphereInclusiveCount;
|
|
pFeModel->m_nCollisionPlanes = pFeDesc->m_CollisionPlanes.Count();
|
|
Assert( pFeDesc->m_TreeChildren.Count() == 0 || pFeDesc->m_TreeChildren.Count() == ( int )pFeDesc->GetDynamicNodeCount() - 1 );
|
|
pFeModel->m_pTreeChildren = ConstCastOffsetPointer( pFeDesc->m_TreeChildren.Base(), nOffsetBytes );
|
|
Assert( pFeDesc->m_TreeParents.Count() == 0 || pFeDesc->m_TreeParents.Count() == 2 * ( int )pFeDesc->GetDynamicNodeCount() - 1 );
|
|
pFeModel->m_pTreeParents = ConstCastOffsetPointer( pFeDesc->m_TreeParents.Base(), nOffsetBytes );
|
|
Assert( pFeDesc->m_TreeParents.Count() == pFeDesc->m_TreeCollisionMasks.Count() );
|
|
pFeModel->m_pTreeCollisionMasks = ConstCastOffsetPointer( pFeDesc->m_TreeCollisionMasks.Base(), nOffsetBytes );
|
|
Assert( pFeDesc->m_NodeInvMasses.Count() == 0 || pFeDesc->m_NodeInvMasses.Count() == pFeDesc->m_nNodeCount );
|
|
pFeModel->m_pNodeInvMasses = pFeDesc->m_NodeInvMasses.Count() ? ConstCastOffsetPointer( pFeDesc->m_NodeInvMasses.Base(), nOffsetBytes ) : NULL;
|
|
if ( pFeDesc->m_CtrlName.IsEmpty() || !pCtrlNames )
|
|
{
|
|
pFeModel->m_pCtrlName = NULL;
|
|
}
|
|
else
|
|
{
|
|
pFeModel->m_pCtrlName = const_cast< const char ** >( pCtrlNames ); //ConstCastOffsetPointer( pFeDesc->m_CtrlName.Base( ), nOffsetBytes );
|
|
for ( int i = 0; i < pFeModel->m_nCtrlCount; ++i )
|
|
{
|
|
const CResourceString &name = pFeDesc->m_CtrlName[ i ];
|
|
if ( name.IsNull() )
|
|
{
|
|
pFeModel->m_pCtrlName[ i ] = "";
|
|
}
|
|
else
|
|
{
|
|
pFeModel->m_pCtrlName[ i ] = ConstCastOffsetPointer( name.GetPtr(), nOffsetBytes );
|
|
}
|
|
}
|
|
}
|
|
AssertDbg( pFeDesc->m_InitPose.Count() == pFeModel->m_nCtrlCount );
|
|
pFeModel->m_pInitPose = ConstCastOffsetPointer( pFeDesc->m_InitPose.Base(), nOffsetBytes );
|
|
}
|
|
|
|
void SetIdentityPerm( CUtlVector< uint > &perm, uint nCount )
|
|
{
|
|
perm.SetCount( nCount );
|
|
for ( uint i = 0; i < nCount; ++i )
|
|
perm[ i ] = i;
|
|
}
|
|
|
|
|
|
struct CtrlHashFunctor_t
|
|
{
|
|
const CFeModel *m_pFeModel;
|
|
CtrlHashFunctor_t( const CFeModel *pFeModel ) : m_pFeModel( pFeModel ){}
|
|
bool operator( )( int nLeft, int nRight ) const
|
|
{
|
|
return m_pFeModel->m_pCtrlHash[ nLeft ] < m_pFeModel->m_pCtrlHash[ nRight ];
|
|
}
|
|
};
|
|
|
|
|
|
CFeModelReplaceContext::CFeModelReplaceContext( const CFeModel *pOld, const CFeModel *pNew )
|
|
{
|
|
m_pOld = pOld;
|
|
m_pNew = pNew;
|
|
m_OldToNewNode.SetCount( pOld->m_nNodeCount ); m_OldToNewNode.FillWithValue( -1 );
|
|
m_OldToNewCtrl.SetCount( pOld->m_nCtrlCount ); m_OldToNewCtrl.FillWithValue( -1 );
|
|
m_NewToOldNode.SetCount( pNew->m_nNodeCount ); m_NewToOldNode.FillWithValue( -1 );
|
|
m_NewToOldCtrl.SetCount( pNew->m_nCtrlCount ); m_NewToOldCtrl.FillWithValue( -1 );
|
|
|
|
CUtlVector< uint > oldCtrlIndex, newCtrlIndex;
|
|
SetIdentityPerm( oldCtrlIndex, pOld->m_nCtrlCount );
|
|
SetIdentityPerm( newCtrlIndex, pNew->m_nCtrlCount );
|
|
HeapSort( oldCtrlIndex, CtrlHashFunctor_t( pOld ) );
|
|
HeapSort( newCtrlIndex, CtrlHashFunctor_t( pNew ) );
|
|
|
|
for ( uint nOld = 0, nNew = 0; nOld < pOld->m_nCtrlCount && nNew < pNew->m_nCtrlCount; )
|
|
{
|
|
uint nOldCtrl = oldCtrlIndex[ nOld ], nNewCtrl = newCtrlIndex[ nNew ];
|
|
uint nOldCtrlHash = pOld->m_pCtrlHash[ nOldCtrl ], nNewCtrlHash = pNew->m_pCtrlHash[ nNewCtrl ];
|
|
if ( nOldCtrlHash == nNewCtrlHash )
|
|
{
|
|
// we found a match!
|
|
m_OldToNewCtrl[ nOldCtrl ] = nNewCtrl;
|
|
m_NewToOldCtrl[ nNewCtrl ] = nOldCtrl;
|
|
uint nOldNode = pOld->CtrlToNode( nOldCtrl );
|
|
uint nNewNode = pNew->CtrlToNode( nNewCtrl );
|
|
if ( nOldNode < pOld->m_nNodeCount && nNewNode < pNew->m_nNodeCount )
|
|
{
|
|
// there's a match in nodes
|
|
m_NewToOldNode[ nNewNode ] = nOldNode;
|
|
m_OldToNewNode[ nOldNode ] = nNewNode;
|
|
}
|
|
nOld++;
|
|
nNew++;
|
|
}
|
|
else if ( nOldCtrlHash < nNewCtrlHash )
|
|
{
|
|
AssertDbg( m_OldToNewCtrl[ nOldCtrl ] == -1 );
|
|
nOld++;
|
|
}
|
|
else
|
|
{
|
|
AssertDbg( m_NewToOldCtrl[ nNewCtrl ] == -1 );
|
|
nNew++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|