Hi everybody,
I'm Gabio from the Blender community. Artist and python coder. Blender
is an opensource 3D package using python as main scripting language. The
API is accessible
here:http://www.blender.org/modules/documentation/237PythonDoc/frames.html .
I recently tried to simulate some tests scenes in Blender using the
pyODE module. And it worked relatively well. I got a problem though. A
crash to be more correct, when having a lot of bodies in the same space.
The fact is I want all of them to be able to collide. I'm not aware ODE
have limit in the number of collisions it can manage.
To test it out. you can get Blender 3D @ www.blender.org. have python
2.3 installed and pyODE.
Then download this file:
http://web.netrevolution.com/gbeloin/ODE_bug_gabio.blend
You can open it in Blender by pressing F1 and browsing to the .blend
file or double click on it (Windows)
You will then face a screen with the scene (plane and ball) and a script
windows on the right. to start the test move your mouse cursor in the
text windows and press ALT-P. for me it crash. in the near_callback. and
the debug give me a stack overflow. If you go at line 95 and change
"for x in range(20):" to "for x in range(5):" the script doesn't crash
anymore. you then can see the anim by moving your mouse in the 3Dspace
on the left and pressing ALT-A.
or you can see the result of the best i could get out of pyODE before
crash: http://media.putfile.com/Render_legowall0001_0200
So I'm limited in the number of bodies i can include in the same space?
Of course if you don't feel like downloading Blender and python 2.3,
I've made an example you can run on any system with pyODE. The crash is
instant:
--------------------------------------
import ode
def draw_body(body):
global frame
x,y,z = body.getPosition()
print x,y,z
# 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(.5)
c.setMu(7000)
j = ode.ContactJoint(world, contactgroup, c)
j.attach(geom1.getBody(), geom2.getBody())
# Create a world object
world = ode.World()
world.setGravity((0,0,-9.81))
world.setERP(0.2) #error correction
world.setCFM(1E-10) #softness of collision
lobj = []
lbody = []
contactgroup = ode.JointGroup()
print "Create a space object"
space = ode.Space()
print "Create a plane geom which prevent the objects from falling forever"
floor = ode.GeomPlane(space, (0,0,1), 0)
print "create array"
a = 1.5
for z in range(20):
for x in range(20):
lobj.append((x*3+a,1,z+.5))
for obj in lobj:
body = ode.Body(world)
M = ode.Mass()
M.setBox(5000,3,1,1)
body.setMass(M)
body.setPosition(obj)
geom = ode.GeomBox(space,(3,1,1))
geom.setBody(body)
lbody.append(body)
body.disable() #wait for the cue
bball = ode.Body(world)
M = ode.Mass()
M.setSphere(700,5)
bball.setMass(M)
bball.setPosition((9,-19,5))
geom2 = ode.GeomSphere(space,5)
geom2.setBody(bball)
bball.setLinearVel((0,20,0)) #give some speed.
lobj.append((9,-19,5))
lbody.append(bball)
print "Simulation loop..."
fps = 24
dt = 1.0/fps
frame = 1 #first frame
totframe = 300
while frame < totframe: #tot of frame to do
for i in range(2):
space.collide((world,contactgroup), near_callback) #colision
for b in range(len(lbody)):
draw_body(lbody[b])
world.quickStep(dt) #shift time
contactgroup.empty() #empty mem
frame += 1
ode.CloseODE()
print "done!"
-------------------------
Thanks for looking.
|