Skip to content

Commit

Permalink
Merge pull request #3 from kion-dgl/encode-verts
Browse files Browse the repository at this point in the history
Encode verts
  • Loading branch information
kion-dgl authored Jul 5, 2024
2 parents 948af37 + 08c3ee0 commit 05011aa
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 7 deletions.
41 changes: 37 additions & 4 deletions src/MeshReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,39 @@ const readStrips = (
return meshes;
}

const readVertex = (
reader: ByteReader,
) => {
const VERTEX_MASK = 0b1111111111;
const VERTEX_MSB = 0b1000000000;
const VERTEX_LOW = 0b0111111111;

const dword = reader.readUInt32();
const xBytes = (dword >> 0x00) & VERTEX_MASK;
const yBytes = (dword >> 0x0a) & VERTEX_MASK;
const zBytes = (dword >> 0x14) & VERTEX_MASK;

const xHigh = (xBytes & VERTEX_MSB) * -1;
const xLow = xBytes & VERTEX_LOW;

const yHigh = (yBytes & VERTEX_MSB) * -1;
const yLow = yBytes & VERTEX_LOW;

const zHigh = (zBytes & VERTEX_MSB) * -1;
const zLow = zBytes & VERTEX_LOW;

const vec3 = new Vector3(
(xHigh + xLow),
(yHigh + yLow),
(zHigh + zLow)
);
vec3.multiplyScalar(SCALE);
vec3.applyMatrix4(ROT);

const { x, y, z } = vec3;
return { x, y, z, dword };
}

const readVertexList = (
reader: ByteReader,
vertexOfs: number,
Expand Down Expand Up @@ -93,8 +126,8 @@ const readVertexList = (

const readFace = (
reader: ByteReader,
faceOfs: number,
faceCount: number,
faceOfs: number,
faceCount: number,
isQuad: boolean
) => {
const FACE_MASK = 0x7f;
Expand All @@ -120,7 +153,7 @@ const readFace = (
const indexC = (dword >> 0x0e) & FACE_MASK;
const indexD = (dword >> 0x15) & FACE_MASK;

const a ={
const a = {
materialIndex,
index: indexA,
u: au * PIXEL_TO_FLOAT_RATIO + PIXEL_ADJUSTMEST,
Expand Down Expand Up @@ -152,4 +185,4 @@ const readFace = (
}
}

export { readStrips, readVertexList, readFace }
export { readStrips, readVertexList, readFace, readVertex }
64 changes: 64 additions & 0 deletions src/MeshWriter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Vector3, Matrix4 } from "three";

const encodeVertex = (xRaw: number, yRaw: number, zRaw: number) => {

const SCALE = 1 / 0.00125;
const ROT_X = new Matrix4();
ROT_X.makeRotationX(Math.PI);

const vec3 = new Vector3(xRaw, yRaw, zRaw);
// vec3.multiplyScalar(SCALE);
// vec3.applyMatrix4(ROT_X);

// // Round each value to nearest whole int
vec3.x = Math.round(vec3.x)
vec3.y = Math.round(vec3.y)
vec3.z = Math.round(vec3.z)

// // Encode x,y,z to signed 10 but values
const { x, y, z } = vec3;
try {
const xInt = encodeVertexBits(x)
const yInt = encodeVertexBits(y)
const zInt = encodeVertexBits(z)
// Shift and merge vertex to make a 32 bit value
const vertex = xInt | (yInt << 10) | (zInt << 20)
return vertex
} catch (err) {
console.log("0 Scale invalid: ", x, y, z)
}

try {
const xInt = encodeVertexBits(Math.floor(x / 2))
const yInt = encodeVertexBits(Math.floor(y / 2))
const zInt = encodeVertexBits(Math.floor(z / 2))
// Shift and merge vertex to make a 32 bit value
const vertex = xInt | (yInt << 10) | (zInt << 20) | (1 << 30)
return vertex
} catch (err) {
console.log("1 Scale invalid: ", x, y, z)
throw err;
}


}

// Encode the Vertices
const encodeVertexBits = (num: number) => {

if (num < 0) {
const lowBits = 512 + num;
const encodedVert = 0x200 | lowBits;
if (encodedVert > 0x3ff) {
return 0x3ff;
}
return encodedVert
} else {
if (num > 0x1ff) {
return 0x1ff;
}
return num;
}
}

export { encodeVertex, encodeVertexBits }
98 changes: 95 additions & 3 deletions tests/body.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ import { readFileSync } from "fs";
import ByteReader from '../src/ByteReader';
import body from '../fixtures/body.json';
import fixtureGeometry from '../fixtures/body-data.json';
import { readStrips, readVertexList, readFace } from '../src/MeshReader';

import { readStrips, readVertexList, readVertex, readFace } from '../src/MeshReader';
import { encodeVertexBits } from '../src/MeshWriter';
import { Vector3, Matrix4 } from "three";
const SCALE = 0.00125;
const RESTORE = 800;
const ROT = new Matrix4();
ROT.makeRotationX(Math.PI);

test("Reading the strip offsets for the body", () => {
const buffer = readFileSync(`./bin/PL00P000.BIN`);
Expand Down Expand Up @@ -37,4 +42,91 @@ test("Reading the vertex and face data for the body", () => {
});

expect(geometry).toEqual(fixtureGeometry);
});
});

const dwordString = (dword: number) => {
const str = dword.toString(2).padStart(32, '0');
// return `${str.slice(0, 2)}-${str.slice(2, 12)}-${str.slice(12 - 22)}-${str.slice(22, 32)}`;
return `00-${str.slice(2, 12)}-${str.slice(12 - 22)}-${str.slice(22, 32)}`;
}

test('Re-encoding the vertices read from the body', () => {
const buffer = readFileSync(`./bin/PL00P000.BIN`);
const dat = buffer.subarray(0x30, 0x30 + 0x2b40);
const reader = new ByteReader(dat.buffer as ArrayBuffer);

body.map((mesh) => {
const { vertOfs, vertCount } = mesh;
reader.seek(vertOfs);

for(let i = 0; i < vertCount; i++) {
const VERTEX_MASK = 0x3ff; // 10 bits
const VERTEX_MSB = 0x200; // bit 9
const VERTEX_LOW = 0x1ff; // bits 0 - 8
const dwords = new Uint32Array(2);

// Read the vertex data
const dword = reader.readUInt32();
dwords[0] = dword;
const xBytes = (dword >> 0x00) & VERTEX_MASK;
const yBytes = (dword >> 0x0a) & VERTEX_MASK;
const zBytes = (dword >> 0x14) & VERTEX_MASK;

// Decode the vertex data
const xHigh = (xBytes & VERTEX_MSB) * -1;
const xLow = xBytes & VERTEX_LOW;

const yHigh = (yBytes & VERTEX_MSB) * -1;
const yLow = yBytes & VERTEX_LOW;

const zHigh = (zBytes & VERTEX_MSB) * -1;
const zLow = zBytes & VERTEX_LOW;

const x = xHigh + xLow
const y = yHigh + yLow
const z = zHigh + zLow

const vec3 = new Vector3(x, y, z);
vec3.multiplyScalar(SCALE);
vec3.applyMatrix4(ROT);

// Encode the vertex data
const v = vec3.clone();
v.applyMatrix4(ROT);
v.multiplyScalar(RESTORE);
v.x = Math.round(v.x)
v.y = Math.round(v.y)
v.z = Math.round(v.z)
v.x === -0 ? v.x = 0 : v.x = v.x;
v.y === -0 ? v.y = 0 : v.y = v.y;
v.z === -0 ? v.z = 0 : v.z = v.z;

const encodedx = encodeVertexBits(v.x);
const encodedy = encodeVertexBits(v.y);
const encodedz = encodeVertexBits(v.z);

// Check that the re-encoded vertex data matches the original
expect(encodedx).toEqual(xBytes);
expect(encodedy).toEqual(yBytes);
expect(encodedz).toEqual(zBytes);

// Check that the re-encoded vertex data matches the original
dwords[1] = encodedx | (encodedy << 0x0a) | (encodedz << 0x14)
expect(dwordString(dwords[1])).toEqual(dwordString(dwords[0]));
}
});

});

// test('Re-encoding the faces read from the body', () => {
// const buffer = readFileSync(`./bin/PL00P000.BIN`);
// const dat = buffer.subarray(0x30, 0x30 + 0x2b40);
// const reader = new ByteReader(dat.buffer as ArrayBuffer);

// const geometry = body.map((mesh) => {
// const { triOfs, triCount } = mesh;

// const triList = readFace(reader, triOfs, triCount, false);

// });
// });

0 comments on commit 05011aa

Please sign in to comment.