//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // &mins - // &maxs - // &origin - // isStatic - // Output : static IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreateOBB( CBaseEntity *pEntity, const Vector &mins, const Vector &maxs, const Vector &origin, const QAngle &angle, bool isStatic ) { int modelIndex = pEntity->GetModelIndex(); const char *pSurfaceProps = "flesh"; solid_t solid; PhysGetDefaultAABBSolid( solid ); Vector dims = maxs - mins; solid.params.volume = dims.x * dims.y * dims.z; if ( modelIndex ) { const model_t *model = modelinfo->GetModel( modelIndex ); if ( model ) { CStudioHdr studioHdr( modelinfo->GetStudiomodel( model ), mdlcache ); if (studioHdr.IsValid()) { pSurfaceProps = Studio_GetDefaultSurfaceProps( &studioHdr ); } } } Q_strncpy( solid.surfaceprop, pSurfaceProps, sizeof( solid.surfaceprop ) ); CPhysCollide *pCollide = PhysCreateBbox( mins, maxs ); if ( !pCollide ) return NULL; return PhysModelCreateCustom( pEntity, pCollide, origin, angle, STRING(pEntity->GetModelName()), isStatic, &solid ); }
void CStudioPhysics::Load( MDLHandle_t mdlHandle ) { m_MDLHandle = mdlHandle; LoadPhysicsProperties(); vcollide_t *pVCollide = GetVCollide( ); if ( !pVCollide ) { m_pList = NULL; m_listCount = 0; return; } m_pList = new CPhysmesh[pVCollide->solidCount]; m_listCount = pVCollide->solidCount; int i; for ( i = 0; i < pVCollide->solidCount; i++ ) { m_pList[i].Clear(); m_pList[i].m_vertCount = physcollision->CreateDebugMesh( pVCollide->solids[i], &m_pList[i].m_pVerts ); m_pList[i].m_pCollisionModel = physcollision->CreateQueryModel( pVCollide->solids[i] ); } ParseKeydata(); CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( mdlHandle ), g_pMDLCache ); for ( i = 0; i < pVCollide->solidCount; i++ ) { CPhysmesh *pmesh = m_pList + i; int boneIndex = FindBoneIndex( &studioHdr, pmesh->m_boneName ); if ( boneIndex < 0 ) continue; if ( pmesh->m_constraint.parentIndex >= 0 ) { CPhysmesh *pparent = m_pList + pmesh->m_constraint.parentIndex; int parentIndex = FindBoneIndex( &studioHdr, pparent->m_boneName ); Studio_CalcBoneToBoneTransform( &studioHdr, boneIndex, parentIndex, pmesh->m_matrix ); } else { MatrixInvert( studioHdr.pBone(boneIndex)->poseToBone, pmesh->m_matrix ); } } // doesn't have a root bone? Make it the first bone if ( !m_edit.rootName[0] ) { strcpy( m_edit.rootName, m_pList[0].m_boneName ); } }
void C_SDKPlayer::PlayReloadEffect() { // Only play the effect for other players. if ( this == C_SDKPlayer::GetLocalSDKPlayer() ) { Assert( false ); // We shouldn't have been sent this message. return; } // Get the view model for our current gun. CWeaponSDKBase *pWeapon = GetActiveSDKWeapon(); if ( !pWeapon ) return; // The weapon needs two models, world and view, but can only cache one. Synthesize the other. const CSDKWeaponInfo &info = pWeapon->GetSDKWpnData(); const model_t *pModel = modelinfo->GetModel( modelinfo->GetModelIndex( info.szViewModel ) ); if ( !pModel ) return; CStudioHdr studioHdr( modelinfo->GetStudiomodel( pModel ), mdlcache ); if ( !studioHdr.IsValid() ) return; // Find the reload animation. for ( int iSeq=0; iSeq < studioHdr.GetNumSeq(); iSeq++ ) { mstudioseqdesc_t *pSeq = &studioHdr.pSeqdesc( iSeq ); if ( pSeq->activity == ACT_VM_RELOAD ) { float poseParameters[MAXSTUDIOPOSEPARAM]; memset( poseParameters, 0, sizeof( poseParameters ) ); float cyclesPerSecond = Studio_CPS( &studioHdr, *pSeq, iSeq, poseParameters ); // Now read out all the sound events with their timing for ( int iEvent=0; iEvent < pSeq->numevents; iEvent++ ) { //mstudioevent_t *pevent = (mstudioevent_for_client_server_t*)pSeq.pEvent(iEvent ); mstudioevent_t *pEvent = (mstudioevent_for_client_server_t*)pSeq->pEvent( iEvent ); if ( pEvent->Event() == CL_EVENT_SOUND ) { CSDKSoundEvent event; event.m_SoundName = pEvent->options; event.m_flEventTime = gpGlobals->curtime + pEvent->cycle / cyclesPerSecond; m_SoundEvents.AddToTail( event ); } } break; } } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // &mins - // &maxs - // &origin - // isStatic - // Output : static IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreateSphere( CBaseEntity *pEntity, float radius, const Vector &origin, bool isStatic ) { int modelIndex = pEntity->GetModelIndex(); const char *pSurfaceProps = "flesh"; solid_t solid; //PhysGetDefaultAABBSolid( solid ); solid.params = g_PhysDefaultObjectParams; if ( modelIndex ) { const model_t *model = modelinfo->GetModel( modelIndex ); if ( model ) { CStudioHdr studioHdr( modelinfo->GetStudiomodel( model ), mdlcache ); if (studioHdr.IsValid()) { pSurfaceProps = Studio_GetDefaultSurfaceProps( &studioHdr ); } } } Q_strncpy( solid.surfaceprop, pSurfaceProps, sizeof( solid.surfaceprop ) ); return PhysSphereCreate( pEntity, radius, origin, isStatic, solid ); }
void CDmeMDL::SetUpBones( const matrix3x4_t& shapeToWorld, int nMaxBoneCount, matrix3x4_t *pOutputMatrices ) { CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_MDLHandle ), g_pMDLCache ); SetUpBones( studioHdr, shapeToWorld, nMaxBoneCount, pOutputMatrices ); }
//----------------------------------------------------------------------------- // Set up the bones for a frame //----------------------------------------------------------------------------- matrix3x4_t* CIHVTestApp::SetUpBones( studiohdr_t *pStudioHdr, const matrix3x4_t &shapeToWorld, int iRun, int model, int boneMask ) { // Default to middle of the pose parameter range float pPoseParameter[MAXSTUDIOPOSEPARAM]; for ( int i = 0; i < MAXSTUDIOPOSEPARAM; ++i ) { pPoseParameter[i] = 0.5f; } CStudioHdr studioHdr( pStudioHdr, g_pMDLCache ); int nFrameCount = Studio_MaxFrame( &studioHdr, g_BenchRuns[iRun].sequence1[model], pPoseParameter ); if ( nFrameCount == 0 ) { nFrameCount = 1; } Vector pos[MAXSTUDIOBONES]; Quaternion q[MAXSTUDIOBONES]; InitPose( &studioHdr, pos, q, boneMask ); AccumulatePose( &studioHdr, NULL, pos, q, g_BenchRuns[iRun].sequence1[model], s_Cycle[model], pPoseParameter, boneMask, 1.0f, 0.0 ); // FIXME: Try enabling this? // CalcAutoplaySequences( pStudioHdr, NULL, pos, q, pPoseParameter, BoneMask( ), flTime ); // Root transform matrix3x4_t rootToWorld, temp; MatrixCopy( shapeToWorld, rootToWorld ); matrix3x4_t *pBoneToWorld = g_pStudioRender->LockBoneMatrices( studioHdr.numbones() ); for ( int i = 0; i < studioHdr.numbones(); i++ ) { // If it's not being used, fill with NAN for errors if ( !(studioHdr.pBone( i )->flags & boneMask) ) { int j, k; for (j = 0; j < 3; j++) { for (k = 0; k < 4; k++) { pBoneToWorld[i][j][k] = VEC_T_NAN; } } continue; } matrix3x4_t boneMatrix; QuaternionMatrix( q[i], boneMatrix ); MatrixSetColumn( pos[i], 3, boneMatrix ); if (studioHdr.pBone(i)->parent == -1) { ConcatTransforms (rootToWorld, boneMatrix, pBoneToWorld[i]); } else { ConcatTransforms (pBoneToWorld[ studioHdr.pBone(i)->parent ], boneMatrix, pBoneToWorld[i] ); } } g_pStudioRender->UnlockBoneMatrices(); return pBoneToWorld; }
//----------------------------------------------------------------------------- // Render a frame //----------------------------------------------------------------------------- void CIHVTestApp::RenderFrame( void ) { VPROF( "RenderFrame" ); IHVTestModel *pModel = NULL; static int currentRun = 0; static int currentFrame = 0; static int currentLightCombo = 0; int modelAlternator = 0; if (g_bInError) { // error context is active // error may be renderer based, avoid re-entrant render to fatal crash return; } if( g_BenchMode ) { if( currentFrame > g_BenchRuns[currentRun].numFrames ) { currentLightCombo++; if( currentLightCombo >= LIGHTING_COMBINATION_COUNT ) { currentRun++; currentLightCombo = 0; if( currentRun >= NUM_BENCH_RUNS ) { g_BenchFinished = true; return; } } currentFrame = 0; } } if( g_BenchMode ) { pModel = &g_BenchModels[currentRun][0]; g_NumCols = g_BenchRuns[currentRun].cols; g_NumRows = g_BenchRuns[currentRun].rows; } else { pModel = m_pIHVTestModel; } Assert( pModel ); g_EngineStats.BeginFrame(); g_pMaterialSystem->BeginFrame( 0 ); g_pStudioRender->BeginFrame(); CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); pRenderContext->ClearColor3ub( 0, 0, 0 ); pRenderContext->ClearBuffers( true, true ); pRenderContext->Viewport( 0, 0, g_RenderWidth, g_RenderHeight ); pRenderContext->MatrixMode( MATERIAL_PROJECTION ); pRenderContext->LoadIdentity(); pRenderContext->PerspectiveX( 90.0f, ( g_RenderWidth / g_RenderHeight), 1.0f, 500000.0f ); pRenderContext->MatrixMode( MATERIAL_VIEW ); pRenderContext->LoadIdentity(); if( g_BenchMode ) { pRenderContext->Translate( 0.0f, 0.0f, ( float )-( g_NumCols * g_BenchRuns[currentRun].modelSize * 0.6f ) ); } else { pRenderContext->Translate( 0.0f, 0.0f, ( float )-( g_NumCols * 80.0f * 0.5f ) ); } pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->LoadIdentity(); QAngle angles; angles[YAW] = -90.0f; angles[PITCH] = -90.0f; angles[ROLL] = 0.0f; matrix3x4_t cameraMatrix; AngleMatrix( angles, cameraMatrix ); int r, c; int trisRendered = 0; float boneSetupTime = 0.0f; for( r = 0; r < g_NumRows; r++ ) { for( c = 0; c < g_NumCols; c++ ) { // If we are alternating models, select the next valid model. if( g_BenchMode ) { do { // If I pass my maximum number of models, wrap around to model 0, which must always be valid. if( ++modelAlternator >= g_nMaxModels ) { modelAlternator = 0; break; } } while( !g_BenchRuns[currentRun].pModelName[modelAlternator] ); pModel = &g_BenchModels[currentRun][modelAlternator]; Assert( pModel ); } if( g_BenchMode ) { cameraMatrix[0][3] = ( ( c + 0.5f ) - ( g_NumCols * .5f ) ) * g_BenchRuns[currentRun].modelSize; cameraMatrix[1][3] = ( ( float )r - ( g_NumCols * .5f ) ) * g_BenchRuns[currentRun].modelSize; } else { cameraMatrix[0][3] = ( ( c + 0.5f ) - ( g_NumCols * .5f ) ) * 75.0f; cameraMatrix[1][3] = ( ( float )r - ( g_NumCols * .5f ) ) * 75.0f; } Vector modelOrigin( cameraMatrix[0][3], cameraMatrix[1][3], 0.0f ); Vector lightOffset( cameraMatrix[0][3], cameraMatrix[1][3], 0.0f ); if (g_LightingCombination < 0) { SetupLighting( g_BenchMode ? currentLightCombo : 0, lightOffset ); } else { SetupLighting( g_LightingCombination, lightOffset ); } float startBoneSetupTime = Sys_FloatTime(); int lod = g_LOD; lod = clamp( lod, pModel->pHardwareData->m_RootLOD, pModel->pHardwareData->m_NumLODs-1 ); int boneMask = BONE_USED_BY_VERTEX_AT_LOD( lod ); matrix3x4_t *pBoneToWorld = SetUpBones( pModel->pStudioHdr, cameraMatrix, currentRun, modelAlternator, boneMask ); boneSetupTime += Sys_FloatTime() - startBoneSetupTime; pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PushMatrix(); DrawModelInfo_t modelInfo; memset( &modelInfo, 0, sizeof( modelInfo ) ); modelInfo.m_pStudioHdr = pModel->pStudioHdr; modelInfo.m_pHardwareData = pModel->pHardwareData; modelInfo.m_Decals = STUDIORENDER_DECAL_INVALID; modelInfo.m_Skin = 0; modelInfo.m_Body = g_BodyGroup; modelInfo.m_HitboxSet = 0; modelInfo.m_pClientEntity = NULL; modelInfo.m_Lod = lod; modelInfo.m_pColorMeshes = NULL; g_pStudioRender->DrawModel( NULL, modelInfo, pBoneToWorld, NULL, NULL, modelOrigin ); DrawModelResults_t results; g_pStudioRender->GetPerfStats( &results, modelInfo, NULL ); trisRendered += results.m_ActualTriCount; pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PopMatrix(); } } pRenderContext->Flush( true ); g_EngineStats.EndFrame(); g_pStudioRender->EndFrame(); g_pMaterialSystem->EndFrame(); // hack - don't count the first frame in case there are any state // transitions computed on that frame. if( currentFrame != 0 ) { g_BenchResults[currentRun][currentLightCombo].totalTime += g_EngineStats.GetCurrentSystemFrameTime(); g_BenchResults[currentRun][currentLightCombo].totalTris += trisRendered; } for ( int model = 0; model < g_nMaxModels; ++model ) { CStudioHdr studioHdr( g_BenchModels[currentRun][model].pStudioHdr, g_pMDLCache ); AdvanceFrame( &studioHdr, currentRun, model, g_EngineStats.GetCurrentSystemFrameTime() ); } g_pMaterialSystem->SwapBuffers(); #ifdef USE_VPROF g_VProfCurrentProfile.MarkFrame(); static bool bBeenHere = false; if( !bBeenHere ) { bBeenHere = true; g_VProfCurrentProfile.Reset(); } #endif currentFrame++; }