PDA

View Full Version : ODE Sample #02 - lets take a joint ... s



Petr Schreiber
09-08-2007, 21:26
Hi,

this is more free translation of Pythonish ODE02.py, it shows two connected bodies.
Quite fun to watch for few seconds ( check out the "I will run circles" behaviour ):



' ODE02 - Connecting bodies with joints

uses "TBGL"
#include "%APP_INCLUDEPATH%\thinbasic_ode.inc"

' -- This will create window
dim hWnd as dword = tbgl_CreateWindowEx("ODE 02 - Bodies and joints", 640, 480, 32, 0)
tbgl_ShowWindow

' -- Yes, to create new world is that easy
dim myWorld as dWorldID = dWorldCreate

' -- Planet Earth
dWorldSetGravity(myWorld, 0, -9.81, 0)

' -- We need two bodies...
dim myBody1 as dBodyID = dBodyCreate( myWorld )
dim myBody2 as dBodyID = dBodyCreate( myWorld )

' -- Mass will be "recycled" for both of them
' -- Here we will store mass
dim myMass AS dMass

' -- Although it might seem like something else, we give DENSITY and RADIUS
dMassSetSphere( myMass, 2500.0, 0.05 )

' -- Assign mass to body
dBodySetMass( myBody1, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody1, 1, 2, 0 )

' -- Assign mass to body
dBodySetMass( myBody2, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody2, 2, 2, 0 )

dim JointPoint1 as dJointID = dJointCreateBall( myWorld, 0 )
dim JointPoint2 as dJointID = dJointCreateBall( myWorld, 0 )

dJointAttach( JointPoint1, myBody1, 0 )
dJointSetBallAnchor( JointPoint1, 0, 2, 0 )

dJointAttach( JointPoint2, myBody1, myBody2 )
dJointSetBallAnchor( JointPoint2, 1, 2, 0 )

dim FPS, dt as double

dim LoopFlag as BYTE = %TRUE
dim Clk as long = gettickcount

tbgl_BackColor 255, 255, 255

dim x1, y1, z1 as dReal
dim x2, y2, z2 as dReal

tbgl_GetAsyncKeyState(-1)

While LoopFlag

FPS = tbgl_getFrameRate

if tbgl_GetWindowKeyState( hWnd, %VK_ESCAPE ) then loopFlag = %FALSE

ParseVector(dBodyGetPosition ( myBody1 ), x1, y1, z1 )
ParseVector(dBodyGetPosition ( myBody2 ), x2, y2, z2 )

tbgl_ClearFrame

tbgl_Camera 0, 1, 5, 0, 1, 0

DrawSphere( x1, y1, z1 )

DrawLine( 0, 2, 0, x1, y1, z1 )
DrawLine( x1, y1, z1, x2, y2, z2 )

DrawSphere( x2, y2, z2 )

tbgl_DrawFrame

dt = 1/FPS
if FPS < 25 then dt = 0.04 ' -- Too big steps mean too unreal simulation :)
dWorldStep( myWorld, dt )

wend

tbgl_DestroyWindow

sub DrawSphere( x as single, y as single, z as single )
tbgl_PushMatrix
tbgl_Translate x, y, z

tbgl_color 255, 0, 0
tbgl_Sphere 0.05

tbgl_PopMatrix
end sub

sub DrawLine( a as single, b as single, c as single, d as single, e as single, f as single)
tbgl_color 0, 255, 0
tbgl_BeginPoly %GL_LINES
tbgl_Vertex a, b, c
tbgl_Vertex d, e, f
tbgl_EndPoly
end sub

sub ParseVector( byval pointer as dword, byref b as SINGLE, byref c as single, byref d as single )

b = peek(single, pointer)
c = peek(single, pointer+4)
d = peek(single, pointer+8)

end sub


This comes with basic graphics, so more exciting than sample 01, although not Id Tech 5 ;D demo

Bye,
Petr

ErosOlmi
10-08-2007, 00:46
Petr,

in a try to avoid those not ... "elegant" PEEK calling (please do not kill me for that :D ) her it is my code. It uses a type to store body coordinates at the same memory location of bodies. Please see if it works. It should also add some little more speed because it avoid to call ParseVector every time.

A lot of fun looking at those forces simulations, thank you VERY MUCH !


' ODE02 - Connecting bodies with joints

uses "TBGL"

#include "%APP_INCLUDEPATH%\thinbasic_ode.inc"

' -- This will create window
dim hWnd as dword = tbgl_CreateWindowEx("ODE 02 - Bodies and joints", 640, 480, 32, 0)
tbgl_ShowWindow

' -- Yes, to create new world is that easy
dim myWorld as dWorldID = dWorldCreate

' -- Planet Earth
dWorldSetGravity(myWorld, 0, -9.81, 0)

' -- We need two bodies...
dim myBody1 as dBodyID = dBodyCreate( myWorld )
dim myBody2 as dBodyID = dBodyCreate( myWorld )

' -- Mass will be "recycled" for both of them
' -- Here we will store mass
dim myMass AS dMass

' -- Although it might seem like something else, we give DENSITY and RADIUS
dMassSetSphere( myMass, 2500.0, 0.05 )

' -- Assign mass to body
dBodySetMass( myBody1, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody1, 1, 2, 0 )

' -- Assign mass to body
dBodySetMass( myBody2, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody2, 2, 2, 0 )

dim JointPoint1 as dJointID = dJointCreateBall( myWorld, 0 )
dim JointPoint2 as dJointID = dJointCreateBall( myWorld, 0 )

dJointAttach( JointPoint1, myBody1, 0 )
dJointSetBallAnchor( JointPoint1, 0, 2, 0 )

dJointAttach( JointPoint2, myBody1, myBody2 )
dJointSetBallAnchor( JointPoint2, 1, 2, 0 )

dim FPS, dt as double

dim LoopFlag as BYTE = %TRUE
dim Clk as long = gettickcount

tbgl_BackColor 255, 255, 255

type t_xyz
x as dReal
y as dReal
z as dReal
end type

dim xyz1 as t_xyz at dBodyGetPosition ( myBody1 )
dim xyz2 as t_xyz at dBodyGetPosition ( myBody2 )

tbgl_GetAsyncKeyState(-1)

While LoopFlag

FPS = tbgl_getFrameRate

if tbgl_GetWindowKeyState( hWnd, %VK_ESCAPE ) then loopFlag = %FALSE

tbgl_ClearFrame

tbgl_Camera 0, 1, 5, 0, 1, 0

DrawSphere( xyz1 )

DrawLine( 0, 2, 0, xyz1.x, xyz1.y, xyz1.z )

DrawLine( xyz1.x, xyz1.y, xyz1.z, xyz2.x, xyz2.y, xyz2.z )

DrawSphere( xyz2 )

tbgl_DrawFrame

dt = 1/FPS
if FPS < 25 then dt = 0.04

dWorldStep( myWorld, dt )

wend

tbgl_DestroyWindow

sub DrawSphere( xyz as t_xyz )
tbgl_PushMatrix
tbgl_Translate xyz.x, xyz.y, xyz.z

tbgl_color 255, 0, 0
tbgl_Sphere 0.05

tbgl_PopMatrix
end sub

sub DrawLine( a as single, b as single, c as single, d as single, e as single, f as single)
tbgl_color 0, 255, 0
tbgl_BeginPoly %GL_LINES
tbgl_Vertex a, b, c
tbgl_Vertex d, e, f
tbgl_EndPoly
end sub



A strage behave in my tests is if mouse is over or outside TBGL window. When mouse is inside I get about 800/900 FPS. If mouse is outside I get around 1200/1300 FPS.
When mouse is inside TBGL window it continue to be refreshed (flicker). Is it expected?

Ciao
Eros

ErosOlmi
10-08-2007, 01:00
Very fun to change world gravity and body masses ;D

sandyrepope
10-08-2007, 03:01
#include "%APP_INCLUDEPATH%\thinbasic_ode.inc"

What is thinbasic_ode.inc? I don't have any include file by that name.

Thanks
Sandy

kryton9
10-08-2007, 03:14
Sandy it is a conversion by Petr of a very popular Physics engine ODE.

You need to download and install:
http://community.thinbasic.com/index.php?topic=820.0

The very first post has the latest files.

Once unzipped copy the thinBasic_ODE.inc file into your c:\thinBasic\inc folder.

kryton9
10-08-2007, 03:22
Thanks Petr, this is very cool. Unfortunately I am getting errors when running yours, but got Eros's to work fine.

this line:
#include "ode/thinbasic_ode.inc"
should be:
#include "thinbasic_ode.inc"

I am also getting an error in the include file about a missing parenthesis in line 2176 of the ODE include file but I don't
when I run Eros's so I did not change anything and will wait for clarification.

Thanks it is fun to watch!

Petr Schreiber
10-08-2007, 08:36
Hi all,

thanks for all your comments and Eros's perfect DIM .. AT workaround - now it is even less work than in Python !

Kent, that error with parenthesis should be from first release of ODE headers, do you have yesterdays one ?
I am now scratching my code, because Eros tuned it in right way :) But I can't see any flicker ?


Thanks,
Petr

Petr Schreiber
10-08-2007, 09:13
Little mod for morbid people - hanged triangle :P

and with pseudo ( but still colored :) ) shadow.



' ODE02B - Connecting bodies with joints - more complex variant

uses "TBGL"

#include "%APP_INCLUDEPATH%/thinbasic_ode.inc"

' -- This will create window
dim hWnd as dword = tbgl_CreateWindowEx("ODE 02 - Bodies and joints - Hanged triangle", 640, 480, 32, 0)
tbgl_ShowWindow
tbgl_UseLighting 1
tbgl_UseLightsource %GL_LIGHT0, 1
' -- Yes, to create new world is that easy
dim myWorld as dWorldID = dWorldCreate

' -- Planet Earth
dWorldSetGravity(myWorld, 0, -9.81, 0)

' -- We need two bodies...
dim myBody1 as dBodyID = dBodyCreate( myWorld )
dim myBody2 as dBodyID = dBodyCreate( myWorld )
dim myBody3 as dBodyID = dBodyCreate( myWorld )
dim myBody4 as dBodyID = dBodyCreate( myWorld )
dim myBody5 as dBodyID = dBodyCreate( myWorld )

' -- Mass will be "recycled" for both of them
' -- Here we will store mass
dim myMass AS dMass

' -- Although it might seem like something else, we give DENSITY and RADIUS
dMassSetSphere( myMass, 2500.0, 0.05 )

' -- Assign mass to body
dBodySetMass( myBody1, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody1, 1, 2, 0 )

' -- Assign mass to body
dBodySetMass( myBody2, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody2, 1, 2, 1 )

' -- Assign mass to body
dBodySetMass( myBody3, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody3, 0, 2, 1 )

' -- Assign mass to body
dBodySetMass( myBody4, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody4, 1, 2, 2 )

' -- Assign mass to body
dBodySetMass( myBody5, myMass )
' -- Lets position mass at x, y, z
dBodySetPosition( myBody5, 0, 2, 2 )

dim JointPoint1 as dJointID = dJointCreateBall( myWorld, 0 )
dim JointPoint2 as dJointID = dJointCreateBall( myWorld, 0 )
dim JointPoint3 as dJointID = dJointCreateBall( myWorld, 0 )
dim JointPoint4 as dJointID = dJointCreateBall( myWorld, 0 )
dim JointPoint5 as dJointID = dJointCreateBall( myWorld, 0 )
dim JointPoint6 as dJointID = dJointCreateBall( myWorld, 0 )

dJointAttach( JointPoint1, myBody1, 0 )
dJointSetBallAnchor( JointPoint1, 0, 2, 0 )

dJointAttach( JointPoint2, myBody1, myBody2 )
dJointSetBallAnchor( JointPoint2, 1, 2, 0 )

dJointAttach( JointPoint3, myBody2, myBody3 )
dJointSetBallAnchor( JointPoint3, 1, 2, 1 )

dJointAttach( JointPoint4, myBody1, myBody3 )
dJointSetBallAnchor( JointPoint4, 1, 2, 0 )

dJointAttach( JointPoint5, myBody2, myBody4 )
dJointSetBallAnchor( JointPoint5, 1, 2, 1 )

dJointAttach( JointPoint6, myBody3, myBody5 )
dJointSetBallAnchor( JointPoint6, 0, 2, 1 )


dim FPS, dt as double

dim LoopFlag as BYTE = %TRUE
dim Clk as long = gettickcount

tbgl_BackColor 255, 255, 255

type t_xyz
x as dReal
y as dReal
z as dReal
end type

dim xyz1 as t_xyz at dBodyGetPosition ( myBody1 )
dim xyz2 as t_xyz at dBodyGetPosition ( myBody2 )
dim xyz3 as t_xyz at dBodyGetPosition ( myBody3 )
dim xyz4 as t_xyz at dBodyGetPosition ( myBody4 )
dim xyz5 as t_xyz at dBodyGetPosition ( myBody5 )

tbgl_GetAsyncKeyState(-1)

doevents on
dim i as long

While LoopFlag

FPS = tbgl_getFrameRate

if tbgl_GetWindowKeyState( hWnd, %VK_ESCAPE ) then loopFlag = %FALSE

tbgl_ClearFrame

tbgl_Camera 0, 0, 5, 0, 0, 0
Render_Scene

tbgl_translate 0,-1,0
tbgl_scale 1,0,1
Render_Scene

tbgl_DrawFrame

dt = 1/FPS
if FPS < 25 then dt = 0.04
incr i
if i > 1000 then
i = 0
tbgl_SetWindowTitle( hWnd, FPS )
end if
dWorldStep( myWorld, dt )

wend

tbgl_DestroyWindow

sub Render_Scene()
DrawSphere( xyz1 )

DrawLine( 0, 2, 0, xyz1.x, xyz1.y, xyz1.z )

DrawLine( xyz1.x, xyz1.y, xyz1.z, xyz2.x, xyz2.y, xyz2.z )

DrawSphere( xyz2 )

DrawLine( xyz2.x, xyz2.y, xyz2.z, xyz3.x, xyz3.y, xyz3.z )

DrawSphere( xyz3 )

DrawLine( xyz1.x, xyz1.y, xyz1.z, xyz3.x, xyz3.y, xyz3.z )

DrawSphere( xyz4 )

DrawLine( xyz2.x, xyz2.y, xyz2.z, xyz4.x, xyz4.y, xyz4.z )

DrawSphere( xyz5 )
DrawLine( xyz3.x, xyz3.y, xyz3.z, xyz5.x, xyz5.y, xyz5.z )

end sub
sub DrawSphere( xyz as t_xyz )
tbgl_PushMatrix
tbgl_Translate xyz.x, xyz.y, xyz.z

tbgl_color 255, 0, 0
tbgl_Sphere 0.05

tbgl_PopMatrix
end sub

sub DrawLine( a as single, b as single, c as single, d as single, e as single, f as single)
tbgl_color 0, 255, 0
tbgl_BeginPoly %GL_LINES
tbgl_Vertex a, b, c
tbgl_Vertex d, e, f
tbgl_EndPoly
end sub


Bye,
Petr

Michael Hartlef
10-08-2007, 09:32
Thanks man, I will test this hopefully on sunday. Today I'm going out with my wife and saturday is booked for my son.

ErosOlmi
10-08-2007, 09:46
New script is really funny :D Quite close to a human body movement.
A question: movements are perpetual or at a certain point, due to continuous gravity, they will calm down till stop?

On my box it run at 340FPS when mouse is out of the window and at 270FPS when mouse is over the window.

Ciao
Eros

Petr Schreiber
10-08-2007, 09:49
Have a nice time Mike,

hope it will run ok :)

I think now it is perpetum mobile :). But there were some functions to set friction in joints, I will have a look ;)


Petr

Michael Hartlef
10-08-2007, 17:27
Hey, I got some minutes before I have to leave. Cool stuff guys. Keep it up!!!!

ErosOlmi
10-08-2007, 17:33
You didn't resist ;D

Petr Schreiber
10-08-2007, 18:27
Thanks for trying it Mike !


Bye,
Petr

kryton9
10-08-2007, 23:15
Haunting to watch that is for sure. The frame rates are incredible, constant framers per second in the way high 300's and many times in the 400's!!

With Physics, thinBasic is now Fun2