General Theory of Chrono Cross Model Data
If everyone agrees, this will be carved into the Grand Obelisk of Chrono knowledge.
The Character Battle Model format consists of the following, in order:
MODEL HEADER
*Section 1
Section 1 Header
"Constructs"
UV Map
Vertex Pool
VDDM (Vestigial Data that Doesn't Matter)
*Section 2 (Skeleton)
Skeletal Units
*Section 3 (Yet Uknown; affects model shading and placement on the battlefield)
*Section 4 (Animations)
*Section 5 (Uknown)
MODEL HEADER:
#S #S #S #S S1 S1 S1 S1 - S2 S2 S2 S2 S3 S3 S3 S3
S4 S4 S4 S4 S5 S5 S5 S5 - S6 S6 S6 S6 EF EF EF EF
Where...
#S = Number of Sections in the model.
S1 = Starting Offset of Section 1.
S2 = Starting Offset of Section 2.
S3 = Starting Offset of Section 3.
S4 = Starting Offset of Section 4.
S5 = Starting Offset of Section 5.
S6 = Starting Offset of Section 6 (usually set to zero, making it de facto nonexistent).
EF = End of File address.
Section 1Section 1 is composed of a number of units I'll call "Constructs" for lack of a better term at the moment. Each "Construct" apparently ties together parts of the model's UV Map, Vertex Pool, the VDDM, and the skeleton defined in Section 2.
Section 1 Header:
#C #C #C #C C1 C1 C1 C1 - C2 C2 C2 C2 ... ?? ?? ?? ?? ?? ?? ?? ??
Where...
#C = Number of Constructs
C1 = Starting Offset of the First Construct, relative to the beginning of Section 1.
C2 = Starting Offset of the Second Construct, relative to the beginning of Section 1.
... = More starting offsets of additional Constructs, relative to the beginning of Section 1.
?? = There are four bytes of data that may be a checksum, followed by an additional four bytes
of unknown purpose.
Construct Format:Each construct consists of a Header followed by 8-byte mode vertex assignments, 16-byte mode vertex assignments, and a UV Footer.
Construct Header...
UM UM UM UM VP VP VP VP - VD VD VD VD
Where...
UM = Offset into the UV Map, relative to the beginning of Section 1;
start grabbing texture pieces here.
VP = Offset into the Vertex Pool, relative to the beginning of Section 1;
start grabbing vertices here.
VD = Offset into unknown Vestigial Data that can be zero'd out
with absolutely no effect on the model.
8-byte mode vertex assignment header format: #A #A #A #A VO VO VO VO
8-byte mode vertex assignment format: NV NV JJ JJ
Where...
#A = Number of assignments that follow.
VO = Offset into the Vertex Pool, relative to the VP offset given in the Construct Header.
NV = Next NV Vertices are assigned to JJ JJ.
JJ =Index of the joint to which the body of vertices is assigned.
16-byte mode vertex assignment header format: #A #A #A #A PP PP PP PP
16-byte mode vertex assigment format: NV NV 00 00 J1 J1 W1 W1 J2 J2 W2 W2
Where...
#A: Number of assignments that follow.
NV: Next NV Vertices are assigned to J1 J1 and J2 J2.
VO = Offset into the Vertex Pool, relative to the VP offset given in the Construct Header.
J1: Index of the first joint to which the body of vertices is assigned.
W1: Weight of the association between NV and J1 for animation purposes.
J2: Index of the second joint to which the body of vertices is assigned.
W2: Weight of the association between NV and J2 for animation purposes.
UV Footer: This tells the game engine where to look in the UV Map
for the triangles and quads assigned to each construct.
#E #E #E #E TQ TQ ## ## UO UO UO UO...
Where...
#E = Number of 8-byte entries.
TQ = First two bytes in the 8-byte entry. If it's set to 0x24, the next bytes refer to
triangles; if set to 0x2C, the next bytes refer to quads.
## = Number of quads or triangles assigned to the Construct.
UO = UV Map offset from which to start pulling the triangles or quads.
Relative to the UM offset given in the construct header.
... = More TQ, ##, and UO information for each additional entry.
Section 2Section 2 sets the model's skeletal orientation.
Section 2 Header
NB NB NB NB
Where NB = Number of Bones
Bone format...
PJ PJ PJ PJ XR XR YR YR - ZR ZR XC XC YC YC ZC ZC
BI BI BI BI
Where...
PJ = Index of parent joint (0xFFFF, or -1 if this bone has no parent joint)
XR = X rotation (range: 0XF000 ~ 0xFFF, or -4096 to 4095, where 4096 = 360 degrees)
YR = Y rotation (range: 0XF000 ~ 0xFFF, or -4096 to 4095, where 4096 = 360 degrees)
ZR = Z rotation (range: 0XF000 ~ 0xFFF, or -4096 to 4095, where 4096 = 360 degrees)
XC = X coordinate in 3D space relative to parent joint
YC = Y coordinate in 3D space relative to parent joint
ZC = Z coordinate in 3D space relative to parent joint
BI = Current bone index (0xFFFF, or -1 if current joint and parent joint do not form a bone)
Below are Serge & Guile's constructs mapped out for everyone's perusal. You can check Serge's Construct Map against the
information we have in the wiki, and I'm going to map out all of Guile's UV Map & Vertex Pool based on his Construct info. If it works out, we'll have confirmed the model. Luminaire, hopefully this will help you fine-tune your model importer so that it can recreate all models properly. I think most of the problems would have originated from Section 1-1 (the "Constructs"), but the number of Constructs determine how many switchovers occur in the UV Map (from triangles to quads and vice versa) and the Vertex Pool (from 8-byte mode to 16-byte mode and vice versa), so I guess any problems encountered there would carry over into the results for Sections 1-2 and 1-3.
Color codes in the attached maps...
Regular text: Section 1 header
Grey background: Construct Header
Boxed, white background: 8-byte and 16-byte mode vertex assignment headers.
Yellow-Plum-Lime-Turquoise-Tan-etc. backgrounds: Vertex Assignments.
Red background: Construct Footer.
Serge's "Constructs"
Guile's "Constructs"
EDIT: Oh! I may have joints and bones mixed up in my model of Construct vertex assignments. Someone let me know if those should be bone indices and not joint indices.
EDIT: Also, I forgot to fit in our findings regarding the UV Map and Vertex Pool data formats, but they're still in the wiki as we described them months ago.