Posted: 22nd May 2007 20:21
Hi!
I have a newton world:
(Directly from Newton FPS Demo)
+ Code Snippet
`--------------------------------------------------
`	NEWTON PHYSICS SDK WRAPPER 
`	DEMO PROJECT 5 - first person shooter example
`
`--------------------------------------------------

`standard DBPro startup code...
sync on
sync rate 60
autocam off

set ambient light 0
set point light 0, 50, 100, 20
set light range 0, 5000

randomize timer()

`load images
load image "./floor.png",1
load image "./bullethole.png", 2

levelstr$ = "land1.x"

`set camera start point
position camera 0.0, 50.0, -20.0


`this is just an array so I can write onscreen if the simulation is running or not.
`it has nothing to do with Newton at all.
dim GOSTR$(2)
GOSTR$(1) = "SIMULATION PAUSED"
GOSTR$(2) = "SIMULATION RUNNING"


`variables used for the first-person camera
global Player = 0

global Player_Mass# = 12.0
global Player_Speed# = 10.0
global Player_Yangle# = 0.0
global Player_Xangle# = 0.0
global Player_ShootPower# = 5000.0
global Player_JumpSpeed# = 35.0

global Door = 0
global DoorSlider = 0


`I am using GOTO in these demos to keep them simple, in a real game situation you
`would probably want to avoid this programming style.
`------------------------------------------------
`------------------------------------------------
TOP:


`Initialize Newton, and create the Newton World.
NDB_NewtonCreate

`Set the temp vector to our gravity constant (acceleration due to gravity)
`then set as our standard gravity force.
NDB_SetVector 0.0, -50.0, 0.0
NDB_SetStandardGravity

`-----------------------------------------
`Set the gun as newton object.
obj = FreeObject()
load object "gun.x", obj
scale object obj, 25, 25, 25

Col = NDB_NewtonCreateTreeCollision(obj)

`Step 3- make the rigid body from the collision data
Room = NDB_NewtonCreateBody(col)

`Step 4- finally, attach the object to the Rigid Body
NDB_BodySetDBProData Room, obj
NDB_NewtonBodySetDestructorCallback Room
NDB_NewtonReleaseCollision col

`Set obj as WeaponObjID for weapon postitioning.
WeaponObjId = obj
`-----------------------------------------

`make the test room!
gosub MakeRoom

`make the player (camera) body used for player movement!
gosub MakePlayer

` the first time you call this command, you may get a very large time#,
` so I call it twice at the start, to make sure we're getting a nice small time# value.
time# = NDB_GetElapsedTimeInSec()
time# = NDB_GetElapsedTimeInSec()


`this variable is used for pausing/unpausing the simulation.
GO = 1



` -----------------------------------
` 			MAIN LOOP                   
` -----------------------------------
do
   if rotated = 1
      xrotate object WeaponObjID, (object angle x(WeaponObjID)+10)
      rotated = 0
   endif
   if MOUSE = 1
      rotated = 0
      xrotate object WeaponObjID, (object angle x(WeaponObjID)-10)
   endif
					
	`get the elapsed time since last frame and save into time# variable.	
	time# = NDB_GetElapsedTimeInSec()

	` Here's the big command that updates the Physics system.
	` Objects are moved and positioned automatically.
	` the if GO=1 part is just a variable check so we can pause and unpause the system.
	if GO = 1 then NDB_NewtonUpdate time#

	`if user presses "q" key, quit the program!
	if lower$(inkey$()) = "q" then exit
	
	`if user presses "r", we need to reset.  so first destroy the Newton World, which will in turn
	`delete all of the DBpro objects for us.  then goto TOP, and start over!
	if lower$(inkey$()) = "r"
		NDB_NewtonDestroy
		goto TOP
	endif
	
	`this part is for pausing/unpausing.  basically it sets the GO variable to 1 or 0.
	if keystate(25) and P_PRESSED = 0 then P_PRESSED = 1
	if P_PRESSED = 1
		P_PRESSED = 2
		inc GO, 1
		if GO > 1 then GO = 0
	endif
	if keystate(25) = 0 then P_PRESSED = 0

		
	`draw the text in the upper left part of the screen.
	`gosub DrawOnscreenData
	
	`handle player movement and jumping!!
	gosub HandleCamera
	
	`handle shooting objects!
	gosub Shooting
	
	`handle the automatic door!
	gosub DoorCheck
	

	`NEWTON DEBUGGING SYSTEM:
	`		This may be a bit confusing to some users... if you don't understand it, ignore it for now.
	`		the DebugMakeNewtonObject command is really cool.  it takes the entire Newton world, and makes
	`		it into a single DBpro object, so you can see the "world according to Newton" onscreen.  you can
	`		use this to make sure that your visual objects and your rigid bodies are lined up, and also see the
	`		actual shape of the object according to Newton.  Here I check if the control key is down, and if
	`		so I make the newton object, and save it into the "obj" variable.  then I update the screen with
	`		te sync command, and then delete the "obj" right after syncing.  
	`		there is also another debug command called DebugDrawNewtonLines, which draws the lines in 2D.  it's
	`		slower than this command, but you don't have to fiddle with making and deleting objects.  see the docs.
	if controlkey()
		obj = NDB_DebugMakeNewtonObject()
		set object light obj, 0
	else
		obj = 0
	endif
	
	positionWeapon(WeaponObjID, 2, -2, 6, walk#, walk2#)
	
	`update the screen
	sync
	
	if obj <> 0
		delete object obj
	endif	
	

loop
` -----------------------------------
` -----------------------------------


` Destory the Newton world, clearing up any memory that was allocated.	
NDB_NewtonDestroy
end






MakeRoom:

	`this example uses TreeCollision objects for the level.  Tree Collisio objects are just another way of
	`describing collision shapes to Newton... but instead of using a primitive shape, it uses the polygon data
	`from a 3D model.  in Newton TreeCollision objects can only have a mass of 0, so they cannot be dynamic objects.
	`this is fine for background pieces, which should never move anyway.
	
	`Step 1- load the model to make the collision from.  In this case it's also out visual model, but you might
	`			want to use another model specifically for collision.  Also see the docs for info about the Serialization
	`			system, which can make loading TreeCollision objects MUCH faster for large, complex models.
	obj = FreeObject()
	load object levelstr$, obj
	texture object obj, 1
	
	`Step 2- make the TreeCollision data from the object, and save into variable "Col"
	Col = NDB_NewtonCreateTreeCollision( obj )
	
	`Step 3- make the rigid body from the collision data
	Room = NDB_NewtonCreateBody( Col )
	
	`next you would position the object + rigid body, but we're leaving them at 0,0,0 for this demo.
	
	`Step 4- finally, attach the object to the Rigid Body
	NDB_BodySetDBProData Room, obj
	NDB_NewtonBodySetDestructorCallback Room
	
	NDB_NewtonReleaseCollision Col
	
	`that's it!  the TreeCollision body is ready, so our level will have collision!
	
	
	`next we want to add a sliding door to our level.  we will make the door from a simple Box rigid body,
	`and connect it to the level body via a SLIDER joint, as we want a sliding door.
	Door = MakeBox( 18.5, 0.0, -11.0, 13.0, 14.0, 1.0, 0.0, 0.0, 0.0, 25.0 )
	NDB_BodySetGravity Door, 0
	
	`When making a joint, you generally set vector 1 to the location of the joint, and vector 2 to a unit vector
	`describing the direction of the joints`s "pin".  see the docs for more information on all joints.
	NDB_SetVector 1, 18.5, 0.0, -11.0
	NDB_SetVector 2, 0.0, 1.0, 0.0
	DoorSlider = NDB_NewtonConstraintCreateSlider( Door, Room )
	
	NDB_SetSliderLimits DoorSlider, -3.0, 20.0
	NDB_SetSliderMotorAccel DoorSlider, -50.0
	
	
	
	`finally, add a few crates around to shoot at!
	x# = -40.0
	y# = 18.0
	z# = 35.0
	
	level = 1
	boxes = 3
	
	repeat
		startz# = z# + -((boxes*5.0) / 2.0)
		for i=1 to boxes
			Body = MakeBox( x#, y#, startz#+(i*6.0), 5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 25.0 )
		next i	
		inc y#, 6.0
		dec boxes
		inc level
	until boxes = 0


	x# = -20.0
	y# = -5.0
	z# = -30.0
	
	level = 1
	boxes = 3
	
	repeat
		startz# = z# + -((boxes*5.0) / 2.0)
		for i=1 to boxes
			Body = MakeBox( x#, y#, startz#+(i*6.0), 5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 5.0 )
		next i
		inc y#, 6.0
		dec boxes
		inc level
	until boxes = 0
	
	
return


`This function makes the rigid body that represents the player
MakePlayer:

	`for the player (camera), we're going to use an ellipsoid shape.  this is a sphere that is "streched"
	`on one or two axis'.  in this case, we'll make it much taller than it is around, to mimick a human.
	Sphere = NDB_NewtonCreateSphere( 2.5, 6.0, 2.5 )
	Player = NDB_NewtonCreateBody( Sphere )
	
	`setting the initial starting position.
	NDB_BuildMatrix 0.0, 8.0, 0.0, 0.0, 10.0, -25.0
	NDB_NewtonBodySetMatrix Player
	
	`setting the mass...
	NDB_SetVector 6.0, 8.0, 6.0
	NDB_CalculateMIBoxSolid Player_Mass#
	NDB_NewtonBodySetMassMatrix Player, Player_Mass#
	
	`Newton automatically "freezes" objects which have come to rest, which means they are no longer calculated
	`each time you call NDB_NewtonUpdate.  they start calculating agani when another object hits them and sets
	`them in motion again.  However with our Player rigid body, we want it to be moved by the user's keyboard input.
	`if the body freezes, Newton will not let the user move the body, because it's not in the active body list.
	`To make a long story short, we need to tell Newton NOT to freeze this body, EVER.  This will make Newton
	`calculate this body every call to NewtonUpdate.  this of course takes processor power, so it's best not to
	`call this for too many bodies.
	NDB_NewtonBodySetAutoFreeze Player, 0
	
	NDB_BodySetGravity Player, 1
	
	`Here's the meat and potatoes of the character system: the UpVector joint.  this joint allows the character to
	`move in 3 dimensions, but won't allow it to "fall over" when it hits other objects.  which is exactly what we want
	`here.  for more info, have a look at the joint example and the documentation.
	NDB_SetVector 0.0, 1.0, 0.0
	UpVector = NDB_NewtonConstraintCreateUpVector( Player )
	
	`Finally, because we want to control the player manually, we don't want friction getting in our way and causing
	`problems... so I remove all friction between the Player material, and the Default material (aka everything else).
	`this makes it MUCH easier to calculate the forces needed to move the player later.
	Default = NDB_NewtonMaterialGetDefaultGroupID()
	PlayerID = NDB_NewtonMaterialCreateGroupID()
	NDB_NewtonMaterialSetDefaultFriction Default, PlayerID, 0.01, 0.01
	NDB_NewtonMaterialSetDefaultElasticity Default, PlayerID, 0.01
	
	`after setting the materials, we need to apply the Player material to the Player rigid body.
	NDB_NewtonBodySetMaterialGroupID Player, PlayerID
	
return

`this subroutine makes the simple in-screen display, which explains how to use the demo.
DrawOnscreenData:

	box 5,5,315,112,rgb(0,0,0),rgb(100,100,100),rgb(0,0,0),rgb(100,100,100)
	line 5,5,315,5
	line 5,5,5,112
	line 315,5,315,112
	line 5,112,315,112
	text 10,10,"Newton Game Dynamics Wrapper version:"+str$(NDB_GetVersion())
	text 10,20,"FIRST PERSON SHOOTER DEMO"
	text 10,40," move with W,S,A,D Keys || Look with mouse"
	text 10,50," LBM to shoot || Hold CTRL for debug data"
	text 10,60," SHIFT to run || SPACE to jump || "p" to (un)pause"
	text 10,70," Press "r" to reset || press "q" to quit"
	text 10,80," FPS:"+str$(screen fps()) + " Body Count:"+str$(NDB_DebugRigidBodyCount())
	
	text 15,95,GOSTR$(GO+1)
	
	ink rgb(255,0,0), rgb(0,0,0)
	line 320, 220, 320, 260
	line 300, 240, 340, 240
	ink rgb(255,255,255), rgb(0,0,0)
	
return


`This is the important subroutine that controls the Player movement.  I will try to explain it in some detail.
`Basically the setup is like this:  I have the Player rigid body I made in the MakePlayer subroutine, which is
`an elipsoid object that always stands up.  Each game loop, I place the camera in same position as that Rigid
`Body.  I also have 2 variables that represent the camera's orientation: Player_Yangle# and Player_Xangle#.
`these are linked to the mouse, to allow the user to look around.  Then, when the user wants to move, I
`use the camera to deterime which way the player is facing, and then apply a force to the body in the direction
`of movement.  The force is calculated in such a way that the player moves at a constant speed when walking.
`
`Here's how we calculate the movement force:
`
`	In physics there is the formula F = m * a, where F is the force, m is the mass, and a is the acceleration.
`
`	we also know that a (acceleration) is a CHANGE in velocity.  so we can write "a" as (v2-v1)/time.
`	this is basically (goal_velocity - current_velocity) / time.
`
`	so in this part, after I calculate the direction I want to go, I get the current velocity, and use that
`	to find the necessary acceleration to achieve that velocity.  then I simlply plug that into Newton, and it
`	takes care of the rest!  I'll write more comments as I go to hopefully make it understandable.
HandleCamera:

	`-------------------------
	`CAMERA
	`-------------------------
	`these variables rotate the camera.
	inc Player_Xangle#, mousemovey() * 0.25
	inc Player_Yangle#, mousemovex() * 0.25
	
	position mouse 320, 240
	
	`put a limit on how much the player can loop up/down.
	if Player_Xangle# > 80.0 then Player_Xangle# = 80.0
	if Player_Xangle# < -80.0 then Player_Xangle# = -80.0

	rotate camera Player_Xangle#, Player_Yangle#, 0.0
	
	`here we get the position of the Player rigid body, and place the camera there.
	NDB_BodyGetPosition Player
	position camera NDB_GetVector_X(), NDB_GetVector_Y(), NDB_GetVector_Z()
	
	`next we set the movement variables to zero.  the will stay at zero unless the user pressed a movement key.
	`player movement defaults to zero each loop.
	MoveX# = 0.0
	MoveZ# = 0.0
	
	if keystate(17) or keystate(31)
		`player is pressing "w" or "s" key, we need to move forward or backward!
		`find direction vector my moving the camera...
		
		`i use some trig to find the direction the player wants to move.
		dx# = sin(Player_Yangle#)
		dz# = cos(Player_Yangle#)
		
		`then I add this to the move vector, making it positive for forward, negative for backward.
		inc MoveX#, dx# * (keystate(17)-keystate(31)) :`makes a positive vector with "w", negative with "s"
		inc MoveZ#, dz# * (keystate(17)-keystate(31))
	endif
	
	if keystate(30) or keystate(32)

		`same thing here, but this is for strafing, so I add 90 degrees to the current angle!
		dx# = sin(Player_Yangle#+90.0)
		dz# = cos(Player_Yangle#+90.0)
		
		inc MoveX#, dx# * (keystate(32)-keystate(30)) :`makes a positive vector with "d", negative with "a"
		inc MoveZ#, dz# * (keystate(32)-keystate(30))
	endif
	
	
	`Now we need ouy direction vector the be a unit vector, so we divide by the length of the vector.
	`if you are confused here, please do a little research on vector math, it's VERY important for any 3D
	`application!
	`finally, re-normalize the move vector
	length# = sqrt( (MoveX#^2)+(MoveZ#^2) )
	
	MoveX# = MoveX# / length#
	MoveZ# = MoveZ# / length#
	
	
	`okay, new let's find the current velocity of the player.  that's easy through newton...
	NDB_NewtonBodyGetVelocity Player
	CurrentVel_X# = NDB_GetVector_X()
	CurrentVel_Y# = NDB_GetVector_Y()
	CurrentVel_Z# = NDB_GetVector_Z()
	
	`and our goal velocity is simply our move direction multiplied by the player's walking speed. (or 2x if running)
	GoalVel_X# = MoveX# * (Player_Speed# * ((shiftkey()+1)*2) )
	GoalVel_Z# = MoveZ# * (Player_Speed# * ((shiftkey()+1)*2) )
	
	`here we calculate the actual acceleration needed to reach our Goal_Velocity.  note that I multiply by 0.3, which
	`is just a damper to keep the forces from getting too large too quickly.
	AccelX# = 0.3 * ((GoalVel_X# - CurrentVel_X#) / time#)
	AccelZ# = 0.3 * ((GoalVel_Z# - CurrentVel_Z#) / time#)
	
	`also we want to limit how big the acceleration can be.  this keeps the player from being able to push
	`really heavy objects, etc.
	if AccelX# > 200.0 then AccelX# = 200.0
	if AccelX# < -200.0 then AccelX# = -200.0
	if AccelZ# > 200.0 then AccelZ# = 200.0
	if AccelZ# < -200.0 then AccelZ# = -200.0
		
	`finally, we just need to apply this force to the Player!  we'll use the AddForceGlobal command.
	`NOTE- in the forumla above, I said F = m * a.  we calculated "a", but we never multiplied by the mass!
	`			this is because my wrapper does this for you.  it automatically multiples the force by the body
	`			mass inside the function.
	
	`set temp vector 1 to force location
	NDB_BodyGetPosition Player
	`set temp vector 2 to force direction
	NDB_SetVector 2, AccelX#, 0.0, AccelZ#
	NDB_BodyAddForceGlobal Player
	
		`we also want jumping to be available.  for this we will use a simple ray cast to determine if we're
	`standing on the ground or not.
	AccelY# = 0.0
	
	if spacekey() and SPACEPRESSED = 0
		SPACEPRESSED = 1
		`user has pressed the space bar, apparently they would like to jump :)
		
		`cast a ray from the player location straight down, see if we hit something.
		NDB_BodyGetPosition Player
		px# = NDB_GetVector_X() : py# = NDB_GetVector_Y() : pz# = NDB_GetVector_Z()
		
		NDB_SetVector 1, px#, py#, pz#
		NDB_SetVector 2, px#, py# - 6.05, pz#
		dist# = NDB_NewtonWorldRayCast()
		
		if dist# < 1.0
			`something has been found!  in this case, we don't care what, just let the player jump!
			`the jump part is just a simple upward force..
			AccelY# = ((Player_JumpSpeed# - CurrentVel_Y#) / time#)
			
			`add another force to the player, the jumping force!  this is just like above, using the
			`new AddForceGlobal command!  easy, huh?
			NDB_BodyGetPosition Player
			NDB_SetVector 2, 0.0, AccelY#, 0.0
			NDB_BodyAddForceGlobal Player
		endif
	endif
	
	if spacekey() = 0 then SPACEPRESSED = 0
	
	`and there you go!!  FPS character controlling in remarkably few lines :)
	

return



Shooting:

	if mouseclick() = 1 and MOUSE = 0
		MOUSE = 1
		
		`user wants to shoot!  let's cast a ray with Newton and see if we've hit something!
		x1# = camera position x() : y1# = camera position y() : z1# = camera position z()
		
		`get a unit vector in the direction the player is facing, by moving the camera 1 unit!
		move camera 1.0
		x2# = camera position x() : y2# = camera position y() : z2# = camera position z()
		move camera -1.0
		
		`we will cast a ray 500 units long.
		dx# = x2# - x1#
		dy# = y2# - y1#
		dz# = z2# - z1#
		
		x2# = x1# + (dx# * 500.0)
		y2# = y1# + (dy# * 500.0)
		z2# = z1# + (dz# * 500.0)
		
		`cast the ray.  put start point in vector 1, end point in vector 2
		NDB_SetVector 1, x1#, y1#, z1#
		NDB_SetVector 2, x2#, y2#, z2#
		
		dist# = NDB_NewtonWorldrayCast()
		
		if dist# < 1.0
			`something hit!
			HitBody = NDB_RayCastGetBody()
			
			castdist# = dist# * 500.0
			cast_x# = x1# + (dx# * castdist#)
			cast_y# = y1# + (dy# * castdist#)
			cast_z# = z1# + (dz# * castdist#)
			
			hitmass# = NDB_NewtonBodyGetMassMatrix( HitBody )
			
			if hitmass# > 0.0
				`this is a live object, give it a kick!
				NDB_SetVector 1, cast_x#, cast_y#, cast_z#
				NDB_SetVector 2, dx# * Player_ShootPower#, dy# * Player_ShootPower#, dz# * Player_ShootPower#, 0.0
				NDB_BodyAddForceGlobal HitBody
				NDB_NewtonWorldUnfreezeBody HitBody
				
			else
				`this is the background (mass=0), add a bullethole!
				obj = FreeObject()
				make object plain obj, 0.5, 0.5
				
				position object obj, cast_x#-(dx#*0.01), cast_y#-(dy#*0.01), cast_z#-(dz#*0.01)
				
				
				NDB_RayCastGetNormal
				nx# = NDB_GetVector_X() : ny# = NDB_GetVector_Y() : nz# = NDB_GetVector_Z()
				
				x# = cast_x# + nx# : y# = cast_y# + ny# : z# = cast_z# + nz#
				
				point object obj, x#, y#, z#
				
				texture object obj, 2
				set object transparency obj, 1
				
			endif
			
		endif
		
	endif
	
	if mouseclick() = 0 then MOUSE = 0
	
	
	text 10,300,"HitBody:"+str$(HitBody)
	text 10,310,"HitMass:"+str$(hitmass#)
	
	
return



`this subroutine simply checks the distance (on the XZ plane) between the Player and the Door.  if it's within
`15 units, it sets the door to open.  if it's not, it sets the door to close.  simple.
DoorCheck:

	NDB_BodyGetPosition Player
	x1# = NDB_GetVector_X() : z1# = NDB_GetVector_Z()
	
	NDB_BodyGetPosition Door
	x2# = NDB_GetVector_X() : z2# = NDB_GetVector_Z()
	
	dx# = x2# - x1#
	dz# = z2# - z1#

	dist# = sqrt( (dx#^2)+(dz#^2) )
	
	if dist# < 15.0
		`player is close to the door, open it!
		NDB_SetSliderMotorAccel DoorSlider, 50.0
		
		`the door may have fallen asleep, so let's un-freeze it!"
		if NDB_BodyActive(Door) = 0 then NDB_NewtonWorldUnfreezeBody Door
		NEARDOOR = 1
		
	else
			
		if NEARDOOR = 1
			`we have just walked away from being under the door, 
			`so make sure the door isn't frozen, or it won't shut!
			if NDB_BodyActive(Door) = 0 then NDB_NewtonWorldUnfreezeBody Door
			NEARDOOR = 0
		endif	
		
		`player is away from door, turn motor off!
		NDB_SetSliderMotorAccel DoorSlider, -50.0
	endif
	
return




`all of these functions are pretty similar, they just make different collision
`primitives.  I'll explain the BOX in detail, and the others are all basically the same,
`except for the Convex Hulls, which I'll explain in detail as well.
function MakeBox(x#,y#,z#,sx#,sy#,sz#,rx#,ry#,rz#,mass#)
	
	Col = NDB_NewtonCreateBox(sx#, sy#, sz#)
	Body = NDB_NewtonCreateBody(Col)
	NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
	NDB_NewtonBodySetMatrix Body
	NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
	NDB_NewtonBodySetMassMatrix Body, mass#
	NDB_NewtonReleaseCollision Col
	
	obj = FreeObject()
	load object "./box.x", obj
	
	scale object obj, sx#*100.0, sy#*100.0, sz#*100.0
	position object obj, x#, y#, z#
	rotate object obj, rx#, ry#, rz#
	color = GetColor()
	color object obj, color
	set object ambience obj, 50
	NDB_BodySetDBProData Body, obj
	NDB_NewtonBodySetDestructorCallback Body
	NDB_BodySetGravity Body, 1
	
endfunction Body



function FreeObject()
	repeat
		inc i 
		if object exist(i)=0 then found=1
	until found
endfunction i

function GetColor()
	repeat
		r = rnd(1)*255
		g = rnd(1)*255
		b = rnd(1)*255
	until r<>0 or g<>0 or b<> 0
	color =  rgb(r,g,b)
endfunction color


`must force DBPro to include the memblock command set, because the wrapper uses these commands internally
`to make TreeCollision objects!  it's also necessary for Convex Hull primitives as well.
function NeverCalled()
	if memblock exist(1) then delete memblock 1
endfunction


function positionWeapon(object as dword, xOffset as float, yOffset as float, zOffset as float, sine as float, sine2 as float)
   sx# = sin(camera angle x()) : cx# = cos(camera angle x())
   sy# = sin(camera angle y()) : cy# = cos(camera angle y())
   sz# = sin(camera angle z()) : cz# = cos(camera angle z())
   xPos# = camera position x() + xOffset*(cy#*cz#) + yOffset*(sx#*sy#*cz#-cx#*sz#) + zOffset*(cx#*sy#*cz#+sx#*sz#)
   yPos# = camera position y() + xOffset*(cy#*sz#) + yOffset*(cx#*cz#+sx#*sy#*sz#) + zOffset*(cx#*sy#*sz#-sx#*cz#)
   zPos# = camera position z() + xOffset*(-1*sy#) + yOffset*(sx#*cy#) + zOffset*(cx#*cy#)
   position object object,xPos#,yPos#,zPos#
   set object to camera orientation object
endfunction


And altered it to load a WORLD map in the game and make a Newton object with it.

+ Code Snippet
`--------------------------------------------------
`	NEWTON PHYSICS SDK WRAPPER 
`	DEMO PROJECT 5 - first person shooter example
`
`--------------------------------------------------

`standard DBPro startup code...
sync on
sync rate 60
autocam off

set ambient light 0
set point light 0, 50, 100, 20
set light range 0, 5000

randomize timer()

INIT_WORLD()
obj = FreeObject()
LOAD_WORLD(obj, "Example/example.wgd", "Example/", (obj+1))
objend = (obj+1+WLD_GET_OBJECT_COUNT())
RoomWorldLoader = obj

`load images
load image "./floor.png",1
load image "./bullethole.png", 2

levelstr$ = "land1.x"

`set camera start point
position camera 40.0, 80.0, 40.0


`this is just an array so I can write onscreen if the simulation is running or not.
`it has nothing to do with Newton at all.
dim GOSTR$(2)
GOSTR$(1) = "SIMULATION PAUSED"
GOSTR$(2) = "SIMULATION RUNNING"


`variables used for the first-person camera
global Player = 0

global Player_Mass# = 12.0
global Player_Speed# = 10.0
global Player_Yangle# = 0.0
global Player_Xangle# = 0.0
global Player_ShootPower# = 5000.0
global Player_JumpSpeed# = 35.0

global Door = 0
global DoorSlider = 0


`I am using GOTO in these demos to keep them simple, in a real game situation you
`would probably want to avoid this programming style.
`------------------------------------------------
`------------------------------------------------
TOP:


`Initialize Newton, and create the Newton World.
NDB_NewtonCreate

`Set the temp vector to our gravity constant (acceleration due to gravity)
`then set as our standard gravity force.
NDB_SetVector 0.0, -50.0, 0.0
NDB_SetStandardGravity

`-----------------------------------------
`Set the gun as newton object.
obj = FreeObject()
load object "gun.x", obj
scale object obj, 25, 25, 25

Col = NDB_NewtonCreateTreeCollision(obj)

`Step 3- make the rigid body from the collision data
Room = NDB_NewtonCreateBody(col)

`Step 4- finally, attach the object to the Rigid Body
NDB_BodySetDBProData Room, obj
NDB_NewtonBodySetDestructorCallback Room
NDB_NewtonReleaseCollision col

`Set obj as WeaponObjID for weapon postitioning.
WeaponObjId = obj
`-----------------------------------------

`make the test room!
gosub MakeRoom

`make the player (camera) body used for player movement!
gosub MakePlayer

` the first time you call this command, you may get a very large time#,
` so I call it twice at the start, to make sure we're getting a nice small time# value.
time# = NDB_GetElapsedTimeInSec()
time# = NDB_GetElapsedTimeInSec()


`this variable is used for pausing/unpausing the simulation.
GO = 1



` -----------------------------------
` 			MAIN LOOP                   
` -----------------------------------
do
   if rotated = 1
      xrotate object WeaponObjID, (object angle x(WeaponObjID)+10)
      rotated = 0
   endif
   if MOUSE = 1
      rotated = 0
      xrotate object WeaponObjID, (object angle x(WeaponObjID)-10)
   endif
					
	`get the elapsed time since last frame and save into time# variable.	
	time# = NDB_GetElapsedTimeInSec()

	` Here's the big command that updates the Physics system.
	` Objects are moved and positioned automatically.
	` the if GO=1 part is just a variable check so we can pause and unpause the system.
	if GO = 1 then NDB_NewtonUpdate time#

	`if user presses "q" key, quit the program!
	if lower$(inkey$()) = "q" then exit
	
	`if user presses "r", we need to reset.  so first destroy the Newton World, which will in turn
	`delete all of the DBpro objects for us.  then goto TOP, and start over!
	if lower$(inkey$()) = "r"
		NDB_NewtonDestroy
		goto TOP
	endif
	
	`this part is for pausing/unpausing.  basically it sets the GO variable to 1 or 0.
	if keystate(25) and P_PRESSED = 0 then P_PRESSED = 1
	if P_PRESSED = 1
		P_PRESSED = 2
		inc GO, 1
		if GO > 1 then GO = 0
	endif
	if keystate(25) = 0 then P_PRESSED = 0

		
	`draw the text in the upper left part of the screen.
	`gosub DrawOnscreenData
	
	`handle player movement and jumping!!
	if inkey$() = "y"
	   control camera using arrowkeys 0, 5, 5
	  else
   	gosub HandleCamera
	endif
	`handle shooting objects!
	gosub Shooting
	
	`handle the automatic door!
	gosub DoorCheck
	

	`NEWTON DEBUGGING SYSTEM:
	`		This may be a bit confusing to some users... if you don't understand it, ignore it for now.
	`		the DebugMakeNewtonObject command is really cool.  it takes the entire Newton world, and makes
	`		it into a single DBpro object, so you can see the "world according to Newton" onscreen.  you can
	`		use this to make sure that your visual objects and your rigid bodies are lined up, and also see the
	`		actual shape of the object according to Newton.  Here I check if the control key is down, and if
	`		so I make the newton object, and save it into the "obj" variable.  then I update the screen with
	`		te sync command, and then delete the "obj" right after syncing.  
	`		there is also another debug command called DebugDrawNewtonLines, which draws the lines in 2D.  it's
	`		slower than this command, but you don't have to fiddle with making and deleting objects.  see the docs.
	if controlkey()
		obj = NDB_DebugMakeNewtonObject()
		set object light obj, 0
	else
		obj = 0
	endif
	
	positionWeapon(WeaponObjID, 2, -2, 6, walk#, walk2#)
	
	`update the screen
	sync
	
	if obj <> 0
		delete object obj
	endif	
	

loop
` -----------------------------------
` -----------------------------------


` Destory the Newton world, clearing up any memory that was allocated.	
NDB_NewtonDestroy
end






MakeRoom:

	`this example uses TreeCollision objects for the level.  Tree Collisio objects are just another way of
	`describing collision shapes to Newton... but instead of using a primitive shape, it uses the polygon data
	`from a 3D model.  in Newton TreeCollision objects can only have a mass of 0, so they cannot be dynamic objects.
	`this is fine for background pieces, which should never move anyway.
	
	`Step 1- load the model to make the collision from.  In this case it's also out visual model, but you might
	`			want to use another model specifically for collision.  Also see the docs for info about the Serialization
	`			system, which can make loading TreeCollision objects MUCH faster for large, complex models.
	`obj = FreeObject()
	`RoomWorldLoader
	for RoomWorldLoade = RoomWorldLoader+1 TO objend
	
	`Step 2- make the TreeCollision data from the object, and save into variable "Col"
	Col = NDB_NewtonCreateTreeCollision( RoomWorldLoader )
	
	`Step 3- make the rigid body from the collision data
	Room = NDB_NewtonCreateBody( Col )
	
	`next you would position the object + rigid body, but we're leaving them at 0,0,0 for this demo.
	
	`Step 4- finally, attach the object to the Rigid Body
	NDB_BodySetDBProData Room, RoomWorldLoader
	NDB_NewtonBodySetDestructorCallback Room
	
	NDB_NewtonReleaseCollision Col
	
	next RoomWorldLoade
	
	`that's it!  the TreeCollision body is ready, so our level will have collision!
	
	
	`next we want to add a sliding door to our level.  we will make the door from a simple Box rigid body,
	`and connect it to the level body via a SLIDER joint, as we want a sliding door.
	Door = MakeBox( 18.5, 0.0, -11.0, 13.0, 14.0, 1.0, 0.0, 0.0, 0.0, 25.0 )
	NDB_BodySetGravity Door, 0
	
	`When making a joint, you generally set vector 1 to the location of the joint, and vector 2 to a unit vector
	`describing the direction of the joints`s "pin".  see the docs for more information on all joints.
	NDB_SetVector 1, 18.5, 0.0, -11.0
	NDB_SetVector 2, 0.0, 1.0, 0.0
	DoorSlider = NDB_NewtonConstraintCreateSlider( Door, Room )
	
	NDB_SetSliderLimits DoorSlider, -3.0, 20.0
	NDB_SetSliderMotorAccel DoorSlider, -50.0
	
	
	
	`finally, add a few crates around to shoot at!
	x# = -40.0
	y# = 18.0
	z# = 35.0
	
	level = 1
	boxes = 3
	
	repeat
		startz# = z# + -((boxes*5.0) / 2.0)
		for i=1 to boxes
			Body = MakeBox( x#, y#, startz#+(i*6.0), 5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 25.0 )
		next i	
		inc y#, 6.0
		dec boxes
		inc level
	until boxes = 0


	x# = -20.0
	y# = -5.0
	z# = -30.0
	
	level = 1
	boxes = 3
	
	repeat
		startz# = z# + -((boxes*5.0) / 2.0)
		for i=1 to boxes
			Body = MakeBox( x#, y#, startz#+(i*6.0), 5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 5.0 )
		next i
		inc y#, 6.0
		dec boxes
		inc level
	until boxes = 0
	
	
return


`This function makes the rigid body that represents the player
MakePlayer:

	`for the player (camera), we're going to use an ellipsoid shape.  this is a sphere that is "streched"
	`on one or two axis'.  in this case, we'll make it much taller than it is around, to mimick a human.
	Sphere = NDB_NewtonCreateSphere( 2.5, 6.0, 2.5 )
	Player = NDB_NewtonCreateBody( Sphere )
	
	`setting the initial starting position.
	NDB_BuildMatrix 0.0, 10.0, 0.0, 0.0, 100.0, -15.0
	NDB_NewtonBodySetMatrix Player
	
	`setting the mass...
	NDB_SetVector 6.0, 8.0, 6.0
	NDB_CalculateMIBoxSolid Player_Mass#
	NDB_NewtonBodySetMassMatrix Player, Player_Mass#
	
	`Newton automatically "freezes" objects which have come to rest, which means they are no longer calculated
	`each time you call NDB_NewtonUpdate.  they start calculating agani when another object hits them and sets
	`them in motion again.  However with our Player rigid body, we want it to be moved by the user's keyboard input.
	`if the body freezes, Newton will not let the user move the body, because it's not in the active body list.
	`To make a long story short, we need to tell Newton NOT to freeze this body, EVER.  This will make Newton
	`calculate this body every call to NewtonUpdate.  this of course takes processor power, so it's best not to
	`call this for too many bodies.
	NDB_NewtonBodySetAutoFreeze Player, 0
	
	NDB_BodySetGravity Player, 1
	
	`Here's the meat and potatoes of the character system: the UpVector joint.  this joint allows the character to
	`move in 3 dimensions, but won't allow it to "fall over" when it hits other objects.  which is exactly what we want
	`here.  for more info, have a look at the joint example and the documentation.
	NDB_SetVector 0.0, 1.0, 0.0
	UpVector = NDB_NewtonConstraintCreateUpVector( Player )
	
	`Finally, because we want to control the player manually, we don't want friction getting in our way and causing
	`problems... so I remove all friction between the Player material, and the Default material (aka everything else).
	`this makes it MUCH easier to calculate the forces needed to move the player later.
	Default = NDB_NewtonMaterialGetDefaultGroupID()
	PlayerID = NDB_NewtonMaterialCreateGroupID()
	NDB_NewtonMaterialSetDefaultFriction Default, PlayerID, 0.01, 0.01
	NDB_NewtonMaterialSetDefaultElasticity Default, PlayerID, 0.01
	
	`after setting the materials, we need to apply the Player material to the Player rigid body.
	NDB_NewtonBodySetMaterialGroupID Player, PlayerID
	
return

`this subroutine makes the simple in-screen display, which explains how to use the demo.
DrawOnscreenData:

	box 5,5,315,112,rgb(0,0,0),rgb(100,100,100),rgb(0,0,0),rgb(100,100,100)
	line 5,5,315,5
	line 5,5,5,112
	line 315,5,315,112
	line 5,112,315,112
	text 10,10,"Newton Game Dynamics Wrapper version:"+str$(NDB_GetVersion())
	text 10,20,"FIRST PERSON SHOOTER DEMO"
	text 10,40," move with W,S,A,D Keys || Look with mouse"
	text 10,50," LBM to shoot || Hold CTRL for debug data"
	text 10,60," SHIFT to run || SPACE to jump || "p" to (un)pause"
	text 10,70," Press "r" to reset || press "q" to quit"
	text 10,80," FPS:"+str$(screen fps()) + " Body Count:"+str$(NDB_DebugRigidBodyCount())
	
	text 15,95,GOSTR$(GO+1)
	
	ink rgb(255,0,0), rgb(0,0,0)
	line 320, 220, 320, 260
	line 300, 240, 340, 240
	ink rgb(255,255,255), rgb(0,0,0)
	
return


`This is the important subroutine that controls the Player movement.  I will try to explain it in some detail.
`Basically the setup is like this:  I have the Player rigid body I made in the MakePlayer subroutine, which is
`an elipsoid object that always stands up.  Each game loop, I place the camera in same position as that Rigid
`Body.  I also have 2 variables that represent the camera's orientation: Player_Yangle# and Player_Xangle#.
`these are linked to the mouse, to allow the user to look around.  Then, when the user wants to move, I
`use the camera to deterime which way the player is facing, and then apply a force to the body in the direction
`of movement.  The force is calculated in such a way that the player moves at a constant speed when walking.
`
`Here's how we calculate the movement force:
`
`	In physics there is the formula F = m * a, where F is the force, m is the mass, and a is the acceleration.
`
`	we also know that a (acceleration) is a CHANGE in velocity.  so we can write "a" as (v2-v1)/time.
`	this is basically (goal_velocity - current_velocity) / time.
`
`	so in this part, after I calculate the direction I want to go, I get the current velocity, and use that
`	to find the necessary acceleration to achieve that velocity.  then I simlply plug that into Newton, and it
`	takes care of the rest!  I'll write more comments as I go to hopefully make it understandable.
HandleCamera:

	`-------------------------
	`CAMERA
	`-------------------------
	`these variables rotate the camera.
	inc Player_Xangle#, mousemovey() * 0.25
	inc Player_Yangle#, mousemovex() * 0.25
	
	position mouse 320, 240
	
	`put a limit on how much the player can loop up/down.
	if Player_Xangle# > 80.0 then Player_Xangle# = 80.0
	if Player_Xangle# < -80.0 then Player_Xangle# = -80.0

	rotate camera Player_Xangle#, Player_Yangle#, 0.0
	
	`here we get the position of the Player rigid body, and place the camera there.
	NDB_BodyGetPosition Player
	position camera NDB_GetVector_X(), NDB_GetVector_Y(), NDB_GetVector_Z()
	
	`next we set the movement variables to zero.  the will stay at zero unless the user pressed a movement key.
	`player movement defaults to zero each loop.
	MoveX# = 0.0
	MoveZ# = 0.0
	
	if keystate(17) or keystate(31)
		`player is pressing "w" or "s" key, we need to move forward or backward!
		`find direction vector my moving the camera...
		
		`i use some trig to find the direction the player wants to move.
		dx# = sin(Player_Yangle#)
		dz# = cos(Player_Yangle#)
		
		`then I add this to the move vector, making it positive for forward, negative for backward.
		inc MoveX#, dx# * (keystate(17)-keystate(31)) :`makes a positive vector with "w", negative with "s"
		inc MoveZ#, dz# * (keystate(17)-keystate(31))
	endif
	
	if keystate(30) or keystate(32)

		`same thing here, but this is for strafing, so I add 90 degrees to the current angle!
		dx# = sin(Player_Yangle#+90.0)
		dz# = cos(Player_Yangle#+90.0)
		
		inc MoveX#, dx# * (keystate(32)-keystate(30)) :`makes a positive vector with "d", negative with "a"
		inc MoveZ#, dz# * (keystate(32)-keystate(30))
	endif
	
	
	`Now we need ouy direction vector the be a unit vector, so we divide by the length of the vector.
	`if you are confused here, please do a little research on vector math, it's VERY important for any 3D
	`application!
	`finally, re-normalize the move vector
	length# = sqrt( (MoveX#^2)+(MoveZ#^2) )
	
	MoveX# = MoveX# / length#
	MoveZ# = MoveZ# / length#
	
	
	`okay, new let's find the current velocity of the player.  that's easy through newton...
	NDB_NewtonBodyGetVelocity Player
	CurrentVel_X# = NDB_GetVector_X()
	CurrentVel_Y# = NDB_GetVector_Y()
	CurrentVel_Z# = NDB_GetVector_Z()
	
	`and our goal velocity is simply our move direction multiplied by the player's walking speed. (or 2x if running)
	GoalVel_X# = MoveX# * (Player_Speed# * ((shiftkey()+1)*2) )
	GoalVel_Z# = MoveZ# * (Player_Speed# * ((shiftkey()+1)*2) )
	
	`here we calculate the actual acceleration needed to reach our Goal_Velocity.  note that I multiply by 0.3, which
	`is just a damper to keep the forces from getting too large too quickly.
	AccelX# = 0.3 * ((GoalVel_X# - CurrentVel_X#) / time#)
	AccelZ# = 0.3 * ((GoalVel_Z# - CurrentVel_Z#) / time#)
	
	`also we want to limit how big the acceleration can be.  this keeps the player from being able to push
	`really heavy objects, etc.
	if AccelX# > 200.0 then AccelX# = 200.0
	if AccelX# < -200.0 then AccelX# = -200.0
	if AccelZ# > 200.0 then AccelZ# = 200.0
	if AccelZ# < -200.0 then AccelZ# = -200.0
		
	`finally, we just need to apply this force to the Player!  we'll use the AddForceGlobal command.
	`NOTE- in the forumla above, I said F = m * a.  we calculated "a", but we never multiplied by the mass!
	`			this is because my wrapper does this for you.  it automatically multiples the force by the body
	`			mass inside the function.
	
	`set temp vector 1 to force location
	NDB_BodyGetPosition Player
	`set temp vector 2 to force direction
	NDB_SetVector 2, AccelX#, 0.0, AccelZ#
	NDB_BodyAddForceGlobal Player
	
		`we also want jumping to be available.  for this we will use a simple ray cast to determine if we're
	`standing on the ground or not.
	AccelY# = 0.0
	
	if spacekey() and SPACEPRESSED = 0
		SPACEPRESSED = 1
		`user has pressed the space bar, apparently they would like to jump :)
		
		`cast a ray from the player location straight down, see if we hit something.
		NDB_BodyGetPosition Player
		px# = NDB_GetVector_X() : py# = NDB_GetVector_Y() : pz# = NDB_GetVector_Z()
		
		NDB_SetVector 1, px#, py#, pz#
		NDB_SetVector 2, px#, py# - 6.05, pz#
		dist# = NDB_NewtonWorldRayCast()
		
		if dist# < 1.0
			`something has been found!  in this case, we don't care what, just let the player jump!
			`the jump part is just a simple upward force..
			AccelY# = ((Player_JumpSpeed# - CurrentVel_Y#) / time#)
			
			`add another force to the player, the jumping force!  this is just like above, using the
			`new AddForceGlobal command!  easy, huh?
			NDB_BodyGetPosition Player
			NDB_SetVector 2, 0.0, AccelY#, 0.0
			NDB_BodyAddForceGlobal Player
		endif
	endif
	
	if spacekey() = 0 then SPACEPRESSED = 0
	
	`and there you go!!  FPS character controlling in remarkably few lines :)
	

return



Shooting:

	if mouseclick() = 1 and MOUSE = 0
		MOUSE = 1
		
		`user wants to shoot!  let's cast a ray with Newton and see if we've hit something!
		x1# = camera position x() : y1# = camera position y() : z1# = camera position z()
		
		`get a unit vector in the direction the player is facing, by moving the camera 1 unit!
		move camera 1.0
		x2# = camera position x() : y2# = camera position y() : z2# = camera position z()
		move camera -1.0
		
		`we will cast a ray 500 units long.
		dx# = x2# - x1#
		dy# = y2# - y1#
		dz# = z2# - z1#
		
		x2# = x1# + (dx# * 500.0)
		y2# = y1# + (dy# * 500.0)
		z2# = z1# + (dz# * 500.0)
		
		`cast the ray.  put start point in vector 1, end point in vector 2
		NDB_SetVector 1, x1#, y1#, z1#
		NDB_SetVector 2, x2#, y2#, z2#
		
		dist# = NDB_NewtonWorldrayCast()
		
		if dist# < 1.0
			`something hit!
			HitBody = NDB_RayCastGetBody()
			
			castdist# = dist# * 500.0
			cast_x# = x1# + (dx# * castdist#)
			cast_y# = y1# + (dy# * castdist#)
			cast_z# = z1# + (dz# * castdist#)
			
			hitmass# = NDB_NewtonBodyGetMassMatrix( HitBody )
			
			if hitmass# > 0.0
				`this is a live object, give it a kick!
				NDB_SetVector 1, cast_x#, cast_y#, cast_z#
				NDB_SetVector 2, dx# * Player_ShootPower#, dy# * Player_ShootPower#, dz# * Player_ShootPower#, 0.0
				NDB_BodyAddForceGlobal HitBody
				NDB_NewtonWorldUnfreezeBody HitBody
				
			else
				`this is the background (mass=0), add a bullethole!
				obj = FreeObject()
				make object plain obj, 0.5, 0.5
				
				position object obj, cast_x#-(dx#*0.01), cast_y#-(dy#*0.01), cast_z#-(dz#*0.01)
				
				
				NDB_RayCastGetNormal
				nx# = NDB_GetVector_X() : ny# = NDB_GetVector_Y() : nz# = NDB_GetVector_Z()
				
				x# = cast_x# + nx# : y# = cast_y# + ny# : z# = cast_z# + nz#
				
				point object obj, x#, y#, z#
				
				texture object obj, 2
				set object transparency obj, 1
				
			endif
			
		endif
		
	endif
	
	if mouseclick() = 0 then MOUSE = 0
	
	
	text 10,300,"HitBody:"+str$(HitBody)
	text 10,310,"HitMass:"+str$(hitmass#)
	
	
return



`this subroutine simply checks the distance (on the XZ plane) between the Player and the Door.  if it's within
`15 units, it sets the door to open.  if it's not, it sets the door to close.  simple.
DoorCheck:

	NDB_BodyGetPosition Player
	x1# = NDB_GetVector_X() : z1# = NDB_GetVector_Z()
	
	NDB_BodyGetPosition Door
	x2# = NDB_GetVector_X() : z2# = NDB_GetVector_Z()
	
	dx# = x2# - x1#
	dz# = z2# - z1#

	dist# = sqrt( (dx#^2)+(dz#^2) )
	
	if dist# < 15.0
		`player is close to the door, open it!
		NDB_SetSliderMotorAccel DoorSlider, 50.0
		
		`the door may have fallen asleep, so let's un-freeze it!"
		if NDB_BodyActive(Door) = 0 then NDB_NewtonWorldUnfreezeBody Door
		NEARDOOR = 1
		
	else
			
		if NEARDOOR = 1
			`we have just walked away from being under the door, 
			`so make sure the door isn't frozen, or it won't shut!
			if NDB_BodyActive(Door) = 0 then NDB_NewtonWorldUnfreezeBody Door
			NEARDOOR = 0
		endif	
		
		`player is away from door, turn motor off!
		NDB_SetSliderMotorAccel DoorSlider, -50.0
	endif
	
return




`all of these functions are pretty similar, they just make different collision
`primitives.  I'll explain the BOX in detail, and the others are all basically the same,
`except for the Convex Hulls, which I'll explain in detail as well.
function MakeBox(x#,y#,z#,sx#,sy#,sz#,rx#,ry#,rz#,mass#)
	
	Col = NDB_NewtonCreateBox(sx#, sy#, sz#)
	Body = NDB_NewtonCreateBody(Col)
	NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
	NDB_NewtonBodySetMatrix Body
	NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
	NDB_NewtonBodySetMassMatrix Body, mass#
	NDB_NewtonReleaseCollision Col
	
	obj = FreeObject()
	load object "./box.x", obj
	
	scale object obj, sx#*100.0, sy#*100.0, sz#*100.0
	position object obj, x#, y#, z#
	rotate object obj, rx#, ry#, rz#
	color = GetColor()
	color object obj, color
	set object ambience obj, 50
	NDB_BodySetDBProData Body, obj
	NDB_NewtonBodySetDestructorCallback Body
	NDB_BodySetGravity Body, 1
	
endfunction Body



function FreeObject()
	repeat
		inc i 
		if object exist(i)=0 then found=1
	until found
endfunction i

function GetColor()
	repeat
		r = rnd(1)*255
		g = rnd(1)*255
		b = rnd(1)*255
	until r<>0 or g<>0 or b<> 0
	color =  rgb(r,g,b)
endfunction color


`must force DBPro to include the memblock command set, because the wrapper uses these commands internally
`to make TreeCollision objects!  it's also necessary for Convex Hull primitives as well.
function NeverCalled()
	if memblock exist(1) then delete memblock 1
endfunction


function positionWeapon(object as dword, xOffset as float, yOffset as float, zOffset as float, sine as float, sine2 as float)
   sx# = sin(camera angle x()) : cx# = cos(camera angle x())
   sy# = sin(camera angle y()) : cy# = cos(camera angle y())
   sz# = sin(camera angle z()) : cz# = cos(camera angle z())
   xPos# = camera position x() + xOffset*(cy#*cz#) + yOffset*(sx#*sy#*cz#-cx#*sz#) + zOffset*(cx#*sy#*cz#+sx#*sz#)
   yPos# = camera position y() + xOffset*(cy#*sz#) + yOffset*(cx#*cz#+sx#*sy#*sz#) + zOffset*(cx#*sy#*sz#-sx#*cz#)
   zPos# = camera position z() + xOffset*(-1*sy#) + yOffset*(sx#*cy#) + zOffset*(cx#*cy#)
   position object object,xPos#,yPos#,zPos#
   set object to camera orientation object
endfunction


Screenshot of map:



Is it possible to make every object in the map physics-enabled?
(I know the WORLD library has the function to name every object)

Any help appreciated!
Thanks!

Jeff
Posted: 22nd May 2007 20:54
No. For one those are lightmapped and Newton requires separate objects to simulate each rigid body. You could try detaching your limbs via code but you'd have to not lightmap the cubes as that would lead to some rather messed up looking maps. If however the map uses separate objects per object / brush then it should be easily implemented.
Posted: 22nd May 2007 21:06
The map DOES actually uses seperate objects.
Posted: 23rd May 2007 0:44
His point is that the shadows would not updated; If you knocked a box over, it would end up leaving a shadow behind and with unnatural shadows on the top whilst the bottom is lit.
Posted: 23rd May 2007 0:50
You could do it, but only with the static objects. But then it would be nonsensical to lightmap dynamic objects anyway.
Posted: 23rd May 2007 8:48
Yes! What dumb of me!! Well, then i only want the whole map and objects in it be static, so you can walk over everything. Then i'll place my own, non-lightmapped, objects. Possible? How?

Thanks!

Jeff
Posted: 6th Sep 2007 18:08
I think the best way to do that would be to just make a program which loads the world and allows you to position objects around it, saving thier number and position in a text file.

(If your going to do that initialise all the objects numbers as x, x+1, x+2 etc. That way if you have objects made before that (say object 1) you can initialise x to be say 5, so the object numbers start at 5 and increase by 1.)