Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.

Commit 4c7c174

Browse files
committed
vertex format
1 parent 4ee7350 commit 4c7c174

File tree

1 file changed

+92
-11
lines changed

1 file changed

+92
-11
lines changed

src/content/docs/mml2/player.mdx

+92-11
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ description: A description of the mesh format used for the player character
55

66
import MermaidDiagram from '@components/MermaidDiagram.astro';
77

8-
## MegaMan Model
9-
108
There is a separate model of MegaMan depending on the equipment.
119
The options for this are if a helmet is equipped or not, and if the shoes are jet, cleat, asbestos, or hover.
1210
What this means is that most of the information in the model is duplicated, with the exception of the helmet and shoes.
@@ -60,8 +58,8 @@ typedef struct {
6058
uint32_t triOffset;
6159
uint32_t quadOffset;
6260
uint32_t vertexOffset;
63-
utin32_t triShadowOffset;
64-
utin32_t quadShadowOffset;
61+
utin32_t activeVertexColors;
62+
utin32_t referenceVertexColors;
6563
} StripHeader;
6664
```
6765

@@ -71,13 +69,96 @@ typedef struct {
7169

7270
### Vertex Format
7371

74-
<MermaidDiagram chart={`
75-
graph TD;
76-
A-->B;
77-
A-->C;
78-
B-->D;
79-
C-->D;
80-
`} />
72+
Each vertex is encoded in a 32-bit word (`uint32_t`) which is split into different bit segments for the X, Y, and Z coordinates, as well as scale data:
73+
74+
- **32-bit word format:**
75+
- **X-axis**: The lowest 10 bits (bits 0–9).
76+
- **Y-axis**: The next 10 bits (bits 10–19).
77+
- **Z-axis**: The following 10 bits (bits 20–29).
78+
- **Scale**: The highest 2 bits (bits 30–31), which encode scaling information.
79+
80+
#### Scale Encoding
81+
82+
The two highest bits (30–31) represent scale data, which determines how much to scale the X, Y, and Z coordinates:
83+
- `0b00`: 1x scale (no scaling).
84+
- `0b01`: 2x scale.
85+
- `0b10`: 4x scale.
86+
- `0b11`: 0.5x scale.
87+
88+
#### Coordinate Representation
89+
90+
Each axis (X, Y, Z) is represented as a signed 10-bit integer:
91+
- **Sign Bit**: The most significant bit (MSB) of each axis segment indicates the sign (negative if set).
92+
- **Magnitude**: The remaining 9 bits represent the magnitude of the value.
93+
94+
#### PSX Coordinate System
95+
96+
The PSX coordinate system uses a convention where **-Y is up**. To align with this, the vertices are rotated by 180 degrees along the X-axis. Additionally, the PSX does not support floating-point values, so we scale down the vertices to bring them closer to real-world units, like meters.
97+
98+
#### Code Example
99+
100+
The following C code demonstrates how to decode the vertex data from a 32-bit word:
101+
102+
```c
103+
#include <stdint.h>
104+
#include <math.h>
105+
#include <stdio.h>
106+
107+
#define SCALE 0.00125
108+
109+
// Function to read a vertex from a 32-bit encoded integer
110+
void readVertex(uint32_t dword, float* x, float* y, float* z) {
111+
const uint32_t VERTEX_MASK = 0b1111111111;
112+
const uint32_t VERTEX_MSB = 0b1000000000;
113+
const uint32_t VERTEX_LOW = 0b0111111111;
114+
115+
// Extract X, Y, Z using bit shifts and masks
116+
int32_t xBytes = (dword >> 0x00) & VERTEX_MASK;
117+
int32_t yBytes = (dword >> 0x0a) & VERTEX_MASK;
118+
int32_t zBytes = (dword >> 0x14) & VERTEX_MASK;
119+
120+
// Apply sign to X, Y, Z
121+
int32_t xSign = (xBytes & VERTEX_MSB) ? -1 : 1;
122+
int32_t xValue = (xBytes & VERTEX_LOW);
123+
124+
int32_t ySign = (yBytes & VERTEX_MSB) ? -1 : 1;
125+
int32_t yValue = (yBytes & VERTEX_LOW);
126+
127+
int32_t zSign = (zBytes & VERTEX_MSB) ? -1 : 1;
128+
int32_t zValue = (zBytes & VERTEX_LOW);
129+
130+
// Extract scale from the top 2 bits (30 and 31)
131+
uint32_t scaleBits = (dword >> 30) & 0b11;
132+
float scale = 1.0;
133+
switch (scaleBits) {
134+
case 0b00:
135+
scale = 1.0;
136+
break;
137+
case 0b01:
138+
scale = 2.0;
139+
break;
140+
case 0b10:
141+
scale = 4.0;
142+
break;
143+
case 0b11:
144+
scale = 0.5;
145+
break;
146+
}
147+
148+
// Combine high and low parts for each axis
149+
*x = (xSign * xValue) * scale;
150+
*y = (ySign * yValue) * scale;
151+
*z = (zSign * zValue) * scale;
152+
153+
// Apply final scaling to make units closer to meters
154+
*x *= SCALE;
155+
*y *= SCALE;
156+
*z *= SCALE;
157+
158+
// Rotate by 180 degrees across the X-axis to match PSX format (-Y is up)
159+
*y = -*y; // Flip Y
160+
}
161+
```
81162
82163
### Face Format
83164

0 commit comments

Comments
 (0)