Newton question and timeline update

BlitzMax Modules Forums/MiniB3D/Newton question and timeline update

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Well, because of the release of version 0.41 I have decided not to release my new version yet. This is because there are alot of bufixes in 0.41 which should all be build in my extended Version.

But to give you something I will give you a short statusreport about the newton implemntation:
I have get it to work on Win32,Linux and MacOS so it is directly passing the no. 1 rule of minib3d ;).
Also I'm very proud to the materialsystem I have build around the Newton Lib. As for a PhysicsEngine noob like me I think it is very easy to understand.

here is small codesample how to setup a materials (currently everthing is OOP) :
Framework sidesign.minib3d
Import BRL.FreeAudioAudio
Import BRL.WAVLoader
Import BRL.Random
Import BRL.StandardIO
Import BRL.System

Strict


Local width=800,height=600,depth=32,mode=2
Global EmitterList:TList = New TList

Graphics3D width,height,depth,mode


Global Boing:TSound = LoadSound("boing.wav")
Global spark:Tsprite = LoadSprite("bluspark.bmp")
HideEntity spark


Global cam:TCamera=CreateCamera()
PositionEntity cam,0,30,0

Local light:TLight=CreateLight(,cam)
RotateEntity light,45,0,0


' used by camera code
Local mxs#=0
Local mys#=0
Local move#=0.5
MouseXSpeed() ' flush
MouseYSpeed() ' flush

' used by fps code
Local old_ms=MilliSecs()
Local renders
Local fps

Local Physic:TPhysic = InitPhysic() 'Will disapear to the inernals

Physic.SetPhysicModel(0,0)

Local Wood:TPhysicMaterial = TPhysicMaterial.Create("Wood")
wood.SetFriction(0.6,0.5)
wood.SetSoftness(1.0)
wood.SetElasticity(0.4)

Local Metal:TPhysicMaterial = TPhysicMaterial.Create("Metal")
Metal.SetFriction(0.5,0.4)
Metal.SetSoftness(1.0)
Metal.SetElasticity(.1)

Physic.AddMaterial(Metal)
Physic.AddMaterial(Wood)

Physic.BuildMaterialLibraries()

Physic.SetCollisionMode(Metal,Wood,PHYS_CONTINUES_COLLISION)

TPhysic.ContactEnd = ContactEndhandle
TPhysic.ContactProcess = ContactProcessHandle



SeedRnd(MilliSecs())


Global plane:TMesh=LoadMesh("media/test.b3d")
ScaleMesh plane,10,10,10

PositionEntity(Plane,0,0,0)
EntityPickMode Plane,2
Plane.UpdateBuffer()




CreateOctree(plane,20,5)

' set camera entity type to 1
EntityType cam,1
EntityRadius cam,4

EntityType plane,2

Collisions 1,2,4,2



Local NPlane:TNewtonObject = TNewtonObject.Create(Plane,PHYS_MESHCOMPLEX_HULL)
NPlane.SetMass(0.0) ' Set it solid
Physic.AddObject(NPlane) 'Give it to the Physic engine
Physic.SetBodyMaterial(NPlane,"Metal")

SetWorldSize(Physic,NPlane.AABB[0],NPlane.AABB[1])




For Local X:Int = 0 To 15
	For Local Y:Int = 0 To 5
		Local cube:TMesh=CreateCube()
		'ScaleEntity(cube,5,5,5)
		EntityRadius cube,2
		EntityPickMode cube,2
		PositionEntity cube,Rand(NPlane.AABB[0].X/2,NPlane.AABB[1].X/2),Rand(NPlane.AABB[0].Y,NPlane.AABB[1].Y),Rand(NPlane.AABB[0].Z,NPlane.AABB[1].Z)
		EntityColor(cube,Rand(255),Rand(255),Rand(255))
		
		Local NCube:TNewtonObject = TNewtonObject.Create(cube,PHYS_BOX_HULL) 'Create the Collision Hull (Parameters are set automatically)
		NCube.SetMass(Rnd(1.0,100.0)) ' Make it movable and a accurate ball
		Physic.AddObject(NCube) 'Give it to the Physic engine
		Physic.ApplyImpulse(cube,0.0,0.0,0.0,0.0,0.0,0.0)
		Physic.SetBodyMaterial(NCube,"Metal")

	Next
Next	
	
Local Timestep:Int = MilliSecs()

Local EValue:Float = 0.5
Local FValue:Float = 0.5
Local SValue:Float = 0.5

Local Mass:Float = 1.0


Global blurpass:Int = 5.0
Global multiply:Float = .02


Global  pick:TEntity



While Not KeyDown(KEY_ESCAPE)	
		
	
	Pick = Null
	
	Local Pitch:Float = EntityPitch(Cam)
	Local Yaw:Float = EntityYaw(Cam)
	Local Roll:Float = EntityRoll(Cam)
	
	Local TempX:Float = EntityX(Cam)
	Local TempY:Float = EntityY(Cam)
	Local TempZ:Float = EntityZ(Cam)

	' control camera
	
	' mouse look
	
	mxs#=mxs#+(MouseXSpeed()/5.0)
	mys#=mys#+(MouseYSpeed()/5.0)

	RotateEntity cam,mys#,-mxs#,0

	If KeyDown(KEY_SPACE)=False
		MoveMouse width/2,height/2
		MouseXSpeed() ' flush
		MouseYSpeed() ' flush
	EndIf

	' move camera forwards/backwards/left/right with cursor keys
	
	If KeyDown(KEY_UP)=True Then MoveEntity cam,0,0,move# ' move camera forward
	If KeyDown(KEY_DOWN)=True Then MoveEntity cam,0,0,-move# ' move camera back

	If KeyDown(KEY_LEFT)=True Then MoveEntity cam,-move#,0,0 ' move camera left
	If KeyDown(KEY_RIGHT)=True Then MoveEntity cam,move#,0,0 ' move camera right
	
	

	' if mousehit then perform camerapick
	If MouseHit(2)
			
		
		pick=CameraPick(cam,MouseX(),MouseY())
		
		If pick<>Null
			Local XP:Float = Rnd(-25.0,25.0)
			Local YP:Float = Rnd(-25.0,25.0)
			Local ZP:Float = Rnd(-25.0,25.0)
			' Apply a random impulse to the picked ball
			Physic.ApplyImpulse(pick,PickedX(),PickedY(),PickedZ(),XP,YP,ZP)
		EndIf
				
	
	EndIf
	
	If MouseHit(1)
	
			CameraPick(Cam,MouseX(),MouseY())
			
						
			Local Bullet:TMesh = CreateSphere(8)
			ScaleMesh(Bullet,3,3,3)
			PositionEntity(Bullet,EntityX(Cam),EntityY(Cam),EntityZ(Cam))
			EntityColor bullet,255-Mass,0,0
			bullet.setrenderpass(1)
			
			Local NBullet:TNewtonObject = TNewtonObject.Create(Bullet,PHYS_SPHERE_HULL)
			NBullet.SetMass(MAss) ' Set it solid
			NBullet.SetCollisionMode(PHYS_CONTINUES_COLLISION)
			Physic.AddObject(NBullet) 'Give it to the Physic engine
			Physic.SetBodyMaterial(NBullet,"Wood")



			Local V1:TVector = TVector.Create(PickedX(),PickedY(),PickedZ())
			Local V2:TVector = TVector.Create(EntityX(Cam),EntityY(Cam),EntityZ(Cam))
			
			Local V3:TVector = V1.Subtract(V2).Multiply(2)
			
			
			Physic.ApplyImpulse(Bullet,EntityX(Bullet),EntityY(Bullet),EntityZ(Bullet),V3.X,V3.Y,V3.Z)
					
	
	EndIf
	
	If KeyDown(KEY_ENTER)
		Local cube:TMesh=CreateCube()
		EntityRadius cube,2
		EntityPickMode cube,2
		PositionEntity cube,Rand(NPlane.AABB[0].X/2,NPlane.AABB[1].X/2),Rand(NPlane.AABB[0].Y,NPlane.AABB[1].Y),Rand(NPlane.AABB[0].Z,NPlane.AABB[1].Z)
		EntityColor(cube,Rand(255),Rand(255),Rand(255))
		Local NCube:TNewtonObject = TNewtonObject.Create(cube,PHYS_BOX_HULL) 'Create the Collision Hull (Parameters are set automatically)
		NCube.SetMass(Rnd(1.0,100.0)) ' Make it movable and a accurate ball
		Physic.AddObject(NCube) 'Give it to the Physic engine
		Physic.ApplyImpulse(cube,0.0,0.0,0.0,0.0,0.0,0.0)
	EndIf	
	
	

	
	If KeyDown(KEY_F1) Then
		EValue:+0.001
		Physic.SetDefaultElasticity(Evalue)
	EndIf
	
	If KeyDown(KEY_F2) Then
		EValue:-0.001
		Physic.SetDefaultElasticity(Evalue)
	EndIf
	
	If KeyDown(KEY_F3) Then
		FValue:+0.001
		Physic.SetDefaultFriction(Fvalue,Fvalue-0.10)
	EndIf
	
	If KeyDown(KEY_F4) Then
		FValue:-0.001
		Physic.SetDefaultFriction(Fvalue,Fvalue-0.10)
	EndIf
	
	If KeyDown(KEY_F5) Then
		SValue:+0.001
		Physic.SetDefaultSoftiness(Svalue)
	EndIf
	
	If KeyDown(KEY_F6) Then
		SValue:-0.001
		Physic.SetDefaultSoftiness(Svalue)
	EndIf
	
	
	If KeyDown(KEY_F7) Then
		Mass:+0.1
		'Physic.SetDefaultSoftiness(Svalue)
	EndIf
	
	If KeyDown(KEY_F8) Then
		Mass:-0.1
		'Physic.SetDefaultSoftiness(Svalue)
	EndIf
	
	For Local E:TEmitter = EachIn EmitterList
		E.Update()
		If MilliSecs()-E.StartTime>E.LifeTime Then
			If ListIsEmpty(E.Particles) = True Then
				ListRemove(Emitterlist,E)
			EndIf
		EndIf
	Next
	

	Physic.Update()
	

	UpdateWorld()
	
	
	RenderWorld()

	renders=renders+1
	
	 ' Update the physics (Update time is automatically calculated and passed as Deltatime within the engine)


	If MilliSecs()-old_ms>=1000
		
		old_ms=MilliSecs()
		fps=renders
		renders=0
	EndIf
	
	SetBlend AlphaBlend
	DrawText "FPS: "+String(fps),0,0
	Text 0,20,"Elasticity : " + EValue
	Text 0,40,"Friction   : " + FValue + " - " + (FValue - 0.10)
	Text 0,60,"Softiness  : " + SValue

	Text 0,80,"TimeStep : " + Physic.GetPhysicTime()
	Text 0,100,"Active Bodies: " + Physic.GetActiveBodyCount()
	Text 0,120,"InActive Bodies: " + Physic.GetUnActiveBodyCount()

	Text 0,140,"Bullet MAss: " + Mass
	
	Text 0,160,"Position : " + EntityX(Cam) + "/" + EntityY(Cam) + "/" + EntityZ(Cam)
	
	Text 0,180,"Emitters : " + Emitterlist.Count()
	
		
	If KeyDown(KEY_Space)
		Flip 0
	Else
		Flip
	EndIf

Wend
End


Function ContactProcesshandle(Info:TContactInfo)
	Local mat1:String = Info.body1.material.name
	Local mat2:String = Info.body2.material.name
	
	
	If (mat1 = "Wood" And mat2 = "Metal") Or (mat2 = "Wood" And mat1 = "Metal")
		If Abs(Info.Body2.GetVelocity().Length()/25.0) > 0.9
						
			Local C:TChannel = AllocChannel()
			SetChannelVolume(C,.6 - Clamp(VectorDistance(Cam,Info.ContactPosition)/300.0,0,.6) )
			PlaySound(boing,c)
			Local E:TEmitter = New TEmitter
			E.Position = Info.ContactPosition
			EmitterList.Addlast(E)
		EndIf
		
		EndIf
End Function


Function ContactEndhandle(Info:TContactInfo)
End Function

Function Clamp:Float(value:Float,_Min:Float,_Max:Float)
	Local Back:Float = Min(value,_Max)
	Return Max(Back,_Min)
End Function



Type TEmitter
	Field Position:TVector
	Field LifeTime:Int = 40
	Field Partperloop:Int = 25
	Field StartTime:Int = MilliSecs()
	Field Particles:TList = New TList
	
		
	Method Update()
		If MilliSecs()-StartTime<LifeTime Then
			For Local I:Int = 0 To PartPerLoop
				Local P:TParticle = New TParticle
				P.Sprite = TSprite(CopyEntity(Spark))'CreateSprite()
				ScaleSprite P.Sprite,0.2,0.2
				'EntityTexture P.Sprite,Texture
			'	EntityBlend(P.sprite,1)
				'EntityFX(P.Sprite,32)
				EntityColor(P.Sprite,200,20,40)
				PositionEntity P.Sprite,Position.X,Position.Y,Position.Z
				P.Position = Position
				P.Velocity = New TVector
				P.Velocity.X = Rnd(-.1,.1)
				P.Velocity.Y = Rnd(-.1,.1)
				P.Velocity.Z = Rnd(-.1,.1)
				ShowEntity P.Sprite
				Particles.Addlast(P)
			Next
		EndIf
			For Local PT:TParticle = EachIn Particles
				PT.Update()
				If MilliSecs()-PT.Starttime > PT.Life Then
					FreeEntity PT.Sprite
					ListRemove(Particles,PT)
				EndIf
			Next
	End Method
End Type



Type TParticle
	Field Sprite:TSprite = New TSprite
	Field Position:TVector
	Field Velocity:TVector
	Field Life:Int = 300
	Field Starttime:Int = MilliSecs()
	
	Method Update()
		EntityAlpha Sprite,1.0-(1.0/Life)*(MilliSecs()-Starttime)
		MoveEntity Sprite,Velocity.x,Velocity.y,Velocity.z
	End Method
	
		
End Type


Maybe you see the ContactProcessCallback here, This a Funcion Pointer which is called from the Physicimplemtation everytime Newton Processes a contact. The Contactinfo(bodies,materials,ContactPoint etc) is gathered directly internally and you could use it in this callback to emit sounds or particles or change the material reaction.