bool CPoseDebuggerImpl::IsModelShown( int iEntNum ) const { Assert( iEntNum < MAX_EDICTS ); if ( iEntNum >= 0 && iEntNum < MAX_EDICTS ) return m_uiMaskShowModels.IsBitSet( iEntNum ); else return false; }
bool UTIL_IsHolidayActive( /*EHoliday*/ int eHoliday ) { #ifdef USES_ECON_ITEMS if ( IsX360() ) return false; if ( !s_HolidaysCalculated ) { UTIL_CalculateHolidays(); } return s_HolidaysActive.IsBitSet( eHoliday ); #else return false; #endif }
bool _ComputeRagdollBones( const ragdoll_t *pRagdoll, matrix3x4_t &parentTransform, matrix3x4_t *pBones, Vector *pPositions, QAngle *pAngles ) { matrix3x4_t inverted, output; #ifdef _DEBUG CBitVec<MAXSTUDIOBONES> vBonesComputed; vBonesComputed.ClearAll(); #endif for ( int i = 0; i < pRagdoll->listCount; ++i ) { const ragdollelement_t& element = pRagdoll->list[ i ]; // during restore if a model has changed since the file was saved, this could be NULL if ( !element.pObject ) return false; int const boneIndex = pRagdoll->boneIndex[ i ]; if ( boneIndex < 0 ) { AssertMsg( 0, "Replay: No mapping for ragdoll bone\n" ); return false; } // Get global transform and put it into the bone cache element.pObject->GetPositionMatrix( &pBones[ boneIndex ] ); // Ensure a fixed translation from the parent (no stretching) if ( element.parentIndex >= 0 && !pRagdoll->allowStretch ) { int parentIndex = pRagdoll->boneIndex[ element.parentIndex ]; #ifdef _DEBUG // Make sure we computed the parent already Assert( vBonesComputed.IsBitSet(parentIndex) ); #endif // overwrite the position from physics to force rigid attachment // NOTE: On the client we actually override this with the proper parent bone in each LOD Vector out; VectorTransform( element.originParentSpace, pBones[ parentIndex ], out ); MatrixSetColumn( out, 3, pBones[ boneIndex ] ); MatrixInvert( pBones[ parentIndex ], inverted ); } else if ( element.parentIndex == - 1 ) { // Decompose into parent space MatrixInvert( parentTransform, inverted ); } #ifdef _DEBUG vBonesComputed.Set( boneIndex, true ); #endif // Compute local transform and put into 'output' ConcatTransforms( inverted, pBones[ boneIndex ], output ); // Cache as Euler/position MatrixAngles( output, pAngles[ i ], pPositions[ i ] ); } return true; }
void CBlobParticleNetworkBypassAutoGame::PreRender( void ) { if( engine->IsRecordingDemo() && g_pBlobNetworkBypass->bDataUpdated ) { //record the update, TODO: compress the data by omitting the holes int iMaxIndex = MAX(g_pBlobNetworkBypass->iHighestIndexUsed, m_iOldHighestIndexUsed); int iBitMax = (iMaxIndex / BITS_PER_INT) + 1; size_t iDataSize = sizeof( int ) + sizeof( float ) + sizeof( int ) + sizeof( int ) + (sizeof( int ) * iBitMax) + iMaxIndex*( sizeof( Vector ) + sizeof( float ) + sizeof( Vector ) ); uint8 *pData = new uint8 [iDataSize]; uint8 *pWrite = pData; //let the receiver know how much of each array to expect *(int *)pWrite = LittleDWord( iMaxIndex ); pWrite += sizeof( int ); //write the update timestamp *(float *)pWrite = g_pBlobNetworkBypass->fTimeDataUpdated; pWrite += sizeof( float ); //record usage information, also helps us effectively compress the subsequent data by omitting the holes. *(int *)pWrite = LittleDWord( g_pBlobNetworkBypass->iHighestIndexUsed ); pWrite += sizeof( int ); *(int *)pWrite = LittleDWord( g_pBlobNetworkBypass->iNumParticlesAllocated ); pWrite += sizeof( int ); int *pIntParser = (int *)&g_pBlobNetworkBypass->bCurrentlyInUse; for( int i = 0; i != iBitMax; ++i ) { //convert and write the bitfield integers *(int *)pWrite = LittleDWord( *pIntParser ); pWrite += sizeof( int ); ++pIntParser; } //write positions memcpy( pWrite, g_pBlobNetworkBypass->vParticlePositions, sizeof( Vector ) * iMaxIndex ); pWrite += sizeof( Vector ) * iMaxIndex; //write radii memcpy( pWrite, g_pBlobNetworkBypass->vParticleRadii, sizeof( float ) * iMaxIndex ); pWrite += sizeof( float ) * iMaxIndex; //write closest surface direction memcpy( pWrite, g_pBlobNetworkBypass->vParticleClosestSurfDir, sizeof( Vector ) * iMaxIndex ); pWrite += sizeof( Vector ) * iMaxIndex; engine->RecordDemoCustomData( BlobNetworkBypass_CustomDemoDataCallback, pData, iDataSize ); Assert( pWrite == (pData + iDataSize) ); delete []pData; } //invalidate interpolation on freed indices, do a quick update for brand new indices { //operate on smaller chunks based on the assumption that LARGE portions of the end of the bitvecs are empty CBitVec<BITS_PER_INT> *pCurrentlyInUse = (CBitVec<BITS_PER_INT> *)&g_pBlobNetworkBypass->bCurrentlyInUse; CBitVec<BITS_PER_INT> *pOldInUse = (CBitVec<BITS_PER_INT> *)&m_bOldInUse; int iStop = (MAX(g_pBlobNetworkBypass->iHighestIndexUsed, m_iOldHighestIndexUsed) / BITS_PER_INT) + 1; int iBaseIndex = 0; //float fNewIndicesUpdateTime = g_pBlobNetworkBypass->bPositionsUpdated ? g_pBlobNetworkBypass->fTimeDataUpdated : gpGlobals->curtime; for( int i = 0; i != iStop; ++i ) { CBitVec<BITS_PER_INT> bInUseXOR; pCurrentlyInUse->Xor( *pOldInUse, &bInUseXOR ); //find bits that changed int j = 0; while( (j = bInUseXOR.FindNextSetBit( j )) != -1 ) { int iChangedUsageIndex = iBaseIndex + j; if( pOldInUse->IsBitSet( iChangedUsageIndex ) ) { //index no longer used g_BlobParticleInterpolation.vInterpolatedPositions[iChangedUsageIndex] = vec3_origin; s_PositionInterpolators[iChangedUsageIndex].ClearHistory(); g_BlobParticleInterpolation.vInterpolatedRadii[iChangedUsageIndex] = 1.0f; s_RadiusInterpolators[iChangedUsageIndex].ClearHistory(); g_BlobParticleInterpolation.vInterpolatedClosestSurfDir[iChangedUsageIndex] = vec3_origin; s_ClosestSurfDirInterpolators[iChangedUsageIndex].ClearHistory(); } else { //index just started being used. Assume we got an out of band update to the position g_BlobParticleInterpolation.vInterpolatedPositions[iChangedUsageIndex] = g_pBlobNetworkBypass->vParticlePositions[iChangedUsageIndex]; s_PositionInterpolators[iChangedUsageIndex].Reset( gpGlobals->curtime ); g_BlobParticleInterpolation.vInterpolatedRadii[iChangedUsageIndex] = g_pBlobNetworkBypass->vParticleRadii[iChangedUsageIndex]; s_RadiusInterpolators[iChangedUsageIndex].Reset( gpGlobals->curtime ); g_BlobParticleInterpolation.vInterpolatedClosestSurfDir[iChangedUsageIndex] = g_pBlobNetworkBypass->vParticleClosestSurfDir[iChangedUsageIndex]; s_ClosestSurfDirInterpolators[iChangedUsageIndex].Reset( gpGlobals->curtime ); //s_PositionInterpolators[iChangedUsageIndex].NoteChanged( gpGlobals->curtime, fNewIndicesUpdateTime, true ); } ++j; if( j == BITS_PER_INT ) break; } iBaseIndex += BITS_PER_INT; ++pCurrentlyInUse; ++pOldInUse; } memcpy( &m_bOldInUse, &g_pBlobNetworkBypass->bCurrentlyInUse, sizeof( m_bOldInUse ) ); m_iOldHighestIndexUsed = g_pBlobNetworkBypass->iHighestIndexUsed; } if( g_pBlobNetworkBypass->iHighestIndexUsed == 0 ) return; static ConVarRef cl_interpREF( "cl_interp" ); //now do the interpolation of positions still in use { float fInterpTime = gpGlobals->curtime - cl_interpREF.GetFloat(); CBitVec<BITS_PER_INT> *pIntParser = (CBitVec<BITS_PER_INT> *)&g_pBlobNetworkBypass->bCurrentlyInUse; int iStop = (g_pBlobNetworkBypass->iHighestIndexUsed / BITS_PER_INT) + 1; int iBaseIndex = 0; for( int i = 0; i != iStop; ++i ) { int j = 0; while( (j = pIntParser->FindNextSetBit( j )) != -1 ) { int iUpdateIndex = iBaseIndex + j; if( g_pBlobNetworkBypass->bDataUpdated ) { g_BlobParticleInterpolation.vInterpolatedPositions[iUpdateIndex] = g_pBlobNetworkBypass->vParticlePositions[iUpdateIndex]; s_PositionInterpolators[iUpdateIndex].NoteChanged( gpGlobals->curtime, g_pBlobNetworkBypass->fTimeDataUpdated, true ); g_BlobParticleInterpolation.vInterpolatedRadii[iUpdateIndex] = g_pBlobNetworkBypass->vParticleRadii[iUpdateIndex]; s_RadiusInterpolators[iUpdateIndex].NoteChanged( gpGlobals->curtime, g_pBlobNetworkBypass->fTimeDataUpdated, true ); g_BlobParticleInterpolation.vInterpolatedClosestSurfDir[iUpdateIndex] = g_pBlobNetworkBypass->vParticleClosestSurfDir[iUpdateIndex]; s_ClosestSurfDirInterpolators[iUpdateIndex].NoteChanged( gpGlobals->curtime, g_pBlobNetworkBypass->fTimeDataUpdated, true ); //s_PositionInterpolators[iUpdateIndex].AddToHead( gpGlobals->curtime, &g_pBlobNetworkBypass->vParticlePositions[iUpdateIndex], false ); } s_PositionInterpolators[iUpdateIndex].Interpolate( fInterpTime ); s_RadiusInterpolators[iUpdateIndex].Interpolate( fInterpTime ); s_ClosestSurfDirInterpolators[iUpdateIndex].Interpolate( fInterpTime ); ++j; if( j == BITS_PER_INT ) break; } iBaseIndex += BITS_PER_INT; ++pIntParser; } g_pBlobNetworkBypass->bDataUpdated = false; } }