Bphsh

From EPD Wiki
Revision as of 10:50, 13 January 2026 by Watertoon (talk | contribs) (Initial page for bphsh)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Bphsh is a "shape" file format. Responsible for storing the underlying physics engine's collision mesh data as well as relevant phive specific data. This page is focused on the version found in Nintendo Switch Online: Playtest Program (021), and Havok 2023.2.

File Structure

  1. Header
  2. Havok Tag File
  3. Material Array
  4. Unknown Array

Structures (phive)

Header

Common phive header for shape. The sections consist of the Havok tagfile containing an hknpMeshShape, an array of phive materials, and a currently unknown section.

Material Array

Offset Size Type Description
0x0 0x4 u32 Material Id. The PhiveConfig byaml stores an application's materials under MaterialCollection.
0x4 0x4 u32 Sub Material. The PhiveConfig byaml stores an application's sub materials under SubMaterialCollection.
0x8 0x8 u64 User Shape Tag Mask. Up to 64 tags can be present, each bit denotes whether a tag exists. The PhiveConfig byaml stores an application's tags under UserShapeTagCollection.

Unknown

0x10 sized per structure.

Structures (Havok Physics)

Common

hkEnum<T,B>, hkFlags<T,B>

Enum of type T, with underlying storage of type B.

hkRelPtr<T>

Offset Size Type Description
0x0 0x8 hkInt64 m_offset; Offset relative to the base address of this object to the template type T.

hkRelArrayView<T,B>

B is an integer type.

Offset Size Type Description
0x0 sizeof(B) B m_offset; Offset relative to the base address of this object to the array of template type T.
sizeof(B) sizeof(B) B m_size; Count of elements in the array

hkRelArray<T>

Offset Size Type Description
0x0 0x8 hkInt64 m_offset; Offset relative to the base address of this object to the array of template type T.
0x8 0x4 int m_size; Count of elements in the array
0xc 0x4 int m_capacityAndFlags; Max capacity of elements the array can store, also flags.

hknpMeshShape

Stores a collision mesh geometry and acceleration structures.

Note; hkBaseObject has an alignment of 8, but hknpMeshShape promotes the alignment to 0x10 due to containing an hkVector4. Unmarked space is padding.

hkBaseObject
Offset Size Type Description
0x0 u64 0x8 _vft_reserve; Vtable pointer, resolved at runtime.
hkReferencedObject
Offset Size Type Description
0x8 0x8 hkUlong m_sizeAndFlags
0x10 0x8 hkUlong m_refCount
hknpShape : hkReferencedObject
Offset Size Type Description
0x18 0x1 hkEnum<hknpShapeType::Enum, hkUint8> m_type; Should always be "MESH" (0x8) for an hknpMeshShape.
0x19 0x1 hkEnum<hknpCollisionDispatchType::Enum, hkUint8> m_dispatchType
0x1a 0x2 hkFlags<hknpShape::FlagsEnum, hkUint16> m_flags
0x1c 0x1 hkUint8 m_numShapeKeyBits
0x1d 0x3
0x20 0x4 hkReal m_convexRadius
0x24 0x4
0x28 0x8 hkUint64 m_userData, this is set at runtime to a phive structure containing references to the material and unknown array.
0x30 0x10 hknpShapeProperties m_properties
hknpCompositeShape : hknpShape
Offset Size Type Description
0x40 0x4 hkUint32 m_shapeTagCodecInfo
0x44 0x4
hknpMeshShape : hknpCompositeShape
Offset Size Type Description
0x48 0x8
0x50 0x20 hknpMeshShapeVertexConversionUtil m_vertexConversionUtil
0x70 0x8 hkRelArrayView<hknpMeshShape::ShapeTagTableEntry, int> m_shapeTagTable
0x78 0x18 hkcdSimdTreeNamespace::hkcdSimdTree<hkcdSimdTreeNamespace::RelArrayStorage<hkcdSimdTreeNamespace::Node>> m_topLevelTree
0x90 0x8 hkRelArrayView<hknpMeshShape::GeometrySection, int> m_geometrySections; Appears to be a convex decomposition, or at least partitioning, of the mesh shape.
0x98 0x8 hkRelPtr<hknpMeshShapePrimitiveMapping> m_primitiveMapping

hknpShapeType::Enum

Name Value Description
CONVEX 0x0
SPHERE 0x1
CAPSULE 0x2
CYLINDER 0x3
TRIANGLE 0x4
BOX 0x5
COMPOSITE 0x6
MESH 0x7
EXTERN_MESH 0x8
COMPOUND 0x9
DISTANCE_FIELD_BASE 0xa
HEIGHT_FIELD 0xb
DISTANCE_FIELD 0xc
PARTICLE_SYSTEM 0xd
TRANSFORMED 0xe
MASKED 0xf
MASKED_COMPOUND 0x10
BREAKABLE_COMPOUND 0x11
LOD 0x12
DUMMY 0x13
LEGACY_COMPRESSED_MESH 0x14
USER_0 0x15
USER_1 0x16
USER_2 0x17
USER_3 0x18
USER_4 0x19
USER_5 0x1b
USER_6 0x1b
USER_7 0x1c
NUM_SHAPE_TYPES 0x1d
INVALID 0x1e

hknpCollisionDispatchType::Enum

Name Value Description
NONE 0x0
CONVEX 0x1
COMPOSITE 0x2
DISTANCE_FIELD 0x3
USER_0 0x4
USER_1 0x5
USER_2 0x6
USER_3 0x7
USER_4 0x8
USER_5 0x9
USER_6 0xa
USER_7 0xb
NUM_TYPES 0xc

hknpShape::FlagsEnum

Name Value Description
IS_CONVEX_SHAPE 0x1
IS_CONVEX_POLYTOPE_SHAPE 0x2
IS_COMPOSITE_SHAPE 0x4
IS_HEIGHT_FIELD_SHAPE 0x8
USE_SINGLE_POINT_MANIFOLD 0x10
IS_INTERIOR_TRIANGLE 0x20
SUPPORTS_COLLISIONS_WITH_INTERIOR_TRIANGLES 0x40
USE_NORMAL_TO_FIND_SUPPORT_PLANE 0x80
IS_TRIANGLE_OR_QUAD_SHAPE 0x100
IS_QUAD_SHAPE 0x200
IS_SDF_EDGE_COLLISION_ENABLED 0x400
HAS_SURFACE_VELOCITY 0x800
USER_FLAG_0 0x1000
USER_FLAG_1 0x2000
USER_FLAG_2 0x4000

hknpShapeProperties

Offset Size Type Description
0x0 0x10 hkRelArray<hknpShapeProperties::Entry> Optional shape properties.
hknpShapeProperties::Entry
Offset Size Type Description
0x0 0x8 hkRelPtr<hknpShapePropertyBase> Pointer to shape property. If present, likely a derived class such as hknpShapeConnectivityGraph, hknpRefDragProperties, hknpShapeMassProperties, hknpShapeMassPropertiesTree, hknpShapeMassConfigProperty, or hknpMaterialPalette.
hknpShapePropertyBase
Offset Size Type Description
0x0 0x2 hkUint16 m_propertyKey; Appears to be a derived class unique identifier.

hknpMeshShapeVertexConversionUtil

Offset Size Type Description
0x0 0x10 hkVector4 m_bitScale16; Appears to be vertex compression parameters.
0x10 0x10 hkVector4 m_bitScale16Inv

hknpMeshShape::ShapeTagTableEntry

Offset Size Type Description
0x0 0x4 hkUint32 m_meshPrimitiveKey
0x4 0x2 hkUint16 m_shapeTag
0x6 0x2

hkcdSimdTreeNamespace::hkcdSimdTree<hkcdSimdTreeNamespace::RelArrayStorage<hkcdSimdTreeNamespace::Node>>

hkcdSimdTreeNamespace::RelArrayStorage<hkcdSimdTreeNamespace::Node>
Offset Size Type Description
0x0 0x10 hkRelArray<hkcdSimdTreeNamespace::Node> m_nodes
hkcdSimdTreeNamespace::hkcdSimdTree : hkcdSimdTreeNamespace::RelArrayStorage<hkcdSimdTreeNamespace::Node>
Offset Size Type Description
0x10 0x4 hkUint32 m_firstFreeIndex
0x14 0x1 bool m_isCompact
0x15 0x3
hkcdSimdTreeNamespace::Node
hkcdFourAabb
Offset Size Type Description
0x0 0x10 hkVector4 m_lx
0x10 0x10 hkVector4 m_hx
0x20 0x10 hkVector4 m_ly
0x30 0x10 hkVector4 m_hy
0x40 0x10 hkVector4 m_lz
0x50 0x10 hkVector4 m_hz
hkcdSimdTreeNamespace::Node : hkcdFourAabb
Offset Size Type Description
0x60 0x10 hkUint32[4] m_data
0x70 0x4 hkUint8[4] m_filterMasks
0x74 0x1 hkFlags<hkcdSimdTreeNamespace::Node::FlagsEnum, unsigned char> m_flags
0x75 0x1 hkUint8 m_maxDepth
0x76 0x1 hkUint8 m_splittingAxisCache
0x77 0x1 hkUint8 m_numAddRemoveOperationsSinceLastRebalance
0x78 0x4 hkUint32 m_parent
0x7c 0x4 hkUint32 m_numLeaves
hkcdSimdTreeNamespace::Node::FlagsEnum
Name Value Description
NODE_IS_LEAF 0x1
NODE_IS_FREE 0x2
INCREMENTAL_OPTIMIZER_NODES_ARE_REBALANCED 0x4
INCREMENTAL_OPTIMIZER_REINSERT_PASS_DID_NOP 0x8
INCREMENTAL_OPTIMIZER_LEAVES_ARE_REBALANCED 0x10
USER_FLAG_0 0x20
USER_FLAG_1 0x40
USER_FLAG_2 0x80

hknpMeshShape::GeometrySection

Offset Size Type Description
0x0 0x8 hkRelArrayView<hknpAabb8TreeNode, int> m_sectionBvh
0x8 0x8 hkRelArrayView<hknpMeshShape::GeometrySection::Primitive, int> m_primitives
0x10 0x8 hkRelArrayView<hkUint8, int> m_vertexBuffer
0x18 0x8 hkRelArrayView<hkUint8, int> m_interiorPrimitiveBitField
0x20 0xc hkUint32[3] m_sectionOffset
0x2c 0xc hkFloat3 m_bitScale8Inv
0x38 0x6 hkInt16[3] m_bitOffset
0x3e 0x2
hknpAabb8TreeNode
hknpTransposedFourAabbs8
Offset Size Type Description
0x0 0x4 hkUint32 m_lx
0x4 0x4 hkUint32 m_hx
0x8 0x4 hkUint32 m_ly
0xc 0x4 hkUint32 m_hy
0x10 0x4 hkUint32 m_lz
0x14 0x4 hkUint32 m_hz
hknpAabb8TreeNode : hknpTransposedFourAabbs8
Offset Size Type Description
0x18 0x3 hkUint8[3] m_data
0x1b 0x1
hknpMeshShape::GeometrySection::Primitive
Offset Size Type Description
0x0 0x1 hkUint8 m_aId
0x1 0x1 hkUint8 m_bId
0x2 0x1 hkUint8 m_cId
0x3 0x1 hkUint8 m_dId
hknpMeshShape::GeometrySection::Vertex16_3

While m_vertexBuffer is untyped in later versions, in previous version it assumed this vertex format struct, which still appears to be the case (u8 mainly forces the m_vertexBuffer.m_size to be in bytes)

Offset Size Type Description
0x0 0x2 hkUint16 m_x
0x2 0x2 hkUint16 m_y
0x4 0x2 hkUint16 m_z

hknpMeshShapePrimitiveMapping

hknpMeshShapePrimitiveMapping : hkReferencedObject
Offset Size Type Description
0x0 0x10 hkRelArray<hkUint32> m_sectionStart
0x10 0x10 hkRelArray<unsigned int> m_bitString
0x20 0x4 hkUint32 m_bitsPerEntry
0x24 0x4 hkUint32 m_triangleIndexBitMask