Irrlicht and Newton

BlitzMax Forums/BlitzMax Programming/Irrlicht and Newton

Oh, for genral interest, here's my first Newton test using primitives. All the textures may be found in the Irrlicht Examples media directory except for the skybox which is from Lugaru.

Ever played Lugaru? It's by a guy called David, and it is WICKED for a freelance game. It has the most innovative fighting system I've ever controlled in gameplay. Lugaru 1 is pretty minimal otherwise, but he is working on Lugaru 2, and is definitely on to something big. http://www.wolfire.com And for the record, he didn't pay me to say that. I just think it's cool.

'my newton physics test

Framework BRL.Blitz          'core module
Import BRL.Random            'random number generator.
Import BRL.LinkedList        'linked list handler
Import Pub.NewtonAndIrrlicht 'Imports Newton, Irrlicht, and some
                             'nice interface functions


Print "HELLO WORLD!!!"

ms=MilliSecs()
SeedRnd ms 'randomize seed based on the system timer -- the best way to get
           'the most random results.
Print "Seeded random number generator with system clock. ("+ms+")"

'irrlicht pointers
Global dvc:IrrlichtDevice
Global dvr:IVideoDriver
Global sne:ISceneManager

'newton pointers and matricies
Global box:Byte Ptr[30]
Global ball:Byte Ptr[30]
Global collision:Byte Ptr

'create irrlicht context
DebugCreateIrrlicht False,False,fullScn,rAccel,dvc,dvr,sne
Print "Successfully created Irrlicht Device context."

dvc.SetResizeable True

Global font:IGUIFont=dvc.getGUIEnvironment().getFont("fontcourier.bmp")
Print "Successfully generated font."

dvr.beginScene True,True
	font.draw "LOADING...",_RECTI(3,3,300,50),_SCOLOR(255,255,255,255)
dvr.endScene()

'create skybox
If rAccel Then
	sne.addSkyBoxSceneNode( ..
	 dvr.getTexture("up.jpg"), ..
	  dvr.getTexture("down.jpg"), ..
	   dvr.getTexture("left.jpg"), ..
	    dvr.getTexture("right.jpg"), ..
	     dvr.getTexture("back.jpg"), ..
	      dvr.getTexture("front.jpg"))
End If
Print "Successfully added skybox."

'create scene camera (viewpoint)
Global cam:ICameraSceneNode=sne.addCameraSceneNodeMaya(Null,32,16,16)
cam.setPosition(_VECTOR3DF(0,-.4,-10))
Print "Successfully added camera."

'add a light source
sne.addLightSceneNode(Null,_VECTOR3DF(0,50,0))
Print "Successfully added light source."

'attach the newton api lib
If Not StartNewton() Then
	Print "Could not attach dynamics engine API."
	Notify "Could not attach dynamics engine API.",True
	End
End If
Print "Successfully attached dynamics engine API!"

'create a newton world using custom memory handlers by pointing
'to the functions; null argument selects standard memory handlers
Global world:Byte Ptr=NewtonCreate(MemAllocate,MemRelease)
NewtonSetMinimumFrameRate world,256

'set the world size to a cube that is [36,36,36]
Local wmn#[]=[-18#,-18#,-18#]
Local wmx#[]=[18#,18#,18#]
NewtonSetWorldSize world,Varptr wmn[0],Varptr wmx[0]

'Set the solver and friction models to perfect.  All calculations are resolved as
'many times as is neccessary to eliminate all drift errors before iterating.  Slower
'but much more accurate.
NewtonSetSolverModel world,0
NewtonSetFrictionModel world,0

'set an event callback for bodies leaving the world
NewtonSetBodyLeaveWorldEvent world,BodyLeftWorld

Print "Successfully generated dynamics world!"

'create a floor with a bump in the middle
Local afloor:ISceneNode=sne.addCubeSceneNode(6)
afloor.setMaterialFlag EMF_LIGHTING,True
If rAccel Then
	afloor.setMaterialTexture 0,dvr.getTexture("terraintex.jpg")
	afloor.setMaterialTexture 1,dvr.getTexture("terrain.jpg")
End If
afloor.setPosition _VECTOR3DF(0,-6,0)
collision=NewtonCreateBox(world,6#,6#,6#,Null)
Local floorbody:Byte Ptr=newtonCreateBody(world,collision)
NewtonReleaseCollision world,collision

Local rfloor:ISceneNode=sne.addSphereSceneNode(2)
rfloor.setMaterialFlag EMF_LIGHTING,True
If rAccel Then
	rfloor.setMaterialTexture 0,dvr.getTexture("terraintex.jpg")
	rfloor.setMaterialTexture 1,dvr.getTexture("terrain.jpg")
End If
rfloor.setPosition _VECTOR3DF(0,-3.5,0)
collision=NewtonCreateSphere(world,2#,2#,2#,Null)
Local rfloorbody:Byte Ptr=newtonCreateBody(world,collision)
NewtonReleaseCollision world,collision

'initialize floor
GetEulerMatrix afloor,Mat
NewtonBodySetMatrix floorbody,Varptr Mat[0]
NewtonBodySetUserData floorbody,Byte Ptr(afloor.handle)
NewtonBodySetDestructorCallback floorbody,BodyDestructor

GetEulerMatrix rfloor,Mat
NewtonBodySetMatrix rfloorbody,Varptr Mat[0]
NewtonBodySetUserData rfloorbody,Byte Ptr(rfloor.handle)
NewtonBodySetDestructorCallback rfloorbody,BodyDestructor
Print "Successfully added floor body."

'add some cubes
WriteStdout "Adding cube nodes..."
Global boxnode:ISceneNode[30]
For j=0 To 29
	boxnode[j]=sne.addCubeSceneNode(.8#)
	boxnode[j].setPosition(_VECTOR3DF(Rnd(-3#,3#),Rnd(9#),Rnd(-3#,3#)))
	boxnode[j].setMaterialFlag EMF_LIGHTING,True
	If rAccel Then
		boxnode[j].setMaterialTexture(0,dvr.getTexture("wall.jpg"))
		boxnode[j].setMaterialTexture(1,dvr.getTexture("wallheight.bmp"))
	End If
	GCCollect
Next
Print "done!"

collision=NewtonCreateBox(world,.8#,.8#,.8#,Null)
Print "Successfully generated cube collision object."

'put the cubes in the dynamics world
WriteStdout "Generating cube collision bodies..."
For j=0 To 29
	GetEulerMatrix boxnode[j],mat
	box[j]=NewtonCreateBody(world,collision)
	NewtonBodySetMassMatrix box[j],1#,1#,1#,1#
	NewtonBodySetMatrix box[j],Varptr mat[0]
	omega[0]=Rnd(-20#,20#)
	omega[1]=Rnd(-20#,20#)
	omega[2]=Rnd(-20#,20#)
	NewtonBodySetOmega box[j],Varptr omega[0]
	NewtonBodySetAutoFreeze box[j],1
	NewtonBodySetUserData box[j],Byte Ptr(boxnode[j].handle)
	NewtonBodySetDestructorCallback box[j],BodyDestructor
	NewtonBodySetTransformCallback box[j],NSetTransform
	NewtonBodySetForceAndTorqueCallback box[j],ApplyForceAndTorque
	GCCollect
Next
Print "done!"

NewtonReleaseCollision world,collision
Print "Successfully released cube collision object."

'add some balls
WriteStdout "Adding sphere nodes..."
Global ballnode:ISceneNode[30]
For j=0 To 29
	ballnode[j]=sne.addSphereSceneNode(.4#)
	ballnode[j].setPosition(_VECTOR3DF(Rnd(-3#,3#),Rnd(9#),Rnd(-3#,3#)))
	ballnode[j].setMaterialFlag EMF_LIGHTING,True
	If rAccel Then
		ballnode[j].setMaterialTexture(0,dvr.getTexture("wall.jpg"))
		ballnode[j].setMaterialTexture(1,dvr.getTexture("wallheight.bmp"))
	End If
	GCCollect
Next
Print "done!"

collision=NewtonCreateSphere(world,.4#,.4#,.4#,Null)
Print "Successfully generated sphere collision object."

'put the balls in the dynamics world
WriteStdout "Generating sphere collision bodies..."
For j=0 To 29
	GetEulerMatrix ballnode[j],mat
	ball[j]=NewtonCreateBody(world,collision)
	NewtonBodySetMassMatrix ball[j],1#,1#,1#,1#
	NewtonBodySetMatrix ball[j],Varptr mat[0]
	omega[0]=Rnd(-5#,5#)
	omega[1]=Rnd(-5#,5#)
	omega[2]=Rnd(-5#,5#)
	NewtonBodySetOmega ball[j],Varptr omega[0]
	NewtonBodySetAutoFreeze ball[j],1
	NewtonBodySetUserData ball[j],Byte Ptr(ballnode[j].handle)
	NewtonBodySetDestructorCallback ball[j],BodyDestructor
	NewtonBodySetTransformCallback ball[j],NSetTransform
	NewtonBodySetForceAndTorqueCallback ball[j],ApplyForceAndTorque
	GCCollect
Next
Print "done!"

NewtonReleaseCollision world,collision
Print "Successfully released sphere collision object."


'okay, here we go
WriteStdout "Begin simulation..."
fps=0
str$=""
timestep!=0
Local intMat[16]

Repeat
	'update world euler matrix
	timestep=NewtonGetTimeStep(world)*(fps/60)
	If timestep>1 Then timestep=1
	NewtonUpdate world,timestep
	
	NodeDestructor 'destroy the deleted/released nodes
	
	dvr.beginScene(True,True)
		sne.drawAll() 'draw scene
		
		'draw general data
		fps=dvr.getFPS()
		str="renderer ~q"
		 str:+dvr.getName()+"~q   physics ~qNewton Dynamics v"
		  str:+NewtonWorldGetVersion(world)+"~q   "
		   str:+"FPS = "+fps+"   TimeStep = "+Float(timestep)
		font.draw str,_RECTI(5,5,300,50),_SCOLOR(255,0,0,0)
		str="renderer ~q"
		 str:+dvr.getName()+"~q   physics ~qNewton Dynamics v"
		  str:+NewtonWorldGetVersion(world)+"~q   "
		   str:+"FPS = "+fps+"   TimeStep = "+Float(timestep)
		font.draw str,_RECTI(3,3,300,50),_SCOLOR(255,255,255,64)
		
		'draw debug data
		curralloced=GCMemAlloced()
		font.draw "CoreMem="+(curralloced/1024)+"KB   "+..
		 "SimMem="+(nMemSize/1024)+..
		  "KB   TotalMem="+((curralloced+nMemSize)/1024)+..
		   "KB   Note: Irrlicht uses a seperate memory system.",..
		    _RECTI(5,21,300,50),_SCOLOR(255,0,0,0)
		font.draw "CoreMem="+(curralloced/1024)+"KB   "+..
		 "SimMem="+(nMemSize/1024)+..
		  "KB   TotalMem="+((curralloced+nMemSize)/1024)+..
		   "KB   Note: Irrlicht uses a seperate memory system.",..
		    _RECTI(3,19,300,50),_SCOLOR(255,255,255,64)
	dvr.endScene()
	
	GCCollect
Until Not dvc.run()
Print "ended properly."

'now we clean up
NewtonDestroyAllBodies world 'destroy all bodies in dynamics world
Print "Successfully destroyed all physical bodies."
NewtonDestroy world 'destroy dynamics world
Print "Successfully destroyed dynamics world."
NodeDestructor
Print "Successfully destroyed scene nodes."
ReleaseIrrlicht dvc 'release irrlicht context
Print "Successfully released Irrlicht Device context."
StopNewton 'drop newton api
Print "Successfully dropped dynamics engine API."

End