Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.
Zero Tolerance for Disrespect

Reverse Engineering Request - OD3XXOBX / TCAXXOBX model format (Noesis Importer)

Featured Replies

Hey, everyone guys:

I'm trying to reverse engineer a proprietary model format used by The House Of The Dead 3 . My goal is to write (or help writing) a Noesis importer capable of importing the render mesh (geometry, UVs ,materials and skeleton if that's possible ).

I have attached two files from the same asset:

zc03.x3x
zc03.xax

File information

zc03.x3x

Size: 48612 bytes

Header:

4F 44 33 58 58 4F 42 58

ASCII:

OD3XXOBX

Immediately followed by

00 00
06 00
D4 BD 00 00

zc03.xax

Size: 43492 bytes

Header:

54 43 41 58 58 4F 42 58

ASCII:

TCAXXOBX

Immediately followed by

02 00
07 00
D4 A9 00 00

The two files clearly belong to the same resource family.


Endianness

The files appear to be Little Endian.

Chunk identifiers are stored as reversed ASCII.

Example:

58 54 52 56

↓

VRTX

instead of

56 52 54 58

X3X Chunk Layout

Current chunk map:

Offset

Stored bytes

Chunk

0x0010

3JBO

OBJ3

0x0134

EMAN

NAME

0x04DC

LEDM

MDEL

0x0568

RTAM

MATR

0x0750

MNXT

TXNM

0x079C

VPRG

Unknown

0x0830

XTRV

VRTX

0x1314

XDNI

INDX

Unknown chunks may have additional internal structures.


NAME chunk

Contains readable strings.

Examples:

zc03_sk_kao

root

chn1

chn2

eff2

jnt_mune

jnt_rhiza

jnt_rmomo

zc03_sk_mune_2dam

This strongly suggests that the model contains a skeleton hierarchy.


MATR chunk

Starts at

0x0568

Contains

PDmat3

mat3

Material names appear to be stored here.


TXNM chunk

Starts at

0x0750

Contains external texture references.

Examples:

d:\FS\xtx_zc03.zip/:4a9a,b9ec.dds

d:\FS\xtx_common.zip/:92,141e.dds

Textures are external DDS files.


VRTX chunk

Starts exactly at

0x0830

The first bytes are

76 CD 12 C0
D7 42 E7 BE
68 97 00 40

Interpreted as float32:

X = -2.2938

Y = -0.4517

Z = 2.0092

These values appear to be valid model-space coordinates.

The following bytes continue as floating point values.

Example:

AE B3 99 3D
5D CF 7D BF
50 B3 DA 3D
64 2C B9 3E
1C 88 71 3E
9F FE 10 C0
01 75 F7 BE
31 A8 32 3F
E2 CF BA 3D
03 C2 53 BF
...

The vertex layout is currently unknown.

Possible vertex stride candidates:

48

52

56

60

64 bytes

I have not yet identified:

  • Normal format

  • Tangent format

  • UV offset

  • Skin weights

  • Bone indices


INDX chunk

Starts exactly at

0x1314

Beginning of the data:

00 00
01 00
02 00
03 00
03 00
02 00
02 00
02 00
00 00
04 00
05 00
06 00
07 00
08 00
09 00
...

This strongly indicates a 16-bit index buffer (uint16).

I found no evidence of uint32 indices.


MDEL

Starts at

0x04DC

Unknown structure.

Possibly mesh descriptor.

May contain counts or offsets.


OBJ3

First chunk in the file.

Likely stores object information or transforms.

Unknown structure.


VPRG

Starts at

0x079C

Unknown.

May describe primitive groups, draw calls or submeshes.

First bytes:

56 50 52 47
00 00 00 00
00 00 00 00
33 00 00 00
00 00 00 00
58 03 00 00
...

Skeleton

The model clearly contains bone names.

However I have not yet identified

  • inverse bind matrices

  • parent table

  • bone transforms

Only names are currently confirmed.


Animation

I could not find any obvious animation data.

No chunks similar to

ANIM

KEYS

TIME

CLIP

MOTN

were found.

Animations may be stored in another resource.


XAX Analysis

Header

TCAXXOBX

Unlike the X3X file, this file does not contain obvious

VRTX

INDX

MATR

chunks.

Instead I found the following chunk identifiers:

RTCA

YRAW

TADW

LDMA

LKSL

MFDL

ILDM

EMAN

LEKS

Known offsets:

Offset

Chunk

0x0010

RTCA

0x019C

TADW

0x09F0

LDMA

0x0A08

LKSL

0x0A54

MFDL

0x0A90

ILDM

0x0B54

EMAN

0x0B70

LEKS

The only readable object name is

zc03_sk_kao

No obvious render geometry is present.

This file appears to be a companion resource.

Its exact purpose is still unknown.


Current assumptions

Little Endian

Chunk-based container

Reversed ASCII chunk identifiers

Render mesh stored inside X3X

External DDS textures

Skeleton names present

uint16 index buffer

Vertex buffer starts at 0x0830

Index buffer starts at 0x1314


Unknowns

The following information is still missing:

  • Exact VRTX structure

  • Vertex stride

  • Position offset

  • Normal format

  • UV offset

  • Tangent format

  • Color format

  • Skin weights

  • Bone indices

  • Primitive group structure

  • MDEL structure

  • VPRG structure


Goal

The objective is to write a Noesis importer capable of importing:

  • Geometry

  • UVs

  • Material names

  • External texture references

Skeletons and animations are not required.


Questions

  1. Has anyone encountered the OD3XXOBX / TCAXXOBX container before?

  2. Can anyone identify the VRTX vertex layout?

  3. Does MDEL contain vertex/index counts and offsets?

  4. Is VPRG the primitive group / draw call table?

  5. Is XAX a companion resource containing skeleton metadata, collision, helpers or animation-related data?

  6. Would anyone be interested in helping write a Noesis importer for this format?


The Objetive

Create a universal Noesis script that can read all the face indices and their geometry and that can be converted to other formats

Files Testing:

I'll upload those formats to the GitHub account https://github.com/randalfcastro-tech/THOD3; and now I think the real fun begins ...

If you need more samples, let me know and I’ll be happy to provide them, or your full dump in hexadecimal.

Also, I think a Noesis script is better, it will take less time and be faster, guys.

But thanks again, we're going to make it. 🙂

THOTDIII.jpg

Edited by Randalf2theReturn

  • Localization

Hello, from quick look chunks seems to contain relative offsets to other chunks
OBJ3 (offsets are relative to right before OBJ3 identifier):

at 144 (counting from before OBJ3) offset to it's name right after NAME identifier

at 156 offset (or zero) to 4 bytes before MDLE which contains exact size of MDLE chunk in bytes

at 268 and 272 offsets (or zeroes) to another OBJ3 (children in tree hierarchy?)

MDLE (offsets are relative to right before MDLE identifier):

at 20 (counting from before MDLE) offset to it's name right after NAME identifier

at 40 int32 count of materials following with offset to material data inside MATR chunk

For each material there seems to be 232 bytes of data inside MATR chunk (offsets are still relative to MDLE):
at 0 (counting from material data start) offset to it's name

at 124 offset to (vertex group?) data inside GRPV

For each material there seems to be 72 bytes of data inside GRPV chunk (offsets are still relative to MDLE):

at 8 (counting from group data start) int32 count of vertices

at 16 offset to vertex data inside VRTX chunk

at 64 offset to indices inside INDX chunk following with int32 count of indices

Vertex layout seems the same but may vary with other files:
3x float32 position, 3x float32 normal, 2x float32 uv

Indices are seems to be triangle strips
Here are one of the meshes (some kind of clothing?):
image.png

  • Author
3 hours ago, HiddenParadise said:

hey your work is amazing i have done the same with hotd1 not 2 fully yet but when would this release?

1 hour ago, other1 said:

Hello, from quick look chunks seems to contain relative offsets to other chunks
OBJ3 (offsets are relative to right before OBJ3 identifier):

at 144 (counting from before OBJ3) offset to it's name right after NAME identifier

at 156 offset (or zero) to 4 bytes before MDLE which contains exact size of MDLE chunk in bytes

at 268 and 272 offsets (or zeroes) to another OBJ3 (children in tree hierarchy?)

MDLE (offsets are relative to right before MDLE identifier):

at 20 (counting from before MDLE) offset to it's name right after NAME identifier

at 40 int32 count of materials following with offset to material data inside MATR chunk

For each material there seems to be 232 bytes of data inside MATR chunk (offsets are still relative to MDLE):
at 0 (counting from material data start) offset to it's name

at 124 offset to (vertex group?) data inside GRPV

For each material there seems to be 72 bytes of data inside GRPV chunk (offsets are still relative to MDLE):

at 8 (counting from group data start) int32 count of vertices

at 16 offset to vertex data inside VRTX chunk

at 64 offset to indices inside INDX chunk following with int32 count of indices

Vertex layout seems the same but may vary with other files:
3x float32 position, 3x float32 normal, 2x float32 uv

Indices are seems to be triangle strips
Here are one of the meshes (some kind of clothing?):
image.png

From what I've seen of the .x3x / OD3XXOBX format:

I've already located the chunks (XTRV, XDNI, RTAM, MNXT, EMAN...).
I know there are several submeshes.
The indices can already be read.
Material and texture names are already showing up.
We've already found the approximate start of the vertex block.

What I still don't know is the actual layout of XTRV:

final stride (32, 36, 40, 44, 48...),
exact UV position,
type of normals,
existence of tangents,
whether the UVs are float, half float, or normalized short,
whether the index is a triangle strip or list,
if there are multiple vertex streams.

What's left is the important part: identifying the exact format of the mesh data. With what I have, I still need to figure out:

The actual stride of the vertices (don’t assume 32).

The layout of each vertex:

position,

normals,

UVs,

tangents (if they exist),

bone weights and indices (if they exist).

Whether XDNI uses a triangle list or triangle strip.

If there are multiple vertex streams associated with the same submesh.

The structure of LEDM, which probably contains the layout description or of each submesh.

How materials (RTAM) and textures (MNXT) are linked to each submesh.

Once that’s identified, the rest is relatively straightforward: bind the correct buffers (rpgBindPositionBufferOfs, rpgBindNormalBufferOfs, rpgBindUV1BufferOfs, etc.), create materials, and build the model.

fmt_x3x_thotd3.py

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.