diff --git a/neo/cm/CollisionModel.h b/neo/cm/CollisionModel.h index 6b4c0e7c..290ef29c 100644 --- a/neo/cm/CollisionModel.h +++ b/neo/cm/CollisionModel.h @@ -93,29 +93,36 @@ public: virtual ~idCollisionModelManager() {} // Loads collision models from a map file. - virtual void LoadMap( const idMapFile* mapFile ) = 0; + virtual void LoadMap( const idMapFile* mapFile, bool ignoreOldCollisionFile ) = 0; // Frees all the collision models. virtual void FreeMap() = 0; virtual void Preload( const char* mapName ) = 0; // Gets the clip handle for a model. - virtual cmHandle_t LoadModel( const char* modelName ) = 0; + virtual cmHandle_t LoadModel( const char* modelName, const bool precache ) = 0; + // Sets up a trace model for collision with other trace models. virtual cmHandle_t SetupTrmModel( const idTraceModel& trm, const idMaterial* material ) = 0; + // Creates a trace model from a collision model, returns true if succesfull. virtual bool TrmFromModel( const char* modelName, idTraceModel& trm ) = 0; // Gets the name of a model. virtual const char* GetModelName( cmHandle_t model ) const = 0; + // Gets the bounds of a model. virtual bool GetModelBounds( cmHandle_t model, idBounds& bounds ) const = 0; + // Gets all contents flags of brushes and polygons of a model ored together. virtual bool GetModelContents( cmHandle_t model, int& contents ) const = 0; + // Gets a vertex of a model. virtual bool GetModelVertex( cmHandle_t model, int vertexNum, idVec3& vertex ) const = 0; + // Gets an edge of a model. virtual bool GetModelEdge( cmHandle_t model, int edgeNum, idVec3& start, idVec3& end ) const = 0; + // Gets a polygon of a model. virtual bool GetModelPolygon( cmHandle_t model, int polygonNum, idFixedWinding& winding ) const = 0; @@ -123,14 +130,17 @@ public: virtual void Translation( trace_t* results, const idVec3& start, const idVec3& end, const idTraceModel* trm, const idMat3& trmAxis, int contentMask, cmHandle_t model, const idVec3& modelOrigin, const idMat3& modelAxis ) = 0; + // Rotates a trace model and reports the first collision if any. virtual void Rotation( trace_t* results, const idVec3& start, const idRotation& rotation, const idTraceModel* trm, const idMat3& trmAxis, int contentMask, cmHandle_t model, const idVec3& modelOrigin, const idMat3& modelAxis ) = 0; + // Returns the contents touched by the trace model or 0 if the trace model is in free space. virtual int Contents( const idVec3& start, const idTraceModel* trm, const idMat3& trmAxis, int contentMask, cmHandle_t model, const idVec3& modelOrigin, const idMat3& modelAxis ) = 0; + // Stores all contact points of the trace model with the model, returns the number of contacts. virtual int Contacts( contactInfo_t* contacts, const int maxContacts, const idVec3& start, const idVec6& dir, const float depth, const idTraceModel* trm, const idMat3& trmAxis, int contentMask, @@ -138,13 +148,17 @@ public: // Tests collision detection. virtual void DebugOutput( const idVec3& origin ) = 0; + // Draws a model. virtual void DrawModel( cmHandle_t model, const idVec3& modelOrigin, const idMat3& modelAxis, const idVec3& viewOrigin, const float radius ) = 0; + // Prints model information, use -1 handle for accumulated model info. virtual void ModelInfo( cmHandle_t model ) = 0; + // Lists all loaded models. virtual void ListModels() = 0; + // Writes a collision model file for the given map entity. virtual bool WriteCollisionModelForMapEntity( const idMapEntity* mapEnt, const char* filename, const bool testTraceModel = true ) = 0; }; diff --git a/neo/cm/CollisionModel_load.cpp b/neo/cm/CollisionModel_load.cpp index 5dcaa0e2..b2a4ec93 100644 --- a/neo/cm/CollisionModel_load.cpp +++ b/neo/cm/CollisionModel_load.cpp @@ -4256,7 +4256,7 @@ void idCollisionModelManagerLocal::ListModels() idCollisionModelManagerLocal::BuildModels ================ */ -void idCollisionModelManagerLocal::BuildModels( const idMapFile* mapFile ) +void idCollisionModelManagerLocal::BuildModels( const idMapFile* mapFile, bool ignoreOldCollisionFile ) { int i; const idMapEntity* mapEnt; @@ -4264,9 +4264,8 @@ void idCollisionModelManagerLocal::BuildModels( const idMapFile* mapFile ) idTimer timer; timer.Start(); - if( !LoadCollisionModelFile( mapFile->GetName(), mapFile->GetGeometryCRC() ) ) + if( ignoreOldCollisionFile || !LoadCollisionModelFile( mapFile->GetName(), mapFile->GetGeometryCRC() ) ) { - if( !mapFile->GetNumEntities() ) { return; @@ -4340,7 +4339,7 @@ void idCollisionModelManagerLocal::Preload( const char* mapName ) const preloadEntry_s& p = manifest.GetPreloadByIndex( i ); if( p.resType == PRELOAD_COLLISION ) { - LoadModel( p.resourceName ); + LoadModel( p.resourceName, false ); numLoaded++; } } @@ -4355,7 +4354,7 @@ void idCollisionModelManagerLocal::Preload( const char* mapName ) idCollisionModelManagerLocal::LoadMap ================ */ -void idCollisionModelManagerLocal::LoadMap( const idMapFile* mapFile ) +void idCollisionModelManagerLocal::LoadMap( const idMapFile* mapFile, bool ignoreOldCollisionFile ) { if( mapFile == NULL ) @@ -4398,7 +4397,7 @@ void idCollisionModelManagerLocal::LoadMap( const idMapFile* mapFile ) common->UpdateLevelLoadPacifier(); // build collision models - BuildModels( mapFile ); + BuildModels( mapFile, ignoreOldCollisionFile ); common->UpdateLevelLoadPacifier(); @@ -4544,7 +4543,7 @@ bool idCollisionModelManagerLocal::GetModelPolygon( cmHandle_t model, int polygo idCollisionModelManagerLocal::LoadModel ================== */ -cmHandle_t idCollisionModelManagerLocal::LoadModel( const char* modelName ) +cmHandle_t idCollisionModelManagerLocal::LoadModel( const char* modelName, const bool precache ) { int handle; @@ -4602,6 +4601,12 @@ cmHandle_t idCollisionModelManagerLocal::LoadModel( const char* modelName ) } } + // if only precaching .cm files do not waste memory converting render models + if( precache ) + { + return 0; + } + // try to load a .ASE or .LWO model and convert it to a collision model models[ numModels ] = LoadRenderModel( modelName ); if( models[ numModels ] != NULL ) @@ -4781,7 +4786,7 @@ bool idCollisionModelManagerLocal::TrmFromModel( const char* modelName, idTraceM { cmHandle_t handle; - handle = LoadModel( modelName ); + handle = LoadModel( modelName, false ); if( !handle ) { common->Printf( "idCollisionModelManagerLocal::TrmFromModel: model %s not found.\n", modelName ); diff --git a/neo/cm/CollisionModel_local.h b/neo/cm/CollisionModel_local.h index 0b48388e..77291826 100644 --- a/neo/cm/CollisionModel_local.h +++ b/neo/cm/CollisionModel_local.h @@ -326,13 +326,13 @@ class idCollisionModelManagerLocal : public idCollisionModelManager { public: // load collision models from a map file - void LoadMap( const idMapFile* mapFile ); + void LoadMap( const idMapFile* mapFile, bool ignoreOldCollisionFile ); // frees all the collision models void FreeMap(); void Preload( const char* mapName ); // get clip handle for model - cmHandle_t LoadModel( const char* modelName ); + cmHandle_t LoadModel( const char* modelName, const bool precache ); // sets up a trace model for collision with other trace models cmHandle_t SetupTrmModel( const idTraceModel& trm, const idMaterial* material ); // create trace model from a collision model, returns true if succesfull @@ -502,7 +502,7 @@ private: // CollisionMap_load.cpp void RemapEdges( cm_node_t* node, int* edgeRemap ); void OptimizeArrays( cm_model_t* model ); void FinishModel( cm_model_t* model ); - void BuildModels( const idMapFile* mapFile ); + void BuildModels( const idMapFile* mapFile, bool ignoreOldCollisionFile ); cmHandle_t FindModel( const char* name ); cm_model_t* CollisionModelForMapEntity( const idMapEntity* mapEnt ); // brush/patch model from .map cm_model_t* LoadRenderModel( const char* fileName ); // ASE/LWO models diff --git a/neo/d3xp/Game_local.cpp b/neo/d3xp/Game_local.cpp index 2ab30f38..f5dc80bb 100644 --- a/neo/d3xp/Game_local.cpp +++ b/neo/d3xp/Game_local.cpp @@ -976,7 +976,7 @@ void idGameLocal::LoadMap( const char* mapName, int randseed ) mapFileName = mapFile->GetName(); // load the collision map - collisionModelManager->LoadMap( mapFile ); + collisionModelManager->LoadMap( mapFile, false ); collisionModelManager->Preload( mapName ); numClients = 0; @@ -1894,7 +1894,7 @@ void idGameLocal::CacheDictionaryMedia( const idDict* dict ) renderModelManager->FindModel( kv->GetValue() ); // precache .cm files only - collisionModelManager->LoadModel( kv->GetValue() ); + collisionModelManager->LoadModel( kv->GetValue(), true ); } } kv = dict->MatchPrefix( "model", kv ); diff --git a/neo/d3xp/Target.cpp b/neo/d3xp/Target.cpp index 634895af..fd32eada 100644 --- a/neo/d3xp/Target.cpp +++ b/neo/d3xp/Target.cpp @@ -851,8 +851,9 @@ void idTarget_SetModel::Spawn() { // precache the render model renderModelManager->FindModel( model ); + // precache .cm files only - collisionModelManager->LoadModel( model ); + collisionModelManager->LoadModel( model, true ); } } diff --git a/neo/d3xp/physics/Clip.cpp b/neo/d3xp/physics/Clip.cpp index 362e98fa..21455f07 100644 --- a/neo/d3xp/physics/Clip.cpp +++ b/neo/d3xp/physics/Clip.cpp @@ -329,7 +329,7 @@ bool idClipModel::LoadModel( const char* name ) FreeTraceModel( traceModelIndex ); traceModelIndex = -1; } - collisionModelHandle = collisionModelManager->LoadModel( name ); + collisionModelHandle = collisionModelManager->LoadModel( name, false ); if( collisionModelHandle ) { collisionModelManager->GetModelBounds( collisionModelHandle, bounds ); @@ -560,7 +560,7 @@ void idClipModel::Restore( idRestoreGame* savefile ) savefile->ReadString( collisionModelName ); if( collisionModelName.Length() ) { - collisionModelHandle = collisionModelManager->LoadModel( collisionModelName ); + collisionModelHandle = collisionModelManager->LoadModel( collisionModelName, false ); } else { @@ -788,7 +788,7 @@ idClipModel::CheckModel */ cmHandle_t idClipModel::CheckModel( const char* name ) { - return collisionModelManager->LoadModel( name ); + return collisionModelManager->LoadModel( name, false ); } @@ -887,9 +887,11 @@ void idClip::Init() memset( clipSectors, 0, MAX_SECTORS * sizeof( clipSector_t ) ); numClipSectors = 0; touchCount = -1; + // get world map bounds - h = collisionModelManager->LoadModel( "worldMap" ); + h = collisionModelManager->LoadModel( "worldMap", false ); collisionModelManager->GetModelBounds( h, worldBounds ); + // create world sectors CreateClipSectors_r( 0, worldBounds, maxSector ); diff --git a/neo/tools/compilers/dmap/dmap.cpp b/neo/tools/compilers/dmap/dmap.cpp index 47068565..dd5dd262 100644 --- a/neo/tools/compilers/dmap/dmap.cpp +++ b/neo/tools/compilers/dmap/dmap.cpp @@ -456,17 +456,16 @@ void Dmap( const idCmdArgs& args ) if( !leaked ) { - if( !noCM ) { - // make sure the collision model manager is not used by the game cmdSystem->BufferCommandText( CMD_EXEC_NOW, "disconnect" ); // create the collision map start = Sys_Milliseconds(); - collisionModelManager->LoadMap( dmapGlobals.dmapFile ); + // write always a fresh .cm file + collisionModelManager->LoadMap( dmapGlobals.dmapFile, true ); collisionModelManager->FreeMap(); end = Sys_Milliseconds();