void CAnimating::GetBoneTransform( int iBone, matrix3x4_t &pBoneToWorld ) { CStudioHdr *pStudioHdr = GetModelPtr( ); if (!pStudioHdr) { Assert(!"CBaseAnimating::GetBoneTransform: model missing"); return; } if (iBone < 0 || iBone >= pStudioHdr->numbones()) { Assert(!"CBaseAnimating::GetBoneTransform: invalid bone index"); return; } CBoneCache *pcache = GetBoneCache( ); matrix3x4_t *pmatrix = pcache->GetCachedBone( iBone ); if ( !pmatrix ) { MatrixCopy( EntityToWorldTransform(), pBoneToWorld ); return; } Assert( pmatrix ); // FIXME MatrixCopy( *pmatrix, pBoneToWorld ); }
bool CAnimating::ComputeHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) { // Note that this currently should not be called during Relink because of IK. // The code below recomputes bones so as to get at the hitboxes, // which causes IK to trigger, which causes raycasts against the other entities to occur, // which is illegal to do while in the Relink phase. CStudioHdr *pStudioHdr = GetModelPtr(); if (!pStudioHdr) return false; mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( m_nHitboxSet ); if ( !set || !set->numhitboxes ) return false; CBoneCache *pCache = GetBoneCache(); // Compute a box in world space that surrounds this entity pVecWorldMins->Init( FLT_MAX, FLT_MAX, FLT_MAX ); pVecWorldMaxs->Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); Vector vecBoxAbsMins, vecBoxAbsMaxs; for ( int i = 0; i < set->numhitboxes; i++ ) { mstudiobbox_t *pbox = set->pHitbox(i); matrix3x4_t *pMatrix = pCache->GetCachedBone(pbox->bone); if ( pMatrix ) { TransformAABB( *pMatrix, pbox->bbmin, pbox->bbmax, vecBoxAbsMins, vecBoxAbsMaxs ); VectorMin( *pVecWorldMins, vecBoxAbsMins, *pVecWorldMins ); VectorMax( *pVecWorldMaxs, vecBoxAbsMaxs, *pVecWorldMaxs ); } } return true; }
//----------------------------------------------------------------------------- // Purpose: Recompute my rendering box //----------------------------------------------------------------------------- void C_QUA_Strider::ClientThink() { int i; Vector vecMins, vecMaxs; Vector vecAbsMins, vecAbsMaxs; matrix3x4_t worldToStrider, hitboxToStrider; Vector vecBoxMins, vecBoxMaxs; Vector vecBoxAbsMins, vecBoxAbsMaxs; mstudiohitboxset_t *set; CBoneCache *pCache = NULL; // The reason why this is here, as opposed to in SetObjectCollisionBox, // is because of IK. The code below recomputes bones so as to get at the hitboxes, // which causes IK to trigger, which causes raycasts against the other entities to occur, // which is illegal to do while in the Relink phase. studiohdr_t *pStudioHdr = GetModel()?modelinfo->GetStudiomodel( GetModel() ):NULL; if (!pStudioHdr) goto doneWithComputation; set = pStudioHdr->pHitboxSet( m_nHitboxSet ); if ( !set || !set->numhitboxes ) goto doneWithComputation; CStudioHdr *hdr = GetModelPtr(); pCache = GetBoneCache( hdr ); matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; pCache->ReadCachedBonePointers( hitboxbones, pStudioHdr->numbones ); // // Compute a box in world space that surrounds this entity m_vecRenderMins.Init( FLT_MAX, FLT_MAX, FLT_MAX ); m_vecRenderMaxs.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); // MatrixInvert( EntityToWorldTransform(), worldToStrider ); // for ( i = 0; i < set->numhitboxes; i++ ) { mstudiobbox_t *pbox = set->pHitbox(i); ConcatTransforms( worldToStrider, *hitboxbones[pbox->bone], hitboxToStrider ); TransformAABB( hitboxToStrider, pbox->bbmin, pbox->bbmax, vecBoxMins, vecBoxMaxs ); VectorMin( m_vecRenderMins, vecBoxMins, m_vecRenderMins ); VectorMax( m_vecRenderMaxs, vecBoxMaxs, m_vecRenderMaxs ); } // // Deberiamos poner aqui lo de la vista?? // // // UNDONE: Disabled this until we can get closer to a final map and tune //#if 0 // // Cut ropes. // if ( gpGlobals->curtime >= m_flNextRopeCutTime ) // { // // Blow the bbox out a little. // Vector vExtendedMins = vecMins - Vector( 50, 50, 50 ); // Vector vExtendedMaxs = vecMaxs + Vector( 50, 50, 50 ); // // C_RopeKeyframe *ropes[512]; // int nRopes = C_RopeKeyframe::GetRopesIntersectingAABB( ropes, ARRAYSIZE( ropes ), GetAbsOrigin() + vExtendedMins, GetAbsOrigin() + vExtendedMaxs ); // for ( int i=0; i < nRopes; i++ ) // { // C_RopeKeyframe *pRope = ropes[i]; // // if ( pRope->GetEndEntity() ) // { // Vector vPos; // if ( pRope->GetEndPointPos( 1, vPos ) ) // { // // Detach the endpoint. // pRope->SetEndEntity( NULL ); // // // Make some spark effect here.. // g_pEffects->Sparks( vPos ); // } // } // } // // m_flNextRopeCutTime = gpGlobals->curtime + 0.5; // } //#endif doneWithComputation: // True argument because the origin may have stayed the same, but the size is expected to always change g_pClientShadowMgr->AddToDirtyShadowList( this, true ); }