model_collision_geometry

Model collision geometry tags contain collision data for an object. This is in contrast to model/gbxmodel tags, which contain the renderable data. Collision meshes tend to be less detailed than render meshes.

Beyond having a collision mesh, these tags can also contain:

  • Pathfinding spheres which prevent AI from trying to walk through the object
  • Damage ratios for each part of the object (e.g. weak points)
  • Shield and health values

Collision geometry, rather than the model, is used to cast scenery shadows in lightmaps.

Pathfinding spheres #

Pathfinding spheres visible in Sapien

Pathfinding spheres (blue) for a50 shown in Sapien after running debug_objects_pathfinding_spheres 1

AI can figure out where to go by checking the pathfinding data on the BSP. However, since objects like scenery and units are not part of the BSP, Bungie implemented pathfinding spheres: spherical markers on objects that AI actively avoid walking into.

By placing these spheres in an object's collision model, artists can tell the AI exactly where not. As far as we know, all object types can make use of pathfinding spheres. The object's bounding sphere does not seem to affect AI avoidance of them.

How to add them #

Pathfinding spheres are imported from the collision jms file of your object. They are marked with #pathfinder and their radius is the actual radius that the AI will avoid walking in relation to the mid-point.

Pathfinding spheres can also be created automatically in some cases:

  • When an artist doesn't specify any pathfinding spheres, the game will assume one at the object's origin at half the size of the bounding sphere (which can be either too small or too big).
  • Vehicle mass points (see physics) also count as pathfinding spheres. AI will actively avoid these.
  • Bipeds by default also have a pathfinding sphere around their feet with the same width as their physics pill.

Limits #

model_collision_geometry tags can only have up to 16 pathfinding spheres(confirmation needed), up to 8 regions, and up to 33 permutations to a region.

  • debug_objects_pathfinding_spheres 1 Can be used to view pathfinding spheres in Sapien.

Animation #

Unlike BSPs, collision geometry can have a self-intersecting mesh. However, this is only permitted between meshes parented by different nodes (e.g. limbs of a biped intersecting each other or the torso). Collision geometry cannot have weighted skinning for animations, so rigidly follows parent nodes in animations.

Phantom BSP #

Phantom BSP exists in the collision model of covenant crates.

Although phantom BSP is typically seen in the context of level geometry, it can also affect model collision geometry because this tag uses the same collision data structures as a scenario_structure_bsp. In the case of models, phantom BSP is limited to the object's bounding radius.

Like with level geometry, these can be troubleshooted in Sapien by running the console commands:

collision_debug 1
collision_debug_phantom_bsp 1

To fix them, use similar tricks as fixing level phantom BSP: avoiding nearly co-planar faces and slightly altering the collision model around the problematic location.

Structure and fields #

Field Type Comments
flags bitfield(32)
Flag Mask Comments
takes shield damage for children 0x1
takes body damage for children 0x2
always shields friendly damage 0x4
passes area damage to children 0x8
parent never takes body damage for us 0x10
only damaged by explosives 0x20
only damaged while occupied 0x40
indirect damage material Index: u16
pad(2)
maximum body vitality f32

Sets the maximum amount of health that a unit has (damage hit points). For example, the cyborg biped has a value of 75. This value can also be changed at runtime for individual units by using unit_set_maximum_vitality in scripts.

body system shock f32
pad(24)
pad(28)
friendly damage resistance Fraction: f32
  • Maximum: 1
pad(8)
pad(32)
area damage effect threshold f32
  • Maximum: 1
body damaged threshold f32
body destroyed threshold f32
maximum shield vitality f32

Sets the maximum amount of shields that a unit has (damage hit points). For example, the cyborg biped has a value of 75. This value can also be changed at runtime for individual units by using unit_set_maximum_vitality in scripts.

pad(2)
shield material type enum

Determines which damage_effect material modifier is used when applying damage to the shield.

Option Value Comments
dirt 0x0
sand 0x1
stone 0x2
snow 0x3
wood 0x4
metal hollow 0x5
metal thin 0x6
metal thick 0x7
rubber 0x8
glass 0x9
force field 0xa
grunt 0xb
hunter armor 0xc
hunter skin 0xd
elite 0xe
jackal 0xf
jackal energy shield 0x10
engineer skin 0x11
engineer force field 0x12
flood combat form 0x13
flood carrier form 0x14
cyborg armor 0x15
cyborg energy shield 0x16
human armor 0x17
human skin 0x18
sentinel 0x19
monitor 0x1a
plastic 0x1b
water 0x1c
leaves 0x1d
elite energy shield 0x1e
ice 0x1f
hunter shield 0x20
pad(24)
shield failure function enum
Option Value Comments
linear 0x0
early 0x1
very early 0x2
late 0x3
very late 0x4
cosine 0x5
pad(2)
shield failure threshold Fraction: f32
failing shield leak fraction Fraction: f32
pad(16)
minimum stun damage f32
stun time f32 (seconds)
recharge time f32 (seconds)
pad(16)
pad(96)
shield damaged threshold f32
pad(8)
shield recharge rate f32 (little endian?)
  • Only set when the tag is compiled into a map cache.
pad(112)
materials Block?
  • Read-only data, not meant to be edited by hand.
Field Type Comments
name char[32]
  • Read-only data, not meant to be edited by hand.
flags bitfield(32)
Flag Mask Comments
head 0x1
material type enum
Option Value Comments
dirt 0x0
sand 0x1
stone 0x2
snow 0x3
wood 0x4
metal hollow 0x5
metal thin 0x6
metal thick 0x7
rubber 0x8
glass 0x9
force field 0xa
grunt 0xb
hunter armor 0xc
hunter skin 0xd
elite 0xe
jackal 0xf
jackal energy shield 0x10
engineer skin 0x11
engineer force field 0x12
flood combat form 0x13
flood carrier form 0x14
cyborg armor 0x15
cyborg energy shield 0x16
human armor 0x17
human skin 0x18
sentinel 0x19
monitor 0x1a
plastic 0x1b
water 0x1c
leaves 0x1d
elite energy shield 0x1e
ice 0x1f
hunter shield 0x20
pad(2)
shield leak percentage Fraction: f32
shield damage multiplier f32
pad(12)
body damage multiplier f32
pad(8)
regions Block?
  • Read-only data, not meant to be edited by hand.
Field Type Comments
name char[32]
  • Read-only data, not meant to be edited by hand.
flags bitfield(32)
Flag Mask Comments
lives until object dies 0x1
forces object to die 0x2
dies when object dies 0x4
dies when object is damaged 0x8
disappears when shield is off 0x10
inhibits melee attack 0x20
inhibits weapon attack 0x40
inhibits walking 0x80
forces drop weapon 0x100
causes head maimed scream 0x200
pad(4)
damage threshold f32
pad(12)
permutations Block?
  • Read-only data, not meant to be edited by hand.
Field Type Comments
name char[32]
modifiers Block?
  • Read-only data, not meant to be edited by hand.
Field Type Comments
pad(52)
pad(16)
x f32 (min & max)
y f32 (min & max)
z f32 (min & max)
pathfinding spheres Block?
  • This field's value may change at build time or have precision errors. It should not be used for exact comparisons between tag data.
Field Type Comments
node Index (nodes)
pad(2)
pad(12)
center
Point3D
  • x: f32
  • y: f32
  • z: f32
radius f32
nodes Block?
  • Read-only data, not meant to be edited by hand.
Field Type Comments
name char[32]
region Index: u16
parent node Index (nodes)
next sibling node Index (nodes)
first child node Index (nodes)
pad(12)
bsps Block?
Field Type Comments
bsp3d nodes Block?
Field Type Comments
plane u32
back child u32 (flagged)
front child u32 (flagged)
planes Block?
Field Type Comments
plane
Plane3D
  • i: f32
  • j: f32
  • k: f32
  • d: f32
leaves Block?
Field Type Comments
flags bitfield(16)
Flag Mask Comments
contains double sided surfaces 0x1
bsp2d reference count u16
first bsp2d reference u32
bsp2d references Block?
Field Type Comments
plane u32 (flagged)
bsp2d node u32 (flagged)
bsp2d nodes Block?
Field Type Comments
plane
Plane2D
  • i: f32
  • j: f32
  • d: f32
left child u32 (flagged)
right child u32 (flagged)
surfaces Block?
Field Type Comments
plane u32 (flagged)
first edge u32
flags bitfield(8)
Flag Mask Comments
two sided 0x1
invisible 0x2
climbable 0x4
breakable 0x8
breakable surface i8
material Index: u16
edges Block?
Field Type Comments
start vertex u32
end vertex u32
forward edge u32
reverse edge u32
left surface u32
right surface u32
vertices Block?
Field Type Comments
point
Point3D
  • x: f32
  • y: f32
  • z: f32
first edge u32

This information was partially generated using Invader tag definitions.

Acknowledgements

Thanks to the following individuals for their research or contributions to this topic:

  • Kavawuvi (Invader tag definitions)
  • Knight Artorias (Region and permutation limits)
  • lag supreme (Visualization of phantom BSP in covie crates)
  • MosesOfEgypt (Tag structure research)