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