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

Commit 806f541

Browse files
committed
face format
1 parent 4c7c174 commit 806f541

File tree

1 file changed

+108
-1
lines changed

1 file changed

+108
-1
lines changed

src/content/docs/mml2/player.mdx

+108-1
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,111 @@ void readVertex(uint32_t dword, float* x, float* y, float* z) {
162162
163163
### Face Format
164164
165-
Issue: https://github.com/kion-dgl/Miku-Legends-2/issues/12
165+
The face format is shared between triangles and quads. The `face_t` structure contains UV coordinates and vertex indices. Here’s how the data is laid out:
166+
167+
```c
168+
typedef struct {
169+
uint8_t au;
170+
uint8_t av;
171+
uint8_t bu;
172+
uint8_t bv;
173+
uint8_t cu;
174+
uint8_t cv;
175+
uint8_t du; // Unused for triangles
176+
uint8_t dv; // Unused for triangles
177+
uint32_t indices; // Encodes vertex indices and material information
178+
} face_t;
179+
```
180+
181+
#### Field Details:
182+
183+
- **UV Coordinates**: The first 8 bytes (au, av, bu, bv, cu, cv, du, dv) represent texture mapping coordinates. These UV values are 8-bit unsigned integers and reference pixels in a 256x256 texture space.
184+
- For triangles, `du` and `dv` are unused.
185+
- For quads, all UV values are used.
186+
187+
- **Vertex Indices**: The `indices` field contains vertex indices and material information:
188+
- **Bits 0–6**: Vertex index for `a`.
189+
- **Bits 7–13**: Vertex index for `b`.
190+
- **Bits 14–20**: Vertex index for `c`.
191+
- **Bits 21–27**: Vertex index for `d` (unused for triangles).
192+
- **Bits 28–29**: Material information, which can have one of four values:
193+
- `0b00`: Megaman’s body texture.
194+
- `0b01`: Megaman’s body texture with a different palette.
195+
- `0b10`: Megaman’s face texture.
196+
- `0b11`: Megaman’s face texture with a different palette (used for special weapons).
197+
198+
#### UV Coordinate Conversion
199+
200+
The UV coordinates are stored as integers but need to be converted to floating-point values for rendering. The texture space is 256x256, so the following formula converts the UVs to normalized floating-point values:
201+
202+
```
203+
u_float = (u_int * 1/256) + 0.001953125
204+
v_float = (v_int * 1/256) + 0.001953125
205+
```
206+
207+
#### Code Example
208+
209+
```c
210+
#include <stdint.h>
211+
#include <stdio.h>
212+
213+
#define PIXEL_TO_FLOAT_RATIO 0.00390625f
214+
#define PIXEL_ADJUSTMENT 0.001953125f
215+
#define FACE_MASK 0x7F
216+
217+
// Structure to hold decoded face data
218+
typedef struct {
219+
float u, v; // UV coordinates
220+
uint8_t index; // Vertex index
221+
uint8_t materialIndex; // Material information
222+
} Vertex;
223+
224+
typedef struct {
225+
Vertex a, b, c, d; // Vertices for a face
226+
uint8_t isQuad; // 1 if quad, 0 if triangle
227+
} Face;
228+
229+
// Function to decode UV coordinates and vertex indices from a face_t structure
230+
void readFace(const uint8_t* faceData, Face* face, uint8_t isQuad) {
231+
// Read UV coordinates
232+
uint8_t au = faceData[0], av = faceData[1];
233+
uint8_t bu = faceData[2], bv = faceData[3];
234+
uint8_t cu = faceData[4], cv = faceData[5];
235+
uint8_t du = faceData[6], dv = faceData[7];
236+
237+
// Read indices and material information
238+
uint32_t indices = *((uint32_t*)(faceData + 8));
239+
uint8_t materialIndex = (indices >> 28) & 0x3;
240+
241+
uint8_t indexA = (indices >> 0) & FACE_MASK;
242+
uint8_t indexB = (indices >> 7) & FACE_MASK;
243+
uint8_t indexC = (indices >> 14) & FACE_MASK;
244+
uint8_t indexD = (indices >> 21) & FACE_MASK;
245+
246+
// Store the decoded UV and index data in the Face struct
247+
face->a.u = au * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
248+
face->a.v = av * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
249+
face->a.index = indexA;
250+
face->a.materialIndex = materialIndex;
251+
252+
face->b.u = bu * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
253+
face->b.v = bv * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
254+
face->b.index = indexB;
255+
face->b.materialIndex = materialIndex;
256+
257+
face->c.u = cu * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
258+
face->c.v = cv * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
259+
face->c.index = indexC;
260+
face->c.materialIndex = materialIndex;
261+
262+
if (isQuad) {
263+
face->isQuad = 1;
264+
face->d.u = du * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
265+
face->d.v = dv * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMENT;
266+
face->d.index = indexD;
267+
face->d.materialIndex = materialIndex;
268+
} else {
269+
face->isQuad = 0;
270+
}
271+
}
272+
```

0 commit comments

Comments
 (0)