//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // modelIndex - // &origin - // &angles - // *pSolid - // Output : IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreate( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles, solid_t *pSolid ) { vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex ); if ( !pCollide || !pCollide->solidCount ) return NULL; solid_t tmpSolid; if ( !pSolid ) { pSolid = &tmpSolid; if ( !PhysModelParseSolidByIndex( tmpSolid, pEntity, pCollide, -1 ) ) return NULL; } int surfaceProp = -1; if ( pSolid->surfaceprop[0] ) { surfaceProp = physprops->GetSurfaceIndex( pSolid->surfaceprop ); } IPhysicsObject *pObject = physenv->CreatePolyObject( pCollide->solids[pSolid->index], surfaceProp, origin, angles, &pSolid->params ); //PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) ); if ( pObject ) { if ( modelinfo->GetModelType(modelinfo->GetModel(modelIndex)) == mod_brush ) { unsigned int contents = modelinfo->GetModelContents( modelIndex ); Assert(contents!=0); // HACKHACK: contents is used to filter collisions // HACKHACK: So keep solid on for water brushes since they should pass collision rules (as triggers) if ( contents & MASK_WATER ) { contents |= CONTENTS_SOLID; } if ( contents != pObject->GetContents() && contents != 0 ) { pObject->SetContents( contents ); pObject->RecheckCollisionFilter(); } } g_pPhysSaveRestoreManager->AssociateModel( pObject, modelIndex); } return pObject; }
//----------------------------------------------------------------------------- // Purpose: // Input : *pEntity - // modelIndex - // &origin - // &angles - // Output : IPhysicsObject //----------------------------------------------------------------------------- IPhysicsObject *PhysModelCreateUnmoveable( CBaseEntity *pEntity, int modelIndex, const Vector &origin, const QAngle &angles ) { vcollide_t *pCollide = modelinfo->GetVCollide( modelIndex ); if ( !pCollide || !pCollide->solidCount ) return NULL; solid_t solid; if ( !PhysModelParseSolidByIndex( solid, pEntity, pCollide, -1 ) ) return NULL; // collisions are off by default solid.params.enableCollisions = true; //solid.params.mass = 1.0; int surfaceProp = -1; if ( solid.surfaceprop[0] ) { surfaceProp = physprops->GetSurfaceIndex( solid.surfaceprop ); } solid.params.pGameData = static_cast<void *>(pEntity); solid.params.pName = STRING(pEntity->GetModelName()); IPhysicsObject *pObject = physenv->CreatePolyObjectStatic( pCollide->solids[0], surfaceProp, origin, angles, &solid.params ); //PhysCheckAdd( pObject, STRING(pEntity->m_iClassname) ); if ( pObject ) { if ( modelinfo->GetModelType(modelinfo->GetModel(modelIndex)) == mod_brush ) { unsigned int contents = modelinfo->GetModelContents( modelIndex ); Assert(contents!=0); if ( contents != pObject->GetContents() && contents != 0 ) { pObject->SetContents( contents ); pObject->RecheckCollisionFilter(); } } g_pPhysSaveRestoreManager->AssociateModel( pObject, modelIndex); } return pObject; }
IPhysicsObject *PhysCreateWorld_Shared( CBaseEntity *pWorld, vcollide_t *pWorldCollide, const objectparams_t &defaultParams ) { solid_t solid; fluid_t fluid; int surfaceData = physprops->GetSurfaceIndex( "default" ); objectparams_t params = defaultParams; params.pGameData = static_cast<void *>(pWorld); params.pName = "world"; IPhysicsObject *pWorldPhysics = physenv->CreatePolyObjectStatic( pWorldCollide->solids[0], surfaceData, vec3_origin, vec3_angle, ¶ms ); // hint - saves vphysics some work pWorldPhysics->SetCallbackFlags( pWorldPhysics->GetCallbackFlags() | CALLBACK_NEVER_DELETED ); //PhysCheckAdd( world, "World" ); // walk the world keys in case there are some fluid volumes to create IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pWorldCollide ); bool bCreateVirtualTerrain = false; while ( !pParse->Finished() ) { const char *pBlock = pParse->GetCurrentBlockName(); if ( !strcmpi( pBlock, "solid" ) || !strcmpi( pBlock, "staticsolid" ) ) { solid.params = defaultParams; pParse->ParseSolid( &solid, &g_SolidSetup ); solid.params.enableCollisions = true; solid.params.pGameData = static_cast<void *>(pWorld); solid.params.pName = "world"; int surfaceData = physprops->GetSurfaceIndex( "default" ); // already created world above if ( solid.index == 0 ) continue; if ( !pWorldCollide->solids[solid.index] ) { // this implies that the collision model is a mopp and the physics DLL doesn't support that. bCreateVirtualTerrain = true; continue; } // create this as part of the world IPhysicsObject *pObject = physenv->CreatePolyObjectStatic( pWorldCollide->solids[solid.index], surfaceData, vec3_origin, vec3_angle, &solid.params ); // invalid collision model or can't create, ignore if (!pObject) continue; pObject->SetCallbackFlags( pObject->GetCallbackFlags() | CALLBACK_NEVER_DELETED ); Assert( solid.contents != 0 ); pObject->SetContents( solid.contents ); if ( solid.contents & CONTENTS_SOLID ) { pObject->SetCollisionHints(COLLISION_HINT_STATICSOLID); } if ( !pWorldPhysics ) { pWorldPhysics = pObject; } } else if ( !strcmpi( pBlock, "fluid" ) ) { pParse->ParseFluid( &fluid, NULL ); // create a fluid for floating if ( fluid.index > 0 ) { solid.params = defaultParams; // copy world's params solid.params.enableCollisions = true; solid.params.pName = "fluid"; solid.params.pGameData = static_cast<void *>(pWorld); fluid.params.pGameData = static_cast<void *>(pWorld); int surfaceData = physprops->GetSurfaceIndex( fluid.surfaceprop ); // create this as part of the world IPhysicsObject *pWater = physenv->CreatePolyObjectStatic( pWorldCollide->solids[fluid.index], surfaceData, vec3_origin, vec3_angle, &solid.params ); pWater->SetCallbackFlags( pWater->GetCallbackFlags() | CALLBACK_NEVER_DELETED ); physenv->CreateFluidController( pWater, &fluid.params ); } } else if ( !strcmpi( pBlock, "materialtable" ) ) { int surfaceTable[128]; memset( surfaceTable, 0, sizeof(surfaceTable) ); pParse->ParseSurfaceTable( surfaceTable, NULL ); physprops->SetWorldMaterialIndexTable( surfaceTable, 128 ); } else if ( !strcmpi(pBlock, "virtualterrain" ) ) { bCreateVirtualTerrain = true; pParse->SkipBlock(); } else { // unknown chunk??? pParse->SkipBlock(); } } physcollision->VPhysicsKeyParserDestroy( pParse ); if ( bCreateVirtualTerrain && physcollision->SupportsVirtualMesh() ) { PhysCreateVirtualTerrain( pWorld, defaultParams ); } return pWorldPhysics; }