• Welcome to Powerbasic Museum 2020-B.
 

ODE: Working sphere-plane collision sample

Started by Petr Schreiber, June 24, 2008, 08:36:50 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Petr Schreiber

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.

Code (thinbasic) Select

'===============================================================================
'=                 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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

Hi Patrice,

ODE and Vista = GPF or my code using ODE and vista = GPF :)


Thanks,
Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

José Roca

 
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.

Patrice Terrier

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.


...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

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)

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

#7
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

AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

José Roca

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.