Hi,
   
  This is a Python ODE performance test. It is cracked when obj count=98 and 
performance is low. maybe 10-20 fps in my Core Duo 1.8G
  
[img]http://3d.247sv.com/bbs/ode01.gif[/img]
   
  I think it is too slow , I remember that novodex demo is 50-80fps with more 
than 1000 boxes, maybe more. Is this the ODE's problem, or PyODE's?
  How to do a test like this with ODE (C++)?
   
  Thanks
   
  This is the code:
[code]
# pyODE example 3: Collision detection
  # Originally by Matthias Baas.
# Updated by Pierre Gay to work without pygame or cgkit.
  import sys, os, random, time
from math import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
  import ode
   
  # geometric utility functions
def scalp (vec, scal):
    vec[0] *= scal
    vec[1] *= scal
    vec[2] *= scal
  def length (vec):
    return sqrt (vec[0]**2 + vec[1]**2 + vec[2]**2)
  # prepare_GL
def prepare_GL():
    """Prepare drawing.
    """
      # Viewport
    glViewport(0,0,640,480)
      # Initialize
    glClearColor(0.8,0.8,0.9,0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST)
    glDisable(GL_LIGHTING)
    glEnable(GL_LIGHTING)
    glEnable(GL_NORMALIZE)
    glShadeModel(GL_FLAT)
      # Projection
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective (45,1.3333,0.2,20)
      # Initialize ModelView matrix
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
      # Light source
    glLightfv(GL_LIGHT0,GL_POSITION,[0,0,1,0])
    glLightfv(GL_LIGHT0,GL_DIFFUSE,[1,1,1,1])
    glLightfv(GL_LIGHT0,GL_SPECULAR,[1,1,1,1])
    glEnable(GL_LIGHT0)
      # View transformation
    gluLookAt (2.4, 3.6, 4.8, 0.5, 0.5, 0, 0, 1, 0)
  # draw_body
def draw_body(body):
    """Draw an ODE body.
    """
      x,y,z = body.getPosition()
    R = body.getRotation()
    rot = [R[0], R[3], R[6], 0.,
           R[1], R[4], R[7], 0.,
           R[2], R[5], R[8], 0.,
           x, y, z, 1.0]
    glPushMatrix()
    glMultMatrixd(rot)
    if body.shape=="box":
        sx,sy,sz = body.boxsize
        glScale(sx, sy, sz)
        glutSolidCube(1)
    glPopMatrix()
  
# create_box
def create_box(world, space, density, lx, ly, lz):
    """Create a box body and its corresponding geom."""
      # Create body
    body = ode.Body(world)
    M = ode.Mass()
    M.setBox(density, lx, ly, lz)
    body.setMass(M)
      # Set parameters for drawing the body
    body.shape = "box"
    body.boxsize = (lx, ly, lz)
      # Create a box geom for collision detection
    geom = ode.GeomBox(space, lengths=body.boxsize)
    geom.setBody(body)
      return body
  # drop_object
def drop_object():
    """Drop an object into the scene."""
      global bodies, counter, objcount
      body = create_box(world, space, 1000, 0.6,0.2,0.2)
    body.setPosition( (random.gauss(0,0.1),3.0,random.gauss(0,0.1)) )
    theta = random.uniform(0,2*pi)
    ct = cos (theta)
    st = sin (theta)
    body.setRotation([ct, 0., -st, 0., 1., 0., st, 0., ct])
    bodies.append(body)
    counter=0
    objcount+=1
    print "obj count =%d " % (objcount)
  # explosion
def explosion():
    """Simulate an explosion.
      Every object is pushed away from the origin.
    The force is dependent on the objects distance from the origin.
    """
    global bodies
      for b in bodies:
        l=b.getPosition ()
        d = length (l)
        a = max(0, 40000*(1.0-0.2*d*d))
        l = [l[0] / 4, l[1], l[2] /4]
        scalp (l, a / length (l))
        b.addForce(l)
  # pull
def pull():
    """Pull the objects back to the origin.
      Every object will be pulled back to the origin.
    Every couple of frames there'll be a thrust upwards so that
    the objects won't stick to the ground all the time.
    """
    global bodies, counter
      for b in bodies:
        l=list (b.getPosition ())
        scalp (l, -1000 / length (l))
        b.addForce(l)
        if counter%60==0:
            b.addForce((0,10000,0))
  # Collision callback
def near_callback(args, geom1, geom2):
    """Callback function for the collide() method.
      This function checks if the given geoms do collide and
    creates contact joints if they do.
    """
      # Check if the objects do collide
    contacts = ode.collide(geom1, geom2)
      # Create contact joints
    world,contactgroup = args
    for c in contacts:
        c.setBounce(0.2)
        c.setMu(5000)
        j = ode.ContactJoint(world, contactgroup, c)
        j.attach(geom1.getBody(), geom2.getBody())
   
  ######################################################################
if __name__ == '__main__':
 # Import Psyco if available
 try:
  import psyco
  psyco.full()
 except ImportError:
  pass
  # Initialize Glut
glutInit ([])
  # Open a window
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE)
  x = 0
y = 0
width = 640
height = 480
glutInitWindowPosition (x, y);
glutInitWindowSize (width, height);
glutCreateWindow ("testode")
  # Create a world object
world = ode.World()
world.setGravity( (0,-9.81,0) )
world.setERP(0.8)
world.setCFM(1E-5)
  # Create a space object
space = ode.Space()
  # Create a plane geom which prevent the objects from falling forever
floor = ode.GeomPlane(space, (0,1,0), 0)
  # A list with ODE bodies
bodies = []
  # A joint group for the contact joints that are generated whenever
# two bodies collide
contactgroup = ode.JointGroup()
  # Some variables used inside the simulation loop
fps = 50
dt = 1.0/fps
running = True
state = 0
counter = 0
objcount = 0
lasttime = time.time()
  
# keyboard callback
def _keyfunc (c, x, y):
    sys.exit (0)
  glutKeyboardFunc (_keyfunc)
  # draw callback
def _drawfunc ():
    # Draw the scene
    prepare_GL()
    for b in bodies:
        draw_body(b)
      glutSwapBuffers ()
  glutDisplayFunc (_drawfunc)
  # idle callback
def _idlefunc ():
    global counter, state, lasttime
      t = dt - (time.time() - lasttime)
    if (t > 0):
        time.sleep(t)
      counter += 1
      if state==0:
        if counter==20:
            drop_object()
        if objcount==200:
            state=1
            counter=0
    # State 1: Explosion and pulling back the objects
    elif state==1:
        if counter==100:
            explosion()
        if counter>300:
            pull()
        if counter==500:
            counter=20
      glutPostRedisplay ()
      # Simulate
    n = 2
      for i in range(n):
        # Detect collisions and create contact joints
        space.collide((world,contactgroup), near_callback)
          # Simulation step
        world.step(dt/n)
          # Remove all contact joints
        contactgroup.empty()
      lasttime = time.time()
  glutIdleFunc (_idlefunc)
  glutMainLoop ()
[/code]

       
---------------------------------
Pinpoint customers who are looking for what you sell. 
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Pyode-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyode-user

Reply via email to