Python Box2D! (howto)

Discuss issues specific the Python port of Box2D
kne
Posts: 88
Joined: Mon Feb 18, 2008 12:30 am

Re: Python Box2D! (howto)

Postby kne » Wed Apr 02, 2008 5:10 am

Python Bindings Release 3 --
Usage here on the wiki: http://www.box2d.org/wiki/index.php?title=Box2D_with_Python
Download here: http://pybox2d.googlepages.com/

* DebugDraw support for vertices (passed in as a tuple of (x, y) vertices)
* Body/Joint/Shape.GetUserData() fixed.

The first fix should take care of your problem, roman_m. Glad to see someone else is using the bindings!

roman_m
Posts: 36
Joined: Sun Nov 25, 2007 1:43 pm

Re: Python Box2D! (howto)

Postby roman_m » Thu Apr 03, 2008 7:56 am

Thanks for supporting this, kne.

Can you tell me how to use world.Query in python? I'm not sure, but it looks like we need to update wrapper.

roman_m
Posts: 36
Joined: Sun Nov 25, 2007 1:43 pm

Re: Python Box2D! (howto)

Postby roman_m » Fri Apr 04, 2008 2:02 am

I started to create TestBed for python using pygame for graphics. Currently it handles only one test and allows user to move viewport (drag with righ mouse button), zoom (use mouse wheel) and drag objects (drag with left mouse button).
Dragging objects is not really good because AFAIK it's not possible to use world.Query with current version of wrapper.

Sample test:

Code: Select all

class MyTest(Test):
    def __init__(self):
        Test.__init__(self)
        groundBodyDef = b2BodyDef();
        groundBodyDef.position.Set(0.0, -10.0);
        groundBody = self.world.CreateStaticBody(groundBodyDef);
        groundShapeDef = b2PolygonDef()
        groundShapeDef.SetAsBox(50.0, 10.0);
        groundBody.CreateShape(groundShapeDef);

        self.n = 0;
       
    def step(self, tm):
        if(tm > self.n and tm < 10):
            self.n += 1
            bodyDef = b2BodyDef()
            bodyDef.position.Set(0.0, 40.0);
            body = self.world.CreateDynamicBody(bodyDef);
            shapeDef = b2PolygonDef()
            shapeDef.SetAsBox(1.0, 1.0);
            shapeDef.density = 1.0
            shapeDef.friction = 0.3;
            body.CreateShape(shapeDef);
            body.SetMassFromShapes();
Attachments
test_framework.zip
(1.95 KiB) Downloaded 3975 times
pybox2d.png
pybox2d.png (22.84 KiB) Viewed 6921 times

kne
Posts: 88
Joined: Mon Feb 18, 2008 12:30 am

Re: Python Box2D! (howto)

Postby kne » Fri Apr 04, 2008 2:46 am

Nice work! I just finished adding Query() support to the bindings.

I updated your code as follows:

Code: Select all

    def StartDragging(self, x, y):
        if(getattr(self, "mouseJoint", None) == None):
            x, y = self.debugDraw.ScreenToWorld(x, y)

            AABB=b2AABB()
            AABB.lowerBound.Set(x, y);
            AABB.upperBound.Set(x+1, y+1);
            res = self.test.world.Query(AABB, 10)
            print res
            if res[0] > 0:
                shape = res[1]
                body = shape[0].GetBody()
                jDef = b2MouseJointDef()
                jDef.body1 = self.test.world.GetGroundBody()
                jDef.body2 = body
                jDef.target = b2Vec2(x, y)
                jDef.maxForce = 1000.0 * body.GetMass()
                self.mouseJoint = self.test.world.CreateJoint(jDef).asMouseJoint()


It works as far as I can tell :)

Python Bindings Release 4
Usage here on the wiki: http://www.box2d.org/wiki/index.php?tit ... ith_Python
Download here: http://pybox2d.googlepages.com/

* b2World.Query now works. Returns a tuple as follows:
(number_of_shapes, shapes) = b2World.Query(AABB, max_shapes_to_return)
* Features more pretty printing. Joints are printed nicely but very verbosely (maybe a good thing or a bad thing?).
* b2Polygon[Shape/Def].getVertices_[tuple/b2Vec2] returns all of the vertices in the specified format

roman_m
Posts: 36
Joined: Sun Nov 25, 2007 1:43 pm

Re: Python Box2D! (howto)

Postby roman_m » Fri Apr 04, 2008 3:21 am

Good work!

I found another problem: when I tried to set s_enablePositionCorrection I've got this error message:

Code: Select all

Traceback (most recent call last):
  File "E:\tttt\test_framework.py", line 174, in <module>
    framework = TestFramework()
  File "E:\tttt\test_framework.py", line 86, in __init__
    self.test = MyTest()
  File "E:\tttt\test_framework.py", line 22, in __init__
    Test.__init__(self)
  File "E:\tttt\test_framework.py", line 15, in __init__
    self.world.s_enablePositionCorrection = 1
TypeError: set() takes exactly 1 argument (2 given)

kne
Posts: 88
Joined: Mon Feb 18, 2008 12:30 am

Re: Python Box2D! (howto)

Postby kne » Fri Apr 04, 2008 5:06 am

Static variables with SWIG are a bit of a special case (as I've just learned myself :) ).

To do what you want, you must use this syntax:

Code: Select all

Box2D2.cvar.b2World_s_enablePositionCorrection=1


This applies to all static members in the Box2D library.
The format is:

Code: Select all

Box2D2.cvar.[classname]_[static_member_name]

Note that that's the *class name* and not the *instance name*.
I'll have to modify the interface to address this.

I'm rather worried though that printing Box2D2.cvar will crash Python without any error whatsoever. That's going to take a good bit of looking into :/ .

roman_m
Posts: 36
Joined: Sun Nov 25, 2007 1:43 pm

Re: Python Box2D! (howto)

Postby roman_m » Fri Apr 04, 2008 6:44 am

I found that performance is very bad. I've just ported the pyramid test and it works really slow on Celeron 2.5GHz.
I guess, may be you compile Box2D without optimization? As I can see from Wiki you use -O3 flag for Linux, but don't use it for Windows.

kne
Posts: 88
Joined: Mon Feb 18, 2008 12:30 am

Re: Python Box2D! (howto)

Postby kne » Fri Apr 04, 2008 7:39 am

The Windows release is compiled with MinGW using -O3. Given a language such as Python, it's pretty much expected to be a lot slower than the C++ counterpart. I haven't done much stress-testing, but I'd be curious to see your pyramid test.

I have a feeling that the callbacks could be a rather large part of the speed problems you're encountering, but I'm not too sure without digging further into it.

roman_m
Posts: 36
Joined: Sun Nov 25, 2007 1:43 pm

Re: Python Box2D! (howto)

Postby roman_m » Fri Apr 04, 2008 7:48 am

All staff is done inside box2d and it is written in c++, so I expect it to work fast.
I'm not using callbacks right now except DebugDraw and it does not slow simulation down.

In the file attached to this post there are updated framework with pyramid test. When you run it you can see that simulation is fast until boxes fall onto the floor and from this moment performance goes down dramatically.

UPDATE: You can see this if you add

Code: Select all

                print tm1-tm

before

Code: Select all

                while tm < tm1:
Attachments
test_framework.zip
(2.11 KiB) Downloaded 4014 times

kne
Posts: 88
Joined: Mon Feb 18, 2008 12:30 am

Re: Python Box2D! (howto)

Postby kne » Mon Apr 07, 2008 1:54 am

I built the latest version of the wrapper (v2.0.0r4) with Visual C++ 2008 Express Edition in release mode. Please let me know if you see any difference in speed.

Download here: http://pybox2d.googlepages.com/ (MSVC9 build link)

Edit:

But while looking at your code, I believe you have some logic errors there. In any case, with this replacement code:

Code: Select all

    def run(self):
        tm = 0
        lastUpdate = time.clock()
        clock = pygame.time.Clock()
        while True:
            for event in pygame.event.get():
...
              # IF block is clipped out!
...                       
            self.test.step(tm)

            self.debugDraw.SetFlags(0)
            nowTime = time.clock()
            while (nowTime - lastUpdate) > 1.0/60:
                lastUpdate += 1/60.0
                if (nowTime - lastUpdate) < 1.0/60:
                    self.screen.fill((0,0,0))
                    self.debugDraw.SetFlags(self.DebugDraw.e_shapeBit)
                lastUpdate = time.clock()
                self.test.world.Step(1.0/60, 20)
            pygame.display.flip()
            clock.tick()
            print clock.get_fps()


It gets significantly slower when the boxes are all shifting around after hitting the ground, but it still manages 30fps on my machine according to clock.get_fps() at least.


Return to “Python”



Who is online

Users browsing this forum: No registered users and 1 guest