News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Box2D Wrapper

Started by slayer93, October 26, 2008, 03:04:29 PM

Previous topic - Next topic

slayer93

Hello guys,

Once I got PlayBasic I have been messing around with making a wrapper for Box2D. I have been hacking away at it all weekend and I got the core of it done. I also figured a nice and easy way for it to control the sprites for you by creating a command set that wraps the commands I wrapped. So you don't use the functions in the dll (unless you want to) but use the command set that does everything for you.

Right now you can create worlds, bodies, and use forces to move them (or let gravity do its work if you want).

The library will also be free to use but I'm not releasing it yet because I want to add a few more things so it can do more but thought I would show what I have now and see what you guys thought. Hopefully I can release it tonight or tomorrow :)

I will show you a couple screenshots though it does not serve justice to what Box2D can do. And here is the code to show how simple (or complex?) it is.

PlayBASIC Code: [Select]
; PROJECT : Box2D Demo
; AUTHOR : Christian Ang
; CREATED : 10/19/2008
; EDITED : 10/26/2008
; ---------------------------------------------------------------------

; Setup
SetFPS 60
CreateCamera 1
RenderToScreen

; Use Box2D
#include "box2D"

; Create a new world
B2DCreateWorld( 1, -100.0, -100.0, 200.0, 200.0, 0.0, 0.5 )
B2DSetWorldStep( 1, 1.0 / 60.0 )
B2DSetWorldVelocity( 1, 1.0 )
B2DSetWorldIterations( 1, 10.0 )
B2DSetWorldMtPRatio( 1, 10.0 )

; Create a ground Body
boxc 0,0,200,10,1,rgb(0,0,120)
getImage 1,0,0,200,10
gSpr=newSprite( 0, 0, 1 )
AutoCenterSpriteHandle gSpr, 1

B2DCreateBody( 1 )
B2DSetBodyPosition( 1, 10.0, 20.0 )
B2DBuildBody( 1 )
B2DCreateShape( 1 )
B2DSetShapeAsBox( 1, 10.0, 0.5 )
B2DAddShapetoBody( 1, 1 )
B2DLinkSpriteToBody( gSpr, 1 )

; Create Boxes


Boxc 0,0,20,20,1,rgb(100,0,0)
getImage 2,0,0,20,20

For i=2 to 20
B2DCreateBody( i )
B2DSetBodyPosition( i, 10.0, 0.0-i*2.2 )
B2DBuildBody( i )
B2DCreateShape( i )
B2DSetShapeAsBox( i, 1.0, 1.0 )
B2DSetShapeFriction( i, 0.1 )
B2DSetShapeDensity( i, 1.0 )
B2DAddShapetoBody( i, i )
B2DCalculateBodyMass( i )
spr=newSprite(0, 0, 2)
AutoCenterSpriteHandle spr, 1
B2DLinkSpriteToBody( spr, i )
Next i


; Main Loop
Do

CaptureToScene
ClsScene

If spacekey()=1 then B2DApplyImpluse( 2, 0.5, 0.5, 0.0, 0.0 )

; Draw the Box2D World
B2DDrawWorld( 1 )

; Update Box2D World
B2DUpdateWorld( 1 )

DrawCamera 1

; Sync
Sync
Loop





thaaks

Ooooooh, physics for PlayBasic! That's just great  :D

The wrapper looks pretty cool. Maybe you add some functions like B2DCreateNewWorld or B2DCreateNewBody where a new index value is automatically generated and returned, just like in PlayBasic. Maybe you even modify the creating functions to always return the index of the created object and never receive it as a parameter! Gasp!

I personally think a coder should never decide which index is to be used on creating a new resource - that should always be returned by the called creating function. Everything else is error prone (reusing indices, forgetting increment and so on)...

Looking forward to play with it! Do you also plan to port the testbed application (The GUI to test all the stuff)?

slayer93

Thanks :)

QuoteThe wrapper looks pretty cool. Maybe you add some functions like B2DCreateNewWorld or B2DCreateNewBody where a new index value is automatically generated and returned, just like in PlayBasic. Maybe you even modify the creating functions to always return the index of the created object and never receive it as a parameter! Gasp!


I'll probably do that ;)

QuoteLooking forward to play with it! Do you also plan to port the testbed application (The GUI to test all the stuff)?

Not sure if I will because of how massive testbed is, maybe once the plugin is completely finished but till then I'll probably create demos and examples here and there to show the new things I added and how it works. Wait a few hours and I'll hopefully finish what I want and upload it ;D

ATLUS

 :o NICE  :o 2d physic!!!!!!!!!!!!!! :P

Green7

Thanks a lot! now that opens a ot of options to a physic-coding noob like me! ;D

kevin


  Nice, good job.   I was wondering when somebody would do this.    Thankfully it's not me :)
 


slayer93

#6
Here is a quick test version you guys can try out (lets call it v0.0.1). No documentation as of yet but all the commands are listed in the Read-me. It is also extremely slow if you use a lot of dynamic objects (you can change the marked piece of code in the example to find out).

Next Update (most likely next weekend or so) I plan to see if there are any ways to improve speed and what is causing the huge speed decrease, it is most likely me trying to do things quickly. I also am going to finish up the destroy commands because although they are in the command set its not completely finished, so dont use them, then I will add in any of the get state information commands and a couple of joints if I have time.

Quick documentation on making a basic demo in Box2D because I can't leave you with a dll and no information


First Create a world using B2DCreateWorld or B2DCreateNewWorld. Box2D works in meters and not pixels, make sure you know that. The commands I have handle the conversion automatically (from meters to pixels).

B2DSetWorldMtPRatio is a command I made which stands for Meter to Pixel Ratio you specify what ratio you want, 1 meter to X pixel. In the example I made it a 1 m:10px ratio.

B2DSetWorldStep sets the step you want.
B2DSetWorldVelocity sets the velocity of the objects each step
B2DSetWorldIterations sets the iterations each step

Play around with those to see what fits you.

B2DUpdateWorld updates specified world

B2DUseWorld This will set a different world to be actively written to. If you noticed you don't have to specify the world ID in any of the body or shape commands because what you set here is what all the commands will write to. When you create a new world it is set automatically.

For bodies

B2DCreateBody( bID ) Creates a new body and later finalized with B2DBuildBody

B2DSetBodyPosition used before you build the body, you usually don't reposition bodies in the middle of a simulation

Same goes for B2DSetBodyAngle, B2DSetBodyMass, B2DSetBodyLinearDamping, B2DSetBodyAnglularDamping, and B2DSetBodyAsBullet

There is also B2DSetBodySleeping

Shapes are added to bodies, they are what is used for collision.

B2DCreateShape and B2DCreateNewShape create new shapes

B2DSetShapeAsBox uses a box shape for collision, this is the only current collision shape

You may also use B2DSetShapeFriction, B2DSetShapeDensity, and B2DSetShapeRestitution to configure the shape

B2DAddShapetoBody will attach a shape to a body (really when you create a shape it only creates a definition for the shape and when you use this command it creates a new shape under the specified body)

B2DCalculateBodyMass this will automatically calculate the body mass (depending on the shapes) for you

B2DLinkSpriteToBody when you create a body you will need to attach it to a sprite that will represent that body (for the sprite to function correctly you must center the sprite with AutoCenterSpriteHandle or CenterSpriteHandle and set the draw mode to 2 [for rotation] )

B2DDrawWorld this will reposition and rotate any attached sprites to the bodies automatically

You can also try out on your bodies B2DApplyForce, B2DApplyImpluse, and B2DApplyTorque

I think that is the gist of most of the commands you need.

[/tt]

New and Improved Example--

PlayBASIC Code: [Select]
; PROJECT : Box2D Demo
; AUTHOR : Christian Ang
; CREATED : 10/19/2008
; EDITED : 10/26/2008
; ---------------------------------------------------------------------

; Setup
SetFPS 0
CreateCamera 1
RenderToScreen

; Use Box2D
#include "box2D"

; Create a new world
wID=B2DCreateNewWorld( -100.0, -100.0, 200.0, 200.0, 0.0, 0.5 )
B2DSetWorldStep( wID, 1.0 / 60.0 )
B2DSetWorldVelocity( wID, 1.0 )
B2DSetWorldIterations( wID, 10.0 )
B2DSetWorldMtPRatio( wID, 10.0 )

; Create a ground Body
boxc 0,0,200,10,1,rgb(0,0,120)
getImage 1,0,0,200,10

gID = B2DCreateNewBody( )
B2DSetBodyPosition( gID, 15.0, 50.0 )
B2DBuildBody( gID )
sID = B2DCreateNewShape( )
B2DSetShapeAsBox( sID, 10.0, 0.5 )
B2DAddShapetoBody( gID, sID )
gSpr = newSprite( 0, 0, 1 )
AutoCenterSpriteHandle gSpr, 1
B2DLinkSpriteToBody( gSpr, gID )

gID = B2DCreateNewBody( )
B2DSetBodyPosition( gID, 35.0, 45.0 )
B2DBuildBody( gID )
sID = B2DCreateNewShape( )
B2DSetShapeAsBox( sID, 10.0, 0.5 )
B2DAddShapetoBody( gID, sID )
gSpr = newSprite( 0, 0, 1 )
AutoCenterSpriteHandle gSpr, 1
B2DLinkSpriteToBody( gSpr, gID )

; Create Boxes
Boxc 0,0,20,20,1,rgb(100,0,0)
getImage 2,0,0,20,20

; -----------------------------------------------------------
; -----------------------------------------------------------
; Change 20 to different numbers to create more or less boxes
; -----------------------------------------------------------
; -----------------------------------------------------------
For i=2 to 20
bID = B2DCreateNewBody( )
B2DSetBodyPosition( bID, rnd(500)/10, rnd(200)/10 )
B2DBuildBody( bID )
sID = B2DCreateNewShape( )
B2DSetShapeAsBox( sID, 1.0, 1.0 )
B2DSetShapeFriction( sID, 0.1 )
B2DSetShapeDensity( sID, 1.0 )
B2DAddShapetoBody( bID, sID )
B2DCalculateBodyMass( sID )
spr = newSprite(0, 0, 2)
AutoCenterSpriteHandle spr, 1
SpriteDrawMode spr,2
B2DLinkSpriteToBody( spr, bID )
Next i


; Main Loop
Do

CaptureToScene
ClsScene

text 0,0,FPS()

; Draw the Box2D World
B2DDrawWorld( wID )

; Update Box2D World
B2DUpdateWorld( wID )

DrawCamera 1

; Sync
Sync
Loop



Download - http://teroton.com/PBbox2D/Box2D.rar

Enjoy :)

slayer93

QuoteNice, good job.   I was wondering when somebody would do this.    Thankfully it's not me Smiley

After getting PlayBasic for free along with some other awesome prizes I thought I would try to give something back :P

kevin

 hmmm, I can't get it working, it's spitting up an DLL link error on the B2D_CreateWorld function.  Seems to think it doesn't exist. 

slayer93

#9
Err...really, hmm well I don't have to much time tonight but I'll see if I can take a closer look at it tomorrow when I have more free time. Here is the demo exe, see if that works.




(Broken Attachment removed)

ATLUS

Quote from: slayer93 on October 26, 2008, 10:45:40 PM
Err...really, hmm well I don't have to much time tonight but I'll see if I can take a closer look at it tomorrow when I have more free time. Here is the demo exe, see if that works.
This Example not work=(

kevin

#11
  The example doesn't work here either.    Moreover, in terms of speed, you're making a common mistake (wrong type of image).

  I suggest reading  this

 Given this is pretty big news, I would like to include a section on it the next edition of our news letter.  So chop, chop :)


slayer93

QuoteThe example doesn't work here either.    Moreover, in terms of speed, you're making a common mistake (wrong type of image). I suggest reading  this

Will have to test it on a different computer I suppose. I'll also give that a read over, thanks :)

QuoteGiven this is pretty big news, I would like to include a section on it the next edition of our news letter.  So chop, chop Smiley

Cool 8). Time to get working

slayer93

I think I got it working, it was the way I was compiling it and took a lot of googling to find it out. Re download from same place - http://teroton.com/PBbox2D/Box2D.rar

Hope it works out

kevin

#14
 Yep, works like a charmer.

When you grab images for use sprite rotation,  the image should be converted to FX format.   

Ie.
  getImage 1,0,0,200,10
  preparefximage 1
 

Note: This assume the code is targeted at PB1.63/PB1.64.  PBFX users should use 3D images (Textures)  with sprite rotation.