void InitVPhysics() { CreateInterfaceFn physicsFactory = GetPhysicsFactory(); physcollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL ); physprops = (IPhysicsSurfaceProps *)physicsFactory( VPHYSICS_SURFACEPROPS_INTERFACE_VERSION, NULL ); LoadSurfacePropsAll(); }
//----------------------------------------------------------------------------- // Purpose: Loads the surface properties database into the physics DLL //----------------------------------------------------------------------------- void LoadSurfaceProperties( void ) { CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( !physicsFactory ) return; physprops = (IPhysicsSurfaceProps *)physicsFactory( VPHYSICS_SURFACEPROPS_INTERFACE_VERSION, NULL ); const char *SURFACEPROP_MANIFEST_FILE = "scripts/surfaceproperties_manifest.txt"; KeyValues *manifest = new KeyValues( SURFACEPROP_MANIFEST_FILE ); if ( manifest->LoadFromFile( g_pFileSystem, SURFACEPROP_MANIFEST_FILE, "GAME" ) ) { for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() ) { if ( !Q_stricmp( sub->GetName(), "file" ) ) { // Add LoadSurfacePropFile( sub->GetString() ); continue; } } } manifest->deleteThis(); }
void CVradStaticPropMgr::Init() { CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( !physicsFactory ) Error( "Unable to load vphysics DLL." ); s_pPhysCollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL ); if( !s_pPhysCollision ) { Error( "Unable to get '%s' for physics interface.", VPHYSICS_COLLISION_INTERFACE_VERSION ); return; } m_pBSPTreeData->Init( ToolBSPTree() ); // Read in static props that have been compiled into the bsp file UnserializeStaticProps(); }
//----------------------------------------------------------------------------- // Purpose: Loads the surface properties database into the physics DLL //----------------------------------------------------------------------------- void LoadSurfaceProperties( void ) { CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( !physicsFactory ) return; physprops = (IPhysicsSurfaceProps *)physicsFactory( VPHYSICS_SURFACEPROPS_INTERFACE_VERSION, NULL ); char buf[1024]; strcpy( buf, gamedir ); strcat( buf, pMaterialFilename ); FILE *fp = fopen( buf, "rb" ); if ( !fp ) { // try base game dir strcpy( buf, basegamedir ); strcat( buf, pMaterialFilename ); fp = fopen( buf, "rb" ); if ( !fp ) return; } fseek( fp, 0, SEEK_END ); int len = ftell(fp); fseek( fp, 0, SEEK_SET ); char *pText = new char[len]; fread( pText, len, 1, fp ); fclose( fp ); physprops->ParseSurfaceData( pMaterialFilename, pText ); delete[] pText; }
// This is the only public entry to this file. // The global data touched in the file is: // from bsplib.h: // g_pPhysCollide : This is an output from this file. // g_PhysCollideSize : This is set in this file. // g_numdispinfo : This is an input to this file. // g_dispinfo : This is an input to this file. // numnodewaterdata : This is an output from this file. // dleafwaterdata : This is an output from this file. // from vbsp.h: // g_SurfaceProperties : This is an input to this file. void EmitPhysCollision() { ClearLeafWaterData(); CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( physicsFactory ) { physcollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL ); } if ( !physcollision ) { Warning("!!! WARNING: Can't build collision data!\n" ); return; } CUtlVector<CPhysCollisionEntry *> collisionList[MAX_MAP_MODELS]; CTextBuffer *pTextBuffer[MAX_MAP_MODELS]; int physModelCount = 0, totalSize = 0; int start = Plat_FloatTime(); Msg("Building Physics collision data...\n" ); int i, j; for ( i = 0; i < nummodels; i++ ) { // Build a list of collision models for this brush model section if ( i == 0 ) { // world is the only model that processes water separately. // other brushes are assumed to be completely solid or completely liquid BuildWorldPhysModel( collisionList[i], NO_SHRINK, VPHYSICS_MERGE); } else { ConvertModelToPhysCollide( collisionList[i], i, MASK_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|MASK_WATER, VPHYSICS_SHRINK, VPHYSICS_MERGE ); } pTextBuffer[i] = NULL; if ( !collisionList[i].Count() ) continue; // if we've got collision models, write their script for processing in the game pTextBuffer[i] = new CTextBuffer; for ( j = 0; j < collisionList[i].Count(); j++ ) { // dump a text file for visualization if ( dumpcollide ) { collisionList[i][j]->DumpCollide( pTextBuffer[i], i, j ); } // each model knows how to write its script collisionList[i][j]->WriteToTextBuffer( pTextBuffer[i], i, j ); // total up the binary section's size totalSize += collisionList[i][j]->GetCollisionBinarySize() + sizeof(int); } // These sections only appear in the world's collision text if ( i == 0 ) { if ( !g_bNoVirtualMesh && physcollision->SupportsVirtualMesh() ) { pTextBuffer[i]->WriteText("virtualterrain {}\n"); } if ( s_WorldPropList.Count() ) { pTextBuffer[i]->WriteText( "materialtable {\n" ); for ( j = 0; j < s_WorldPropList.Count(); j++ ) { int propIndex = s_WorldPropList[j]; if ( propIndex < 0 ) { pTextBuffer[i]->WriteIntKey( "default", j+1 ); } else { pTextBuffer[i]->WriteIntKey( physprops->GetPropName( propIndex ), j+1 ); } } pTextBuffer[i]->WriteText( "}\n" ); } } pTextBuffer[i]->Terminate(); // total lump size includes the text buffers (scripts) totalSize += pTextBuffer[i]->GetSize(); physModelCount++; } // add one for tail of list marker physModelCount++; // DWORD align the lump because AddLump assumes that it is DWORD aligned. byte *ptr ; g_PhysCollideSize = totalSize + (physModelCount * sizeof(dphysmodel_t)); g_pPhysCollide = (byte *)malloc(( g_PhysCollideSize + 3 ) & ~3 ); memset( g_pPhysCollide, 0, g_PhysCollideSize ); ptr = g_pPhysCollide; for ( i = 0; i < nummodels; i++ ) { if ( pTextBuffer[i] ) { int j; dphysmodel_t model; model.modelIndex = i; model.solidCount = collisionList[i].Count(); model.dataSize = sizeof(int) * model.solidCount; for ( j = 0; j < model.solidCount; j++ ) { model.dataSize += collisionList[i][j]->GetCollisionBinarySize(); } model.keydataSize = pTextBuffer[i]->GetSize(); // store the header memcpy( ptr, &model, sizeof(model) ); ptr += sizeof(model); for ( j = 0; j < model.solidCount; j++ ) { int collideSize = collisionList[i][j]->GetCollisionBinarySize(); // write size memcpy( ptr, &collideSize, sizeof(int) ); ptr += sizeof(int); // now write the collision model collisionList[i][j]->WriteCollisionBinary( reinterpret_cast<char *>(ptr) ); ptr += collideSize; } memcpy( ptr, pTextBuffer[i]->GetData(), pTextBuffer[i]->GetSize() ); ptr += pTextBuffer[i]->GetSize(); } delete pTextBuffer[i]; } dphysmodel_t model; // Mark end of list model.modelIndex = -1; model.dataSize = -1; model.keydataSize = 0; model.solidCount = 0; memcpy( ptr, &model, sizeof(model) ); ptr += sizeof(model); Assert( (ptr-g_pPhysCollide) == g_PhysCollideSize); Msg("done (%d) (%d bytes)\n", (int)(Plat_FloatTime() - start), g_PhysCollideSize ); // UNDONE: Collision models (collisionList) memory leak! }
void EmitStaticProps() { CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( physicsFactory ) { s_pPhysCollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL ); if( !s_pPhysCollision ) return; } // Generate a list of lighting origins, and strip them out int i; for ( i = 0; i < num_entities; ++i) { char* pEntity = ValueForKey(&entities[i], "classname"); if (!Q_strcmp(pEntity, "info_lighting")) { s_LightingInfo.AddToTail(i); } } // Emit specifically specified static props for ( i = 0; i < num_entities; ++i) { char* pEntity = ValueForKey(&entities[i], "classname"); if (!strcmp(pEntity, "static_prop") || !strcmp(pEntity, "prop_static")) { StaticPropBuild_t build; GetVectorForKey( &entities[i], "origin", build.m_Origin ); GetAnglesForKey( &entities[i], "angles", build.m_Angles ); build.m_pModelName = ValueForKey( &entities[i], "model" ); build.m_Solid = IntForKey( &entities[i], "solid" ); build.m_Skin = IntForKey( &entities[i], "skin" ); build.m_FadeMaxDist = FloatForKey( &entities[i], "fademaxdist" ); build.m_Flags = 0;//IntForKey( &entities[i], "spawnflags" ) & STATIC_PROP_WC_MASK; if (IntForKey( &entities[i], "disableshadows" ) == 1) { build.m_Flags |= STATIC_PROP_NO_SHADOW; } if (IntForKey( &entities[i], "disablevertexlighting" ) == 1) { build.m_Flags |= STATIC_PROP_NO_PER_VERTEX_LIGHTING; } if (IntForKey( &entities[i], "disableselfshadowing" ) == 1) { build.m_Flags |= STATIC_PROP_NO_SELF_SHADOWING; } if (IntForKey( &entities[i], "screenspacefade" ) == 1) { build.m_Flags |= STATIC_PROP_SCREEN_SPACE_FADE; } const char *pKey = ValueForKey( &entities[i], "fadescale" ); if ( pKey && pKey[0] ) { build.m_flForcedFadeScale = FloatForKey( &entities[i], "fadescale" ); } else { build.m_flForcedFadeScale = 1; } build.m_FadesOut = (build.m_FadeMaxDist > 0); build.m_pLightingOrigin = ValueForKey( &entities[i], "lightingorigin" ); if (build.m_FadesOut) { build.m_FadeMinDist = FloatForKey( &entities[i], "fademindist" ); if (build.m_FadeMinDist < 0) { build.m_FadeMinDist = build.m_FadeMaxDist; } } else { build.m_FadeMinDist = 0; } AddStaticPropToLump( build ); // strip this ent from the .bsp file entities[i].epairs = 0; } } // Strip out lighting origins; has to be done here because they are used when // static props are made for ( i = s_LightingInfo.Count(); --i >= 0; ) { // strip this ent from the .bsp file entities[s_LightingInfo[i]].epairs = 0; } SetLumpData( ); }