Box2D Forums

It is currently Thu Dec 18, 2014 12:27 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 51 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next
Author Message
 Post subject: Python Box2D! (howto)
PostPosted: Sat Dec 29, 2007 6:46 am 
Offline

Joined: Sat Dec 29, 2007 6:18 am
Posts: 2
Hsssss. No, I mean, hi.

I just got Box2D, managed to compile it (without any problems!) on MinGW under Windows, and since I'm a Python fan, I thought... it'd be cool if we could have Box2D working under Python. Like any programmer (I guess), I'm lazy, and I thought, what the hell, I could just do it the easiest possible way, that is, using SWIG to auto-generate everything. Guess what - it works! I just ran Hello.py (ported Box2D HelloWorld.cpp), and it.. well, it just seems to work, which is obviously just awesome.

Okay, so here's what I did. I'm expecting you to have MinGW, SWIG and Python (I used 2.4) installed.
  1. Compiled Box2D. (I can't remember the exact command line, now, but this should be close enough.
    Code:
    Box2D\Source> g++ -c -O3 -w Common\*.cpp Collision\*.cpp Dynamics\*.cpp Dynamics\Contacts\*.cpp Dynamics\Joints\*.cpp
    Box2D\Source> ar rcvs ..\Library\libBox2D.a *.o
  2. Wrote the trivial SWIG wrapper file, Box2D.i, in our wrapper-building directory, Box2D\Swig.
    Code:
    %module Box2D
    %{
    #include "../Include/Box2D.h"
    %}
    %include "../Include/Box2D.h"
  3. EDIT: There's one function declared in the headers that isn't in the .cpp files. SWIG will try to futilely wrap this, making the compilation step fail, unless you comment it out. The function is b2BroadPhase::ValidatePairs (line 88 in Source\Collision\b2BroadPhase.h). Just comment that out, ie.
    Code:
       //void ValidatePairs();

    And you'll be done. :)
  4. So far so easy, right? Let's make SWIG crunch that file then. (I'll just go ahead and expect you to have SWIG in your %PATH%.)
    Code:
    Box2D\Swig> swig.exe -python -c++ -O -includeall -ignoremissing Box2D.i

    This should complete with a few warnings, but those didn't seem to matter. Maybe they will with something less trivial than Hello World.
  5. Compile the wrapper DLL. This command line will vary with your installation paths and Python version.
    You might also probably need a GCC (.a) version of the Python library. See http://www.dabeaz.com/cgi-bin/wiki.pl?S ... UsingMingw for instructions (that Perl part). Though try without, first!
    Code:
    Box2D\Swig> g++ -shared -o _Box2D.dll -O3 -I \Programs\python24\include -L \Programs\Python24\Libs box2d_wrap.cxx ..\Library\libbox2d.a -lpython24

    Since that's running in optimization mode three, it'll take some time to finish. Grab a cup of cof.. oh, it's ready.
  6. Try it! Here's Hello.py. (Place it in the Swig directory, so it can find your new Box2D module.)
    Code:
    from Box2D import *

    worldAABB=b2AABB()
    worldAABB.minVertex.Set(-100.0, -100.0)
    worldAABB.maxVertex.Set(100.0, 100.0)
    gravity=b2Vec2(0,-10)
    doSleep = True
    world=b2World(worldAABB, gravity, doSleep)

    groundBoxDef=b2BoxDef()
    groundBoxDef.extents.Set(50.0, 10.0)
    groundBoxDef.density = 0.0
    groundBodyDef=b2BodyDef()
    groundBodyDef.position.Set(0.0, -10.0)
    groundBodyDef.AddShape(groundBoxDef)

    world.CreateBody(groundBodyDef)

    boxDef=b2BoxDef()
    boxDef.extents.Set(1.0, 1.0)
    boxDef.density = 1.0
    boxDef.friction = 0.3
    bodyDef=b2BodyDef()
    bodyDef.position.Set(0.0, 4.0)
    bodyDef.AddShape(boxDef)
    body = world.CreateBody(bodyDef)

    timeStep = 1 / 60.0
    iterations = 10

    for i in xrange(60):
        world.Step(timeStep, iterations)
        position = body.GetOriginPosition()
        rotation = body.GetRotation()
        print "%4.2f %4.2f %4.2f"%(position.x, position.y, rotation)

Hope this process works for you people, too! :)

Here are the compiled wrappers for Python 2.4 and 2.5 / MingW / Windows, as well as Hello.py if you just want to tinker (at a whopping 449 KiB, the ZIP is too big to attach...): http://servut.us/akx/Box2DPy.zip

Enjoy and ask if you have problems. I'm no expert, but I might be able to help nevertheless.


Top
 Profile  
 
PostPosted: Sat Dec 29, 2007 10:55 pm 
Offline

Joined: Thu Dec 06, 2007 6:21 pm
Posts: 8
I recommend grabbing remo's box2d.i file and using that, it has more fixes than your simple version, such as support for userdata (i assume its just as broken on python as it is ruby)
but otherwise nice work.


Top
 Profile  
 
PostPosted: Sun Jan 27, 2008 5:32 am 
Offline

Joined: Sun Jan 27, 2008 5:25 am
Posts: 15
Hi. I wonder if you could help me here. I ran the hello.py in the box2d that you compiled for python 2.5. And I got this. I'm not really familiar with binding stuff from other languages, so I'm lost here. Please show me why it isn't working. A pointer to a good article on bindings like this would be much appreciated also.


Traceback (most recent call last):
File "C:\Documents and Settings\Owner\My Documents\NIm's code\sandbox\2.5\Hello.py", line 1, in <module>
from Box2D import *
File "C:\Documents and Settings\Owner\My Documents\NIm's code\sandbox\2.5\Box2D.py", line 6, in <module>
import _Box2D
ImportError: No module named _Box2D

My guess is that it was trying to create a new namespace, but is using the wrong syntax. Or perhaps the line was meant to grab that dll. I'm afraid I'm just not knowledgeable to have any clue.


Top
 Profile  
 
PostPosted: Sun Jan 27, 2008 2:30 pm 
Offline

Joined: Sat Dec 29, 2007 6:18 am
Posts: 2
Um.. Try renaming _Box2D.dll to _Box2D.pyd. >_>


Top
 Profile  
 
PostPosted: Sun Jan 27, 2008 3:57 pm 
Offline

Joined: Sun Jan 27, 2008 5:25 am
Posts: 15
Ok, I've clearly missed something rather obvious, and need to reread the docs. What should I search the docs for?


Top
 Profile  
 
PostPosted: Sun Feb 03, 2008 8:21 pm 
Offline

Joined: Sun Jan 27, 2008 5:25 am
Posts: 15
How is swig likely to have bound shapeDef.vertices? I 've been trying for days to make an irregular polygon, but I can't figure it out.
heres the line I have problems with:

for n in range(0,shapeDef.vertexCount):
shapeDef.vertices[n].Set(self.points[n][0],self.points[n][1])

In the Docs, It seems to indicate that shapeDef.vertices is an array, but it seems to be acting like a b2Vec2. I don't understand what it says in box2d.py either:

vertices = _swig_property(_Box2D.b2PolyDef_vertices_get, _Box2D.b2PolyDef_vertices_set)

It seems to say something about having get and set functions, but I Can't figure out why it doesn't say anything about an array for these vertices.


Top
 Profile  
 
PostPosted: Sun Feb 03, 2008 8:44 pm 
Offline

Joined: Mon Dec 17, 2007 10:11 pm
Posts: 185
Python confuses me, but in AS3 I can do this:

Code:
arcDef.vertexCount=3;
arcDef.vertices[0].Set(width, 0);
arcDef.vertices[1].Set(0, height);
arcDef.vertices[2].Set(0, 0);


Unless something was changed over for the AS3 port, "vertices" is an array of b2Vec2s.


Top
 Profile  
 
PostPosted: Mon Feb 04, 2008 6:36 am 
Offline

Joined: Sun Jan 27, 2008 5:25 am
Posts: 15
That's what has me confused. It should be an array, but it's not acting like one. Maybe I take it to the swig people.


Top
 Profile  
 
PostPosted: Mon Feb 18, 2008 12:53 am 
Offline

Joined: Mon Feb 18, 2008 12:30 am
Posts: 88
Upgraded to Python 2.5.1 and it works for me now (2.4 was giving me problems).

If anyone else wants more info on building it for Python on OSX, just let me know. I did it in a messy fashion, but it'll work at least.


Top
 Profile  
 
PostPosted: Fri Feb 29, 2008 9:51 pm 
Offline

Joined: Mon Feb 18, 2008 12:30 am
Posts: 88
I'm working on trying to get userData working, but with only a small amount of luck. Did Remo's version of Box2D.i fix the problem? I've scoured the forums, and it appears that his version is long gone. This is what I've been trying, with moderate success:

Code:
%module Box2D
%{
    #include "../Include/Box2D.h"
%}

//extern PyObject* _wrap_b2Shape_m_userData_set(PyObject*, PyObject *args);

#ifdef SWIGPYTHON
    %typemap(in) void* userData, void* m_userData {
//        printf("\n(Typemap in $symname)\n");
        if ($input == Py_None) {
            $1 = NULL;
        } else {
            $1 = (void*)( $input );
            Py_INCREF($input);
        }
    }
    %typemap(out) void* userData, void* m_userData {
//        printf("\n(Typemap out $symname)\n");
        if ($1 == NULL) {
            $result = Py_None;
        } else {
            $result = (PyObject*)( $1 );
            Py_INCREF($result);
        }
    }
#endif


%include "../Include/Box2D.h"


Edit: The above seems to be mostly working. Instead of .GetUserData(), [shape, etc].m_userData should be accessed directly.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 51 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group