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
+24
-2
@@ -1,6 +1,7 @@
|
||||
// Orte: fest platzierte Modelle aus dem Editor three-d-stage, getrennt vom Chunk-Streaming
|
||||
// (docs/superpowers/specs/2026-09-14-hood-yard-design.md). Aufbereitet werden sie mit
|
||||
// tools/assets/places.mjs; hier stehen Lage, Laden und Kollision.
|
||||
import { BufferAttribute } from "three";
|
||||
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
||||
import { MeshoptDecoder } from "three/examples/jsm/libs/meshopt_decoder.module.js";
|
||||
import { worldToThree } from "./coords.js";
|
||||
@@ -79,6 +80,23 @@ export function wantedPlaces(position, places, { show, hide, active }) {
|
||||
return { add, remove };
|
||||
}
|
||||
|
||||
// tools/assets/places.mjs komprimiert mit meshopt() (KHR_mesh_quantization): Positionen fester Meshes
|
||||
// liegen als normalisierte Ganzzahlen vor, erst über die Mesh-Transform auf echte Maße skaliert.
|
||||
// colliderBuild.ts im three-player-controller klont die Geometrie aber und rechnet matrixWorld per
|
||||
// applyMatrix4 in die Kopie hinein — dabei würden normalisierte Werte beim Zurückschreiben auf ±1
|
||||
// geklemmt. Deshalb hier vorher in echte, nicht normalisierte Float32-Koordinaten entquantisieren.
|
||||
function dequantizePosition(geometry) {
|
||||
const position = geometry.attributes.position;
|
||||
if (!position.normalized && position.array instanceof Float32Array) return;
|
||||
const values = new Float32Array(position.count * 3);
|
||||
for (let i = 0; i < position.count; i++) {
|
||||
values[i * 3] = position.getX(i);
|
||||
values[i * 3 + 1] = position.getY(i);
|
||||
values[i * 3 + 2] = position.getZ(i);
|
||||
}
|
||||
geometry.setAttribute("position", new BufferAttribute(values, 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt Lage und Schatten und nimmt nicht feste Meshes aus der Kollision (colliderBuild.ts im
|
||||
* three-player-controller überspringt userData.excludeFromCollider). Gibt zurück, ob ein Teil fest ist.
|
||||
@@ -93,8 +111,12 @@ export function prepareModel(root, place) {
|
||||
object.castShadow = true;
|
||||
object.receiveShadow = true;
|
||||
const materials = Array.isArray(object.material) ? object.material : [object.material];
|
||||
if (materials.some((material) => isSolidMaterial(material?.name))) solid = true;
|
||||
else object.userData.excludeFromCollider = true;
|
||||
if (materials.some((material) => isSolidMaterial(material?.name))) {
|
||||
solid = true;
|
||||
dequantizePosition(object.geometry);
|
||||
} else {
|
||||
object.userData.excludeFromCollider = true;
|
||||
}
|
||||
});
|
||||
root.updateMatrixWorld(true);
|
||||
return solid;
|
||||
|
||||
Reference in new issue
Block a user