-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathxac.txt
189 lines (165 loc) · 6.46 KB
/
xac.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
vec3d = float x, float y, float z
vec4d = float x, float y, float z, float w
quat = float x, float y, float z, float w
string = uint32 len, char[len]
matrix44 = vec4d col1, vec4d col2, vec4d col3, vec4d pos
file:
byte magic[4] = 58 41 43 20 ("XAC ")
byte majorVersion = 1
byte minorVersion = 0
byte bBigEndian
byte multiplyOrder
chunk[...]
int32 chunkType
int32 length (sometimes incorrect!)
int32 version
byte data[length]
chunk 1: mesh (v1)
int32 nodeId
int32 numInfluenceRanges
int32 numVertices (total number of vertices of submeshes)
int32 numIndices (total number of indices of submeshes)
int32 numSubMeshes
int32 numAttribLayers
byte bIsCollisionMesh (each node can have 1 visual mesh and 1 collision mesh)
byte pad[3]
VerticesAttribute[numAttribLayers]
int32 type (determines meaning of data)
0 = positions (vec3d)
1 = normals (vec3d)
2 = tangents (vec4d)
3 = uv coords (vec2d)
4 = 32-bit colors (uint32)
5 = influence range indices (uint32) - index into the InfluenceRange[] array of chunk 2, indicating the bones that affect it
6 = 128-bit colors
typically: 1x positions, 1x normals, 2x tangents, 2x uv, 1x colors, 1x influence range indices
int32 attribSize (size of 1 attribute, for 1 vertex)
byte bKeepOriginals
byte bIsScaleFactor
byte pad[2]
byte data[numVertices * attribSize]
SubMesh[numSubMeshes]
int32 numIndices
int32 numVertices
int32 materialId
int32 numBones
int32 relativeIndices[numIndices] (actual index = relative index + total number of vertices of preceding submeshes. each group of 3 sequential indices (vertices) defines a polygon)
int32 boneIds[numBones] (unused)
chunk 2: skinning (v3)
int32 nodeId
int32 numLocalBones (number of distinct boneId's in InfluenceData)
int32 numInfluences
byte bIsForCollisionMesh
byte pad[3]
InfluenceData[numInfluences]
float fWeight (0..1) (for every vertex, the resulting transformed position is calculated for every influencing bone;
int16 boneId the final position is the weighted average of these positions using fWeight as weight)
byte pad[2]
InfluenceRange[bIsForCollisionMesh ? nodes[nodeId].colMesh.numInfluenceRanges : nodes[nodeId].visualMesh.numInfluenceRanges]
int32 firstInfluenceIndex (index into InfluenceData)
int32 numInfluences (number of InfluenceData entries relevant for one or more vertices, starting at firstInfluenceIndex)
chunk 3: material definition (v2)
vec4d ambientColor
vec4d diffuseColor
vec4d specularColor
vec4d emissiveColor
float shine
float shineStrength
float opacity
float ior
byte bDoubleSided
byte bWireframe
byte unused
byte numLayers
string name
Layer[numLayers]:
float amount
float uOffset
float vOffset
float uTiling
float vTiling
float rotationInRadians
int16 materialId (index of the material this layer belongs to = number of preceding chunk 3's)
byte mapType
byte unused
string texture
chunk 7: metadata (v2)
uint32 repositionMask
1 = repositionPos
2 = repositionRot
4 = repositionScale
int32 repositioningNode
byte exporterMajorVersion
byte exporterMinorVersion
byte unused[2]
float retargetRootOffset
string sourceApp
string origFileName
string exportDate
string actorName
chunk B: node hierarchy (v1)
int32 numNodes
int32 numRootNodes (number of nodes with parentId = -1)
NodeData[numNodes]
quat rotation
quat scaleRotation
vec3d position
vec3d scale
float unused[3]
int32 -1 (?)
int32 -1 (?)
int32 parentNodeId (index of parent node or -1 for root nodes)
int32 numChildNodes (number of nodes with parentId = this node's index)
int32 bIncludeInBoundsCalc
matrix44 transform
float fImportanceFactor
string name
chunk C: morph targets (v1)
int32 numMorphTargets
int32 lodMorphTargetIdx (presumably always 0; this is the index of a *collection* of numMorphTargets morph targets, not an
individual target, and an EmoActor only has one such collection)
MorphTarget[numMorphTargets]
float fRangeMin (at runtime, fMorphAmount must be >= fRangeMin)
float fRangeMax (at runtime, fMorphAmount must be <= fRangeMax)
int32 lodLevel (LOD of visual mesh; presumably always 0)
int32 numDeformations
int32 numTransformations
int32 phonemeSetBitmask (indicates which phonemes the morph target can be used for - facial animation)
0x1: neutral
0x2: M, B, P, X
0x4: AA, AO, OW
0x8: IH, AE, AH, EY, AY, H
0x10: AW
0x20: N, NG, CH, J, DH, D, G, T, K, Z, ZH, TH, S, SH
0x40: IY, EH, Y
0x80: UW, UH, OY
0x100: F, V
0x200: L, EL
0x400: W
0x800: R, ER
string name
Deformation[numDeformations]
int32 nodeId
float fMinValue
float fMaxValue
int32 numVertices
DeformVertex16 positionOffsets[numVertices]
uint16 x (fXOffset = fMinValue + (fMaxValue - fMinValue)*(x / 65535); vecDeformedPos.fX = vecPos.fX + fXOffset*fMorphAmount)
uint16 y
uint16 z
DeformVertex8 normalOffsets[numVertices]
byte x (fXOffset = x/127.5 - 1.0; vecDeformedNormal.fX = vecNormal.fX + fXOffset * fMorphAmount)
byte y
byte z
DeformVertex8 tangentOffsets[numVertices] (offsets for first tangent)
uint32 vertexIndices[numVertices] (index of the node's visual mesh vertex which the offsets apply to)
Transformation[numTransformations] (appears to be unused, i.e. numTransformations = 0)
int32 nodeId
quat rotation
quat scaleRotation
vec3d pos
vec3d scale
chunk D: material totals (v1)
int32 numTotalMaterials
int32 numStandardMaterials
int32 numFxMaterials