Skip to main content

Namespace FFXIVClientStructs.FFXIV.Common.Component.BGCollision

Classes

BGCollisionModule.Addresses

BGCollisionModule.MemberFunctionPointers

Structs

BGCollisionModule

Entry point for collision related operations. Collision scene supports two ways to filter colliders - layers and material masks.

Each collider, when constructed, is provided a layer mask. Collider is ignored during raycasts if raycast request layer mask AND collider layer mask == 0. Note that individual collider raycast operations are inconsistent in how they handle zero layer mask in raycast request:

  • primitive shape (non-mesh) colliders skip layer check in that case (so 0 is equivalent to 'all 1s' mask, meaning no colliders are rejected by layer check)
  • mesh colliders do a normal check, meaning that all mesh colliders are rejected by a layer check Note that some colliders provide functions to perform raycast without layer check.

Each collider also has a material value (0x7000 by default on construction). When doing raycasts with material filtering, you supply a mask and a value. For primitive shape (non-mesh) colliders, the filtering is simple:

  • if material filter value is 0, the collider is considered if (collider-material AND filter-mask) != 0
  • otherwise, the collider is considered if (collider-material AND filter-mask) == filter-value For mesh colliders, things are slightly more complicated. Collider still contains a material value + a material mask (this mask is ignored by all other collider types). Each individual triangle of the mesh also defines its own material value (primitive material). The effective material of a triangle is calculated as follows:
  • if object material mask is 0, it's just whatever is stored in primitive
  • otherwise, it is calculated as (primitive-material AND NOT object-material-mask) OR object-material-value (so masked bits are replaced by per-object value) This effective material is then used as collider-material value in the material filtering logic described above.

There are three main options that are used to customize raycast algorithm - these are stored as 'raycast algorithm type' bitfield, meaning there are 8 total flavours of raycasts: Default (no bits set): usual ray/shape intersection without material filtering. Bit 0 set: use sphere sweep instead of a ray; when choosing between potential intersection points at comparable (within epsilon) distance, select one that has 'more orthogonal' normal (smaller ray-direction dot normal) Bit 1 set: ignore 'horizontal' collisions (ones where normal.Y is > threshold, i.e. angle to vertical axis is smaller than some threshold) Bit 2 set: perform material filtering

Collider

Collider.ColliderVTable

ColliderBox

Box collider - local center is at origin, half-width is 1 in each dimension - so local bounds are (-1,-1,-1) to (1,1,1).

ColliderCylinder

Cylinder collider - local center is at origin, local axis is (0,1,0), half-height and radius are 1 - so local bounds are (-1,-1,-1) to (1,1,1).

ColliderMesh

Generic mesh collider.

ColliderPlane

Plane collider - local center is at origin, local normal is (0,0,1), half-side is 1 - so local bounds are (-1,-1,0) to (1,1,0). There are two flavours of planes - one-sided and two-sided (latter is implemented as a derived class without any new fields).

ColliderSphere

Sphere collider - local center is at origin, radius is 1 - so local bounds are (-1,-1,-1) to (1,1,1). At least some parts of the code assume that scale is always uniform.

ColliderStreamed

Streamed collider does not contribute to the collision scene by itself, however it adds and removes other mesh colliders that are inside streaming sphere. In the file system, the whole streamable scene is located in a single directory; the root file is typically called list.pcb. Individual streamable meshes are called /trXXXX.pcb, where XXXX is MeshId field (with zero padding - formatted as %04d).

ColliderStreamed.Element

ColliderStreamed.FileEntry

ColliderStreamed.FileHeader

IMesh

IMesh.IMeshVTable

Mesh

Mesh.MeshVTable

Mesh.Primitive

MeshPCB

MeshPCB.FileHeader

MeshPCB.FileNode

Node

NodeEnumerator<Der>

NodeLink.NodeLinkVTable

Object

Object.ObjectVTable

Quadtree

Each collider is added to the appropriate quad-tree node, which is then used to speed up raycasts. Nodes are laid in a contiguous array, level by level, in Morton order swizzle per level.

QuadtreeNode

QuadtreeNode.Enumerator

RaycastHit

RaycastMaterialFilter

RaycastParams

Resource

Resource.ResourceVTable

Scene

SceneManager

SceneManager.SceneManagerVTable

SceneWrapper

SceneWrapper.ColliderList

SceneWrapper.SceneWrapperVTable

Enums

ColliderType