Collision Map Asset (MW2)

From COD Engine Research
Jump to: navigation, search

The collision map (or clip map) has existed on every Call of Duty so far and is part of the D3DBSP system produced by Radiant. Modern Warfare 2 has 2 clip map asset types (col_map_sp and col_map_mp) and they are loaded exactly the same.

/* dmaterial_t->contentFlags */
#define CONTENTS_NONE		0x0
#define CONTENTS_SOLID		0x1
#define CONTENTS_FOLIAGE	0x2
#define CONTENTS_AI_AVOID	0x4
#define CONTENTS_VEHICLETRIGGER	0x8
#define CONTENTS_GLASS		0x10
#define CONTENTS_WATER		0x20
#define CONTENTS_CANSHOOTCLIP	0x40
#define CONTENTS_CLIPMISSILE	0x80
#define CONTENTS_ITEM		0x100
#define CONTENTS_VEHICLECLIP	0x200
#define CONTENTS_ITEMCLIP	0x400
#define CONTENTS_SKY		0x800
#define CONTENTS_AI_NOSIGHT	0x1000
#define CONTENTS_CLIPSHOT	0x2000
#define CONTENTS_ACTOR		0x4000
#define CONTENTS_FAKE_ACTOR	0x8000
#define CONTENTS_PLAYERCLIP	0x10000
#define CONTENTS_MONSTERCLIP	0x20000
#define CONTENTS_AXISTRIGGER	0x40000
#define CONTENTS_ALLIESTRIGGER	0x80000
#define CONTENTS_NEUTRALTRIGGER		0x100000
#define CONTENTS_USE			0x200000
#define CONTENTS_NONSENTIENTTRIGGER	0x400000
#define CONTENTS_VEHICLE		0x800000
#define CONTENTS_MANTLE		0x1000000
#define CONTENTS_PLAYER		0x2000000
#define CONTENTS_CORPSE		0x4000000
#define CONTENTS_DETAIL		0x8000000
#define CONTENTS_STRUCTURAL	0x10000000
#define CONTENTS_LOOKAT		0x20000000
#define CONTENTS_TRANSLUCENT	0x20000000
#define CONTENTS_PLAYERTRIGGER	0x40000000
#define CONTENTS_NODROP		0x80000000
 
/* dmaterial_t->surfaceFlags */
#define SURF_NODAMAGE	0x1
#define SURF_SLICK	0x2
#define SURF_SKY	0x4
#define SURF_LADDER	0x8
#define SURF_NOIMPACT		0x10
#define SURF_NOMARKS		0x20
#define SURF_HDRPORTAL		0x40
#define SURF_NODRAW		0x80
#define SURF_NOPENETRATE	0x100
#define SURF_STAIRS		0x200
#define SURF_NOLIGHTMAP		0x400
#define SURF_SOFT		0x1000
#define SURF_NOSTEPS		0x2000
#define SURF_NONSOLID		0x4000
#define SURF_NODLIGHT		0x20000
#define SURF_NOCASTSHADOW	0x40000
#define SURF_MANTLEOVER	0x1000000
#define SURF_MANTLEON	0x2000000
#define SURF_PORTAL	0x80000000
 
typedef char cbrushedge_t;
 
#pragma pack(push, 4)
struct cplane_s
{
  float normal[3];
  float dist;
  char type;
  char signbits;
};
 
struct cStaticModel_s
{
  XModel *xmodel;
  float origin[3];
  float invScaledAxis[3][3];
  float absmin[3];
  float absmax[3];
};
 
struct dmaterial_t
{
  char * material;
  int surfaceFlags;
  int contentFlags;
};
 
struct cbrushside_t
{
  cplane_s *plane;
  unsigned int materialNum;
};
 
struct cNode_t
{
  cplane_s *plane;
  __int16 children[2];
};
 
struct cLeaf_t
{
  unsigned __int16 firstCollAabbIndex;
  unsigned __int16 collAabbCount;
  int brushContents;
  int terrainContents;
  float mins[3];
  float maxs[3];
  int leafBrushNode;
};
 
struct cLeafBrushNodeLeaf_t
{
  unsigned __int16 *brushes;
};
 
struct cLeafBrushNodeChildren_t
{
  float dist;
  float range;
  unsigned __int16 childOffset[6];
};
 
union cLeafBrushNodeData_t
{
  cLeafBrushNodeLeaf_t leaf;
  cLeafBrushNodeChildren_t children;
};
 
struct cLeafBrushNode_s
{
  char axis;
  __int16 leafBrushCount;
  int contents;
  cLeafBrushNodeData_t data;
};
 
struct CollisionBorder
{
  float distEq[3];
  float zBase;
  float zSlope;
  float start;
  float length;
};
 
struct CollisionPartition
{
  char triCount;
  char borderCount;
  int firstTri;
  CollisionBorder *borders;
};
 
union CollisionAabbTreeIndex
{
  int firstChildIndex;
  int partitionIndex;
};
 
struct CollisionAabbTree
{
  float origin[3];
  float halfSize[3];
  unsigned __int16 materialIndex;
  unsigned __int16 childCount;
  CollisionAabbTreeIndex u;
};
 
struct cmodel_t
{
  float mins[3];
  float maxs[3];
  float radius;
  cLeaf_t leaf;
};
 
struct cbrush_t
{
  int contents;
  cbrushside_t * sides;
  cbrushedge_t * edge;
       char unknown[0x18];
};
 
enum DynEntityType
{
  DYNENT_TYPE_INVALID = 0x0,
  DYNENT_TYPE_CLUTTER = 0x1,
  DYNENT_TYPE_DESTRUCT = 0x2,
  DYNENT_TYPE_COUNT = 0x3,
};
 
struct GfxPlacement
{
  float quat[4];
  float origin[3];
};
 
struct PhysMass
{
  float centerOfMass[3];
  float momentsOfInertia[3];
  float productsOfInertia[3];
};
 
struct DynEntityDef
{
  DynEntityType type;
  GfxPlacement pose;
  XModel *xModel;
  unsigned __int16 brushModel;
  unsigned __int16 physicsBrushModel;
  FxEffectDef *destroyFx;
  PhysPreset *physPreset;
  int health;
  PhysMass mass;
  int contents;
};
 
struct DynEntityPose
{
  GfxPlacement pose;
  float radius;
};
 
struct DynEntityClient
{
  int physObjId;
  unsigned __int16 flags;
  unsigned __int16 lightingHandle;
  int health;
};
 
struct DynEntityColl
{
  unsigned __int16 sector;
  unsigned __int16 nextEntInSector;
  float linkMins[2];
  float linkMaxs[2];
};
 
struct clipMap_t
{
  const char *name;
       int unknown1;
  int planeCount;
  cplane_s *planes;
  unsigned int numStaticModels;
  cStaticModel_s *staticModelList;
  unsigned int numMaterials;
  dmaterial_t *materials;
  unsigned int numBrushSides;
  cbrushside_t *brushsides;
  unsigned int numBrushEdges;
  cbrushedge_t *brushEdges;
  unsigned int numNodes;
  cNode_t *nodes;
  unsigned int numLeafs;
  cLeaf_t *leafs;
  unsigned int leafbrushNodesCount;
  cLeafBrushNode_s *leafbrushNodes; //Leafbrushes loaded before this in FFs.
  unsigned int numLeafBrushes;
  unsigned __int16 *leafbrushes;
  unsigned int numLeafSurfaces;
  unsigned int *leafsurfaces;
  unsigned int vertCount;
  float (*verts)[3];
  int triCount;
  unsigned __int16 *triIndices;
  char *triEdgeIsWalkable; //Size = ((triCount << 1) + triCount + 0x1F) >> 3 << 2
  int borderCount;
  CollisionBorder *borders;
  int partitionCount;
  CollisionPartition *partitions;
  int aabbTreeCount;
  CollisionAabbTree *aabbTrees;
  unsigned int numSubModels;
  cmodel_t *cmodels;
  unsigned __int16 numBrushes;
  cbrush_t *brushes;
       char * unknown2;   //Size = ((numBrushes << 1) + numBrushes) << 3
       char * unknown3;   //Size = numBrushes << 2
  MapEnts *mapEnts;
       unsigned __int16 unknownCount1;
       char * unknown4;   //Size = unknownCount1 * 0x1C
  unsigned __int16 dynEntCount[2];
  DynEntityDef *dynEntDefList[2];
  DynEntityPose *dynEntPoseList[2];
  DynEntityClient *dynEntClientList[2];
  DynEntityColl *dynEntCollList[2];
  unsigned int checksum;
	char unknown5[0x30];
};
#pragma pack(pop)

Keep in mind that the checksum is checked on other clients using the mapcrc dvar.

Source Format

The currently accepted source format is to dump the verticies and faces to "raw/maps/mp/(MAPNAME).d3dbsp.obj" because obj files are simple and easy to dump to. This clearly skips most of the clip map, so a more effiecient dumping method must be found.