Hi José,
as a little "thank you" for nice ODE headers conversion, here comes basic sample of Open Dynamics Engine performing collision sphere/plane.
What is in this demo:
- Basic graphic output
- Collision callback used for handling collision
What is interesting ( and cost me gray hair ) is that callback must be specified with CDECL, else GPF will visit your PC soon :)
Hope you will like it. I used latest ODE 0.9 for tests.
'===============================================================================
'= ODE - Simple demo of collision sphere-plane =
'= Petr Schreiber, 2008 =
'= =
'= Based on code by José Roca and ODE community =
'===============================================================================
#COMPILE EXE
#DIM ALL
#INCLUDE "ODE.INC"
GLOBAL pWorld AS DWORD
GLOBAL contactgroup AS DWORD
SUB NearCallback CDECL ( BYVAL aData AS DWORD, BYVAL o1 AS DWORD, BYVAL o2 AS DWORD )
REGISTER i AS LONG
IF (dGeomIsSpace (o1) OR dGeomIsSpace (o2)) THEN
' Colliding a space with something
dSpaceCollide2 (o1, o2, aData, CODEPTR(NearCallback))
' Collide all geoms internal to the space(s)
IF dGeomIsSpace (o1) THEN dSpaceCollide (o1, aData, CODEPTR(NearCallback))
IF dGeomIsSpace (o2) THEN dSpaceCollide (o2, aData, CODEPTR(NearCallback))
ELSE
LOCAL bigN AS LONG
LOCAL litN AS LONG
bigN = 32
DIM contact(0 TO bigN-1) AS LOCAL dContact
litN = dCollide (o1, o2, bigN,contact(0).geom,SIZEOF(dContact))
IF litN > 0 THEN
FOR i = 0 TO litN-1
contact(i).surface.slip1 = 0.7
contact(i).surface.slip2 = 0.7
contact(i).surface.mode = %dContactApprox1 OR %dContactSlip1 OR %dContactSlip2
contact(i).surface.mu = 1.0
LOCAL c AS DWORD
c = dJointCreateContact (pWorld,contactgroup,contact(i))
dJointAttach (c,dGeomGetBody(contact(i).geom.g1), dGeomGetBody(contact(i).geom.g2))
NEXT
END IF
END IF
END SUB
FUNCTION PBMAIN () AS LONG
LOCAL hWin AS DWORD
GRAPHIC WINDOW "Box", 300, 300, 640, 640 TO hWin
GRAPHIC ATTACH hWin, 0, REDRAW
LOCAL pSpace AS DWORD
LOCAL pSphereBody AS DWORD
LOCAL pSphereGeom AS DWORD
LOCAL pPlaneGeom AS DWORD
LOCAL tMass AS dMass
LOCAL total_time AS DOUBLE
LOCAL dt AS DOUBLE
LOCAL ps AS SINGLE PTR
LOCAL x, y, z AS SINGLE
LOCAL u, v, w AS SINGLE
LOCAL dummy AS LONG
LOCAL strTmp AS STRING
' Create new world
pWorld = dWorldCreate
' Esoteric constants affecting joints behaviour :D
dWorldSetERP(pWorld, 0.99)
dWorldSetCFM(pWorld, 0.001)
' Create a collision space
pSpace = dSimpleSpaceCreate(0)
' Create general body and geom
pSphereBody = dBodyCreate(pWorld)
pSphereGeom = dCreateSphere(pSpace, 1)
' Contact group for collisions
contactgroup = dJointGroupCreate (1000000)
' Attach them
dGeomSetBody(pSphereGeom, pSphereBody)
' Create a plane, to have something to collide with
pPlaneGeom = dCreatePlane(pSpace, 0, 1, 0, 0)
' Planet Earth
dWorldSetGravity(pWorld, 0, -9.81, 0)
' Give density and radius
dMassSetSphere(tMass, 1.0, 1)
' Actual mass
tMass.mass = 4.1
' Assign mass to the body
dBodySetMass(pSphereBody, tMass)
' Position mass at x, y, z
dBodySetPosition(pSphereBody, 0, 10, 0)
' Add force
dBodyAddForce(pSphereBody, 10000, 2000, 0)
' Do the simulation
dt = 0.001
WHILE total_time < 10.0!
ps = dBodyGetPosition(pSphereBody)
IF ps THEN
x = @ps[0]
y = @ps[1]
z = @ps[2]
END IF
ps = dBodyGetLinearVel(pSphereBody)
IF ps THEN
u = @ps[0]
v = @ps[1]
w = @ps[2]
END IF
strTmp = FORMAT$(total_time, "0.00") & " sec: " & _
"pos = (" & FORMAT$(x, "0.000") & "," & FORMAT$(y, "0.000") & "," & FORMAT$(z, "0.000") & ")" & _
"vel = (" & FORMAT$(u, "0.000") & "," & FORMAT$(v, "0.000") & "," & FORMAT$(w, "0.000") & ")"
' Increase step in simulation
' Check for collisions and pass dummy variable with data
' In case collision will happen, NearCallback is invoked
dSpaceCollide(pSpace, dummy, CODEPTR(NearCallback) )
dWorldStep(pWorld, dt)
dJointGroupEmpty (contactgroup)
total_time = total_time + dt
' -- Render output
GRAPHIC CLEAR %WHITE
GRAPHIC PRINT strTmp
GRAPHIC SCALE (-20, 20)-(20, -20)
' -- Draw the plane
GRAPHIC WIDTH 3
GRAPHIC LINE (-20, 0)-(20, 0), RGB(255,0,0)
' -- Draw the ball
GRAPHIC ELLIPSE (x-1,y-1)-(x+1, y+1)
GRAPHIC REDRAW
WEND
' Cleanup
IF pSphereBody THEN dBodyDestroy(pSphereBody)
IF pWorld THEN dWorldDestroy(pWorld)
IF pSpace THEN dSpaceDestroy(pSpace)
GRAPHIC WINDOW END
END FUNCTION
Bye,
Petr
Petr,
ODE and VISTA = GPF 8)
...
Hi Patrice,
ODE and Vista = GPF or my code using ODE and vista = GPF :)
Thanks,
Petr
Hi Petr,
Many thanks for your example. Unfortunately, I can't run it right now because ODE has a dependency on msvcp71.dll and I don't have it installed in my computer.
Petr,
See previous José's answer.
Also there are many problems with most OpenGL encapsulation(s) on VISTA.
Better to use directly the core OpenGL engine with it.
...
Thanks a lot guys,
I did not know that :(
For graphic I did not used OpenGL, but PBs GRAPHIC.
When I use OpenGL, I go for core OpenGL or my own encapsulation :)
Regarding msvcp71.dll - it probably installed with some game to my PC.
Thanks for the replies, I will think twice whether to continue using ODE or not, if it causes such a trouble. Good to know.
Thanks and sorry,
Petr
QuoteFor graphic I did not used OpenGL, but PBs GRAPHIC.
When it comes to graphic on VISTA... it is better to move ahead and use plain 32-bit with alpha channel, and forget the twenty years old GDI technology. 8)
...
I know I know Patrice :D
... but PBs GRAPHIC commands took me just few lines of code.
They are maybe not the most modern thing, but I must admit they are very neat when I need to do a simple graphics very fast.
Petr
Quote
Regarding msvcp71.dll - it probably installed with some game to my PC.
Thanks for the replies, I will think twice whether to continue using ODE or not, if it causes such a trouble. Good to know.
Isn't good to link with a runtime library and not provide it. msvcp71 comes with Visual Studio 7.1, that must have been used to compile the dll. There are many sites where it can be downloaded, but since there are versions that are trojans, it is risky business. Probably it can be compiled without that dependency.