0
\$\begingroup\$

I have a compound object, consisting of a b2Body, vector-graphics and a list polygons which describe the b2body's shapes. This object has its own transformation matrix to centralize the storage of transformations. So far everything is working quiet fine, even scaling works, but not if i scale around a point.

In the initialization phase of the object it is scaled around a point. This happens in this order:

  1. transform the main matrix
  2. transform the vector graphics and the polygons
  3. recreate the b2Body

After this function ran, the shapes and all the graphics are exactly where they should be, BUT: after the first steps of the b2World the graphical stuff moves away from the body. When I ran the debugger I found out that the position of the body is 0/0at start after first few steps

the red dot shows the center of scaling. the first image shows the basic setup and the second the final position of the graphics. This distance stays constant for the rest of the simulation.

If I set the position via

myBody.SetPosition( sx, sy );

the whole scenario just plays a bit more distant for the origin. Any Idea how to fix this?

EDIT::

I came deeper down to the problem and it lies in the fact that i must not scale the transform matrix for the b2body shapes around the center, but set the b2body's position back to the point after scaling. But how can I calculate that point?

EDIT 2 ::

I came ever deeper down to it, even solved it, but this is a slow solution and i hope that there is somebody who understands what formula I need.

assuming to have a set polygons relative to an origin as basis shapes for a b2body:

scaling the whole object around a certain point is done in the following steps:

  1. i scale everything around the center except the polygons
  2. i create a clone of the polygons matrix
  3. i scale this clone around the point
  4. i calculate dx, dy as difference of clone.tx - original.tx and clone.ty - original.ty
  5. i scale the original polygon matrix NOT around the point
  6. i recreate the body
  7. i create the fixture
  8. i set the position of the body to dx and dy

done!

So what i an interested in is a formula for dx and dy without cloning matrices, scaling the clone around a point, getting dx and dy and finally scale the vertex matrix.

\$\endgroup\$
2
  • \$\begingroup\$ Why would you want to scale the Box2D world? If you want to use a camera have a separate world-space from your display-space. \$\endgroup\$ Commented Apr 1, 2012 at 20:37
  • \$\begingroup\$ i want to scale a b2body.. did i wrote world?? \$\endgroup\$
    – philipp
    Commented Apr 1, 2012 at 20:45

1 Answer 1

1
\$\begingroup\$

I finally write this post because I just got right now! All the differences between the shapes, the body, the save geometry and the graphical assets could not be wiped out with one transform matrix.

The final Idea which works just great was to use two matrices for the compound Object, one for translation and rotation and another for scaling. So in fact this first Matrix is actualized by the body in the following way:

function update(){
    var pos = this._body.GetTransform();
    var s = WorldController.scale;
    this._transform.set(
        pos.R.col1.x,
        pos.R.col1.y,
        pos.R.col2.x,
        pos.R.col2.y,
        pos.position.x * s,
        pos.position.y * s
    );
    draw.call( this );
}

and in the scale functions this happens:

function scale( sx, sy, center ){
    var s = WorldController.scale;
    this._body.SetActive( false );
    var c = center || null;
    if( c == null ){
        var local = this._body.GetLocalCenter();
        c = new paper.Point(
            local.x * s,
            local.y * s );
    }

    var x = sx || 1;
    var y = sy || sx;


    this._scale.scale( x, y, c );
    cleanFixtureList.call( this );

    makeFixture.call( this );

    this.queue( start );

}

and finally when drawing the objects this function comes into play:

function draw(){
    var t = this._transform;

    var test = t.clone().concatenate( this._scale.clone() );

    this._ahtml.draw( test );

    this._group._matrix.set(
        t._a, t._c, t._b, t._d, t._tx, t._ty );
    this._group._matrix.concatenate( this._scale.clone() )
}

this is working quiet good and is even faster than my first solutions. I know that there are still some redundant clone() calls and there might be another, better solution with only one matrix, but keeping in mind that box2d does not provide scaling, this adds it in a certain way.

How to finally resize the b2Body, i found here

Greetings, philipp

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .