@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
57 lines (56 loc) • 2.1 kB
JavaScript
;
import { Vector3 } from "three";
import { ThreeMeshBVHHelper } from "../../../core/geometry/bvh/ThreeMeshBVHHelper";
import { CoreMath } from "../../math/_Module";
import { CorePhysicsAttribute } from "../PhysicsAttribute";
import { createRaycaster } from "../../RaycastHelper";
const bboxSize = new Vector3();
const bboxCenter = new Vector3();
const scale = new Vector3();
const raycaster = createRaycaster();
export function createPhysicsHeightField(PhysicsLib2, object) {
const geometry = object.geometry;
if (!geometry) {
return;
}
ThreeMeshBVHHelper.assignDefaultBVHIfNone(object);
geometry.computeBoundingBox();
const boundingBox = geometry.boundingBox;
if (!boundingBox) {
return;
}
boundingBox.getSize(bboxSize);
boundingBox.getCenter(bboxCenter);
const nrows = CorePhysicsAttribute.getHeightFieldRows(object);
const ncols = CorePhysicsAttribute.getHeightFieldCols(object);
const arraySize = (nrows + 1) * (ncols + 1);
const array = new Array(arraySize);
raycaster.ray.direction.set(0, -1, 0);
raycaster.ray.origin.y = boundingBox.max.y + 1;
let i = 0;
const maxMult = 0.99;
const minMult = 1 - maxMult;
for (let col = 0; col <= ncols; col++) {
const coln = CoreMath.clamp(col / ncols, minMult, maxMult);
for (let row = 0; row <= nrows; row++) {
const rown = CoreMath.clamp(row / nrows, minMult, maxMult);
raycaster.ray.origin.x = boundingBox.min.x + bboxSize.x * coln;
raycaster.ray.origin.z = boundingBox.min.z + bboxSize.z * rown;
const intersections = raycaster.intersectObject(object);
let value = boundingBox.min.y;
if (intersections) {
const firstIntersect = intersections[0];
if (firstIntersect) {
value = raycaster.ray.origin.y - firstIntersect.distance;
}
}
array[i] = value;
i++;
}
}
const heights = new Float32Array(array);
scale.set(bboxSize.x, 1, bboxSize.z);
const desc = PhysicsLib2.ColliderDesc.heightfield(nrows, ncols, heights, scale);
desc.setTranslation(bboxCenter.x, 0, bboxCenter.z);
return desc;
}