Skip to content

Commit 3d28a47

Browse files
committed
create a CANNON.Heightfield shape to use with static-body if physics is available
1 parent 04298d7 commit 3d28a47

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

index.js

+53-1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,15 @@ AFRAME.registerComponent('environment', {
172172

173173
this.dressing = document.createElement('a-entity');
174174

175+
// add static-body component to the ground if physics available
176+
const physicsAvail = !!this.el.sceneEl.getAttribute('physics');
177+
if (physicsAvail) {
178+
this.ground.setAttribute('static-body', 'shape', 'none');
179+
// Specifying hull as shape works but is slow. We create
180+
// a Heightfield shape at the same time as modifying the plane
181+
// geometry and attach it to the body.
182+
}
183+
175184
this.gridCanvas = null;
176185
this.gridTexture = null;
177186

@@ -462,14 +471,26 @@ AFRAME.registerComponent('environment', {
462471
return;
463472
}
464473

474+
var segments = resolution - 1;
475+
var planeSize = this.STAGE_SIZE + 2;
476+
var planeSizeHalf = planeSize / 2;
477+
var segmentSize = planeSize / segments;
465478
if (!this.groundGeometry) {
466-
this.groundGeometry = new THREE.PlaneGeometry(this.STAGE_SIZE + 2, this.STAGE_SIZE + 2, resolution - 1, resolution - 1);
479+
this.groundGeometry = new THREE.PlaneGeometry(planeSize, planeSize, segments, segments);
467480
}
468481
var perlin = new PerlinNoise();
469482
var verts = this.groundGeometry.vertices;
470483
var numVerts = this.groundGeometry.vertices.length;
471484
var frequency = 10;
472485
var inc = frequency / resolution;
486+
var physicsAvail = !!this.el.sceneEl.getAttribute('physics');
487+
if (physicsAvail) {
488+
var maxH = 0;
489+
var matrix = [];
490+
for (var j = 0; j < resolution; j++) {
491+
matrix.push(new Float32Array(resolution));
492+
}
493+
}
473494

474495
for (var i = 0, x = 0, y = 0; i < numVerts; i++) {
475496
if (this.data.ground == 'flat') {
@@ -511,6 +532,16 @@ AFRAME.registerComponent('environment', {
511532
// set height
512533
verts[i].z = h;
513534

535+
// construct matrix to create the Heightfield
536+
if (physicsAvail) {
537+
// We reverse the calculation that is done when creating the
538+
// PlaneGeometry to get back the original x and y for the matrix.
539+
matrix[Math.round((verts[i].x + planeSizeHalf) / segmentSize)][Math.round((verts[i].y + planeSizeHalf) / segmentSize)] = h * this.data.groundYScale;
540+
if (h > maxH) {
541+
maxH = h;
542+
}
543+
}
544+
514545
// calculate next x,y ground coordinates
515546
x += inc;
516547
if (x >= 10) {
@@ -519,6 +550,27 @@ AFRAME.registerComponent('environment', {
519550
}
520551
}
521552

553+
554+
if (physicsAvail) {
555+
// Create the heightfield
556+
var hfShape = new CANNON.Heightfield(matrix, {
557+
elementSize: segmentSize,
558+
minValue: 0,
559+
maxValue: maxH * this.data.groundYScale
560+
});
561+
hfShape.offset = new THREE.Vector3(-planeSize / 2, -planeSize / 2, 0);
562+
this.ground.addEventListener('body-loaded', () => {
563+
this.ground.body.addShape(hfShape, hfShape.offset, hfShape.orientation);
564+
// Show wireframe
565+
if (this.el.sceneEl.systems.physics.debug) {
566+
var bodyComponent = this.ground.components['static-body'];
567+
var createWireframe = bodyComponent.createWireframe.bind(bodyComponent);
568+
createWireframe(this.ground.body, hfShape);
569+
this.el.sceneEl.object3D.add(bodyComponent.wireframe);
570+
}
571+
});
572+
}
573+
522574
this.groundGeometry.computeFaceNormals();
523575
if (this.data.flatShading) {
524576
this.groundGeometry.computeFlatVertexNormals();

0 commit comments

Comments
 (0)