Fling - a port of the physaxe 2D physics library

Monkey Archive Forums/Monkey Projects/Fling - a port of the physaxe 2D physics library

muddy_shoes(Posted 2011) [#1]
I thought it best to have a separate topic rather than clutter up the chipmonkey thread.

The code isn't completely converted (there are still some compilation issues with one demo) but it's in a generally working state, so I've pushed it up to a google code project at http://code.google.com/p/fling/ so that people can have a play if they want.

Please be aware that a number of things will change and that includes the API, if only to make the casing style consistent with Monkey, so I wouldn't write a ton of code against what is there just yet.

Quick instructions:

* Grab the fling project code via mercurial and put it in your modules directory.
* Create a new monkey file like so:

import fling.demo.maindemo

Function Main() 
	new MainDemo()
End


* Build it and you'll have the same thing as this Flash demo or this HTML5 demo. (Warning! The HTML5 performance on Firefox is currently terrible and it may cause the browser to throw an error. Use Chrome if possible.)

MainDemo extends the mojo App class so you can look at that if you want to see how you can build your own -- with the caveat as above about the state of the library.


muddy_shoes(Posted 2011) [#2]
And if anyone looks at the code and wonders why it's a little crazy. It's because most of the conversion work was done by regexes and some C#. The first priority was to get something running so I could verify that it would work at all and things like formatting, naming conventions and nicely encapsulated classes haven't been part of the agenda yet.


Xaron(Posted 2011) [#3]
This is very, very cool. I can sit back and relax now... Well just kidding of course. ;)


slenkar(Posted 2011) [#4]
looks great so far, just a little request...


Im using physaxe for a little basketball game and it seems you can only create one 'world' otherwise it crashes,
i need 2 worlds
one for the gameplay and one to show the player where the ball would go if he shoots it
would it be possible to have 2 worlds in fling?

I tested on Firefox 4 for a laff it seemed ok, just a little slow
fast in opera(!)


muddy_shoes(Posted 2011) [#5]
@slenkar

All things are possible but the first priority is to get to full parity with the physaxe release and to tidy the code so I can have a baseline version 1.0. That shouldn't take long and once that's done I can start seeing if there are changes/improvements to be made (and possibly backporting those to physaxe).


muddy_shoes(Posted 2011) [#6]
Okay, I've done a bunch of jiggery and pokery to change names and such to what looks like more standard Monkey and tagged it up as v1.0. You can grab it from the project page downloads area as a zip if you don't want to install mercurial.

In the medium term it looks like a future version will be better based on nape, once the current rewrite of that library is complete.


skid(Posted 2011) [#7]
Nice work!

I started converting nape using the haxe output and not the original caxe source.

This turned out to possibly be the wrong approach, after going through my rudimentary haxe to monkey converter I ended up with a lot of files with a lot of weird syntax.


muddy_shoes(Posted 2011) [#8]
About 80% of the work in converting physaxe was done with a set of regexes. The syntax problems with haXe conversion are mostly down to the availability of funky scoping like "return if { expression } else { expression }", which can't be easily processed without getting serious about parsing.

Ultimately though, the real show stopper for automatic conversion is the type inference and Monkey's curious "pretend dynamic typing". The debugging process was mostly about finding instances where physaxe declared something without a type that was used as a float. Monkey happily assumes that such variables are ints and doesn't complain if you are assigning a float. I think this is really a flaw in Monkey as it's really error-prone.

Anyway, with the regexes and having learned a few things about processing the haXe code before converting to remove problematic structures I doubt it will take long to convert nape. I just don't want to spend the time until the project lead has finished his rewrite.


slenkar(Posted 2011) [#9]
ah ah version 1.0! checking it out now


MikeHart(Posted 2011) [#10]
@muddy_shoes

Monkey happily assumes that such variables are ints and doesn't complain if you are assigning a float. I think this is really a flaw in Monkey as it's really error-prone.


You are using the STRICT mode, right?


slenkar(Posted 2011) [#11]
I noticed the shapes were all just lines so I compiled to DS for a laff


and it actually frickin worked :_)







Loofadawg(Posted 2011) [#12]
Okay, that is just geeky cool. My son is going to freak if I pull that off on his DS.

Maybe a quick "How To Setup the DS as a Target guide" ? :D


slenkar(Posted 2011) [#13]
its too zoomed in ATM, im trying to get loadmatrix to work so it will fit the screen


slenkar(Posted 2011) [#14]
I tried to create a little demo of a ball bouncing ,
but the ball acts weirdly:

Strict 
Import mojo
Import fling.allfling

Class physapp Extends App
	
	Field floor : Float
	Field size : Vector
	Field updates : Int
	Field debug : Bool
	Field stopped : Bool
	Field recalStep : Bool
	Field world : World
	Field draw : Bool
	Field curbf : Int
	Field frame : Int
	Field ballmaterial:Material
	Field broadphases : BroadPhase[] = [BroadPhase(New SortedList()), BroadPhase(New Quantize(6)),BroadPhase(New BruteForce())]
	Field fd : MojoDraw = New MojoDraw()
Method OnRender:Int()
	Cls 0,0,0
		
		If( debug ) 
		
			'fd.boundingBox.line = 0x000000
			'fd.contact.line = 0xFF0000
			'fd.sleepingContact.line = 0xFF00FF
			fd.drawCircleRotation = True
		End

		If( draw )
		   fd.DrawWorld(world)
		End
End Method
Method OnUpdate:Int()
'// Update
		Local Updates :=  updates
		If(  stopped  )
		    Updates = 0 
		End

		Local dt : Float = 1.0
		Local niter := 5
		For Local i := 0 Until Updates 
			world.Update(dt/Updates,niter)
		End

		If( recalStep )
		   world.Update(0,1)
		End

End Method
	Method CreateFloor:Void(  mat : Material = Null  ) 
		Local s  := Shape.MakeBox(600,40,0,floor,mat)
		world.AddStaticShape(s)
	End 
Method OnCreate:Int()
	frame = 0
		curbf = 0
		draw = True
		debug = False
		stopped = False
		ballmaterial= New Material(0.1, 0.5, 1)
		SetUpdateRate(20)
		updates=2
		floor = 580
		recalStep = False
		world = New World(New AABB(-2000,-2000,2000,2000),broadphases[curbf])
		fd = New MojoDraw()
		Print("Press 1-8 to change demo scene. Mouse click fires block.")
world.gravity.Set(0,0.1875)
		CreateFloor()
		Local box  := Shape.MakeBox( 30, 30, Constants.NaN, Constants.NaN, New Material(0.0, 0.8, 1) )
		Local startY  := floor - 15

Local body  := New Body(150,50)
body.AddShape(New Circle(12,New Vector(-30,0),ballmaterial))
world.AddBody(body)

End Method
Method CreatePoly : Void( x : Float, y : Float, a : Float, shape : Polygon,  props : Properties = Null  ) 
		Local b  := New Body(x,y)
		Local vl := New HaxeArray<Vector>()
		Local v  := shape.verts

		While( Not( v = Null ) ) 
			vl.Push(v)
			v = v.nextItem
		End 

		b.AddShape( New Polygon(vl,New Vector(0,0),shape.material) )
		b.SetAngle(a)
		
		If( Not( props = Null ) ) 
		   b.properties = props
		End 
		
		world.AddBody(b)
	End 

End Class

Function Main:Int()
New physapp
End Function



muddy_shoes(Posted 2011) [#15]
body.AddShape(New Circle(12,New Vector(-30,0),ballmaterial))


In that line you're adding the circle 30 units to the left of the centre of the body. This appears to be causing the odd behaviour. I'm not sure it's correct, as I thought the body was abstract in physics terms, but moving the circle to (0,0) fixes the problem.

You might also want to increase the restitution of the ball material if you want it to bounce.


slenkar(Posted 2011) [#16]
thanks!
(i copy pasted the code from the demo with the offset balls - thats why I had that offset)


muddy_shoes(Posted 2011) [#17]
@Mike Hart

>You are using the STRICT mode, right?

Nope, because haXe is a dynamically typed language and so Strict mode was not a good match considering the wide use of type inference.

My issue with the Int and Float behaviour is that is seems inconsistent with the rest of the inference behaviour.

Local myVal = 3.542


I would say that that line expresses the intent to use a floating point value, and yet Monkey just assumes any number being assigned to an untyped variable should be truncated to an int.


muddy_shoes(Posted 2011) [#18]
I've updated Fling to 1.01. This just fixes a few bugs.

Downloads are here: https://code.google.com/p/fling/downloads/list.


skid(Posted 2011) [#19]
Looks great. HTML5 performance is more than great when DEBUG mode is not enabled.

You should upload the demo app on this site.

I'm planning on using Fling in my next project, IMHO it is the best thing to hit monkey yet.


Volker(Posted 2011) [#20]
How do I apply forces and torque to bodies?
Or is cpBodyApplyImpulse, cpBodyApplyForce etc. not implied yet?


skid(Posted 2011) [#21]
It seems iPod C++ performance is no where near Chrome desktop speeds so am hoping to post some profiler results soon.


muddy_shoes(Posted 2011) [#22]
@Volker

I'm guessing those are chipmonkey method names. Fling is a port of physaxe, which is not an exact port of chipmonkey and is missing some features, such as constraints. If those methods weren't in physaxe then they aren't currently in Fling. I'll take a look at the chipmonkey code sometime in the next day or two. If the methods look useful and fit with how Fling works I'll port them over.

@skid

That would be interesting to see.


slenkar(Posted 2011) [#23]
Thanks 1.01 fixed the restitution bug

The angle of bodies seems to go from about 1 to -1
When I multiply body.a by 360 to get the angle to draw the image at it seems a bit extreme,
multiplying by 90 seems better


MikeHart(Posted 2011) [#24]
Maybe the angle is stored as a radian value.


OvineByDesign(Posted 2011) [#25]
Nice work muddy_shoes.

I've tweaked the debugdraw so you can specify a screen offset - handy for scrolling screens. - can this be contributed ? - I see no contact details etc in the google code project.


muddy_shoes(Posted 2011) [#26]
You can send the changes to the mail address in my profile. I'm kind of busy with another related project at the moment (and also moving house this weekend) so it might be next week before I get around to patching it in.


MikeHart(Posted 2011) [#27]
Hi,

with #40, I can't get fling to be compiled anymore and get teh following error:


Translating alldemo
/Users/michaelhartlef/Desktop/Monkey/MonkeyPro40/bin/trans_macos -target=html5 -run /Users/michaelhartlef/Desktop/Monkey/MonkeyPro40/modules/fling/demo/alldemo.monkey

TRANS monkey compiler V1.13
Parsing...
Semanting...
terminate called after throwing an instance of 'char*'

Process Complete




muddy_shoes(Posted 2011) [#28]
It works for me. Looking at your output, you seem to be trying to compile from the alldemo.monkey file. That's not the intended compilation start point. Have you tried creating a monkey file as in the first post of this thread and compiling that?


MikeHart(Posted 2011) [#29]
Nope, the same file compiled fine under #38. Where do you have the demo files located so they compile fine for you?


OvineByDesign(Posted 2011) [#30]
Works fine here, as long as you compile and run maindemo.monkey


MikeHart(Posted 2011) [#31]
Thanks, that worked.


muddy_shoes(Posted 2011) [#32]
Nope, the same file compiled fine under #38. Where do you have the demo files located so they compile fine for you?


My setup is as outlined in the first post of the thread. Fling is installed as a module and I include the maindemo.monkey file and initialise the App that it defines.

Alldemo.monkey is just a "package include" file and not meant to be the compilation start point. If that worked and now doesn't, it is something to do with a change in Monkey behaviour and, as it was never intended to work that way, it's not something I'd be looking to fix.


Volker(Posted 2011) [#33]
Are there some informations in there about the force of impact of collided objects? Should be in the Arbiter or Contact class.


muddy_shoes(Posted 2011) [#34]
I'm not entirely sure what you mean by "should". Are you saying that physaxe has some feature that Fling is missing?

If you're just asking how to get collision information then maybe this thread will help you: http://www.0x61.com/forum/programming-haxe-f233/physaxe-collision-info-t1286121.html .

Please remember that Fling is a port of physaxe and I converted the code without becoming an expert on the details of how it works. Searching for information about physaxe usage is probably going to get you an answer sooner than asking me here.

If you want to do some fancy stuff with collision responses, such as breakable objects, then you might want to wait for the Box2D release as Box2D has hooks for that sort of thing.


Volker(Posted 2011) [#35]
I'm not entirely sure what you mean by "should".

Ehm, I meant like "if it's there, it is in this classes".
If you want to do some fancy stuff with collision responses, such as breakable objects..

No no, I'm creating a quite simple lander game and I'm happy with
the simplicity of fling. Box2D took a long span to get in it and Fling
is MUCH easier to use.
Please remember that Fling is a port of physaxe

I forgot. Searching for "physaxe" instead of "fling" pointed me in
the right direction. jnAcc and jtAcc in class contact are the proper fields.
Thanks for the link (and for fling)!


luggage(Posted 2011) [#36]
I'm just trying the same thing at the moment. I want to find out if body A has hit body B. Do you have any example code or anything? All I've found on the Haxe forums are quite confusing responses that would require editing world.monkey which I'd like to avoid.

Thanks!


muddy_shoes(Posted 2011) [#37]
@luggage

The link I gave in my last post in the thread is about as much help as I can offer. At some point I may revisit Fling to see about adding some basic hooks for collisions but the lack of those things was part of the reason for porting Box2D. Physaxe was written to provide a fast but minimal physics library that specialises in large structures rather than a competitor to more complete game-physics libraries like Box2D/Chipmunk.


luggage(Posted 2011) [#38]
No probs. I've switched over to Box2D now based on your advice.

Thanks!


Volker(Posted 2011) [#39]
Sorry luggage, I missed your post. In case some followers will stumble
over collision detection:
' Pseudocode
Field haxes:HaxeFastList< Arbiter > ' arbiters contain collision data
haxes=body.GetArbiters() ' get the arbiters of a body
For Local arb:Arbiter=eachin haxes 
  local shape1:Shape=arb.s1
  local shape2:Shape=arb.s2
  local body1:Body=shape1.body 'get 1st body involved in collision
  local body2:Body=shape2.body 'get 2nd other body involved in collision
  ' now you can compare the bodies involved in collision with
  ' your object bodies
Next



luggage(Posted 2011) [#40]
Thanks Volker. I'll give that a try. I can flick between both physics engines at the moment and I don't need anything too stressful for my game so it might be a better fit.