@@ -172,6 +172,15 @@ AFRAME.registerComponent('environment', {
172
172
173
173
this . dressing = document . createElement ( 'a-entity' ) ;
174
174
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
+
175
184
this . gridCanvas = null ;
176
185
this . gridTexture = null ;
177
186
@@ -462,14 +471,26 @@ AFRAME.registerComponent('environment', {
462
471
return ;
463
472
}
464
473
474
+ var segments = resolution - 1 ;
475
+ var planeSize = this . STAGE_SIZE + 2 ;
476
+ var planeSizeHalf = planeSize / 2 ;
477
+ var segmentSize = planeSize / segments ;
465
478
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 ) ;
467
480
}
468
481
var perlin = new PerlinNoise ( ) ;
469
482
var verts = this . groundGeometry . vertices ;
470
483
var numVerts = this . groundGeometry . vertices . length ;
471
484
var frequency = 10 ;
472
485
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
+ }
473
494
474
495
for ( var i = 0 , x = 0 , y = 0 ; i < numVerts ; i ++ ) {
475
496
if ( this . data . ground == 'flat' ) {
@@ -511,6 +532,16 @@ AFRAME.registerComponent('environment', {
511
532
// set height
512
533
verts [ i ] . z = h ;
513
534
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
+
514
545
// calculate next x,y ground coordinates
515
546
x += inc ;
516
547
if ( x >= 10 ) {
@@ -519,6 +550,27 @@ AFRAME.registerComponent('environment', {
519
550
}
520
551
}
521
552
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
+
522
574
this . groundGeometry . computeFaceNormals ( ) ;
523
575
if ( this . data . flatShading ) {
524
576
this . groundGeometry . computeFlatVertexNormals ( ) ;
0 commit comments