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) :
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.
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.