Browse Source

Added WIP TerrainCollider.

Mark Sibly 8 years ago
parent
commit
ec47f60acb

+ 1 - 1
modules/bullet/bullet.monkey2

@@ -371,7 +371,7 @@ Class btHeightfieldTerrainShape Extends btConcaveShape
 
 	Method setUseDiamondSubdivision( useDiamondSubdivision:Bool=True )	
 
-	Method setUseZigZagSubdivision( useZigZagSubdivision:Bool=True )	
+	Method setUseZigzagSubdivision( useZigZagSubdivision:Bool=True )	
 End
 
 Class btTriangleMeshShape Extends btConcaveShape

+ 89 - 8
modules/mojo3d/scene/components/collider.monkey2

@@ -700,21 +700,102 @@ Class MeshCollider Extends ConcaveCollider
 	
 End
 
-#rem
 Class TerrainCollider Extends ConcaveCollider
 
-	Method New( box:Boxf,data:Pixmap )
+	Method New( entity:Entity )
+		
+		Super.New( entity )
+		
+		Bounds=New Boxf( -1,1 )
+		
+		AddInstance()
+	End
 	
-		Local shape:=New btHeightfieldTerrainShape( data.Width,data.Height,data.Data,1.0/255.0,0.0,1.0,1,PHY_UCHAR,False )
+	Method New( entity:Entity,collider:TerrainCollider )
 		
-		shape.setUseDiamondSubdivision( True )
+		Super.New( entity,collider )
+		
+		Heightmap=collider.Heightmap
+		Bounds=collider.Bounds
+		UseDiamondSubdivision=collider.UseDiamondSubdivision
+		UseZigzagSubdivision=collider.UseZigzagSubdivision
+		
+		AddInstance( collider )
+	End
+	
+	Property Heightmap:Pixmap()
 		
-		_btshape=shape
+		Return _heightmap
 		
-		_btshape.setLocalScaling( New Vec3f( box.Width/data.Width,box.Height,box.Depth/data.Height ) )
+	Setter( heightmap:Pixmap )
 		
-		SetOrigin( box.Center )
+		If heightmap=_heightmap Return
+		
+		Assert( heightmap.Format=PixelFormat.I8,"Heightmap must be in I8 format" )
+		
+		_heightmap=heightmap
+		
+		Invalidate()
+		
+		_shape=Null
+	End
+	
+	Property Bounds:Boxf()
+		
+		Return _bounds
+	
+	Setter( bounds:Boxf )
+		
+		_bounds=bounds
+		
+		Invalidate()
 	End
+	
+	Property UseDiamondSubdivision:Bool()
+		
+		Return _diamondSubdiv
+		
+	Setter( diamondSubdiv:Bool )
+			
+		_diamondSubdiv=diamondSubdiv
+		
+		If _shape _shape.setUseDiamondSubdivision( _diamondSubdiv )
+	End
+	
+	Property UseZigzagSubdivision:Bool()
+		
+		Return _zigzagSubdiv
+	
+	Setter( zigzagSubdiv:Bool )
+		
+		_zigzagSubdiv=zigzagSubdiv
+
+		If _shape _shape.setUseZigzagSubdivision( _zigzagSubdiv )
+	End
+	
+	Protected
+	
+	Method OnCreate:btCollisionShape() Override
+		
+		If Not _shape
+			_shape=New btHeightfieldTerrainShape( _heightmap.Width,_heightmap.Height,_heightmap.Data,1.0/255.0,0.0,1.0,1,PHY_UCHAR,False )
+			_shape.setUseDiamondSubdivision( _diamondSubdiv )
+			_shape.setUseZigzagSubdivision( _zigzagSubdiv )
+		Endif
+		
+		_shape.setLocalScaling( New Vec3f( _bounds.Width/_heightmap.Width,_bounds.Height,_bounds.Depth/_heightmap.Height ) )
+		
+		Return SetOrigin( _shape,_bounds.Center )
+	End
+	
+	Private
+	
+	Field _heightmap:Pixmap
+	Field _bounds:Boxf
+	
+	Field _diamondSubdiv:Bool
+	Field _zigzagSubdiv:Bool
+	
+	Field _shape:btHeightfieldTerrainShape
 
 End
-#end

+ 25 - 3
modules/mojo3d/tests/terrainmesh.monkey2

@@ -42,7 +42,7 @@ Class MyWindow Extends Window
 		_camera=New Camera
 		_camera.Near=.1
 		_camera.Far=100
-		_camera.Move( 0,15,-20 )
+		_camera.Move( 0,16,0 )
 		New FlyBehaviour( _camera )
 		
 		'create light
@@ -56,7 +56,7 @@ Class MyWindow Extends Window
 		Local terrainBox:=New Boxf( -256,0,-256,256,32,256 )
 		
 		'heightmap
-		Local terrainHMap:=Pixmap.Load( "asset::terrain_256.png" )
+		Local terrainHMap:=Pixmap.Load( "asset::terrain_256.png",PixelFormat.I8 )
 
 		'material		
 		Local terrainMaterial:=PbrMaterial.Load( "asset::mossy-ground1.pbr" )
@@ -64,9 +64,31 @@ Class MyWindow Extends Window
 		
 		'model+mesh
 		_terrain=Model.CreateTerrain( terrainHMap,terrainBox,terrainMaterial )
-
 		_terrain.CastsShadow=False
 		
+		Local collider:=New TerrainCollider( _terrain )
+		collider.Heightmap=terrainHMap'.Convert( PixelFormat.I8 )
+		collider.Bounds=terrainBox
+		Local body:=New RigidBody( _terrain )
+		body.Mass=0
+		
+		Local material:=New PbrMaterial( Color.Sky,1,.5 )
+		
+		For Local i:=0 Until 360 Step 3
+			
+			Local box:=New Boxf( -.5,.5 )
+		
+			Local model:=Model.CreateBox( box,1,1,1,material )
+			Local collider:=New BoxCollider( model )
+			Local body:=New RigidBody( model )
+
+			collider.Box=box
+			
+			model.Rotate( 0,i,0 )
+			model.Move( 0,32,Rnd( 5,10 ) )
+			
+		Next			
+		
 	End
 	
 	Method OnRender( canvas:Canvas ) Override