UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

62 lines (56 loc) 2.1 kB
import {Mesh, Object3D, Vector3} from 'three'; import {PhysicsLib} from '../CorePhysics'; 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(PhysicsLib: PhysicsLib, object: Object3D) { const geometry = (object as Mesh).geometry; if (!geometry) { return; } ThreeMeshBVHHelper.assignDefaultBVHIfNone(object as Mesh); 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 = PhysicsLib.ColliderDesc.heightfield(nrows, ncols, heights, scale); desc.setTranslation(bboxCenter.x, 0, bboxCenter.z); return desc; }