Mark Sibly пре 8 година
родитељ
комит
0b47caca98

+ 23 - 7
modules/mojo3d-physics/physics/collider.monkey2

@@ -11,6 +11,15 @@ Function CreateInternalEdgeInfo( mesh:btBvhTriangleMeshShape )="bbBullet::create
 Public
 
 Class Collider
+	
+	Property Margin:Float()
+		
+		Return _btshape.getMargin()
+	
+	Setter( margin:Float )
+		
+		_btshape.setMargin( margin )
+	End
 
 	Property btShape:btCollisionShape()
 	
@@ -34,7 +43,11 @@ Protected
 	
 End
 
-Class BoxCollider Extends Collider
+Class ConvexCollider Extends Collider
+	
+End
+
+Class BoxCollider Extends ConvexCollider
 	
 	Method New( box:Boxf )
 	
@@ -45,7 +58,7 @@ Class BoxCollider Extends Collider
 	
 End
 
-Class SphereCollider Extends Collider
+Class SphereCollider Extends ConvexCollider
 	
 	Method New( radius:Float,origin:Vec3f=Null )
 		
@@ -56,7 +69,7 @@ Class SphereCollider Extends Collider
 	
 End
 
-Class CylinderCollider Extends Collider
+Class CylinderCollider Extends ConvexCollider
 	
 	Method New( radius:Float,length:Float,axis:Axis,origin:Vec3f=Null )
 		
@@ -76,7 +89,7 @@ Class CylinderCollider Extends Collider
 
 End
 
-Class CapsuleCollider Extends Collider
+Class CapsuleCollider Extends ConvexCollider
 	
 	Method New( radius:Float,length:Float,axis:Axis,origin:Vec3f=Null )
 		
@@ -96,7 +109,7 @@ Class CapsuleCollider Extends Collider
 	
 End
 
-Class ConeCollider Extends Collider
+Class ConeCollider Extends ConvexCollider
 	
 	Method New( radius:Float,length:Float,axis:Axis,origin:Vec3f=Null )
 		
@@ -116,7 +129,10 @@ Class ConeCollider Extends Collider
 
 End
 
-Class MeshCollider Extends Collider
+Class ConcaveCollider Extends Collider
+End
+
+Class MeshCollider Extends ConcaveCollider
 
 	Method New( mesh:Mesh )
 	
@@ -153,7 +169,7 @@ Class MeshCollider Extends Collider
 	
 End
 
-Class TerrainCollider Extends Collider
+Class TerrainCollider Extends ConcaveCollider
 
 	Method New( box:Boxf,data:Pixmap )
 	

+ 11 - 0
modules/mojo3d-physics/physics/native/objecthandle.h

@@ -0,0 +1,11 @@
+
+#ifndef BB_OBJECT_HANDLE_H
+#define BB_OBJECT_HANDLE_H
+
+#include <bbmonkey.h>
+
+inline void *bb_object_to_handle( bbObject *object ){ return object; }
+
+inline bbObject *bb_handle_to_object( void *handle ){ return static_cast<bbObject*>( handle ); }
+
+#endif

+ 56 - 4
modules/mojo3d-physics/physics/rigidbody.monkey2

@@ -36,12 +36,15 @@ Class RigidBody
 	
 	#rem monkeydoc Creates a new rigid body.
 	#end
-	Method New( mass:Float,collider:Collider,entity:Entity,kinematic:Bool=False )
+	Method New( mass:Float,collider:Collider,entity:Entity,kinematic:Bool=False,collGroup:Int=1,collMask:Int=1 )
 		
 		_mass=mass
 		_collider=collider
 		_entity=entity
 		_kinematic=kinematic
+		_collGroup=collGroup
+		_collMask=collMask
+		
 		_world=World.GetDefault()
 		
 		If _kinematic
@@ -53,7 +56,7 @@ Class RigidBody
 		Local inertia:btVector3=_collider ? _collider.btShape.calculateLocalInertia( _mass ) Else New btVector3( 0,0,0 )
 		
 		_btbody=New btRigidBody( _mass,_btmotion,_collider.btShape,inertia )
-			
+		
 		If _kinematic 
 			_btbody.setCollisionFlags( _btbody.getCollisionFlags() | btCollisionObject.CF_KINEMATIC_OBJECT )
 			_btbody.setActivationState( DISABLE_DEACTIVATION )
@@ -98,6 +101,16 @@ Class RigidBody
 		Return _collider
 	End
 	
+	Property CollisionGroup:Short()
+		
+		Return _collGroup
+	End
+	
+	Property CollisionMask:Short()
+		
+		Return _collMask
+	End
+	
 	Property Entity:Entity()
 	
 		Return _entity
@@ -139,7 +152,42 @@ Class RigidBody
 		_btbody.setRollingFriction( friction )
 	End
 	
-	'***** INTERNAL *****
+	Method ApplyForce( force:Vec3f,relativePos:Vec3f )
+		
+		_btbody.applyForce( force,relativePos )
+	End
+	
+	Method ApplyCentralForce( force:Vec3f )
+		
+		_btbody.applyCentralForce( force )
+	End
+	
+	Method ApplyTorque( torque:Vec3f )
+		
+		_btbody.applyTorque( torque )
+	End
+	
+	Method ApplyImpulse( impulse:Vec3f,relativePos:Vec3f )
+		
+		_btbody.applyImpulse( impulse,relativePos )
+	End
+	
+	Method ApplyTorqueImpulse( torque:Vec3f )
+		
+		_btbody.applyTorqueImpulse( torque )
+	End
+	
+	Method ApplyCentralImpulse( impulse:Vec3f )
+		
+		_btbody.applyCentralImpulse( impulse )
+	End
+	
+	Function Get:RigidBody( btobject:btCollisionObject )
+		
+		Return Cast<RigidBody>( handle_to_object( btobject.getUserPointer() ) )
+	End
+
+	Internal
 	
 	Property btBody:btRigidBody()
 	
@@ -167,13 +215,17 @@ Class RigidBody
 		
 		_seq=_entity.Seq
 	End
-
+	
 Private
 
+	Field _self:RigidBody
+
 	Field _mass:Float	
 	Field _collider:Collider
 	Field _entity:Entity
 	Field _kinematic:Bool
+	Field _collGroup:Int
+	Field _collMask:Int
 	Field _world:World
 	Field _seq:Int
 	

+ 78 - 5
modules/mojo3d-physics/physics/world.monkey2

@@ -1,6 +1,46 @@
 
 Namespace mojo3d.physics
 
+#Import "native/objecthandle.h"
+
+Extern
+
+Function object_to_handle:Void Ptr( obj:Object )="bb_object_to_handle"
+
+Function handle_to_object:Object( handle:Void Ptr )="bb_handle_to_object"
+
+Public
+
+Class RaycastResult
+
+	Field time:Float
+	Field body:RigidBody
+	Field point:Vec3f
+	Field normal:Vec3f
+	
+	Method New()
+	End
+	
+	Method New( btresult:btCollisionWorld.ClosestRayResultCallback )
+		time=btresult.m_closestHitFraction
+		body=Cast<RigidBody>( handle_to_object( btresult.m_collisionObject.getUserPointer() ) )
+		point=btresult.m_hitPointWorld
+		normal=btresult.m_hitNormalWorld
+	End
+	
+	Method New( btresult:btCollisionWorld.ClosestConvexResultCallback )
+		
+		Local castFrom:=Cast<Vec3f>( btresult.m_convexFromWorld )
+		Local castTo:=Cast<Vec3f>( btresult.m_convexToWorld )
+		
+		time=btresult.m_closestHitFraction
+		body=Cast<RigidBody>( handle_to_object( btresult.m_hitCollisionObject.getUserPointer() ) )
+		point=(castTo-castFrom) * btresult.m_closestHitFraction + castFrom
+		normal=btresult.m_hitNormalWorld
+	End
+	
+End
+
 Class World
 	
 	Method New()
@@ -14,7 +54,7 @@ Class World
 		Local solver:=New btSequentialImpulseConstraintSolver()
 		
 		_btworld=New btDiscreteDynamicsWorld( dispatcher,broadphase,solver,config )
-		
+
 		Gravity=New Vec3f( 0,-9.81,0 )
 		
 	End
@@ -44,6 +84,35 @@ Class World
 		
 	End
 	
+	Method RayCast:RaycastResult( rayFrom:Vec3f,rayTo:Vec3f )
+		
+		Local btresult:=New btCollisionWorld.ClosestRayResultCallback( rayFrom,rayTo )
+		
+		_btworld.rayTest( rayFrom,rayTo,Cast<btCollisionWorld.RayResultCallback Ptr>( Varptr btresult ) )
+		
+		If Not btresult.hasHit() Return Null
+		
+		Return New RaycastResult( btresult )
+	End
+	
+	Method ConvexSweep:RaycastResult( collider:ConvexCollider,castFrom:AffineMat4f,castTo:AffineMat4f )
+		
+		Local btresult:=New btCollisionWorld.ClosestConvexResultCallback( castFrom.t,castTo.t )
+		
+		_btworld.convexSweepTest( Cast<btConvexShape>( collider.btShape ),castFrom,castTo,Cast<btCollisionWorld.ConvexResultCallback Ptr>( Varptr btresult ),0 )
+		
+		If Not btresult.hasHit() Return Null
+		
+		Return New RaycastResult( btresult )
+		
+	End
+	
+	Method ConvexSweep:RaycastResult( collider:ConvexCollider,castFrom:Vec3f,castTo:Vec3f )
+		
+		Return ConvexSweep( collider,AffineMat4f.Translation( castFrom ),AffineMat4f.Translation( castTo ) )
+
+	End
+	
 	Function GetDefault:World()
 	
 		Global _default:=New World
@@ -51,13 +120,15 @@ Class World
 		Return _default
 	End
 
-	'***** INTERNAL *****
-		
+	Internal
+	
 	Method Add( body:RigidBody )
 		
 		_bodies.Add( body )
 		
-		_btworld.addRigidBody( body.btBody )
+		_btworld.addRigidBody( body.btBody,body.CollisionGroup,body.CollisionMask )
+		
+		body.btBody.setUserPointer( object_to_handle( body ) )
 	End
 	
 	Method Remove( body:RigidBody )
@@ -65,8 +136,10 @@ Class World
 		_bodies.Remove( body )
 
 		_btworld.removeRigidBody( body.btBody )
+
+		body.btBody.setUserPointer( Null )
 	End
-		
+	
 	Private
 	
 	Field _btworld:btDynamicsWorld

+ 22 - 3
modules/mojo3d-physics/tests/shapes.monkey2

@@ -1,3 +1,4 @@
+
 Namespace myapp
 
 #Import "<std>"
@@ -56,6 +57,8 @@ Class MyWindow Extends Window
 	
 	Field _sphere:Model
 	
+	Field _collider:SphereCollider
+	
 	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
 
 		Super.New( title,width,height,flags )
@@ -97,6 +100,12 @@ Class MyWindow Extends Window
 		Local collider:Collider=New BoxCollider( groundBox )
 		
 		Local body:=New RigidBody( 0,collider,_ground )
+
+		_sphere=Model.CreateSphere( .5,24,12,New PbrMaterial( Color.White ) )
+		
+		_collider=New SphereCollider( .5 )
+		
+'		Return
 		
 		'create some meshes/colliders
 		
@@ -129,7 +138,6 @@ Class MyWindow Extends Window
 				
 				Local model:=New Model( mesh,material )
 				model.Move( x,10,z )
-'				model.RotateZ( Rnd(-.1,.1) )
 				
 				Local body:=New RigidBody( 1,colliders[i],model )
 				
@@ -140,16 +148,27 @@ Class MyWindow Extends Window
 	End
 	
 	Method OnRender( canvas:Canvas ) Override
-	
+		
 		RequestRender()
 		
 		util.Fly( _camera,Self )
 		
+'		Local cresult:=World.GetDefault().ConvexSweep( _collider,_camera.Position,_camera.Position+_camera.Basis.k * 100 )
+
+		Local cresult:=World.GetDefault().ConvexSweep( _collider,_camera.Position+_camera.Basis.k * 2,_camera.Position+_camera.Basis.k * 100 )
+		
+		'Local cresult:=World.GetDefault().RayCast( _camera.Position,_camera.Position+_camera.Basis.k * 100 )
+		
+		If cresult 
+			Print "pos="+cresult.point
+			_sphere.Position=cresult.point'+cresult.normal
+		Endif
+			
 		World.GetDefault().Update()
 		
 		_scene.Render( canvas,_camera )
 		
-		canvas.DrawText( "Width="+Width+", Height="+Height+", FPS="+App.FPS,0,0 )
+		canvas.DrawText( "Camera pos="+_camera.Position+", Width="+Width+", Height="+Height+", FPS="+App.FPS,0,0 )
 	End
 	
 End

+ 10 - 10
modules/mojo3d-physics/tests/util.monkey2

@@ -4,23 +4,23 @@ Namespace util
 Function Fly( entity:Entity,view:View )
 
 	If Keyboard.KeyDown( Key.Up )
-		entity.RotateX( .1 )
+		entity.RotateX( .05 )
 	Else If Keyboard.KeyDown( Key.Down )
-		entity.RotateX( -.1 )
-	Endif
-	
-	If Keyboard.KeyDown( Key.Q )
-		entity.RotateZ( .1 )
-	Else If Keyboard.KeyDown( Key.W )
-		entity.RotateZ( -.1 )
+		entity.RotateX( -.05 )
 	Endif
 	
 	If Keyboard.KeyDown( Key.Left )
-		entity.RotateY( .1,True )
+		entity.RotateY( .025,True )
 	Else If Keyboard.KeyDown( Key.Right )
-		entity.RotateY( -.1,True )
+		entity.RotateY( -.025,True )
 	Endif
 
+	If Keyboard.KeyDown( Key.Q )
+		entity.RotateZ( .01 )
+	Else If Keyboard.KeyDown( Key.W )
+		entity.RotateZ( -.01 )
+	Endif
+	
 	If Mouse.ButtonDown( MouseButton.Left )
 		If Mouse.X<view.Width/3
 			entity.RotateY( .1,True )