Skip to content

Commit 2890e06

Browse files
committed
create a CANNON.Heightfield shape to use with static-body if physics is available
1 parent 33e7980 commit 2890e06

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
@@ -173,6 +173,15 @@ AFRAME.registerComponent('environment', {
173173
this.dressing = document.createElement('a-entity');
174174
this.dressing.classList.add('environmentDressing');
175175

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

@@ -463,14 +472,26 @@ AFRAME.registerComponent('environment', {
463472
return;
464473
}
465474

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

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

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

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

0 commit comments

Comments
 (0)