Havok

Revision as of 11:15, 28 October 2021 by Greenlord (talk | contribs) (Relative offsets tend to be relative to the provided absolute offset.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Havok is a middleware software suite developed by the Irish company Havok. Havok provides a physics engine component and related functions to video games.

On September 14, 2007, Intel announced it had signed a definitive agreement to acquire Havok Inc.[1] In 2008, Havok was honored at the 59th Annual Technology & Engineering Emmy Awards for advancing the development of physics engines in electronic entertainment. On October 2, 2015, Microsoft announced it had acquired Havok.[2]


Products

The Havok middleware suite consists of the following modules:[3]

  • Havok Physics: It is designed primarily for video games, and allows for real-time collision and dynamics of rigid bodies in three dimensions. It provides multiple types of dynamic constraints between rigid bodies (e.g. for ragdoll physics), and has a highly optimized collision detection library. By using dynamical simulation, Havok Physics allows for more realistic virtual worlds in games. The company was developing a specialized version of Havok Physics called Havok FX that made use of ATI and NVIDIA GPUs for physics simulations;[4] however, the goal of GPU acceleration did not materialize until several years later.[5]
  • Havok AI: In 2009, Havok released Havok AI, which provides advanced pathfinding capabilities for games. Havok AI provides navigation mesh generation, pathfinding and path following for video game environments.
  • Havok Cloth: Released in 2008, Havok Cloth deals with efficient simulation of character garments and soft body dynamics.
  • Havok Destruction: Also released in 2008, Havok Destruction provides tools for creation of destructible and deformable rigid body environments.
  • Havok Animation Studio (discontinued): Havok Animation Studio is formally known as Havok Behavior and Havok Animation. Havok Behavior is a runtime SDK for controlling game character animation at a high level using finite state machines. Havok Animation provides efficient playback and compression of character animations in games, and features such as inverse kinematics.
  • Havok Script (discontinued): Havok Script is a Lua-compatible virtual machine designed for video game development. It is shipped as part of the Havok Script Studio.
  • Havok Vision Engine (discontinued): On August 8, 2011, Havok announced their acquisition of German game engine development company Trinigy and their Vision Engine and toolset.

Usage

Breath of the Wild uses the Havok Physics, Havok AI and Havok Cloth.

File Extensions
Extension Product Description Locations
hknm2 Havok AI Navigation meshes (used by AI for path finding) NavMesh/
hkrb Havok Physics Rigid body physics Physics/RigidBody/
hkcl Havok Cloth Cloth physics Physics/Cloth/
hkrg Havok Physics Rag doll physics Physics/Ragdoll/
hksc Havok Physics Static compound physics Physics/StaticCompound/
hktmrb Havok Physics Terrain mesh rigid body physics Physics/TeraMeshRigidBody/

File Types

hknm2

Used in shrines and field sections.

hkrb

Used in actors.

hkcl

Used in actors.

hkrg

Used in actors.

hksc

Used in shrines and field sections.

hktmrb

Used in field sections.

Havok File Specification

Havok files serve as a data container for multiple Havok classes per file and sometimes multiple Havok files per file[6]. The class names are defined in each file.

Note that this specification only applies to version 2014.2.0-r1

File Structure

 
File structure

Each file contains a header and three sections: classnames, types and data

classnames

The classnames section (__classnames__ internally) contains a list of Havok classes used by the file to correctly decompile the binary data into a usable data structure.

types

The types section (__types__ internally) does not appear to be used by Breath of the Wild.

data

the data section (__data__ internally) contains binary data to be serialized into Havok data structures for use by the Havok engine.

Header

The header seems to have a 16-byte alignment and can be 64-bytes (short header) or 80-bytes (long header) in length, depending on if Section offset equals 0 (short header) or 16 (long header).

Header Specification
Offset (h) Size Data Type Description
0x00 8 Bytes Havok file signature (magic) 57 E0 E0 57 10 C0 C0 10
0x08 4 Int User tag (always 0)
0x0c 4 Int Version (always 11)
0x10 1 Byte Pointer size (always 4 on Wii U, 8 on Switch)
0x11 1 Byte Endian (always 0 on WiiU, 1 on Switch)
0x12 1 Byte Padding option (always 0 on WiiU, 1 on Switch)
0x13 1 Byte Base class (always 1)
0x14 4 Int Section count (always 3)
0x18 4 Int Contents section index (always 2)
0x1c 4 Int Contents section offset (always 0)
0x20 4 Int Contents classname section index (always 0)
0x24 4 Int Contents classname section offset (always 75)
0x28 16 String Havok version hk_2014.2.0-r1 for BotW files
0x38 4 Int Flags (always 0)
0x3c 2 Short Unknown (always 21)
0x3e 2 Short Section offset (0 or 16; if 16, the header is 16 bytes longer)

Optional Header Bytes

There are optional header bytes for a long header. If Section offset equals 16, an additional 16 bytes are added to the header for a total of 80 bytes.

Optional Header Bytes
Offset (h) Size Data Type Description
0x40 4 Int Unknown (always 20)
0x44 4 Int Unknown (always 0; probably padding for alignment)
0x48 4 Int Unknown (always 0; probably padding for alignment)
0x4c 4 Int Unknown (always 0; probably padding for alignment)

Section Headers

 
FF bytes indicate section header boundaries

Each section has a 64-byte header which includes the section name, absolute offset to the section start and six relative offsets to segments within the section. These relative offsets are often relative to the absolute offset. [check] All three section headers follow the file header and are delimited by 16 delimiter bytes (0xFF).

Section Header Specification
Offset (h) Size Data Type Description
0x00 20 String Section name
0x14 4 Unsigned Int Absolute offset
0x18 4 Unsigned Int Relative offset 1
0x1c 4 Unsigned Int Relative offset 2
0x20 4 Unsigned Int Relative offset 3
0x24 4 Unsigned Int Relative offset 4
0x28 4 Unsigned Int Relative offset 5
0x2c 4 Unsigned Int Relative offset 6

Section Name

There are only three section names: __classnames__, __types__ and __data__. The section name is a null-terminated string with a delimiter byte (0xFF) in byte 20.

Absolute Offset

The absolute offset to the section.

Relative Offsets

The relative offsets point to different large structures within the section.

For example, given the following section header:

5F 5F 64 61 74 61 5F 5F 00 00 00 00 00 00 00 00 | __data__........
00 00 00 FF 00 00 01 60 00 00 3C 00 00 00 3C 10 | .......`..<...<.
00 00 3C 10 00 00 3C 20 00 00 3C 20 00 00 3C 20 | ..<...< ..< ..< 
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | ................

The section name is __data__.

The absolute offset is the beginning of the data section, right after the class names.

This following tables shows to which sections the offsets are pointing:

Data Header Specification
Offset (h) Size Data Type Description / Section
0x00 20 String Section name
0x14 4 Unsigned Int Beginning of data section
0x18 4 Unsigned Int Pointer - Data Pointer
0x1c 4 Unsigned Int Pointer - Linked Entries
0x20 4 Unsigned Int Pointer - Class Mapping
0x24 4 Unsigned Int EOF
0x28 4 Unsigned Int EOF
0x2c 4 Unsigned Int EOF

Class Names Section

 
Class names binary data

The classnames section header includes the absolute offset to the class names data and a single unique relative offset to the end of the section. The section is made up of an array of hash ids and a null-terminated string class name.

Class Name

Class names are read until the end of the section or a delimiter byte (0xFF) is is reached.

Class Name Specification
Offset (h) Size Type Description
0x00 4 Unsigned Int An integer associated with the class type
0x05 1 Byte Unknown (always 0x09)[7]
0x06 n String Class name (null-terminated string)

Types Section

The types section is unused in Breath of the Wild. The absolute offset points to the beginning of the data section with all null (0x00) relative offsets.

Data Section

 
Data structure

Data

The bulk of the file is devoted to the data section which is divided into smaller segments dependent on the file type. All files follow a general structure as you can see in the picture.

Right after the header begins the data section which contains multiple chunks, luckily, the first four chunks are always the same.

After that, several more chunks can be found depending on the file.

Pointer

The next section, at the end of the file, contains three different pointer arrays. It is used to connect the whole file together, and should be used as an entry point while reading the file.

The offsets to these three sections can be found in the header.

Data Pointer

An array of offsets relative to the beginning of the data section, pointing into various chunks.

Which offsets ends up in this list, depends completely on the chunks used in the data section.

However, since the first four classes are always the same, the first 14 offsets will be the constant.

 
Data Pointer


Linked Entries

Contains pointer-pairs to connect chunks together.

Each pair has the following format:

Pointer Pair
Offset (h) Size Type Name Description
0x00 4 Unsigned Int base Offset somewhere in the parent chunk
0x04 4 Unsigned Int flags Unknown (always 0x00000002)
0x08 4 Unsigned Int target Target chunk (always beginning of the chunk)

To connect a chunk with another, a base pointer somewhere inside the base-chunk (depending on the class/type) is used as the first pointer.

Then, the target pointer is the offset of the beginning of the target chunk.

 
Linked Entries


Class Mapping

The last section contains the mapping between the chunks and the classes they are using.

They, again, use pointer pairs:

Class Mapping Pointer
Offset (h) Size Type Name Description
0x00 4 Unsigned Int data Offset to the start of an chunk, relative to data-section
0x04 4 Unsigned Int flags Unknown (always 0x00000000)
0x08 4 Unsigned Int class Offset to the class name, relative to class-section

To link a chunk to a class, the data pointer is set to the beginning of the chunk.

The class pointer is set to the first character of the class name found in the header section.

 
Class Mapping


This also marks the end of the file, if the offset is not aligned to 16 bytes, the rest is filled with 0xFF.

Data Classes

All known classes that chunks can use are listed here.

Generally used classes
Signature Name
0x2772c11e hkRootLevelContainer
Havok Animation classes
Signature Name
0x26859f4c hkaAnimationContainer
0xfec1cedb hkaSkeleton
0xace9849c hkaSkeletonMapper
0x5448f464 hkaRagdollInstance
Havok Physics classes
Signature Name
0x47a8ca83 hkpPhysicsData
0xb3cc6e64 hkpPhysicsSystem
0xcd2e69e5 hkpRigidBody
0xfda179f3 hkpCapsuleShape
0xda4ce91e hkpConstraintInstance
0xed9648f7 hkpRagdollConstraintData
0x75aae5a3 hkpLimitedHingeConstraintData
0x143dd400 hkpPositionConstraintMotor
0xabab6bb3 hkpBvCompressedMeshShape
Havok Cloth classes
Signature Name
0x3512912b hclClothContainer
0xf14068be hclCollidable
0xdd03f524 hclCapsuleShape
0xd779f2c5 hclSphereShape
0x92f3edba hclClothData
0xe6105187 hclSimClothData
0x426b3354 hclStandardLinkConstraintSet
0x426b3354 hclStretchLinkConstraintSet
0x82567805 hclLocalRangeConstraintSet
0x9cfe2c7d hclTransitionConstraintSet
0x26824757 hclBendLinkConstraintSet
0x1b254ca1 hclSimClothPose
0xa0130a2c hclScratchBufferDefinition
0x7f4a5bfc hclBufferDefinition
0x18fd4565 hclTransformSetDefinition
0x6171b106 hclObjectSpaceSkinPOperator
0xe65a701c hclMoveParticlesOperator
0x75c72f0f hclSimulateOperator
0x80d9769f hclSimpleMeshBoneDeformOperator
0xda737296 hclGatherAllVerticesOperator
0x7b02cd1b hclClothState
0xe6db074c hclCopyVerticesOperator
Havok AI classes
Signature Name
0x6d493bdb hkaiNavMesh
0x2f02d92c hkaiDirectedGraphExplicitCost
0x433a1e61 hkaiStaticTreeNavMeshQueryMediator
Havok Compound classes
Signature Name
0x99e8d0cb hkcdStaticAabbTree
0x33735476 hkcdStaticTreeDefaultTreeStorage6
0x5115a202 StaticCompoundInfo


  1. Intel To Acquire Havok
  2. Havok to join Microsoft
  3. Product Overview
  4. Havok Intros Havok FX Engine to Compute Physics Effects on GPUs
  5. Havok Physics Playstation 4 Demo
  6. Static Compound files (hksc) include two Havok file definitions. The first file defines StaticCompoundInfo and the second defines hkpPhysicsData (which includes hkpRigidBody, hkpStaticCompoundShape, hkpBvCompressedMeshShape, hkpConvexVerticesShape, et. al.).
  7. It is assumed to be a delimiter between the id and the class name string. However, 0x09 is also the tab character and could imply something to the engine.