Hi,
I'm a new user of ODE, working with the PyODE interface in order to
build games with PyGame. I've written a test program (attached) but
it doesn't seem to work right. Basically, it involves two objects (a
box and a sphere) dropping onto a floor (a plane). When they collide
with the floor, they are supposed to stop.
It all works fine, until I give the objects mass. Once I add the
following lines:
M = ode.Mass()
M.setSphere(10, self.radius)
self.body.setMass(M)
The Circle object starts to significantly penetrate the floor, and
bounce a lot. It eventually comes to rest half-embedded in the floor.
If I reduce the density from 10 to 1, the problem is significantly
reduced, but still there is a lot of bouncing before the objects come
to rest on the surface.
Can anyone explain what is going on here?
Thanks,
Malcolm
--
"Cleanliness is not next to godliness nowadays,
for cleanliness is made an essential
and godliness is regarded as an offence.
- G.K.Chesterton, On Lying in Bed
import pygame, ode
from pygame.locals import *
SCREENRECT = Rect(0, 0, 800, 600)
TRANSPARENT = (1,2,3)
class Circle(pygame.sprite.Sprite):
def __init__(self, world, space, (x,y), r):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = pygame.Surface((r*2+1, r*2+1))
self.image.fill(TRANSPARENT)
self.image.set_colorkey(TRANSPARENT)
pygame.draw.circle(self.image, (255,0,0), (r, r), r)
pygame.draw.circle(self.image, (0,0,0), (r, r), r, 1)
self.rect = self.image.get_rect(center=(x,y))
self.hitmask = pygame.surfarray.array_colorkey(self.image)
self.body = ode.Body(world)
self.body.setPosition((x,y,0))
# comment out these lines to make it work
M = ode.Mass()
M.setSphere(10, r)
self.body.setMass(M)
geom = ode.GeomSphere(space, r)
geom.setBody(self.body)
geom.setCollideBits(1)
self.join2d = ode.Plane2DJoint(world)
self.join2d.attach(self.body, ode.environment)
def update(self):
(x,y,z) = self.body.getPosition()
self.rect.center = (x,y)
class Block(pygame.sprite.Sprite):
def __init__(self, world, space, rect):
pygame.sprite.Sprite.__init__(self, self.containers)
x = rect.centerx
y = rect.centery
w = rect.width
h = rect.height
self.image = pygame.Surface((w, h))
r = Rect(0,0,w,h)
pygame.draw.rect(self.image, (0,255,0), r)
pygame.draw.rect(self.image, (0,0,0), r, 1)
self.rect = self.image.get_rect(center=rect.center)
self.body = ode.Body(world)
self.body.setPosition((x,y,0))
# comment out these lines to make it work
M = ode.Mass()
M.setBox(10, w, h, 10)
self.body.setMass(M)
geom = ode.GeomBox(space, (w,h, 10))
geom.setBody(self.body)
geom.setCollideBits(1)
self.join2d = ode.Plane2DJoint(world)
self.join2d.attach(self.body, ode.environment)
def update(self):
(x,y,z) = self.body.getPosition()
self.rect.center = (x,y)
# Collision callback
def collision(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.0)
c.setMu(5000)
j = ode.ContactJoint(world, contactgroup, c)
j.attach(geom1.getBody(), geom2.getBody())
def main():
pygame.init()
bestdepth = pygame.display.mode_ok(SCREENRECT.size, 0, 32)
screen = pygame.display.set_mode(SCREENRECT.size, 0, bestdepth)
world = ode.World()
world.setGravity((0,9.81,0))
space = ode.Space()
contactgroup = ode.JointGroup()
background = pygame.Surface(SCREENRECT.size)
background.fill((255,255,255))
fh = 50
fy = SCREENRECT.height - fh
floor = ode.GeomPlane(space, (0,-1,0), -fy)
floor.setCollideBits(1)
fr = Rect(0, fy, SCREENRECT.width, fh)
pygame.draw.rect(background, (0,0,0), fr, 1)
screen.blit(background, (0,0))
pygame.display.flip()
# assign default groups to each sprite class
all = pygame.sprite.RenderUpdates()
Block.containers = all
Circle.containers = all
rect = Rect(200,300,50,50)
Block(world, space, rect)
Circle(world, space, (400,325), 25)
clock = pygame.time.Clock()
while True:
#cap the framerate
dt = clock.tick(60) / 1000.0
pygame.event.pump()
for event in pygame.event.get():
if event.type == QUIT or \
(event.type == KEYDOWN and event.key == K_ESCAPE):
return
# run the ODE sim
n = 2
for i in range(n):
# Detect collisions and create contact joints
space.collide((world,contactgroup), collision)
# Simulation step
world.step(dt / n)
# Remove all contact joints
contactgroup.empty()
# clear/erase the last drawn sprites
all.clear(screen, background)
# update all the sprites
all.update()
#draw the scene
dirty = all.draw(screen)
pygame.display.update(dirty)
if __name__ == '__main__': main()
-------------------------------------------------------------------------
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