Hi,to all
@Tachyon:
I had a problem too with Materials and Collision newton demo.
I was using 5.8 version and later version 6.0 of DBPro(Newton1.32b),but demo 4 shows only flying ball.
Then I have changed the functions used for making walls,and MakeRoom subroutine.That routine I have puted at the top of the code.If you put it somewhere down in subroutine and call it with Gosub-return command it won`t work.Why?Had no time to check it way.Maybe materials are not defined as global variables or something like that...Compare this codes with yours and try to
identify what`s causing problems...
Here is working demo4:
`--------------------------------------------------
` NEWTON PHYSICS SDK WRAPPER
` DEMO PROJECT 4 - materials and collision
`
`
`--------------------------------------------------
`standard DBPro startup code...
sync on
sync rate 60
autocam off
hide mouse
set ambient light 100
set point light 0, 50, 100, -50
set light range 0, 5000
randomize timer()
`load images
CementImg = FreeImage()
load image "..mediademo04cement.jpg", CementImg
BrickImg = FreeImage()
load image "..mediademo04brick.jpg", BrickImg
WoodImg = FreeImage()
load image "..mediademo04wood.jpg", WoodImg
TargetImg = FreeImage()
load image "..mediademo04target.jpg", TargetImg
`load sounds
BallOnBrick = 1
BallOnCement = 2
BallOnWood = 3
BallOnTarget = 4
load sound "..mediademo04ball_on_brick.wav", BallOnBrick
load sound "..mediademo04ball_on_cement.wav", BallOnCement
load sound "..mediademo04ball_on_wood.wav", BallOnWood
load sound "..mediademo04ball_on_target.wav", BallOnTarget
`set camera start point
position camera 0.0, 0.0, -100.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"
`this variable holds the "program state", as in waiting to throw, throwing, etc..
global ProgState
`constants for the variable
#constant PROG_WAITING 1
#constant PROG_THROWING 2
`variable for tennis ball and target rigid bodies
global TennisBall = 0
global Target = 0
`and, the throw power (velocity)
global ThrowPower# = 200.0
`initialize ProgState variable
ProgState = PROG_WAITING
`this is a simple plain used to make a fake shadow for the ball!
ShadowObj = FreeObject()
make object plain ShadowObj, 6.0, 6.0
rotate object ShadowObj, 90.0, 0.0, 0.0
shadowimg = FreeImage()
load image "..mediademo04shadow.png", shadowimg
texture object ShadowObj, shadowimg
ghost object on ShadowObj, 4
hide object ShadowObj
`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
`In this example, we'll set a specific size for the Newton world. we'll also make
`it so that if a body leaves the boundaries of the Newton world, it is automatically
`destroyed.
NDB_SetVector 1, -300.0, -300.0, -300.0
NDB_SetVector 2, 300.0, 300.0, 300.0
NDB_NewtonSetWorldSize
NDB_NewtonSetBodyLeaveWorldEvent 1 :` a flag of "1" = "delete body on exit", it's the only flag at the moment.
`Set the temp vector to our gravity constant (acceleration due to gravity)
`then set as our standard gravity force.
NDB_SetVector 0.0, -150.0, 0.0
NDB_SetStandardGravity
`make the Room of different materials...
`*************************************************
MakeRoom:
`obj=1
`first make all 5 walls, simple boxes using our MakeBox helper function...
RightWall = MakeBox( 52.5, 0.0, 0.0, 5.0, 100.0, 200.0, 0.0, 0.0, 0.0, 0.0 )
LeftWall = MakeBox( -52.5, 0.0, 0.0, 5.0, 100.0, 200.0, 0.0, 0.0, 0.0, 0.0 )
TopWall = MakeBox( 0.0, 52.5, 0.0, 100.0, 5.0, 200.0, 0.0, 0.0, 0.0, 0.0 )
BotWall = MakeBox( 0.0, -52.5, 0.0, 100.0, 5.0, 200.0, 0.0, 0.0, 0.0, 0.0 )
EndWall = MakeBox( 0.0, 0.0, 102.5, 100.0, 100.0, 5.0, 0.0, 0.0, 0.0, 0.0 )
`also make a small floating "target" box
Target = MakeBox( 0.0, 0.0, 20.0, 8.0, 8.0, 8.0, 0.0, 0.0, 0.0, 50.0 )
NDB_BodySetGravity Target, 0 : `remove gravity from this body
`PREINACIO SAM SPHERE F-JU DA KORISTI I MATERIJAL KAO
`ULAZNI PARAMETAR
`next we need to make some materials, and set them to the walls!
`first we'll get the index to the default material, that Newton sets for each rigid body when first created.
DefaultMat = NDB_NewtonMaterialGetDefaultGroupID()
ballMat = NDB_NewtonMaterialCreateGroupID()
`next, we'll make Material ID's for our 4 materials:
CementMat = NDB_NewtonMaterialCreateGroupID()
BrickMat = NDB_NewtonMaterialCreateGroupID()
WoodMat = NDB_NewtonMaterialCreateGroupID()
TargetMat = NDB_NewtonMaterialCreateGroupID()
`Now, we have to define how objects of different materials should react to each other!
`for example, our tennis ball will have DefaultMat, so let's set how it should react when it
`hits a body of CementMat!
`in this demo, we're interested in how the ball bounces off the bodies, so we'll focus on
`friction, and "Elasticity" settings.
`KAO GUMENA LOPTA-RUBBER BALL
NDB_NewtonMaterialSetDefaultFriction DefaultMat, CementMat, 0.7, 0.5
NDB_NewtonMAterialSetDefaultElasticity DefaultMat, CementMat, 0.8
NDB_NewtonMaterialSetDefaultFriction DefaultMat, WoodMat, 0.5, 0.2
NDB_NewtonMAterialSetDefaultElasticity DefaultMat, WoodMat, 0.99
NDB_NewtonMaterialSetDefaultFriction DefaultMat, BrickMat, 0.9, 0.8
NDB_NewtonMAterialSetDefaultElasticity DefaultMat, BrickMat, 0.5
NDB_NewtonMaterialSetDefaultFriction DefaultMat, TargetMat, 0.9, 0.9
NDB_NewtonMAterialSetDefaultElasticity DefaultMat, TargetMat, 0.3
`A OVO JE MALO TVRDJA LOPTA izradjena od ballMat-rijala-HARD BALL
NDB_NewtonMaterialSetDefaultFriction ballMat, CementMat, 0.4, 0.2
NDB_NewtonMAterialSetDefaultElasticity ballMat, CementMat, 0.5
NDB_NewtonMaterialSetDefaultFriction ballMat, WoodMat, 0.2, 0.2
NDB_NewtonMAterialSetDefaultElasticity ballMat, WoodMat, 0.5
NDB_NewtonMaterialSetDefaultFriction ballMat, BrickMat, 0.5, 0.4
NDB_NewtonMAterialSetDefaultElasticity ballMat, BrickMat, 0.5
NDB_NewtonMaterialSetDefaultFriction ballMat, TargetMat, 0.9, 0.9
NDB_NewtonMAterialSetDefaultElasticity ballMat, TargetMat, 0.3
`NDB_NewtonMaterialSetDefaultFriction ballMat, DefaultMat, 0.1, 0.05
`finally, don't forget to assign the materials to the walls! Let's also texture the walls at the same
`time, so they look right...
NDB_NewtonBodySetMaterialGroupID RightWall, BrickMat
texture object NDB_GetDBPro( RightWall ), BrickImg
NDB_NewtonBodySetMaterialGroupID LeftWall, BrickMat
texture object NDB_GetDBPro( LeftWall ), BrickImg
NDB_NewtonBodySetMaterialGroupID TopWall, WoodMat
texture object NDB_GetDBPro( TopWall ), WoodImg
NDB_NewtonBodySetMaterialGroupID BotWall, WoodMat
texture object NDB_GetDBPro( BotWall ), WoodImg
NDB_NewtonBodySetMaterialGroupID EndWall, CementMat
texture object NDB_GetDBPro( EndWall ), CementImg
NDB_NewtonBodySetMaterialGroupID Target, TargetMat
texture object NDB_GetDBPro( Target ), TargetImg
`and last but not least, we must tell the wrapper which collisions to keep track of.
NDB_NewtonMaterialSetCollisionCallback DefaultMat, CementMat
NDB_NewtonMaterialSetCollisionCallback DefaultMat, BrickMat
NDB_NewtonMaterialSetCollisionCallback DefaultMat, WoodMat
NDB_NewtonMaterialSetCollisionCallback DefaultMat, TargetMat
NDB_NewtonMaterialSetCollisionCallback ballMat, CementMat
NDB_NewtonMaterialSetCollisionCallback ballMat, BrickMat
NDB_NewtonMaterialSetCollisionCallback ballMat, WoodMat
NDB_NewtonMaterialSetCollisionCallback ballMat, TargetMat
` 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
`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 spacekey() and SPACEPRESSED = 0 then SPACEPRESSED = 1
if SPACEPRESSED = 1
SPACEPRESSED = 2
inc GO, 1
if GO > 1 then GO = 0
endif
if spacekey()=0 then SPACEPRESSED = 0
`draw the text in the upper left part of the screen.
gosub DrawOnscreenData
`this subroutine is for moving/rotating the camera.
gosub HandleCamera
`this command throws the tennis ball, based in user input!
gosub UserInput
`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
`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
`This subroutine sets up the basic room we'll be using for this demo. it makes 5 walls, with various materials.
`the material settings define how other bodies will react when they collide...
`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,"target hit= "+str$(meta)
if NDB_BodyExist(TennisBall)
text 10,30,"ball material= "+str$(NDB_NewtonBodyGetMaterialGroupID(TennisBall))
endif
text 10,50," Space to (un)pause"
text 10,70," FPS:"+str$(screen fps()) + " Body Count:"+str$(NDB_DebugRigidBodyCount())
text 10,90,GOSTR$(GO+1)
ink rgb(255,0,0), rgb(0,0,0)
circle 320, 240, 3
ink rgb(255,255,255), rgb(0,0,0)
return
UserInput:
select ProgState
case PROG_WAITING
`the program is waiting for the player to throw the ball... first, put a message onscreen to
`let them know!
text 10,110,"CLICK LMB TO THROW!"
`let's see if they clicked for us!
if mouseclick() = 1
`left mouse button clicked, so let's create a tennis ball, and throw it!
`camera is always at (0,0,-100), we'll create it just below the camera.
TennisBall = MakeSphere( 0.0, -5.0, -100.0, 3.0, 10.0,DefaultMat )
`now we need to set an initial velocity for the body, as if we've thrown it.
`we want to throw in the direction we are looking, so we'll use the camera to get
`a simple vector in our look direction, and multiply that by the throw power.
x1# = camera position x() : y1# = camera position y() : z1# = camera position z()
move camera 1.0
x2# = camera position x() : y2# = camera position y() : z2# = camera position z()
move camera -1.0
unit_x# = x2# - x1#
unit_y# = y2# - y1#
unit_z# = z2# - z1#
`now, to get the initial velocity, we multiply by the throw power!
vel_x# = unit_x# * ThrowPower#
vel_y# = unit_y# * ThrowPower#
vel_z# = unit_z# * ThrowPower#
NDB_SetVector vel_x#, vel_y#, vel_z#
NDB_NewtonBodySetVelocity TennisBall
`finally, set the ProgState variable to "Throwing"
ProgState = PROG_THROWING
`show the shadow object
show object ShadowObj
endif
endcase
case PROG_THROWING
`the program is watching the tennis ball bounce around. put a message onscreen to let the user
`know if they click the right mouse button, they can reset and try again.
text 10,110,"CLICK RMB TO RESET!"
`this is where we check if the ball hit something, and if so, we play a sound effect!
gosub CheckCollisions
`check if the TennisBall still exists. if it doesn't, that means it has gone outside
`of the Newton World (remember we set WorldSize at the beginning?)... so we should automatically
`reset so the player can throw again!
if NDB_BodyExist( TennisBall )
`the body does exist, so update the position of our little shados object
NDB_BodyGetPosition TennisBall
position object ShadowObj, NDB_GetVector_X(), -49.99, NDB_GetVector_Z()
else
`the body doesn't exist, so let's hide the shadow object, and set the program back to WAIT mode!
hide object ShadowObj
ProgState = PROG_WAITING
endif
`did they click?
if mouseclick() = 2
`okay, delete the TennisBall!
if NDB_BodyExist( TennisBall ) then NDB_NewtonDestroyBody TennisBall : TennisBall = 0
`and reset the program variable.
ProgState = PROG_WAITING
`hide shadow object
hide object ShadowObj
endif
endcase
endselect
return
CheckCollisions:
`in previous versions of the wrapper, the collision checker required you give it 2 body IDs, and it would
`tell you if they collided. this became a pain with many bodies, because you have to loop through them
`every time.
`however the new wrapper has the ability to check for a body vs. a material! in our demo, we have
`several materials with more than one body... for example the "brick" material is assigned to two bodies.
`rather than check each body individually, I simply ask "did the Ball body hit any bodies of material X?"
`and the wrapper will answer. then I will play the approriate sound effect.
`first check if the ball hit any "wood" surfaces
hit = NDB_GetCollisionBodyToMaterial( TennisBall, WoodMat )
if hit <> 0
`we have hit a body, and now the "hit" variable contains an index to further information about the collision.
`you can get the collision position, normal, and what body was hit. look in the docs for more info!
`you can do even more interesting things, like change sound volume based on collision speed, etc!
play sound BallOnWood
else
`check for cement!
hit = NDB_GetCollisionBodyToMaterial( TennisBall, CementMat )
if hit <> 0
play sound BallOnCement
else
`check for brick!
hit = NDB_GetCollisionBodyToMaterial( TennisBall, BrickMat )
if hit <> 0
play sound BallOnBrick
else
`check for TARGET!
`there is only 1 target body, so I'll do a Body vs. Body check!
meta = NDB_GetCollisionBodyToBody( TennisBall, Target )
if meta <> 0
if sound playing (BallOnTarget)=0
play sound BallOnTarget
endif
else
meta=0
endif
endif
endif
endif
return
` FUNCTIONS ---------------------------------
`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 "..mediabox.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, 0
endfunction Body
`This function makes a rigid body with a sphere shape. the code is almost identical to the BOX function, except that
`it creates a sphere collision, and sphere primitive shape instead of a box. everythins else is identical.
function MakeSphere(x#,y#,z#,s#,mass#,mat)
Col = NDB_NewtonCreateSphere( s# )
Body = NDB_NewtonCreateBody(Col)
`Set initial position and rotation
NDB_BuildMatrix 0.0, 0.0, 0.0, x#, y#, z#
NDB_NewtonBodySetMatrix Body
`notice that I calculate the MI (moment of inertia) for a sphere shape this time.
NDB_CalculateMISphereSolid mass#, s#
NDB_NewtonBodySetMassMatrix Body, mass#
`ballMat = NDB_NewtonMaterialCreateGroupID()
NDB_NewtonBodySetMaterialGroupID Body, mat
NDB_NewtonReleaseCollision Col
obj = FreeObject()
load object "..mediasphere.x", obj
color object obj, GetColor()
set object ambience obj, 100
scale object obj, s#*100.0, s#*100.0, s#*100.0
position object obj, x#, y#, z#
NDB_BodySetDBProData Body, obj
NDB_NewtonBodySetDestructorCallback Body
NDB_BodySetGravity Body, 1
endfunction Body
` This subroutine handles moving/rotating the camera. should be pretty straightforward.
HandleCamera:
`-------------------------
`CAMERA
`-------------------------
inc CamAngleX#, mousemovey() * 0.5
inc CamAngleY#, mousemovex() * 0.5
position mouse 320, 240
if CamAngleY# > 60.0 then CamAngleY# = 60.0
if CamAngleY# < -60.0 then CamAngleY# = -60.0
if CamAngleX# > 60.0 then CamAngleX# = 60.0
if CamAngleX# < -60.0 then CamAngleX# = -60.0
rotate camera CamAngleX#, CamAngleY#, 0.0
return
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
function FreeImage()
repeat
inc i
if image exist(i)=0 then found=1
until found
endfunction i
function NeverCalled()
if memblock exist(1) then delete memblock 1
endfunction
and some fixes for demo3-joints
`--------------------------------------------------
` NEWTON PHYSICS SDK WRAPPER
` DEMO PROJECT 3 - Joints!!
`
` Joints are one of the coolest parts of the Newton
` physics engine. They allow you to simulate many
` real world connections between rigid bodies.
`
` in this demo I show how to setup a simple version
` of each joint type available in Newton.
`
` look at the various Make...Joint() functions
` for more details!!
`
`--------------------------------------------------
`standard DBPro startup code...
sync on
sync rate 60
autocam off
set ambient light 100
set point light 0, 50, 100, -50
set light range 0, 5000
randomize timer()
`load images
`load image "..mediafloor.png",1
`set camera start point
position camera 0.0, 5.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"
`these are objects for the object dragging system..
`they have nothing to do with Newton either.
gosub MakePickObjects
`these are just some arrays for the little window that pops up to describe the joints
`onscreen. they are not used by Newton in any way.
dim JOINTS$(6)
JOINTS$(1) = "Ball/Socket Joint"
JOINTS$(2) = "Hinge Joint"
JOINTS$(3) = "Slider Joint"
JOINTS$(4) = "Corkscrew Joint"
JOINTS$(5) = "UniversalJoint"
JOINTS$(6) = "UpVector Joint"
dim JointObj(6,2)
`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
`make the ground for objects to fall on.
gosub MakeFloor
MakeBallJoint(-30.0, -5.0, 0.0)
MakeHingeJoint(-20.0, -7, 0.0)
MakeSliderJoint(-10.0, -5.0, 0.0)
MakeCorkscrewJoint(0.0, -5.0, 0.0)
MakeUniversalJoint(10.0, -5.0, 0.0)
MakeUpVectorJoint(20.0, -5.0, 0.0)
time# = NDB_GetElapsedTimeInSec()
time# = NDB_GetElapsedTimeInSec()
GO = 1
` -----------------------------------
` MAIN LOOP
` -----------------------------------
do
`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 spacekey() and SPACEPRESSED = 0 then SPACEPRESSED = 1
if SPACEPRESSED = 1
SPACEPRESSED = 2
inc GO, 1
if GO > 1 then GO = 0
endif
if spacekey()=0 then SPACEPRESSED = 0
`draw the text in the upper left part of the screen.
gosub DrawOnscreenData
`this subroutine is for moving/rotating the camera.
gosub HandleCamera
`thi subroutine allows the user to drag objects around.
gosub ObjectDragging
`this command calls the Make functions, based on keypresses.
gosub UserInput
`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
`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
MakeFloor:
` GROUND OBJECT
col = NDB_NewtonCreateBox( 1000.0, 10.0, 1000.0 )
level = NDB_NewtonCreateBody( col )
NDB_BuildMatrix 0.0, 0.0, 0.0, 0.0, -20.0, 0.0
NDB_NewtonBodySetMatrix level
obj = FreeObject()
load object "..mediabox.x", obj
position object obj, 0.0, -20.0, 0.0
scale object obj, (1000.0*100.0), (10.0*100.0), (1000.0*100.0)
scale object texture obj, 10.0, 10.0
texture object obj, 1
ghost object on obj
NDB_NewtonBodySetDestructorCallback level
NDB_BodySetDBProData level, obj
return
` FUNCTIONS ---------------------------------
`all of these MakeJoint functions are pretty similar. basically, I build 2 bodies, one with no mass (the "anchor"),
`and another with a mass of 10.0. first I place them around the origin, to make it easier to align them. then I
`add a joint between them. finally, I move the entire structure over to the X,Y,Z coordinated passed into the function.
function MakeBallJoint(x#, y#, z#)
`make 3 boxes...
Box1 = MakeBox( 0.0, 3.0, 0.0, 1.0, 6.0, 2.0, 0.0, 0.0, 1.0 )
Box2 = MakeBox( 0.0, 5.0, 0.0, 2.0, 6.0, 2.0, 0.0, 0.0, 0.0, 10.0 )
`When making a joint, temp vector 1 is usually the global position of the joint,
`and temp vector 2/3 are used for defining the direction of the joint's axis(s).
`in this case, we built our objects around the origin, so we place the ball joint at (0,0,0),
`and with the pin pointing straight down.
NDB_SetVector 1, 0.0, 0.0, 0.0
NDB_SetVector 2, 0.0, -1.0, 0.0
Joint = NDB_NewtonConstraintCreateBall( Box2, Box1 )
`the NewtonBodySetMatrixRecursive command is really cool. you set a position for a body, and it will automatically
`also update the position of any objects connected to it by joints. so by simple placing Box1 at X,Y,Z, Box2 will
`get placed with it, because they are connected by a ball joint!
`POZICIONIRANJE ZGLOBA IMA NEKI BUG
`NDB_BuildMatrix 0.0, 10.0, -90.0, x#, y#, z#
`NDB_NewtonBodySetMatrixRecursive Box1
`position object NDB_GetDBPro(Box1), x#, y#, z#
`this last part is just for my little pop-up description window, it has nothing to to with Newton itself!
`JointObj(1,1) = NDB_GetDBPro(Box1)
`JointObj(1,2) = NDB_GetDBPro(Box2)
endfunction
function MakeHingeJoint(x#, y#, z#)
Box1 = MakeBox( 0.0, 0.0, 0.0, 1.0, 1.0, 6.0, 0.0, 0.0, 0.0, 0.0 )
Box2 = MakeBox( 0.0, 0.0, 0.0, 2.0, 12.0.0, 2.0, 0.0, 0.0, 0.0, 10.0 )
NDB_SetVector 1, 0.0, 0.0, 0.0
NDB_SetVector 2, 0.0, 0.0, 1.0
Joint = NDB_NewtonConstraintCreateHinge( Box2, Box1 )
NDB_BuildMatrix 0.0, 0.0, 0.0, x#, y#, z#
NDB_NewtonBodySetMatrixRecursive Box1
position object NDB_GetDBPro(Box1), x#, y#, z#
JointObj(2,1) = NDB_GetDBPro(Box1)
JointObj(2,2) = NDB_GetDBPro(Box2)
endfunction
function MakeSliderJoint(x#, y#, z#)
Box1 = MakeBox(0.0, 0.0, 0.0, 1.0, 12.0, 0.5, 0.0, 0.0, 0.0, 0.0 )
Box2 = MakeBox(0.0, 0.0, 0.0, 2.0, 6.0, 2.0, 0.0, 0.0, 0.0, 10.0 )
NDB_SetVector 1, 0.0, 0.0, 0.0
NDB_SetVector 2, 0.0, 1.0, 0.0
Joint = NDB_NewtonConstraintCreateSlider( Box2, Box1 )
NDB_BuildMatrix 0.0, 0.0, 0.0, x#, y#, z#
NDB_NewtonBodySetMatrixRecursive Box1
position object NDB_GetDBPro(Box1), x#, y#, z#
JointObj(3,1) = NDB_GetDBPro(Box1)
JointObj(3,2) = NDB_GetDBPro(Box2)
endfunction
function MakeCorkscrewJoint(x#, y#, z#)
Box1 = MakeBox(0.0, 0.0, 0.0, 0.5, 12.0, 0.5, 0.0, 0.0, 0.0, 0.0 )
Box2 = MakeBox(0.0, 0.0, 0.0, 3.0, 6.0, 1.0, 0.0, 0.0, 0.0, 10.0 )
NDB_SetVector 1, 0.0, 0.0, 0.0
NDB_SetVector 2, 0.0, 1.0, 0.0
Joint = NDB_NewtonConstraintCreateCorkscrew( Box2, Box1 )
NDB_BuildMatrix 0.0, 0.0, 0.0, x#, y#, z#
NDB_NewtonBodySetMatrixRecursive Box1
position object NDB_GetDBPro(Box1), x#, y#, z#
JointObj(4,1) = NDB_GetDBPro(Box1)
JointObj(4,2) = NDB_GetDBPro(Box2)
endfunction
function MakeUniversalJoint(x#, y#, z#)
Box1 = MakeBox(0.0, 0.0, 0.0, 0.5, 12.0, 0.5, 0.0, 0.0, 0.0, 0.0 )
Box2 = MakeBox(0.0, 0.0, 0.0, 3.0, 3.0, 1.0, 0.0, 0.0, 0.0, 10.0 )
NDB_SetVector 1, 0.0, 0.0, 0.0
NDB_SetVector 2, 0.0, 0.0, 1.0
NDB_SetVector 3, 0.0, 1.0, 0.0
Joint = NDB_NewtonConstraintCreateUniversal( Box2, Box1 )
NDB_BuildMatrix 0.0, 0.0, 0.0, x#, y#, z#
NDB_NewtonBodySetMatrixRecursive Box1
position object NDB_GetDBPro(Box1), x#, y#, z#
JointObj(5,1) = NDB_GetDBPro(Box1)
JointObj(5,2) = NDB_GetDBPro(Box2)
endfunction
function MakeUpVectorJoint(x#, y#, z#)
`the UpVector joint is special, because it does not connect 2 rigid bodies. instead, it alters a single
`rigid body so that it will never "fall over".
Box1 = MakeBox(x#, y#, z#, 2.0, 6.0, 2.0, 0.0, 0.0, 0.0, 10.0 )
`this is the "pin" for the upvector, it won't allow the body to rotate away from this pin.
NDB_SetVector 1, 0.0, 1.0, 0.0
Joint = NDB_NewtonConstraintCreateUpVector( Box1 )
JointObj(6,1) = NDB_GetDBPro(Box1)
JointObj(6,2) = NDB_GetDBPro(Box1)
endfunction
function MakeBox(x#,y#,z#,sx#,sy#,sz#,rx#,ry#,rz#,mass#)
Col = NDB_NewtonCreateBox(sx#, sy#, sz#)
Body = NDB_NewtonCreateBody(Col)
`Set initial position and rotation
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 "..mediabox.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 MakeSphere(x#,y#,z#,s#,mass#)
Col = NDB_NewtonCreateSphere( s# )
Body = NDB_NewtonCreateBody(Col)
`Set initial position and rotation
NDB_BuildMatrix 0.0, 0.0, 0.0, x#, y#, z#
NDB_NewtonBodySetMatrix Body
NDB_CalculateMISphereSolid mass#, s#
NDB_NewtonBodySetMassMatrix Body, mass#
NDB_NewtonReleaseCollision Col
obj = FreeObject()
load object "..mediasphere.x", obj
color object obj, GetColor()
set object ambience obj, 50
scale object obj, s#*100.0, s#*100.0, s#*100.0
position object obj, x#, y#, z#
NDB_BodySetDBProData Body, obj
NDB_NewtonBodySetDestructorCallback Body
NDB_BodySetGravity Body, 1
endfunction Body
function MakeCylinder(x#,y#,z#,r#,h#,rx#,ry#,rz#,mass#)
Col = NDB_NewtonCreateCylinder( r#, h# )
Body = NDB_NewtonCreateBody(Col)
`Set initial position and rotation
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix Body
NDB_CalculateMICylinderSolid mass#, r#, h#
NDB_NewtonBodySetMassMatrix Body, mass#
NDB_NewtonReleaseCollision Col
obj = FreeObject()
load object "..mediacylinder.x", obj
color object obj, GetColor()
set object ambience obj, 50
scale object obj, h#*100.0, r#*100.0, r#*100.0
position object obj, x#, y#, z#
rotate object obj, rx#, ry#, rz#
NDB_BodySetDBProData Body, obj
NDB_NewtonBodySetDestructorCallback Body
NDB_BodySetGravity Body, 1
endfunction Body
function MakeCapsule(x#,y#,z#,r#,h#,rx#,ry#,rz#,mass#)
Col = NDB_NewtonCreateCapsule( r#, h# )
Body = NDB_NewtonCreateBody(Col)
`Set initial position and rotation
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix Body
NDB_CalculateMICylinderSolid mass#, r#, h#
NDB_NewtonBodySetMassMatrix Body, mass#
NDB_NewtonReleaseCollision Col
obj = FreeObject()
load object "..mediacap_mid.x", obj
obj2 = FreeObject()
load object "..mediacap_cap.x", obj2
make mesh from object 1, obj2
delete object obj2
add limb obj, 5, 1
add limb obj, 6, 1
rotate limb obj, 6, 0.0, 180.0, 0.0
color object obj, GetColor()
set object ambience obj, 50
position object obj, x#, y#, z#
rotate object obj, rx#, ry#, rz#
h# = h# - (r#*2)
if h# < 0.0 then h# = 0.0
scale limb obj, 2, h#*100.0, r#*100.0, r#*100.0
scale limb obj, 5, r#*100.0, r#*100.0, r#*100.0
scale limb obj, 6, r#*100.0, r#*100.0, r#*100.0
offset limb obj, 5, h#/2.0, 0.0, 0.0
offset limb obj, 6, -h#/2.0, 0.0, 0.0
NDB_BodySetDBProData Body, obj
NDB_NewtonBodySetDestructorCallback Body
NDB_BodySetGravity Body, 1
endfunction Body
function MakeCone(x#,y#,z#,r#,h#,rx#,ry#,rz#,mass#)
Col = NDB_NewtonCreateCone( r#, h# )
Body = NDB_NewtonCreateBody(Col)
`Set initial position and rotation
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix Body
NDB_CalculateMICylinderSolid mass#, r#, h#
NDB_NewtonBodySetMassMatrix Body, mass#
NDB_NewtonReleaseCollision Col
obj = FreeObject()
load object "..mediacone.x", obj
color object obj, GetColor()
set object ambience obj, 50
scale object obj, h#*100.0, r#*100.0, r#*100.0
position object obj, x#, y#, z#
rotate object obj, rx#, ry#, rz#
NDB_BodySetDBProData Body, obj
NDB_NewtonBodySetDestructorCallback Body
NDB_BodySetGravity Body, 1
endfunction Body
function MakeConvexHull(file$,x#,y#,z#,rx#,ry#,rz#,mass#)
obj = FreeObject()
load object file$, obj
Col = NDB_NewtonCreateConvexHull( obj )
Body = NDB_NewtonCreateBody(Col)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
`delete object obj
`Set initial position and rotation
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix Body
NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
NDB_NewtonBodySetMassMatrix Body, mass#
NDB_NewtonReleaseCollision Col
NDB_NewtonBodySetDestructorCallback Body
NDB_BodySetDBProData Body, obj
color object obj, GetColor()
set object ambience obj, 50
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
if memblock exist(1) then delete memblock 1
UserInput:
if lower$(inkey$()) = "b"
x# = rnd(100) - 50
y# = rnd(20) + 20
z# = rnd(5) - 2.5
sx# = rnd(5) + 1
sy# = rnd(5) + 1
sz# = rnd(5) + 1
rx# = rnd(360)
ry# = rnd(360)
rz# = rnd(360)
mass# = rnd(10) + 10.0
MakeBox(x#,y#,z#,sx#,sy#,sz#,rx#,ry#,rz#,mass#)
endif
if lower$(inkey$()) = "s"
x# = rnd(100) - 50
y# = rnd(20) + 20
z# = rnd(5) - 2.5
s# = rnd(5) + 1
mass# = rnd(10) + 10.0
MakeSphere(x#,y#,z#,s#,mass#)
endif
if lower$(inkey$()) = "c"
x# = rnd(100) - 50
y# = rnd(20) + 20
z# = rnd(5) - 2.5
r# = rnd(3) + 1
h# = rnd(5) + 1
rx# = rnd(360)
ry# = rnd(360)
rz# = rnd(360)
mass# = rnd(10) + 10.0
MakeCylinder(x#,y#,z#,r#,h#,rx#,ry#,rz#,mass#)
endif
if lower$(inkey$()) = "p"
x# = rnd(100) - 50
y# = rnd(20) + 20
z# = rnd(5) - 2.5
r# = rnd(1) + 1
h# = rnd(5) + 3
rx# = rnd(360)
ry# = rnd(360)
rz# = rnd(360)
mass# = rnd(10) + 10.0
MakeCapsule(x#,y#,z#,r#,h#,rx#,ry#,rz#,mass#)
endif
if lower$(inkey$()) = "n"
x# = rnd(100) - 50
y# = rnd(20) + 20
z# = rnd(5) - 2.5
r# = rnd(2) + 1
h# = rnd(5) + 3
rx# = rnd(360)
ry# = rnd(360)
rz# = rnd(360)
mass# = rnd(10) + 10.0
MakeCone(x#,y#,z#,r#,h#,rx#,ry#,rz#,mass#)
endif
if lower$(inkey$()) = "h"
x# = rnd(100) - 50
y# = rnd(20) + 20
z# = rnd(100) - 50
rx# = rnd(360)
ry# = rnd(360)
rz# = rnd(360)
mass# = rnd(10) + 10.0
set dir "..mediahulls"
perform checklist for files
filecount = checklist quantity()
repeat
file = rnd(filecount-1)+1
filen$ = checklist string$(file)
until right$(filen$,1) = "x"
MakeConvexHull(filen$,x#,y#,z#,rx#,ry#,rz#,mass#)
write string 5, filen$
set dir "....demo02 - collision primitives"
endif
return
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,"JOINTS DEMO"
text 10,35," [B]ox | [S]phere | [C]ylinder | ca[P]sule | co[N]e | convex [H]ull"
text 10,45," hold CTRL for debug data | drag RMB to move bodies"
text 10,55," Drag Mouse to look | Arrows to move | Space to (un)pause"
text 10,65," 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)
`little text window describing joint types
obj = pick object(mousex(), mousey(), 1, 100)
if obj <> 0
for i=1 to 6
for j=1 to 2
if obj = JointObj(i,j)
`mouse is over a joint object, make pop-up window
x = mousex() + 15
y = mousey() + 5
w=80
h=13
box x,y,x+w,y+h,rgb(0,0,0),rgb(100,100,100),rgb(0,0,0),rgb(100,100,100)
line x,y,x+w,y
line x,y,x,y+h
line x+w,y,x+w,y+h
line x,y+h,x+w,y+h
text x+2,y+1,JOINTS$(i)
endif
next j
next i
endif
return
HandleCamera:
`-------------------------
`CAMERA
`-------------------------
if upkey() then move camera 1.0
if downkey() then move camera -1.0
if leftkey()
turn camera left 90.0
move camera 1.0
turn camera right 90.0
endif
if rightkey()
turn camera right 90.0
move camera 1.0
turn camera left 90.0
endif
if mouseclick()=1 and MOUSE = 0
MOUSE = 1
dump = mousemovex()
dump = mousemovey()
endif
if mouseclick()=1 and MOUSE = 1
inc CamAngleX#, mousemovey()
inc CamAngleY#, mousemovex()
rotate camera CamAngleX#, CamAngleY#, 0.0
endif
return
ObjectDragging:
`this part is for object dragging... slightly complicated, ignore it if you don't understand it! :P
if mouseclick() = 2 and MOUSE = 0
MOUSE = 1
`shoot a ray!
raydist# = 350.0
pick screen mousex(), mousey(), raydist#
x1# = camera position x() : y1# = camera position y() : z1# = camera position z()
x2# = x1# + get pick vector x() : y2# = y1# + get pick vector y() : z2# = z1# + get pick vector z()
unitx# = (x2#-x1#) / raydist# : unity# = (y2#-y1#) / raydist# : unitz# = (z2#-z1#) / raydist#
NDB_SetVector 1, x1#, y1#, z1#
NDB_SetVector 2, x2#, y2#, z2#
dist# = NDB_NewtonWorldRayCast( 1 )
if dist# > 1.0
MOUSE = 0
DragBody = 0
hide object PickObj1
hide object PickObj2
return
endif
Body = NDB_RayCastGetBody()
GrabDist# = dist#*raydist#
x# = x1# + (unitx#*GrabDist#)
y# = y1# + (unity#*GrabDist#)
z# = z1# + (unitz#*GrabDist#)
position object PickObj2, x#, y#, z#
DragBody = body
DragObj = NDB_GetDBPro(body)
`okay get the rotation matrix for the body.
NDB_NewtonWorldUnFreezeBody DragBody
NDB_NewtonBodySetAutoFreeze DragBody, 0
NDB_NewtonBodyGetMatrix DragBody
NDB_SetVector 1, x#, y#, z#
`unrotate the point by this matrix
NDB_UntransformVector 1, 1
`now vector2 should be the local point of contact!
GrabX# = NDB_GetVector_X(1)
GrabY# = NDB_GetVector_Y(1)
GrabZ# = NDB_GetVector_Z(1)
show object PickObj2
show object PickObj1
endif
if mouseclick()=2 and MOUSE = 1
if DragBody <> 0
`drag the object here!
NDB_NewtonBodyGetMatrix DragBody
NDB_SetVector 1, GrabX#, GrabY#, GrabZ#
NDB_TransformVector 1, 2
x1# = NDB_GetVector_X(2)
y1# = NDB_GetVector_Y(2)
z1# = NDB_GetVector_Z(2)
position object PickObj1, x1#, y1#, z1#
pick screen mousex(), mousey(), GrabDist#
x2# = camera position x() + get pick vector x()
y2# = camera position y() + get pick vector y()
z2# = camera position z() + get pick vector z()
position object PickObj2, x2#, y2#, z2#
`calculate the force between the points
DragX# = (x2# - x1#) * 50.0
DragY# = (y2# - y1#) * 50.0
DragZ# = (z2# - z1#) * 50.0
NDB_NewtonBodyGetVelocity DragBody
dec DragX#, NDB_GetVector_X()*(2)
dec DragY#, NDB_GetVector_Y()*(2)
dec DragZ#, NDB_GetVector_Z()*(2)
`setup global force.
NDB_SetVector 1, x1#, y1#, z1#
NDB_SetVector 2, DragX#, DragY#, DragZ#
NDB_BodyAddForceGlobal DragBody
if object in screen(PickObj1)
line mousex(), mousey(), object screen x(PickObj1), object screen y(PickObj1)
endif
endif
endif
if mouseclick() = 0
MOUSE = 0
hide object PickObj1
hide object PickObj2
if DragBody <> 0
NDB_NewtonBodySetAutoFreeze DragBody, 1
DragBody = 0
endif
GrabX# = 0.0
GrabY# = 0.0
GrabZ# = 0.0
DragX# = 0.0
DragY# = 0.0
DragZ# = 0.0
GrabDist# = 0.0
endif
return
MakePickObjects:
`PickObjects
PickObj1 = FreeObject()
make object sphere PickObj1, 0.5
set object emissive PickObj1, rgb(255,255,0)
set object ambience PickObj1, 100
hide object PickObj1
PickObj2 = FreeObject()
make object sphere PickObj2, 0.5
set object emissive PickObj2, rgb(255,0,255)
set object ambience PickObj2, 100
hide object PickObj2
return
Posting demo5 code tags makes some erors so I have ziped it.
The friction is low,but there is no more "spring" efect.
Hope this solves your problem.
Nikola