Collision Map Asset (BO2)

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. Black Ops 2 still has 2 clip map asset types (col_map_sp and col_map_mp) and they are loaded exactly the same.

/* The following flags were obtained from Com_SurfaceTypeFromName */
 
/* ClipMaterial->contentFlags */
#define CONTENTS_CANSHOOTCLIP 	0x40
#define CONTENTS_CLIPMISSILE 	0x80
#define CONTENTS_VEHICLECLIP 	0x200
#define CONTENTS_ITEMCLIP 	0x400
#define CONTENTS_SKY 		0x800
#define CONTENTS_AI_NOSIGHT 	0x1000
#define CONTENTS_CLIPSHOT 	0x2000
#define CONTENTS_PLAYERCLIP 	0x10000
#define CONTENTS_MONSTERCLIP 	0x20000
#define CONTENTS_MANTLEON 	0x1000000
#define CONTENTS_MANTLEOVER 	0x1000000
#define CONTENTS_MOUNT 		0x1000000
#define CONTENTS_DETAIL 	0x8000000
#define CONTENTS_STRUCTURAL 	0x10000000
#define CONTENTS_NODROP 	0x80000000
 
/* ClipMaterial->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_NODRAW 		0x80
#define SURF_NOPENETRATE 	0x100
#define SURF_NORECEIVEDYNAMICSHADOW 	0x800
#define SURF_CAULK 		0x1000
#define SURF_NOSTEPS 		0x2000
#define SURF_NONSOLID 		0x4000
#define SURF_AREALIGHT 		0x8000
#define SURF_NODLIGHT 		0x20000
#define SURF_NOCASTSHADOW 	0x40000
#define SURF_ONLYCASTSHADOW 	0x80000
#define SURF_OPAQUEGLASS 	0x900000
#define SURF_MANTLEON 		0x4000000
#define SURF_MANTLEOVER 	0x8000000
#define SURF_MOUNT 		0x10000000
#define SURF_PORTAL 		0x80000000
 
enum rope_constraint_e
{
  ROPE_PAIR_CONSTRAINT = 0x0,
  ROPE_WORLD_CONSTRAINT = 0x1,
  ROPE_DENTITY_CONSTRAINT = 0x2,
  ROPE_CENTITY_CONSTRAINT = 0x3,
};
 
enum DynEntityType
{
  DYNENT_TYPE_INVALID = 0x0,
  DYNENT_TYPE_CLUTTER = 0x1,
  DYNENT_TYPE_DESTRUCT = 0x2,
  DYNENT_TYPE_COUNT = 0x3
};
 
struct cStaticModelWritable
{
  unsigned __int16 nextModelInWorldSector;
};
 
struct cplane_s
{
  float normal[3];
  float dist;
  char type;
  char signbits;
};
 
#pragma pack(push, 2)
struct cbrushside_t
{
  cplane_s *plane;
  int cflags;
  int sflags;
};
#pragma pack(pop)
 
struct __declspec(align(8)) cbrush_t //Total size = 0x60
{
  vec3_t mins;
  int contents;
  vec3_t maxs;
  unsigned int numsides;
  cbrushside_t *sides;
  int axial_cflags[2][3];
  int axial_sflags[2][3];
  unsigned int numverts;
  vec3_t *verts; //Only 1 is loaded, at least on 360.
};
 
#pragma pack(push, 4)
struct cplane_s
{
  float normal[3];
  float dist;
  char type;
  char signbits;
};
 
struct cStaticModel_s
{
  cStaticModelWritable writable;
  XModel *xmodel;
  int contents;
  vec3_t origin;
  vec3_t invScaledAxis[3];
  vec3_t absmin;
  vec3_t absmax;
};
 
struct ClipMaterial
{
  const char *name;
  int surfaceFlags;
  int contentFlags;
};
 
struct cNode_t
{
  cplane_s *plane;
  __int16 children[2];
};
 
struct cLeaf_s
{
  unsigned __int16 firstCollAabbIndex;
  unsigned __int16 collAabbCount;
  int brushContents;
  int terrainContents;
  vec3_t mins;
  vec3_t maxs;
  int leafBrushNode;
  __int16 cluster;
};
 
struct cLeafBrushNodeLeaf_t
{
  unsigned __int16 *brushes;
};
 
struct cLeafBrushNodeChildren_t
{
  float dist;
  float range;
  unsigned __int16 childOffset[2];
};
 
union cLeafBrushNodeData_t
{
  cLeafBrushNodeLeaf_t leaf;
  cLeafBrushNodeChildren_t children;
};
 
struct cLeafBrushNode_s
{
  char axis;
  __int16 leafBrushCount;
  int contents;
  cLeafBrushNodeData_t data;
};
 
const struct CollisionPartition
{
  char triCount;
  int firstTri;
  int nuinds;
  int fuind;
};
 
union CollisionAabbTreeIndex
{
  int firstChildIndex;
  int partitionIndex;
};
 
struct CollisionAabbTree
{
  vec3_t origin;
  unsigned __int16 materialIndex;
  unsigned __int16 childCount;
  vec3_t halfSize;
  CollisionAabbTreeIndex u;
};
 
struct GfxPlacement
{
  vec4_t quat;
  vec3_t origin;
};
 
struct XModelPiece
{
  XModel *model;
  float offset[3];
};
 
struct XModelPieces
{
  const char * name;
  int numpieces;
  XModelPiece *pieces;
};
 
struct DynEntityDef
{
  DynEntityType type;
  GfxPlacement pose;
  XModel *xModel;
  XModel *destroyedxModel;
  unsigned __int16 brushModel;
  unsigned __int16 physicsBrushModel;
  FxEffectDef *destroyFx;
  unsigned int destroySound;
  XModelPieces *destroyPieces;
  PhysPreset *physPreset;
  __int16 physConstraints[4];
  int health;
  int flags;
  int contents;
  ScriptString targetname;
  ScriptString target;
};
 
struct DynEntityPose
{
  GfxPlacement pose;
  float radius;
};
 
struct Bounds
{
  vec3_t midPoint;
  vec3_t halfSize;
};
 
struct ClipInfo
{
  int planeCount;
  cplane_s *planes;
  unsigned int numMaterials;
  ClipMaterial *materials;
  unsigned int numBrushSides;
  cbrushside_t *brushsides;
  unsigned int leafbrushNodesCount;
  cLeafBrushNode_s *leafbrushNodes;
  unsigned int numLeafBrushes;
  unsigned __int16 *leafbrushes;
  unsigned int brushVertCount;
  vec3_t *brushVerts;
  unsigned int nuinds;
  unsigned __int16 *uinds;
  unsigned __int16 numBrushes;
  cbrush_t *brushes;
  Bounds *brushBounds;
  int *brushContents;
};
 
struct cmodel_t
{
  vec3_t mins;
  vec3_t maxs;
  float radius;
  ClipInfo *info;
  cLeaf_s leaf;
};
 
struct DynEntityClient
{
  int physObjId;
  unsigned __int16 flags;
  unsigned __int16 lightingHandle;
  int health;
  unsigned __int16 burnTime;
  unsigned __int16 fadeTime;
  int physicsStartTime;
};
 
struct DynEntityServer
{
  unsigned __int16 flags;
  int health;
};
 
struct DynEntityColl
{
  unsigned __int16 sector;
  unsigned __int16 nextEntInSector;
  vec3_t linkMins;
  vec3_t linkMaxs;
  int contents;
};
 
struct par_t
{
  vec3_t p;
  vec3_t p0;
  vec3_t p_prev;
  int flags;
};
 
struct constraint_t
{
  vec3_t p;
  rope_constraint_e type;
  int entity_index;
  int bone_name_hash;
  char pi1;
  char pi2;
};
 
struct rope_frame_verts_t
{
  int num_verts;
  vec3_t v[50];
};
 
struct rope_client_verts_t
{
  rope_frame_verts_t frame_verts[2];
  unsigned int frame_index;
};
 
struct rope_t
{
  par_t m_particles[25];
  constraint_t m_constraints[30];
  int m_entity_anchors[3];
  int m_num_particles;
  int m_num_constraints;
  int m_num_entity_anchors;
  int m_num_draw_verts;
  rope_client_verts_t m_client_verts;
  vec3_t m_min;
  vec3_t m_max;
  vec3_t m_start;
  vec3_t m_end;
  int m_in_use;
  int m_visible;
  int m_dist_constraint;
  int m_flags;
  Material *m_material;
  float m_seglen;
  float m_length;
  float m_width;
  float m_scale;
  float m_force_scale;
  int m_health;
  int m_frame;
  int m_stable_count;
  int m_static_rope;
  unsigned __int16 m_lightingHandle;
};
 
struct clipMap_t
{
  const char *name;
  int isInUse;
  ClipInfo info;
  ClipInfo *pInfo;
  unsigned int numStaticModels;
  cStaticModel_s *staticModelList;
  unsigned int numNodes;
  cNode_t *nodes;
  unsigned int numLeafs;
  cLeaf_s *leafs;
  unsigned int vertCount;
  vec3_t *verts;
  int triCount;
  unsigned __int16 *triIndices;
  char *triEdgeIsWalkable; //Size = ((triCount << 1) + triCount + 0x1F) >> 3 << 2
  int partitionCount;
  CollisionPartition *partitions;
  int aabbTreeCount;
  CollisionAabbTree *aabbTrees;
  unsigned int numSubModels;
  cmodel_t *cmodels;
  int numClusters;
  int clusterBytes;
  char *visibility; //Size = numClusters * clusterBytes
  int vised;
  MapEnts *mapEnts;
  cbrush_t *box_brush;
  cmodel_t box_model;
  unsigned __int16 originalDynEntCount;
  unsigned __int16 dynEntCount[4];  //Refer to DYNENT_COLL_TYPE
  DynEntityDef *dynEntDefList[2];
  DynEntityPose *dynEntPoseList[2];
  DynEntityClient *dynEntClientList[2];
  DynEntityServer *dynEntServerList[2];
  DynEntityColl *dynEntCollList[4];
  int num_constraints;
  PhysConstraint *constraints;
  int max_ropes;
  rope_t *ropes;
  int checksum;
};
#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.