fix(world): quantisierte Positionen vor dem Kollisionsaufbau in Float32 wandeln
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9f6570b11d
commit
522101c026
3 files changed
+70
-3
No files matched your search
+44
-1
@@ -1,5 +1,6 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { BoxGeometry, Group, Mesh, MeshStandardMaterial, Scene, Vector3 } from "three";
|
||||
import { BoxGeometry, BufferAttribute, BufferGeometry, Group, Mesh, MeshStandardMaterial, Scene,
|
||||
Vector3 } from "three";
|
||||
import { PLACES, PlaceLayer, SOLID_MATERIALS, isSolidMaterial, placeTransform, prepareModel,
|
||||
wantedPlaces } from "../src/world/places.js";
|
||||
|
||||
@@ -91,6 +92,48 @@ describe("prepareModel", () => {
|
||||
it("meldet, wenn kein Teil fest ist", () => {
|
||||
expect(prepareModel(fakeModel(["grass_medium_01"]), { at: [0, 0], rotation: 0, lift: 0 })).toBe(false);
|
||||
});
|
||||
|
||||
// Bruch: colliderBuild.ts im three-player-controller klont die Geometrie und rechnet matrixWorld
|
||||
// per applyMatrix4 hinein. Bei einer normalisierten Int16-Position (KHR_mesh_quantization aus
|
||||
// meshopt() in tools/assets/places.mjs) klemmt das Zurückschreiben die Weltkoordinaten auf ±1 —
|
||||
// der Hof kollidierte dann nahe dem Weltursprung statt an seiner Stelle im Hood Yard.
|
||||
it("entquantisiert feste Positionen, bevor der Collider die Weltmatrix hineinrechnet", () => {
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute("position",
|
||||
new BufferAttribute(new Int16Array([-32767, 0, -32767, 32767, 32767, 32767]), 3, true));
|
||||
const mesh = new Mesh(geometry, new MeshStandardMaterial({ name: "cont_a_side" }));
|
||||
mesh.scale.setScalar(17);
|
||||
const root = new Group();
|
||||
root.add(mesh);
|
||||
|
||||
prepareModel(root, { at: [1489, 1067.5], rotation: 0, lift: -0.28 });
|
||||
|
||||
expect(mesh.geometry.attributes.position.array).toBeInstanceOf(Float32Array);
|
||||
expect(mesh.geometry.attributes.position.normalized).toBe(false);
|
||||
|
||||
// Wie colliderBuild.ts: Geometrie klonen und die Weltmatrix hineinrechnen.
|
||||
const worldGeometry = mesh.geometry.clone();
|
||||
worldGeometry.applyMatrix4(mesh.matrixWorld);
|
||||
worldGeometry.computeBoundingBox();
|
||||
|
||||
expect(worldGeometry.boundingBox.min.x).toBeCloseTo(1472);
|
||||
expect(worldGeometry.boundingBox.max.x).toBeCloseTo(1506);
|
||||
expect(worldGeometry.boundingBox.min.z).toBeCloseTo(-1084.5);
|
||||
expect(worldGeometry.boundingBox.max.z).toBeCloseTo(-1050.5);
|
||||
});
|
||||
|
||||
it("lässt eine durchlässige Position quantisiert", () => {
|
||||
const geometry = new BufferGeometry();
|
||||
const position = new BufferAttribute(new Int16Array([0, 0, 0, 32767, 32767, 32767]), 3, true);
|
||||
geometry.setAttribute("position", position);
|
||||
const mesh = new Mesh(geometry, new MeshStandardMaterial({ name: "grass_medium_01" }));
|
||||
const root = new Group();
|
||||
root.add(mesh);
|
||||
|
||||
prepareModel(root, { at: [0, 0], rotation: 0, lift: 0 });
|
||||
|
||||
expect(mesh.geometry.attributes.position).toBe(position);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PLACES", () => {
|
||||
|
||||
Reference in new issue
Block a user