Experimental Scala port

Discuss issues specific the Scala port of Box2D
BorisTheBrave
Posts: 1911
Joined: Mon Jan 07, 2008 10:51 am
Contact:

Re: Experimental Scala port

Postby BorisTheBrave » Mon Jun 01, 2009 3:29 pm

I think that's asking a bit much, Villane. But it would be good to have a small set of samples which are designed to stress performance and measure it in a canonical way. Ones to stress the engine in different ways. And configurable with a (single!) parameter to increase the load, so that we can scale benchmarks according to performance.
So, say: pistons, pyramids, 100% sensors, vast world with low collision rate, raycast test.

It might be easiest just to classify the existing C++ testbed examples into feature/performance/showing off, and then mandate that the performance and feature ones must be ported.

Villane
Posts: 101
Joined: Mon Sep 01, 2008 6:32 am

Re: Experimental Scala port

Postby Villane » Mon Jun 01, 2009 3:35 pm

BorisTheBrave wrote:I think that's asking a bit much, Villane. But it would be good to have a small set of samples which are designed to stress performance and measure it in a canonical way. Ones to stress the engine in different ways. And configurable with a (single!) parameter to increase the load, so that we can scale benchmarks according to performance.
So, say: pistons, pyramids, 100% sensors, vast world with low collision rate, raycast test.

It might be easiest just to classify the existing C++ testbed examples into feature/performance/showing off, and then mandate that the performance and feature ones must be ported.


You're right, it probably is too much. Could be done only if developers of several ports really want to do that.

I'm probably creating something like that for the Scala port though (except it'll run in a single JVM, not launch each test separately) and since it's not too much effort for me to do the same for Java, I'll probably do that too.

Zzzzrrr
Posts: 103
Joined: Sat Mar 15, 2008 5:49 am
Location: Washington, DC
Contact:

Re: Performance Timings

Postby Zzzzrrr » Tue Jun 02, 2009 6:28 am

ewjordan wrote:I've thought for a while that it would be good to have a standard benchmarking scene for this reason


Excellent idea. I also think it would be good to have a standard test that simulates the following:

    Various joints
    Compound shapes
    Stacking
    Multiple Islands
    Bullets
    Constant motion (no sleeping)

How about the washing machine demo filled with ragdolls, compund shapes, and bullets, all rotating above the standard demo platform with various stacked islands? To make sure we cover all the joints we could also connect the compound shapes as needed...

Villane
Posts: 101
Joined: Mon Sep 01, 2008 6:32 am

Re: Experimental Scala port

Postby Villane » Mon Jun 08, 2009 6:55 pm

To make it easier to create box2d scenes, I once experimented with an external DSL (i.e. some text file format), but it didn't seem that useful because if I wanted to use computations or loops for defining shapes, the language would become too big. And without all that you can do very little.
But I'd still like to be able to define scenes really easily, so I'm experimenting with an internal DSL now (i.e. the code is still in Scala, but it looks somewhat like a DSL). Here's an example of what I've got so far, the definition of the pyramid test:

Code: Select all

import box2d.dsl.DSL._
implicit val world = ...//create world

def createScene {
    body {
      pos(0, -10)
      box(50, 10)
    }

    // Put some heavy cannonballs in the middle of the pyramid
    for (i <- 1 to 3) body {
      pos(-5 + i * 5, 20)
      circle(0.5f) density 40
      massFromShapes
    }

    val box1 = box(0.5f, 0.5f) density 5 restitution 0 friction 0.9f

    val sx = (-10.0f, 0.75f)
    val Δx = (0.5625f, 2.0f)
    val ex = sx + Δx * 25
    val Δy = (1.125f, 0.0f)

    for {
      x <- sx to ex by Δx
      y <- x to (x + Δy * (ex.y - x.y) / Δx.y) by Δy
    } body {
      pos(y)
      fixture(box1)
      massFromShapes
    }
}


Some explanation: body {...} creates a context object behind the scenes, and takes a closure parameter. It also requires an implicit world to be present. Every fixture/shape defined in that closure is created on the body after the block is completed. Various attributes of the body can be specified in that closure too: pos(x,y) fixedRotation(true) etc., similarly attributes of fixtures can be specified after a shape definition. fixture(...) is used to add an existing fixture definition to the body.
You can of course use any other code inside the closure for doing calculations etc.

The for loop is an experiment with Vector ranges (similar to Int ranges in scala library): define a starting point, an end point and the step/delta (v1 to v2 by deltaV) and it will generate vectors as you would expect. Of course, in this example, the math to determine the end of y is probably harder to understand than the original code which used two nested loops over integers

Source is currently in this branch: http://github.com/Villane/scalabox2d/tr ... from_box2d

Zzzzrrr
Posts: 103
Joined: Sat Mar 15, 2008 5:49 am
Location: Washington, DC
Contact:

Re: Experimental Scala port

Postby Zzzzrrr » Mon Jun 08, 2009 7:16 pm

Villane wrote:so I'm experimenting with an internal DSL now


That's quite neat and certainly makes creating scenes by hand much easier.

BTW, how about creating scenes via. SVG graphics or XML? You could draw your scenes in an external graphics editor, define properties, and then load at runtime...

kellrott
Posts: 7
Joined: Sun Jun 07, 2009 3:04 pm

Re: Experimental Scala port

Postby kellrott » Tue Jun 09, 2009 9:28 am

One of the other ongoing thread topics on this board deals with the performance of JBox2d in Android. I've read it's possible to run Scala on Android. Has anybody tried the to run Scala Box2D on Android?

BorisTheBrave
Posts: 1911
Joined: Mon Jan 07, 2008 10:51 am
Contact:

Re: Experimental Scala port

Postby BorisTheBrave » Tue Jun 09, 2009 12:07 pm

I've defined an XML format for scenes, though I've only written a parser for AS3.

ewjordan
Posts: 803
Joined: Sun Sep 23, 2007 2:35 pm

Re: Experimental Scala port

Postby ewjordan » Tue Jun 09, 2009 12:13 pm

kellrott wrote:One of the other ongoing thread topics on this board deals with the performance of JBox2d in Android. I've read it's possible to run Scala on Android. Has anybody tried the to run Scala Box2D on Android?

I imagine it would be far easier to get ScalaBox2d converted to fixed point math than JBox2d (in Scala you should simply be able to define your own Float class using fixed point math and switch the imports so that you use that instead of the built in Float - if only we could do that in Java!). The main problems getting JBox2d running on Android were 1) floating point emulation on Android is really slow, and 2) GC is not too fast either. 2) would still have to be tackled by reducing temp object creation, but that's a lot easier than converting to fixed point by hand.

I would love to hear about the results if anyone has the energy to try it.

Villane
Posts: 101
Joined: Mon Sep 01, 2008 6:32 am

Re: Experimental Scala port

Postby Villane » Tue Jun 09, 2009 12:37 pm

I might try it on Android in a month or two, probably won't have time sooner.

I also have thought about replacing Float in Scala, a few thoughts:

You currently cannot do that very well (or you'll have to import an object every time to get the type). In Scala 2.8 you can define package level type aliases so there it will be a lot easier:

Code: Select all

package object box2d {
  type Float = FixedPoint // or type Float = Double
}

And every package under box2d will automatically see that type.
// NOTE: I'm not sure this will actually hide the type scala.Float, maybe it needs a different name?

What about literal definitions? 0.0f, 1.0f etc.? They can of course be implicitly converted from Float to a Fixed point type, but that might raise other performance issues?

I think (but not sure) the only possibility to have literals be of the right type too is to introduce a compiler plug-in to add a new suffix to number literals. for example 10s would be replaced with 10f, 10d, or FixedPoint(10).
Or actually 10.s might be just as fast for a fixedpoint class, but it will be slower for primitives. if the s method is defined like this:

Code: Select all

class FixedPoint(v: Int) {
  def s = this
}
implicit def int2fixedpoint(v: Int) = FixedPoint(v)
Maybe we could even do units with this? meters, seconds etc.? Probably not worth it.

What do you think? A compiler plug-in requirement would probably be too much of a hindrance for using the library, but I'm starting to like the second option. it may make primitives slower, or compile time inlining might eliminate most of the problems... would have to test this.

Villane
Posts: 101
Joined: Mon Sep 01, 2008 6:32 am

Re: Experimental Scala port

Postby Villane » Sun Jun 14, 2009 8:47 am

Float is now replaceable. This required hundreds of changes to the code and may require changes in user code, so I commited it to a branch for now: http://github.com/Villane/scalabox2d/tree/scalar_type

How this is achieved:

Everywhere in the code, the alias Scalar is used instead of Float (I could have just defined the alias Float to mean something else, but that might cause some confusions, so I think it's better to use a different name).

The alias Scalar is defined to be either Float (in the FloatMath trait) or Double (DoubleMath trait). To change from Float to Double, you have to change vecmath.Preamble: extends DoubleMath instead of extends FloatMath. And recompile everything!

It is necessary to add vecmath.Preamble._ imports everywhere Scalar is used. In Scala 2.8 an import of vecmath._ will be sufficient.

Other changes this caused: some fields and variables were defined with type inference. I had to add type annotations (x: Scalar) to lots of places, including some mutable local variables.
I didn't change any literal values, so it is possible that some local compuations are still done using Float. The literals are all still Float literals, but they will be implicitly converted to Double where needed.

I haven't done much benchmarking, but it seems performance doesn't suffer very much when using Double. In fact, bodies seem to be falling asleep earlier so it might even improve performance in some cases. Does this seem correct?


Return to “Scala”



Who is online

Users browsing this forum: No registered users and 1 guest