Ninja Model Formats
The following information delves into the model formats used in games that utilize the Ninja SDK, such as Sonic Adventure and Sonic Adventure 2. While the contents of the raw data vary between formats, they all share the same OBJECT container.
OBJECT Container
When viewed in code, an OBJECT container will have the following arrangement. Despite the existence of this container, it may often not be used as a reference point for calling model data within the specified game. This is determined on a case-by-case basis, and all models exported by SA Tools and SAIO will include it by default.
| Offset (Hex) | Type | Description |
|---|---|---|
| 0 | INT32 | OBJECT Evaluation flags |
| 4 | Pointer | Model data. This points to the main container for the specified model. This value can also be null to establish an empty node in a hierarchy. |
| 8 | Float(3) | Position |
| 14 | INT32(3) | Rotation. If there is a quaternion value defined, this section will store its values as a series of three floats. |
| 20 | Float(3) | Scale |
| 2C | Pointer | Child OBJECT. |
| 30 | Pointer | Sibling OBJECT. |
| 34 | Float | Quaternion value. Some games may not account for this space being present within their data, so its inclusion may cause issues. Sonic Adventure 2 (PC) incorporates this space for models in the game's code but not Sonic Adventure, for example. This portion is not included by default in SA Tools Hub/SAIO exports except for "Ginja" models. |
OBJECT Evaluation Flags
The following evaluation flags can be used:
| Name | Flag bits | Description |
|---|---|---|
| NJD_EVAL_UNIT_POS | BIT_0 | Ignore the model's position. |
| NJD_EVAL_UNIT_ANG | BIT_1 | Ignore the model's rotation. |
| NJD_EVAL_UNIT_SCL | BIT_2 | Ignore the model's scale. |
| NJD_EVAL_HIDE | BIT_3 | Do not render the model. |
| NJD_EVAL_BREAK | BIT_4 | Node is the end of the hierarchy (do not check children). |
| NJD_EVAL_ZXY_ANG | BIT_5 | Inverted order of rotation. |
| NJD_EVAL_SKIP | BIT_6 | Do not animate (ignore) this node. |
| NJD_EVAL_SHAPE_SKIP | BIT_7 | Do not animate (ignore) this node in shape animations. |
| NJD_EVAL_CLIP | BIT_8 | If this node is clipped, do not clip child nodes. |
| NJD_EVAL_MODIFIER | BIT_9 | The node has a modifier volume. |
Common Data
While the different model formats often contain standalone flags and implementations, some elements are shared between them.
Blend Alpha Modes
Alpha modes can be as follows:
Source alpha
|
Destination alpha
|
|---|
Basic Models
Primarily used in Sonic Adventure, Basic models are the first model type developed for Ninja. Skinning is not normally possible with this format, but a specialized variant has been developed for use with Sonic Adventure DX (2004) with the "Weighted Characters" mod. In the case of Sonic Adventure, "skinning" is done at runtime via instructions tied to the "join vertex" or "weld" system.
Sonic Adventure 2 utilizes this format for collisions and death barriers, never in a visible sense.
Sonic Adventure DX introduces a variation of Basic models - referred to as "Basic+" or "BasicDX" - and is the primary format of that game.
| Offset (Hex) | Type | Description |
|---|---|---|
| 0 | Pointer | Vertex data |
| 4 | Pointer | Normals data |
| 8 | INT32 | Vertex/Normal count |
| C | Pointer | Mesh data |
| 10 | Pointer | Material data |
| 14 | INT16 | Mesh count |
| 16 | INT16 | Material count |
| 18 | Float(3) | Model center. This is used for bounds calculation |
| 24 | Float | Model radius. This is used for bounds calculation |
| 28 | Pointer | Used in "Basic+"/"BasicDX" model data only. This space is always empty and is meant to point to the Direct3D mesh buffer. |
In the 2004 PC port of SADX this struct contains an extra field for the mesh buffer (buffer). This version of the struct is used in the PC, X360 and PS3 versions.
SA2 and Gamecube versions of SADX use the original struct without the extra field.
In SADX Mod Loader headers the original Ninja version is NJS_MODEL, and the one with the extra field is NJS_MODEL_SADX.
In the SADX X360 prototype with symbols, the one with the extra field is NJS_MODEL, and the original Ninja version is NJS_MODEL_OLD.
The size of the original NJS_MODEL is 40 (0x28) bytes, and the size of NJS_MODEL_SADX is 44 (0x2C) bytes.
In old modding terminology, the Model struct was referred to as the "attach" struct. You can still see this label in SA Tools' C exports.
Vertex Array
The model's vertices are in an array of NJS_POINT3 (NJS_VECTOR in Mod Loader headers).
NJS_VECTOR vertex_00000ADC[] = {
{ 0, 26.04398f, 0 },
{ 3.602116f, 18.50802f, 0 },
{ 1.801057f, 18.50802f, -3.119523f },
{ -1.801059f, 18.50802f, -3.119523f },
// And so on...
};
Normal Array
The model's normals are in an array of NJS_VECTOR.
NJS_VECTOR normal_00000D28[] = {
{ 0, 1, 0 },
{ 0.902229f, 0.431257f, 0 },
{ 0.451115f, 0.431256f, -0.781354f },
{ -0.451115f, 0.431256f, -0.781354f },
// And so on...
}
Meshset Struct (NJS_MESHSET) and Meshset Array
Multiple connected polygons form meshes. The NJS_MESHSET struct defines a single mesh.
| Field | Offset | Type | Size | Description | Notes |
|---|---|---|---|---|---|
| type_matId | 0 | Uint16 | 2 | Diffuse color. | Bits 0-13 are material id (0-4095) in the material array.
Bits 14-15 are meshset type bits. |
| nbMesh | 0x2 | Uint16 | 2 | Number of meshes. | |
| *meshes | 0x4 | Sint16* | 4 | Pointer to the poly array. | |
| *attrs | 0x8 | Uint32* | 4 | Pointer to the poly attribute array. | Unused in SA games. |
| *normals | 0xC | NJS_VECTOR* | 4 | Pointer to the polynormal array. | Almost never used. |
| *vertcolor | 0x10 | NJS_COLOR* | 4 | Pointer to the vertex color array. | Unused in SA1 DC, used in SADX. |
| *vertuv | 0x14 | NJS_TEX* | 4 | Pointer to the UV array. | |
| buffer | 0x18 | void | 4 | Pointer to the Direct3D mesh buffer. | Always null.
SADX PC 2004, SADX X360 and SADX PS3 only. |
In the 2004 PC port of SADX this struct contains an extra field for the mesh buffer (buffer). This version of the struct is used in the PC, X360 and PS3 versions.
SA2 and Gamecube versions of SADX use the original struct without the extra field.
In SADX Mod Loader headers the original Ninja version is NJS_MESHSET, and the one with the extra field is NJS_MESHSET_SADX.
In the SADX X360 prototype with symbols, the one with the extra field is NJS_MESHSET, and the original Ninja version is NJS_MESHSET_OLD.
The size of the original NJS_MESHSET is 24 (0x18) bytes, and the size of NJS_MESHSET_SADX is 28 (0x1C) bytes.
Meshset Type Bits
Meshset type bits are as follows:
| Meshset type | Value | Description |
|---|---|---|
| NJD_MESHSET_3 | 0x0000 | Triangle. |
| NJD_MESHSET_4 | 0x4000 | Quad (four vertices). |
| NJD_MESHSET_N | 0x8000 | N-Gon (custom number of vertices). |
| NJD_MESHSET_TRIMESH | 0xC000 | Trimesh (strips of connected triangles), the most common meshset type. |
| NJS_MESHSET_MASK | 0xC000 | Meshset type mask. |
To get the material ID from the type_matId field in your code, use type_matId & ~NJD_MESHSET_MASK. To get the mesh type, use type_matId >> 0xE.
Meshes in Basic models are stored in arrays of NJS_MESHSET:
NJS_MESHSET_SADX meshlist_00000294[] = {
{ NJD_MESHSET_TRIMESH | 0, 9, poly_00000044, NULL, NULL, NULL, uv_00000128, NULL },
{ NJD_MESHSET_TRIMESH | 1, 10, poly_000000A4, NULL, NULL, NULL, uv_000001C4, NULL },
{ NJD_MESHSET_TRIMESH | 2, 3, poly_00000108, NULL, NULL, NULL, uv_00000264, NULL }
};
Poly Array
The poly array in an array of Sint16 that lists the model's primitives (polygons). It is commonly formatted with the number of vertices (points) followed by vertex indices. The indices are used to pick the specific vertices from the model's vertices array.
Here is an example of a polys array. The 4 in each new line indicates the number of vertices in the surface, and the following four values are vertex indices.
Sint16 poly_0000002C[] = {
4, 13, 12, 5, 4,
4, 9, 8, 1, 0,
4, 11, 10, 3, 2,
4, 15, 14, 7, 6
};
The direction of listing vertices can be clockwise or counter-clockwise. To use the clockwise winding direction, add the 0x8000 flag to the number of vertices:
Sint16 poly_00000044[] = {
0x8000u | 5, 2, 1, 0, 7, 6,
// And so on...
};
Polygon Attribute Array
This is an array of Uint32 containing polygon-specific attributes. It is not used in Sonic Adventure games.
Polynormal Array
Normals determine the model's lighting and environment mapping distortion. Normals can be specified per-vertex or por-polygon. Almost no models in SA1 use per-poly normals (polynormals), with the exception of Tails' tails and Sonic's stretchy shoes. When polynormals are used, this is the array they are expected to be in.
Normals and polynormals are defined as arrays of NJS_VECTOR. NJS_VECTOR consists of three floats for X, Y and Z.
NJS_VECTOR polynormal_007383D8[] = {
{ 0 },
{ 0 },
{ 0 },
{ 0 },
{ 0 },
{ 0 }
};
Vertex Color Array
This is an array of NJS_COLOR that determines the colors of the model's vertices. Vertex colors are used per-polygon, not per-vertex.
NJS_COLOR vcolor_0000003C[] = {
{ 0xFFFFFFDF },
{ 0xFFFFFFFF },
{ 0xFFFFDFBF },
{ 0xFFFFFFFF },
{ 0xFFFFDFBF },
// And so on...
};
Note: In SA1 Dreamcast, vertex colors are ignored and the pointer to the vertex colors array is null in all models.
UV Array
The UV array is an array of NJS_TEX. UVs determine how the texture is applied to the model's surface. For exampled, bigger UV values will make the texture "zoomed in", adding values to U will make the texture offset horizontally etc. UVs are per-polygon.
NJS_TEX uv_000003A4[] = {
{ 130, 145 },
{ 212, 225 },
{ 124, 230 },
// And so on...
};
Material struct (NJS_MATERIAL) and Material Array
The material affects how the model's surface looks. It defines which texture to use, whether to use environment mapping etc.
| Field | Offset | Type | Size | Description | Notes |
|---|---|---|---|---|---|
| diffuse | 0 | NJS_COLOR | 4 | Diffuse color. | In SA1 with palette lighting, only alpha is used. |
| specular | 0x4 | NJS_COLOR | 4 | Specular color. | In SA1 with palette lighting, only alpha is used. The alpha value of 0 is treated as the "ignore specular" flag. |
| exponent | 0x8 | Float | 4 | Strength of specular light. | Can range from 0 to 300. Usage of it in Sonic Adventure games is not confirmed. |
| attr_texId | 0xC | Uint32 | 4 | Texture ID. | |
| attrflags | 0x10 | Uint32 | 4 | Material flags. | Bits 31-29 and 28-26 are used for source and destination alpha blending instructions respectively. |
Size: 20 bytes (0x14).
NJS_COLOR is a union that can be either NJS_BGRA, NJS_TEX or Uint32 (4 bytes).
NJS_BGRAis a 4-byte struct that consists of blue, green, red and alpha values ranging from 0 to 255. For example, the color A255 R178 G178 B178 would be 0xFFB2B2B2.
NJS_TEX (4 bytes) is a struct commonly used in UVs. It consists of two Sint16 values: one for U (horizontal) and one for V (vertical). UVs used in SA1 range from 0 to 255.
Attribute Flags
The following flags can be used in attrflags:
| Flag name | Flag bit | Description | Comments |
|---|---|---|---|
| NJD_FLAG_IGNORE_LIGHT | BIT_25 | Ignore lighting. | |
| NJD_FLAG_USE_FLAT | BIT_24 | Flat lighting. | Has no effect when palette-based lighting in SA1 is used. |
| NJD_FLAG_DOUBLE_SIDE | BIT_23 | Double-sided mesh. | Also used for collision. |
| NJD_FLAG_USE_ENV | BIT_22 | Enable environment mapping. | |
| NJD_FLAG_USE_TEXTURE | BIT_21 | Enable texture. | |
| NJD_FLAG_USE_ALPHA | BIT_20 | Enable transparency. | |
| NJD_FLAG_IGNORE_SPECULAR | BIT_19 | Disable specular lighting. | Used for specular palette selection in palette-based lighting in SA1. |
| NJD_FLAG_FLIP_U | BIT_18 | Flip Us. | |
| NJD_FLAG_FLIP_V | BIT_17 | Flip Vs. | |
| NJD_FLAG_CLAMP_U | BIT_16 | Clamp Us. | |
| NJD_FLAG_CLAMP_V | BIT_15 | Clamp Vs. | |
| NJD_FLAG_USE_ANISOTROPIC | BIT_12 | Enable anisotropic filtering, | Unused. |
| NJD_FLAG_PICK | BIT_7 | "Pick status" | Unused. |
Chunk Models
Chunk models are the premier format used in Sonic Adventure 2. This format supports skinning by default.
Sonic Adventure DX incorporates this model format for specific parts of the game, notably the Chao models and the Cream the Rabbit cameos.
| Offset (Hex) | Type | Description |
|---|---|---|
| 0 | Pointer | Vertex data |
| 4 | Pointer | Polygon data |
| 8 | Float(3) | Model center. This is used for bounds calculation |
| 14 | Float | Model radius. This is used for bounds calculation |
Vertex Chunk List
The library first parses the vertex chunk list. A vertex chunk contains a list of vertices. Each vertex will be placed in an intermediate vertex buffer that will be used for strip indices.
A vertex chunk is composed of a header, followed by data:
| Header (32 bits) | Vertex data information (32 bits) | Data | ||
|---|---|---|---|---|
| Type (0-15) | Next chunk (16-31) | Vertex count (0-15) | Index offset (16-31) | |
| Vertex type | Chunk size - 1 | Number of vertices | Start position in intermediate vbuffer | Depends on type |
The data depends on the vertex chunk type:
| Vertex chunk | Components | Vertex stream | Comment |
|---|---|---|---|
| NJD_CV_SH | Position | x, y, z,1.0f, ... | SH4 optimized (aligned) |
| NJD_CV_VN_SH | Position + Normal | x, y, z,1.0f, nx, ny, ny, 0.0f, ... | SH4 optimized (aligned) |
| NJD_CV | Position | x, y, z, ... | |
| NJD_CV_D8 | Position + Diffuse | x, y, z, D8888, ... | |
| NJD_CV_UF | Position + UserFlag | x, y, z, UF32 | |
| NJD_CV_NF | Position + NinjaFlag | x, y, z, NF32 | Used for weights |
| NJD_CV_S5 | Position + Diffuse + Specular | x, y, z, D565, S565, ... | |
| NJD_CV_S4 | Position + Diffuse + Specular | x, y, z, D4444, S565, ... | |
| NJD_CV_IN | Position + Diffuse + Specular | x, y, z, D16, S16, ... | |
| NJD_CV_VN | Position + Normal | x, y, z, nx, ny, nz, ... | |
| NJD_CV_VN_D8 | Position + Normal + Diffuse | x, y, z, nx, ny, nz, D8888, ... | |
| NJD_CV_VN_UF | Position + Normal + Diffuse + UserFlag | x, y, z, nx, ny, nz, D8888, UF32, ... | |
| NJD_CV_VN_NF | Position + Normal + Diffuse + NinjaFlag | x, y, z, nx, ny, nz, D8888, NF32, ... | Used for weights |
| NJD_CV_VN_S5 | Position + Normal + Diffuse + Specular | x, y, z, nx, ny, nz, D565, S565, ... | |
| NJD_CV_VN_S4 | Position + Normal + Diffuse + Specular | x, y, z, nx, ny, nz, D4444, S565, ... | |
| NJD_CV_VN_IN | Position + Normal + Diffuse + Specular | x, y, z, nx, ny, nz, D16, S16, ... | |
| NJD_CV_VNX | Position + Normal | x, y, z, nx10, ny10, nz(10), pad, ... | |
| NJD_CV_VNX_D8 | Position + Normal + Diffuse | x, y, z, nx10, ny10, nz(10), pad, D8888, ... | |
| NJD_CV_VNX_UF | Position + Normal + UserFlag | x, y, z, nx10, ny10, nz(10), pad, UF32, ... |
Note that the library only supports one chunk type per model.
The data is continuous until the end chunk is reached (255).
Polygon Chunk List
The library then processes the polygon chunk list, which consists of chunks that specify how to render the vertices.
These chunks follow the following structure:
| Header (16 bits) | Next chunk, optional | Data, optional | |
|---|---|---|---|
| Type (0-7) | Headbits (8-15) | ||
| Vertex type | Depends on type | Chunk size - 2 | Depends on type |
Chunks are continuous until the end chunk is reached (255).
There are 5 categories of polygon chunks:
- Bits chunk (fixed 16 bit size) : some rendering attributes
- Tiny chunks (fixed 32 bit size) : texture ID
- Material chunks : diffuse color, ambient color, specular color, blending flags
- Volume chunks : collision/modifier volumes
- Strip chunks : strip data
Bits Chunks
| Header (16 bits) | |
|---|---|
| Type (0-7) | Headbits (8-15) |
The next chunk is directly after.
Bits chunk types:
| Type | Description | Components/Notes |
|---|---|---|
| NJD_CB_BA | Blend Alpha | Source, Destination |
| NJD_CB_DA | Mipmap 'D' Adjust | |
| NJD_CB_EXP | Specular Exponent | |
| NJD_CB_CP | Cache Polygon | Null, necessary for skinned models |
| NJD_CB_DP | Draw Polygon | Null, necessary for skinned models |
Tiny Chunks
| Header (16 bits) | Data (16 bits) | |
|---|---|---|
| Type (0-7) | Headbits (8-15) | |
The next chunk is directly after.
Tiny chunk types:
| Type | Description | Components/Notes |
|---|---|---|
| NJD_CT_TID | Texture ID | |
| NJD_CT_TID2 | Texture ID 2 |
Material Chunks
| Header (16 bits) | Next chunk | Data | |
|---|---|---|---|
| Type (0-7) | Headbits (8-15) | ||
Material chunk types:
| Type | Description | Components/Notes |
|---|---|---|
| NJD_CM_D | Material Diffuse | NJS_COLOR |
| NJD_CM_A | Material Ambient | NJS_COLOR |
| NJD_CM_S | Material Specular | NJS_COLOR |
| NJD_CM_DA | Material Diffuse + Ambient | NJS_COLOR, NJS_COLOR |
| NJD_CM_DS | Material Diffuse + Specular | NJS_COLOR, NJS_COLOR |
| NJD_CM_AS | Material Ambient + Specular | NJS_COLOR, NJS_COLOR |
| NJD_CM_DAS | Material Diffuse + Ambient + Specular | NJS_COLOR, NJS_COLOR, NJS_COLOR |
| NJD_CM_D2 | Material Second Diffuse | NJS_COLOR |
| NJD_CM_A2 | Material Second Ambient | NJS_COLOR |
| NJD_CM_S2 | Material Second Specular | NJS_COLOR |
| NJD_CM_DA2 | Material Second Diffuse + Ambient | NJS_COLOR, NJS_COLOR |
| NJD_CM_DS2 | Material Second Diffuse + Specular | NJS_COLOR, NJS_COLOR |
| NJD_CM_AS2 | Material Second Ambient + Specular | NJS_COLOR, NJS_COLOR |
| NJD_CM_DAS2 | Material Second Diffuse + Ambient + Specular | NJS_COLOR, NJS_COLOR, NJS_COLOR |
| NJD_CM_BM | Bump Material | (DX, DY, DZ), (UX, UY, UZ) |
Volume Chunks
...
Strip Chunks
A strip chunk renders a triangle strip using vertices from the intermediate buffer generated by the vertex chunk list.
It can contain additional information, such as UV coordinates, vertex color or user data.
The chunk structure is as follows:
| Header (16 bits) | Next chunk | Strip data information | Data, optional | ||
|---|---|---|---|---|---|
| Type (0-7) | Headbits (8-15) | Strip count (0-13) | User area size (14-15) | ||
| Strip type | Rendering flags | Chunk size - 2 | Number of strips | NJD_UFO_0 = 0 bits NJD_UFO_1 = 16 bits |
Depends on type |
The data itself follows this structure:
| Strip header | Strip stream | |||||||
|---|---|---|---|---|---|---|---|---|
| Length (0-14) | Winding flag (15) | First element | Second element | Element N .... | ||||
| Number of vertices | If set, reverse order | Index | Data | Index | Data | Index | Data | User area (optional) |
* The user area is per-triangle, so it only starts at the third element, from there every other vertex is another triangle.
The data stream depends on the strip type:
| Strip chunk | Components | Data stream |
|---|---|---|
| NJD_CS | None | index |
| NJD_CS_UVN | UV (255 = 1.0) | index, u, v |
| NJD_CS_UVH | UV (1023 = 1.0) | index, u, v |
| NJD_CS_VN | Normal | index, nx, ny, nz |
| NJD_CS_UVN_VN | UV (255), normal | index, u, v, nx, ny, nz |
| NJD_CS_UVH_VN | UV (1023), normal | index, u, v, nx, ny, nz |
| NJD_CS_D8 | Diffuse | index, ar, gb |
| NJD_CS_UVN_D8 | UV (255), diffuse | index, u, v, ar, gb |
| NJD_CS_UVH_D8 | UV (1023), diffuse | index, u, v, ar, gb |
| NJD_CS_2 | None | index |
| NJD_CS_UVN2 | UV (255) | index, u, v |
| NJD_CS_UVH2 | UV (1023) | index, u, v |
"Ginja" (GC) Models
This format was introduced in Sonic Adventure 2 Battle and further refined in Billy Hatcher and the Giant Egg. Utilizing a combination of Ninja and Nintendo's systems, "Ginja" models (a portmanteau of "GameCube" and "Ninja") are often Chunk models converted to make use of newer technologies. Sonic Adventure 2 Battle's implementation does not have skinning support, which was addressed in Billy Hatcher.
Currently, neither SA Tools Hub nor SAIO has the ability to read or export "Ginja" models with skinning.
| Offset (Hex) | Type | Description |
|---|---|---|
| 0 | Pointer | Vertex data |
| 4 | Pointer | Weight data |
| 8 | Pointer | Opaque polygon data |
| C | Pointer | Translucent polygon data |
| 10 | INT16 | Opaque polygon data count |
| 12 | INT16 | Translucent polygon data count |
| 14 | Float(3) | Model center. This is used for bounds calculation |
| 20 | Float | Model radius. This is used for bounds calculation |
"Ginja" Vertex Data
"Ginja" models store their point data quite differently from the other model types. Sonic Adventure 2 Battle uses a combination of four data sets in this section: Points (always exist), normals, color data, and UV data. Other data types exist, but these are the main four types and are often used together, up to a maximum of three data types at a time. Headers are read continuously and are designed to stop when encountering a null state, indicated by vertex attribute 255 (FF).
| Offset | Type | Description | Notes |
|---|---|---|---|
| 0 | Byte | Attribute | |
| 1 | Byte | Size of vertex struct | |
| 2 | INT16 | Vertex struct count | |
| 4 | INT32 | Structure type (Bits 0-3) Data type (Bits 4-7) |
Values are constant in Sonic Adventure 2 Battle |
| 8 | Pointer | Vertex data array | |
| C | UINT32 | Vertex data array length |
"Ginja" Vertex Attributes
| Value | Description | Notes |
|---|---|---|
| 0 | Position Matrix Index | Seemingly unused |
| 1 | Position | Value must exist and be used first within vertex headers |
| 2 | Normal | |
| 3 | Color0 | |
| 4 | Color1 | Unused in Sonic Adventure 2 Battle |
| 5 | Tex0 | |
| 6 | Tex1 | Unused in Sonic Adventure 2 Battle |
| 7 | Tex2 | Unused in Sonic Adventure 2 Battle |
| 8 | Tex3 | Unused in Sonic Adventure 2 Battle |
| 9 | Tex4 | Unused in Sonic Adventure 2 Battle |
| 10 | Tex5 | Unused in Sonic Adventure 2 Battle |
| 11 | Tex6 | Unused in Sonic Adventure 2 Battle |
| 12 | Tex7 | Unused in Sonic Adventure 2 Battle |
| 255 | Null | Value must be used in the last header |
"Ginja" Vertex Structure Types
| Value | Description | Notes |
|---|---|---|
| 0 | Position (XY) | Unused in Sonic Adventure 2 Battle |
| 1 | Position (XYZ) | |
| 2 | Normal (XYZ) | |
| 3 | Normal (NBT) | Unused in Sonic Adventure 2 Battle |
| 4 | Normal (NBT3) | Unused in Sonic Adventure 2 Battle |
| 5 | Color (RGB) | Unused in Sonic Adventure 2 Battle |
| 6 | Color (RGBA) | |
| 7 | Texture Coordinates (S) | Unused in Sonic Adventure 2 Battle |
| 8 | Texture Coordinates (ST) |
"Ginja" Vertex Data Types
| Value | Description | Notes |
|---|---|---|
| 0 | Unsigned int8 | Unused in Sonic Adventure 2 Battle |
| 1 | Signed int8 | Unused in Sonic Adventure 2 Battle |
| 2 | Unsigned int16 | Unused in Sonic Adventure 2 Battle |
| 3 | Signed int16 | |
| 4 | Float | |
| 5 | RGB565 | Unused in Sonic Adventure 2 Battle |
| 6 | RGB8 | Unused in Sonic Adventure 2 Battle |
| 7 | RGBX8 | Unused in Sonic Adventure 2 Battle |
| 8 | RGBA4 | Unused in Sonic Adventure 2 Battle |
| 9 | RGBA6 | Unused in Sonic Adventure 2 Battle |
| 10 | RGBA8 |
"Ginja" Vertex Arrays
The following arrays are used in Sonic Adventure 2 Battle.
| Type | Data | Size |
|---|---|---|
| Point | Float(3) | 12 |
| Normal | Float(3) | 12 |
| Color0 | RGBA | 4 |
| Tex0 | INT16(2) | 4 |
"Ginja" Polygon Data
When viewed in its raw state, "Ginja" polygon data is separated into two components: one side featuring parameter data, and the other containing primitives.
| Offset | Type | Description | Notes |
|---|---|---|---|
| 0 | Pointer | Parameter data | Value is not required to exist past the first entry. |
| 4 | INT32 | Parameter data count | |
| 8 | Pointer | Primitive data | |
| C | INT32 | Primitive data size |
"Ginja" Parameter Data
| Offset | Type | Description | Notes |
|---|---|---|---|
| 0 | Byte | Data Type | |
| 1 | Byte(3) | Padding | |
| 4 | UINT32 | Data | This section's data depends on the set data type. |
"Ginja" Parameter Types
| Type Value | Description | Data | Notes |
|---|---|---|---|
| 0 | Vertex Attribute Format | Vertex Attribute (Bits 0-15) Vertex Structure Type (Bits 16-19) |
Attribute data must match any of the attributes set within the model's vertex data |
| 1 | Index Attribute Flags | Flags (All bits) | Data is necessary for parsing primitives properly |
| 2 | Lighting | Flags (Bits 0-15) Shadow Stencil (Bits 16) |
Lighting flags are usually set to 0xB11, and Shadow Stencil is usually 1 |
| 3 | Strip Flags | Unused in Sonic Adventure 2 Battle | |
| 4 | Blend Alpha | Source Alpha (Bit 11) Destination Alpha (Bit 8) |
|
| 5 | Diffuse | NJS_COLOR | |
| 6 | Ambient | Unused in Sonic Adventure 2 Battle | |
| 7 | Specular | Unused in Sonic Adventure 2 Battle | |
| 8 | Texture Data | Texture ID (Bits 0-15) Tile Mode (Bits 16-31) |
|
| 9 | Texture TEV Order | Unknown 1 (Bits 0-15) Unknown 2 (Bits 16-31) |
Unknown 1 is usually set to 4, and Unknown 2 is usually 0 |
| 10 | Texture Coordinate Generator | Texture Coord ID (Bits 9-15) Texture Coord Generator Type (Bits 16-19) |
"Ginja" Primitive Data
| Offset | Type | Description | Notes |
|---|---|---|---|
| 0 | Byte | Primitive Type | |
| 1 | INT16 | Loop count | |
| 3 | Primitive Loop[] | Loop data | Size and structure varies depending on the index attribute flags defined within the model's parameter data |
| General Information | File Formats • Model Formats • Level List • Texture Files • Game Builds • CAM & SET Files | |
|---|---|---|
| Character Information | Character List • Actions • Animation Lists • Faces | |
| Sound Information | General | Voice List • Music Files |
| Sound Effects | Stage Sounds • Stage Background Sounds | |
| Other | Cutscene List • Fish List | |
| General Information | File Formats • Model Formats • Levels • Texture Files • Light and Fog Data • Game Builds | ||
|---|---|---|---|
| Character Information | General | Model Data • Animation Files • Actions | |
| Animation Lists | Speed-Types | Sonic • Shadow • Amy • Metal Sonic | |
| Hunting-Types | Knuckles • Rouge • Tikal • Chaos Zero | ||
| Shooting-Types | Mech Tails • Mech Eggman • Chao Walker • Dark Chao Walker | ||
| Miscellaneous | Tails • Eggman • Super Sonic • Super Shadow | ||
| Sound Information | Voice List • Music Files • Sound Effects | ||
| Other | Cutscenes | ||