Hello there,
Well i will be away for a loooong time because i need to do my military service, meanwhile i felt like i should leave these series of tutorials about Newton and DBPro programming so maybe it will help some people here.This is not very advanced, so those experienced guys should not expect much, but not very newbie stuff either and surely can find something for yourself too and do not hesitate correcting mistakes.
Okay here we go:
What you need:
1-DBPro 5.8
2-Newton wrapper 1.32 installed
(will add more when we need them
)
Important Stuff:
1- Dark basic reads lines just like you read a book;
line by line so writing the commands have to follow an order.
2- Always use variables with prefix like (pthLevels, mdlEnemy...etc)
3- working with include files and Sub routines makes your life easier and makes your code re-usable
(will add more when i realise them
)
NEWTON ENVIRONMENT CREATION
1.PART:
1- Create a blank project with the name you want in your projects folder.And start typing the following code, type it yourself instead copy/paste so you can get used to some commands.
with this code we define some variables to be GLOBAL incase we may need them later on.
These variables are path variables(prefix: pth)
pthRoot = current folder we are working on, and will be the folder wherever the user installs or copies your program with the help of the command
GET DIR$()
pthBin = will be a folder we will create in your project folder to keep included files, if we include some
pthMdl = models folder
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
I believe i dont need to explain what the above do.
2- Now we keep adding some more variables we will need further on
(prefix: scr) is shortly "screen"
simply we set screenfps, screen fov, screen width..etc variables here.
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
Now your code should look somethin like this:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
3- And then we shall set the screen commands with the variables above:
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
And your code should look like this:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
2.PART:
1- Now is a good time to setup Newton in our program, and we better make a new include file in our "Bin" Folder, to keep things less complicated and more re-usable.
Now lets first create a folder named "Bin" in our project folder and Lets add a new source file called "Newton.dba" in this new folder.
So we are ready to work in our new file now, this file will contain some re-usable subroutines for any future newton projects.
Open the Newton.dba and start entering the following code:
2- First we make 3 subroutines as follows
prepareNewton:
RETURN
debugNewton:
RETURN
destroyNewton:
RETURN
4.2- And we start with the prepareNewton routine
(Prefix n = newton)
prepareNewton:
`---------------------------------------------------------
REM SOME VARIABLES WE WILL NEED
`---------------------------------------------------------
nFps = scrFps `Newton screen fps(we need it)
nGravity# = -98.0 `Gravity variable
nFluidDensity# = 0.9 `Buoyancy variable
nFluidLinearVisc# = 0.5 `Buoyancy variable
nFluidAngularVisc# = 0.5 `Buoyancy variable
nWorldSize# = 5000.0 `Newton Environment Size
`---------------------------------------------------------
REM CREATE NEWTON AND SET GRAVITY, BUOYANCY AND FRAME RATE
`---------------------------------------------------------
REM Newton Creation
NDB_NewtonCreate `Creates newton environment must be called before any other newton commands
REM Newton Gravity
NDB_SetVector 0.0, nGravity#, 0.0
NDB_SetStandardGravity
REM Newton Buoyancy
NDB_GetStandardGravity
NDB_SetStandardLiquid nFluidDensity#, nFluidLinearVisc#, nFluidAngularVisc#
REM NEwtons minimum frame rate
NDB_NewtonSetMinimumFrameRate nFps
REM NEwton World Box
NDB_SetVector 1, -nWorldSize#, -nWorldSize#, -nWorldSize#
NDB_SetVector 2, nWorldSize#, nWorldSize#, nWorldSize#
NDB_NewtonSetWorldSize
NDB_NewtonSetBodyLeaveWorldEvent 1 `what happens when an object leaves the newton world(it gets destroyed)
RETURN
NEwton has support for different materials,(read newton help files for further explanation)
We will use these materials later in our program, but we will do the creation here at the very beginning just so i can finish this tutorial faster.
Edit the
prepareNewton routine as follows:
prepareNewton:
`---------------------------------------------------------
REM VARIABLES
`---------------------------------------------------------
nFps = scrFps
nGravity# = -98.0
nFluidDensity# = 0.9
nFluidLinearVisc# = 0.5
nFluidAngularVisc# = 0.5
nWorldSize# = 5000.0
`---------------------------------------------------------
REM CREATE NEWTON AND SET GRAVITY, BUOYANCY AND FRAME RATE
`---------------------------------------------------------
NDB_NewtonCreate
NDB_SetVector 0.0, nGravity#, 0.0
NDB_SetStandardGravity
NDB_GetStandardGravity
NDB_SetStandardLiquid nFluidDensity#, nFluidLinearVisc#, nFluidAngularVisc#
NDB_NewtonSetMinimumFrameRate nFps
`---------------------------------------------------------
REM SET NEWTON WORLD
`---------------------------------------------------------
NDB_SetVector 1, -nWorldSize#, -nWorldSize#, -nWorldSize#
NDB_SetVector 2, nWorldSize#, nWorldSize#, nWorldSize#
NDB_NewtonSetWorldSize
NDB_NewtonSetBodyLeaveWorldEvent 1
`---------------------------------------------------------
REM SET NEWTON MATERIALS
`---------------------------------------------------------
Rem HERE WE CREATE SEVERAL DIFFERENT MATERIAL GROUPS
nMatDefault = NDB_NewtonMaterialGetDefaultGroupID()
nMatPlayer = NDB_NewtonMaterialCreateGroupID()
nMatWater = NDB_NewtonMaterialCreateGroupID()
nMatWood = NDB_NewtonMaterialCreateGroupID()
nMatMetal = NDB_NewtonMaterialCreateGroupID()
REM AND HERE WE SET UP THESE MATERIALS AND THE RELATIONS BETWEEN THEM
REM HERE I JUST LET NEWTON KNOW THAT IT SHOULD KEEP TRACK OF nMatPlayer to other materials
`what happens when nMatPlayer has collision with nMatDefault
NDB_NewtonMaterialSetDefaultFriction nMatPlayer, nMatDefault, 0.7, 0.5
NDB_NewtonMaterialSetDefaultElasticity nMatPlayer, nMatDefault, 0.5
`what happens when nMatPlayer has collision with nMatWater
NDB_NewtonMaterialSetDefaultFriction nMatPlayer, nMatWater, 0.7, 0.5
NDB_NewtonMaterialSetDefaultElasticity nMatPlayer, nMatWater, 0.5
`what happens when nMatPlayer has collision with nMatWood
NDB_NewtonMaterialSetDefaultFriction nMatPlayer, nMatWood, 0.7, 0.5
NDB_NewtonMaterialSetDefaultElasticity nMatPlayer, nMatWood, 0.5
`what happens when nMatPlayer has collision with nMatMetal
NDB_NewtonMaterialSetDefaultFriction nMatPlayer, nMatMetal, 0.7, 0.5
NDB_NewtonMaterialSetDefaultElasticity nMatPlayer, nMatMetal, 0.5
`---------------------------------------------------------
REM FINISH NEWTON CREATION
`---------------------------------------------------------
RETURN
Okay we are finished with the creation part.
3.PART:
1-We have done with the newton creation and the subroutine, so we can now add this to our main.dba file
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
GOSUB prepareNewton
2- But hey, i think we will need these material variables later on, so lets make them global too
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
GOSUB prepareNewton
3- Now lets add our loop to the main file
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
GOSUB prepareNewton
`*/-------------------/
DO
LOOP
`/-------------------/*
4.PART:
1- Newton has debugging, so lets set it up first and we can use it later on.Go back to Newton.dba
go to debugNewton subroutine, thats where we will add code now
and change it as follows:
debugNewton:
`---------------------------------------------------------
REM DEBUG NEWTON - F12 KEY
`---------------------------------------------------------
if scancode() = 88 and N_DEBUG_ON = 0 then N_DEBUG_ON = 1
if N_DEBUG_ON = 1
N_DEBUG_ON = 2
inc N_Debug, 1
if N_Debug > 1 then N_Debug = 0
endif
if keystate(88) = 0 then N_DEBUG_ON = 0
if N_Debug = 1
obj = NDB_DebugMakeNewtonObject()
SET OBJECT LIGHT obj, 0
else
obj = 0
endif
`---------------------------------------------------------
REM SYNC SCREEN
`---------------------------------------------------------
sync
if obj <> 0
DELETE OBJECT obj
endif
`---------------------------------------------------------
REM FINISH NEWTON DEBUGGING
`---------------------------------------------------------
RETURN
Now when we will press F12 key on your keyboard, we will debug newton, dont ask how now, ill explain it later.
2- Now lets go back to main.dba and add this new subroutine to the veeery end of the loop
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
GOSUB prepareNewton
`*/-------------------/
DO
GOSUB debugNewton
LOOP
`/-------------------/*
3- While we are there, lets add the final newton subroutine to the exit of the loop:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
GOSUB prepareNewton
`*/-------------------/
DO
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
we added an empty routine to the end, so lets go to Newton.dba and fill it, open Newton.dba in the included files and edit destroyNewton routine as follows:
`---------------------------------------------------------
REM DESTROY NEWTON AND END THE PROGRAM
`---------------------------------------------------------
NDB_NewtonDestroy
END
`---------------------------------------------------------
REM BYE BYE
`---------------------------------------------------------
This will make sure we first destroy the newton environment and then exit the program when user presses ESC Key
Now you have set up the newton environment perfectly, and can compile the program to see a black blank screen
later on ill explain object creation
To be continued..
NEWTON OBJECTS CREATION
1.PART:
Newton objects are actually collision data for your visual DBPRo objects and there are many of them such as, empty, box, sphere, cylinders, capsules, cones, convexhull, compound and tree collision.
but before we go into these, we need some functions for our actual program to make things easier, i wont explain these functions, and i didnt make them but i found them somewhere in this forum and credits goes to the author.
Lets make a new include file in our "Bin" folder to hold such functions concerning the DBPRo environment.
1- Add a new file called "gameFunctions.dba" in your "Bin" Folder and open it for editing.
2-Paste the following function in it and save.
`---------------------------------------------------------
Function free_object()`This function increases i value up until it finds a free object number available
Repeat
Inc i
Until Object Exist(i) = 0
EndFunction i
well, why dont we make a smiliar function for all available DBPRo stuff like images, sprites...etc
change the "gameFunctions.Dba" as follows:
`---------------------------------------------------------
Function free_dll()
Repeat
Inc i
Until DLL Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_memblock()
Repeat
Inc i
Until MemBlock Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_object()
Repeat
Inc i
Until Object Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_sound()
Repeat
Inc i
Until Sound Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_music()
Repeat
Inc i
Until Music Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_animation()
Repeat
Inc i
Until Animation Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_bitmap()
Repeat
Inc i
Until Bitmap Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_effect()
Repeat
Inc i
Until Effect Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_image()
Repeat
Inc i
Until Image Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_light()
Repeat
Inc i
Until Light Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_limb()
Repeat
Inc i
Until Limb Exist(i,i) = 0
EndFunction i
`---------------------------------------------------------
Function free_matrix()
Repeat
Inc i
Until Matrix Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_mesh()
Repeat
Inc i
Until Mesh Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_pixelshader()
Repeat
Inc i
Until Pixel Shader Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_particles()
Repeat
Inc i
Until Particles Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_sprite()
Repeat
Inc i
Until Sprite Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_terrain()
Repeat
Inc i
Until Terrain Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_vertexshader()
Repeat
Inc i
Until Vertex Shader Exist(i) = 0
EndFunction i
`---------------------------------------------------------
Function free_file()
Repeat
Inc i
Until File Open(i) = 0
EndFunction i
`---------------------------------------------------------
now it will be very easy and automatic for any file creation.
Example usage:
obj = free_object()
load object "myObject.x", obj
2.PART:
Now, functions are very useful and very re-usable, they will help you write less code.
so we want to make whole newton object creation into functions which means we wont need to type same code for every visual object we create.
1- now lets create another include file in our "Bin" folder with the name "newtonFunctions.dba"
this file will hold functions for newton collision data creation and will be totally automated, which means we wont need to pay attention on newton as much as to our actual game.
2- lets edit this new file and create a function inside as follows:
now what we need for this function, is:
obj = object number that we want to work on
mass# = objects mass
Gravity = if the object will be effected with gravity or not
buoyancy = if the object will be effected with buoyancy or not
nMaterial = which collision material will the object use
function newtonCollisionForBox(obj, mass#, Gravity, buoyancy, nMaterial)
`TODO CREATE Box collision for newton here
EndFunction
As Dbpro reads the program line by line, at the beginning of the function lets get objects visual data:
function newtonCollisionForBox(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
EndFunction
as we know enough of the object, lets create the collision data for it now:
(i dont need to explain the commands i believe, but the order of the commands is important.)
function newtonCollisionForBox(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateBox(sx#, sy#, sz#) `Col newton primitive
nBody = NDB_NewtonCreateBody(Col) `nBody is the collision data
EndFunction
what we need now is a math matrix to hold rotation and position data of this collision
function newtonCollisionForBox(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateBox(sx#, sy#, sz#) `Col newton primitive
nBody = NDB_NewtonCreateBody(Col) `nBody is the collision data
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix nBody
NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
NDB_NewtonBodySetMassMatrix nBody, mass#
EndFunction
now we can link the visual object to newton collision data
function newtonCollisionForBox(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateBox(sx#, sy#, sz#) `Col newton primitive
nBody = NDB_NewtonCreateBody(Col) `nBody is the collision data
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix nBody
NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
NDB_NewtonBodySetMassMatrix nBody, mass#
NDB_NewtonReleaseCollision Col `we dont need newton primitive anymore
NDB_BodySetDBProData nBody, obj `we link the newton obj to visual obj
NDB_NewtonBodySetDestructorCallback nBody `if newton obj leaves the world borders, it destroys itself and the linked visual object as well
EndFunction
The object has been created, now all we have to do is define if it will get affected by gravity, buoyancy and set its material
function newtonCollisionForBox(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateBox(sx#, sy#, sz#) `Col newton primitive
nBody = NDB_NewtonCreateBody(Col) `nBody is the collision data
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix nBody
NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
NDB_NewtonBodySetMassMatrix nBody, mass#
NDB_NewtonReleaseCollision Col `we dont need newton primitive anymore
NDB_BodySetDBProData nBody, obj `we link the newton obj to visual obj
NDB_NewtonBodySetDestructorCallback nBody `if newton obj leaves the world borders, it destroys itself and the linked visual object as well
NDB_BodySetGravity nBody, Gravity
if Buoyancy > 0
NDB_BodySetBuoyancy nBody, Buoyancy
NDB_SetVector 1, 0.0, 10.0, 0.0, 0.0 `buoyancy plain is at y=10, you can change this value to your need.
NDB_BodySetBuoyancyPlane nBody
endif
NDB_NewtonBodySetMaterialGroupID nBody, nMaterial
EndFunction
as the function is ready to use now, we better get the id of the newton data for further use, just change the last line
function newtonCollisionForBox(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateBox(sx#, sy#, sz#) `Col newton primitive
nBody = NDB_NewtonCreateBody(Col) `nBody is the collision data
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix nBody
NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
NDB_NewtonBodySetMassMatrix nBody, mass#
NDB_NewtonReleaseCollision Col `we dont need newton primitive anymore
NDB_BodySetDBProData nBody, obj `we link the newton obj to visual obj
NDB_NewtonBodySetDestructorCallback nBody `if newton obj leaves the world borders, it destroys itself and the linked visual object as well
NDB_BodySetGravity nBody, Gravity
if Buoyancy > 0
NDB_BodySetBuoyancy nBody, Buoyancy
NDB_SetVector 1, 0.0, 10.0, 0.0, 0.0 `buoyancy plain is at y=10, you can change this value to your need.
NDB_BodySetBuoyancyPlane nBody
endif
NDB_NewtonBodySetMaterialGroupID nBody, nMaterial
EndFunction nBody
here, our first newton function is ready to serve.
ADDING FREE MOTION CAMERA TO OUR PROGRAM
1.PART:
Again make a new include file in our "Bin" directory with the name "Camera.dba", and open to edit and just add the following camera routine for a free motion camera
(wasd keys and mouse)
Camera_Setup:
dummyCam = 997
Cam_Start_X# = 0.0
Cam_Start_Y# = 20.0
Cam_Start_Z# = -20.0
MAKE OBJECT BOX dummyCam, 5, 5, 5 : HIDE OBJECT dummyCam
REM POSITION THE START CAMERA
POSITION OBJECT dummyCam, Cam_Start_X#, Cam_Start_Y#, Cam_Start_Z#
camMoveSpeed# = 1.0 : mouseSpeed = 4
RETURN
`-----------FREE CAMERA LOOP-----------
Camera_Free_Loop:
if shiftkey() > 0
inc camMoveSpeed#, 0.1
if camMoveSpeed# => 10.0 then camMoveSpeed# = 10.0
else
if camMoveSpeed# > 1.0
dec camMoveSpeed#, 0.1
if camMoveSpeed# =< 1.0 then camMoveSpeed# = 1.0
endif
endif
if keystate(17)=1 then MOVE OBJECT dummyCam, camMoveSpeed#
if keystate(30)=1 then MOVE OBJECT LEFT dummyCam, camMoveSpeed#
if keystate(31)=1 then MOVE OBJECT dummyCam, -camMoveSpeed#
if keystate(32)=1 then MOVE OBJECT RIGHT dummyCam, camMoveSpeed#
rem camera rotation
camAngX# = wrapvalue((mousemovey() / mouseSpeed) + camAngX#)
camAngY# = wrapvalue((mousemovex() / mouseSpeed) + camAngY#)
rem stops mouse from going upside down
if camAngX# > 80 and camAngX# < 180 then camAngX# = 80
if camAngX# > 180 and camAngX# < 310 then camAngX# = 310
ROTATE OBJECT dummyCam, camAngX#, camAngY#, object angle z(dummyCam)
camPosX# = object position x(dummyCam)
camPosY# = object position y(dummyCam)
camPosZ# = object position z(dummyCam)
camAngX# = object angle x(dummyCam)
camAngY# = object angle y(dummyCam)
camAngZ# = object angle z(dummyCam)
POSITION CAMERA 0, camPosX#, camPosY#, camPosZ#
ROTATE CAMERA 0, camAngX#, camAngY#, object angle z(dummyCam)
RETURN
after then, we shall call these routines in our main.dba
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
GOSUB Camera_Setup `Camera create
`*/-------------------/
DO
GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
Well, enough for today, to summarise, we have newton set properly and a working camera.
we are ready to visualise the environment with newton now, but you need to give me couple of hours to rest
NEWTON OBJECTS CREATION 2
1.PART:
Now we are ready to create some objects, we will work on the main.dba file
our object creation is simple as this
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 2.0, 1, 0, nMatDefault)
why dont you just add this to your main.dba and see your new box object (it will look static for the moment but we will fix it in a minute)
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
GOSUB Camera_Setup `Camera create
REM CREATE NEWTON OBJECTS HERE
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 2.0, 1, 0, nMatDefault)
`*/-------------------/
DO
GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
your box wont react because we did not tell newton to start working yet.
so lets make it get effected:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
GOSUB Camera_Setup `Camera create
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 2.0, 1, 0, nMatDefault)
`*/-------------------/
`SET THE NEWTON TIMER START
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
DO
`SET THE NEWTON TIMER TO UPDATE
nTime# = NDB_GetElapsedTimeInSec()
NDB_NewtonUpdate nTime#
GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
a nice falling box, it will keep falling down until y is smaller than the newton world size we set before in the prepare newton part.
then both the newton data and visual object will be destroyed and cleaned out of the memory.
Now why dont you change the newton object to be effected by buoyancy and watch whats happening. and meanwhile alittle visualisation for the buoyancy plain might help you see it:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
GOSUB Camera_Setup `Camera create
REM VISUALISE THE BUOYANCY PLANE
obj = free_object()
make object plain obj, 10000, 10000
xrotate object obj, 90
position object obj, 0, 10, 0 `remember we set the buoyancy plain to y=10
ghost object on obj, 1
REM CREATE NEWTON OBJECTS HERE
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 2.0, 1, 1, nMatDefault)
`*/-------------------/
`SET THE NEWTON TIMER START
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
DO
`SET THE NEWTON TIMER TO UPDATE
nTime# = NDB_GetElapsedTimeInSec()
NDB_NewtonUpdate nTime#
GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
now, why dont you try messing with the mass# value and add some rotation on the z axis forexample and watch the results
Okay, this is it with the buoyancy, now i shall delete the buoyancy for the rest of the tutorial and show you something else.
But first lets add another function for the newton using the same style but this time lets create a sphere object.
open the "newtonFunctions.dba" and add a new function just like the following:
`---------------------------------------------------------
Function newtonCollisionForSphere(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateSphere( sx#/2.0, sy#/2.0, sz#/2.0 ) `we need to know the half value of the radius
nBody = NDB_NewtonCreateBody(Col)
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix nBody
NDB_CalculateMISphereSolid mass#, sy#/2.0
NDB_NewtonBodySetMassMatrix nBody, mass#
NDB_NewtonReleaseCollision Col
NDB_BodySetDBProData nBody, obj
NDB_NewtonBodySetDestructorCallback nBody
NDB_BodySetGravity nBody, Gravity
if Buoyancy > 0
NDB_BodySetBuoyancy nBody, buoyancy
NDB_SetVector 1, 0.0, 10.0, 0.0, 0.0 `buoyancy plain is at y=10, you can change this value to your need.
NDB_BodySetBuoyancyPlane nBody
endif
NDB_NewtonBodySetMaterialGroupID nBody, nMaterial
EndFunction nBody
`---------------------------------------------------------
Now we can create sphere objects, and if you check the code you can see its very smiliar to the box object.
Lets go back to "main.dba" and clean up the water plain and add a solid ground plain with the help of newton box function:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
GOSUB Camera_Setup `Camera create
REM VISUALISE THE SOLID GROUND PLAIN
obj = free_object()
make object box obj, 10000, 10, 10000
position object obj, 0, -5, 0
color object obj, rgb(10,100,10)
`gravity and mass 0 means object is a static box
newtonCollisionForBox(obj, 0.0, 0, 0, nMatDefault)
REM CREATE NEWTON OBJECTS HERE
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 200.0, 1, 0, nMatDefault)
`*/-------------------/
`SET THE NEWTON TIMER START
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
DO
`SET THE NEWTON TIMER TO UPDATE
nTime# = NDB_GetElapsedTimeInSec()
NDB_NewtonUpdate nTime#
REM SOME INFO HERE
text 0, 0, "press F12 key to debug newton on or off"
GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
its easy to add a sphere object here now:
(add it in the main.dba where we should create newton objects)
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
GOSUB Camera_Setup `Camera create
REM VISUALISE THE SOLID GROUND PLAIN
obj = free_object()
make object box obj, 10000, 10, 10000
position object obj, 0, -5, 0
color object obj, rgb(10,100,10)
`gravity and mass 0 means object is a static box
newtonCollisionForBox(obj, 0.0, 0, 0, nMatDefault)
REM CREATE NEWTON OBJECTS HERE
`BOX OBJECT
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 200.0, 1, 0, nMatDefault)
`SPHERE OBJECT
obj = free_object()
make object sphere obj, 10
position object obj, 0, 150, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForSphere(obj, 100.0, 1, 0, nMatDefault)
`*/-------------------/
`SET THE NEWTON TIMER START
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
DO
`SET THE NEWTON TIMER TO UPDATE
nTime# = NDB_GetElapsedTimeInSec()
NDB_NewtonUpdate nTime#
text 0, 0, "press F12 key to debug newton on or off"
GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
SOME MORE NEWTON FUNCTIONS BELOW
Following are couple more functions that you can include to your "newtonFunctions.dba"
(Convex hulls, tree collision and an innocent function to include memblock.dlls to our program that tree collision needs)
`---------------------------------------------------------
Function newtonCollisionForConvexHull(obj, mass#, Gravity, buoyancy, nMaterial)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateConvexHull( obj )
nBody = NDB_NewtonCreateBody(Col)
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix nBody
NDB_CalculateMIBoxSolid mass#, sx#, sy#, sz#
NDB_NewtonBodySetMassMatrix nBody, mass#
NDB_NewtonReleaseCollision Col
NDB_BodySetDBProData nBody, obj
NDB_NewtonBodySetDestructorCallback nBody
NDB_NewtonBodySetAutoFreeze nBody, 0
NDB_BodySetGravity nBody, Gravity
if Buoyancy > 0
NDB_BodySetBuoyancy nBody, buoyancy
NDB_SetVector 1, 0.0, 10.0, 0.0, 0.0 `buoyancy plain is at y=10, you can change this value to your need.
NDB_BodySetBuoyancyPlane nBody
endif
NDB_NewtonBodySetMaterialGroupID nBody, nMaterial
EndFunction nBody
`---------------------------------------------------------
Function newtonCollisionForTreeCollision(obj, limbs)
x# = object position x(obj)
y# = object position y(obj)
z# = object position z(obj)
sx# = object size x(obj)
sy# = object size y(obj)
sz# = object size z(obj)
rx# = object angle x(obj)
ry# = object angle y(obj)
rz# = object angle z(obj)
Col = NDB_NewtonCreateTreeCollision( obj, limbs )
nStatic = NDB_NewtonCreateBody( Col )
NDB_BuildMatrix rx#, ry#, rz#, x#, y#, z#
NDB_NewtonBodySetMatrix nStatic
NDB_NewtonReleaseCollision Col
NDB_BodySetDBProData nStatic, obj
NDB_NewtonBodySetDestructorCallback nStatic
NDB_NewtonBodySetMaterialGroupID nStatic, nMatDefault
EndFunction nStatic
`---------------------------------------------------------
Function NewtonNeverCalled()
Rem we need this for tree collision
if memblock exist(1) then end
if mesh exist (1) then end
EndFunction
`---------------------------------------------------------
MORE NEWTON OBJECTS
Before we create more objects, you better read the newton manual for the above convexhull and treecollision datas, then you will probably understand what they are for. All i can say is, we will use tree collision for static objects like game levels.
oh, by the way our functions return values for the newton objects id's, so lets make them
global in our main.dba too:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nBody
GLOBAL nStatic
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
GOSUB Camera_Setup `Camera create
REM VISUALISE THE SOLID GROUND PLAIN
obj = free_object()
make object box obj, 10000, 10, 10000
position object obj, 0, -5, 0
color object obj, rgb(10,100,10)
`gravity and mass 0 means object is a static box
newtonCollisionForBox(obj, 0.0, 0, 0, nMatDefault)
REM CREATE NEWTON OBJECTS HERE
`BOX OBJECT
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 200.0, 1, 0, nMatDefault)
`SPHERE OBJECT
obj = free_object()
make object sphere obj, 10
position object obj, 0, 150, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForSphere(obj, 100.0, 1, 0, nMatDefault)
`*/-------------------/
`SET THE NEWTON TIMER START
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
DO
`SET THE NEWTON TIMER TO UPDATE
nTime# = NDB_GetElapsedTimeInSec()
NDB_NewtonUpdate nTime#
text 0, 0, "press F12 key to debug newton on or off"
GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
1.PART
First lets steal some code from Walaber's demos for interaction with newton objects (i wont explain this part, because its more maths rather than newton and you should try to understand it yourself.)
1- Lets make a new include file called "newtonInteraction.dba" in our "Bin" Folder, just to keep things tidy.
And Paste the following in it:
HandleCamera:
`-------------------------
`CAMERA
`-------------------------
if scancode() = 17 then move camera 1.0
if scancode() = 31 then move camera -1.0
if scancode() = 30
turn camera left 90.0
move camera 1.0
turn camera right 90.0
endif
if scancode() = 32
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 = Free_Object()
make object sphere PickObj1, 0.5
set object emissive PickObj1, rgb(255,255,0)
set object ambience PickObj1, 100
hide object PickObj1
PickObj2 = Free_Object()
make object sphere PickObj2, 0.5
set object emissive PickObj2, rgb(255,0,255)
set object ambience PickObj2, 100
hide object PickObj2
return
2- Lets edit our "main.dba" to include these new sub routines
(meanwhile we will rem out some of ours to prevent camera routines to intersect)
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nBody
GLOBAL nJoint
GLOBAL nStatic
GLOBAL nPlayer
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
GOSUB MakePickObjects
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
`GOSUB Camera_Setup `Camera create
REM VISUALISE THE SOLID GROUND PLAIN
obj = free_object()
make object box obj, 10000, 10, 10000
position object obj, 0, -5, 0
color object obj, rgb(10,100,10)
`gravity and mass 0 means object is a static box
newtonCollisionForBox(obj, 0.0, 0, 0, nMatDefault)
REM CREATE NEWTON OBJECTS HERE
`BOX OBJECT
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 200.0, 1, 0, nMatDefault)
`SPHERE OBJECT
obj = free_object()
make object sphere obj, 10
position object obj, 0, 150, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForSphere(obj, 100.0, 1, 0, nMatDefault)
`*/-------------------/
`SET THE NEWTON TIMER START
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
DO
`SET THE NEWTON TIMER TO UPDATE
nTime# = NDB_GetElapsedTimeInSec()
NDB_NewtonUpdate nTime#
text 0, 0, "press F12 key to debug newton on or off"
GOSUB HandleCamera
GOSUB ObjectDragging
`GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
Now you should be able to use your mouse2 button to interact with newton objects.
NEWTON JOINTS
1 - A Hanging Lamp using joints
here is a cool looking, untextured hanging lamp, you can watch it swing by any force applied to it
1.1- download the attached media and extract it in the "mdl" folder in your project (if it doesnt exist, create the folder)
1.2- add the following function to your "newtonFunctions.dba"
`---------------------------------------------------------
Function NewtonLamp(x#, y#, z#)
REM DUMMY
obj = free_object()
MAKE OBJECT CUBE obj, 2
POSITION OBJECT obj, 0, 1, 0
jDummy = newtonCollisionForBox(obj, 0.0, 1, 0, nMatDefault)
REM ROPES
SET DIR pthMdl
obj = free_object()
LOAD OBJECT "lampRope.x", obj
s1# = object size y(obj)
POSITION OBJECT obj, 0.0, (s1#/2.0)*-1, 0.0
jOne = newtonCollisionForBox(obj, 0.5, 1, 0, nMatDefault)
obj = free_object()
LOAD OBJECT "lampRope.x", obj
s1# = object size y(obj)
POSITION OBJECT obj, 0.0, (s1#/2.0)*-3, 0.0
jTwo = newtonCollisionForBox(obj, 0.5, 1, 0, nMatDefault)
obj = free_object()
LOAD OBJECT "lamp.x", obj
s2# = object size y(obj)
POSITION OBJECT obj, 0.0, ((s1#/2.0)*-4)+((s2#/2.0)*-1), 0.0
jLamp = newtonCollisionForBox(obj, 0.5, 1, 0, nMatDefault)
SET DIR pthRoot
REM JOINTS
NDB_SetVector 1, 0.0, 0.0, 0.0
NDB_SetVector 2, 0.0, -1.0, 0.0
nJoint = NDB_NewtonConstraintCreateBall( jOne, jDummy )
NDB_SetVector 1, 0.0, (s1#/2.0)*-2, 0.0
NDB_SetVector 2, 0.0, ((s1#/2.0)*-2)-1.0, 0.0
nJoint = NDB_NewtonConstraintCreateBall( jTwo, jOne )
NDB_SetVector 1, 0.0, (s1#/2.0)*-4, 0.0
NDB_SetVector 2, 0.0, ((s1#/2.0)*-4)-1.0, 0.0
nJoint = NDB_NewtonConstraintCreateBall( jLamp, jTwo )
NDB_SetVector 0.0, -1.0, 0.0
NDB_NewtonBallSetConeLimits nJoint, 5.0, 5.0
NDB_BuildMatrix 0.0, 0.0, 0.0, x#, y#, z#
NDB_NewtonBodySetMatrixRecursive jDummy
POSITION OBJECT NDB_GetDBPro(jDummy), x#, y#, z#
EndFunction nJoint
`---------------------------------------------------------
1.3- call this function in your "main.dba"
REM JOINTS
`A HANGING LAMP
NewtonLamp(10, 60, 10)
now your main.dba should look somethin like this:
REM PATH GLOBALS
GLOBAL pthRoot As String
GLOBAL pthBin As String
GLOBAL pthMdl As String
pthRoot = GET DIR$()
pthBin = "Bin"
pthMdl = "Mdl"
REM SCREEN GLOBALS
GLOBAL scrFps As Integer
GLOBAL scrF As Integer
GLOBAL scrW As Integer
GLOBAL scrH As Integer
GLOBAL scrD As Integer
scrFps = 60
scrF = 62
scrW = 800
scrH = 600
scrD = 32
REM GENERIC SCREEN SET
AUTOCAM OFF
RANDOMIZE TIMER()
SET IMAGE COLORKEY 0, 0, 0
SET NORMALIZATION ON
SET DISPLAY MODE scrW, scrH, scrD
SYNC RATE scrFps
SYNC ON
REM NEWTON GLOBALS
GLOBAL nBody
GLOBAL nJoint
GLOBAL nStatic
GLOBAL nPlayer
GLOBAL nMatDefault
GLOBAL nMatPlayer
GLOBAL nMatWater
GLOBAL nMatWood
GLOBAL nMatMetal
GOSUB MakePickObjects
REM CALL PREPERATION ROUTINES HERE
GOSUB prepareNewton
`GOSUB Camera_Setup `Camera create
REM VISUALISE THE SOLID GROUND PLAIN
obj = free_object()
make object box obj, 10000, 10, 10000
position object obj, 0, -5, 0
color object obj, rgb(10,100,10)
`gravity and mass 0 means object is a static box
newtonCollisionForBox(obj, 0.0, 0, 0, nMatDefault)
REM CREATE NEWTON OBJECTS HERE
`BOX OBJECT
obj = free_object()
make object box obj, 10,20,10
position object obj, 0, 50, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForBox(obj, 200.0, 1, 0, nMatDefault)
`SPHERE OBJECT
obj = free_object()
make object sphere obj, 10
position object obj, 0, 150, 0
zrotate object obj, 45
color object obj, rgb(100,10,10)
`obj = object number, mass=2.0, effected by gravity and buoyancy,defaultmat
newtonCollisionForSphere(obj, 100.0, 1, 0, nMatDefault)
REM JOINTS
`A HANGING LAMP
NewtonLamp(10, 60, 10)
`*/-------------------/
`SET THE NEWTON TIMER START
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
GLOBAL nTime# = NDB_GetElapsedTimeInSec()
DO
`SET THE NEWTON TIMER TO UPDATE
nTime# = NDB_GetElapsedTimeInSec()
NDB_NewtonUpdate nTime#
text 0, 0, "press F12 key to debug newton on or off"
GOSUB HandleCamera
GOSUB ObjectDragging
`GOSUB Camera_Free_Loop `camera loop
GOSUB debugNewton
LOOP
GOSUB destroyNewton
`/-------------------/*
Summary:
Okay this is it, now you know most of newton
if you already knew these, thats good what can i say..
But if you have learnt somethin, do not forget to give me credits and donations would also be cool
im just kidding, you dont even need to thank me at all...but ill appreciate it
id like to go on with this tutorial, but for now ill wait for your comments and wishes. But just remember ill be around for 15 more days and thats it.
CuCuMBeR