Jump to content
  • Advertisement
Sign in to follow this  
Finalspace

How to combine polygon and circle local/world transformation?

This topic is 1005 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a rigid body, it have a world position and rotation.

The rigid body may have multiple shapes, each shape may have a local rotation and offset.

 

Maybe one shape is a polygon and another is a circle - so its a combined thing.

Each of that has its local offset to some extend - so that its not on the body center anymore.

 

When i for example want to draw a polygon in world space with all the transformation applied i do it like this:

Mat2f localRotation(0.05f);
Vec2f localOffset(100, 0);

Mat2f worldRotation(0.15f);
Vec2f worldPosition(0, 0);

for (int i = 0; i < numVerts; i++) {
  v2 p0 = (V2(localVertices[i]) * localRotation + localOffset) * worldRotation + worldPosition;
  v2 p1 = (V2(localVertices[i < numVerts - 1 ? i + 1 : 0]) * localRotation + localOffset) * worldRotation + worldPosition;
  drawLine(p0, p1);
}

But what about circle shapes? They will change the position when the local offset is not zero.

//Mat2f localRotation(0f); // Circles dont have a local rotation at all
Vec2f localOffset(-100, 0);

Mat2f worldRotation(0.15f);
Vec2f worldPosition(0, 0);

Vec2f pos = V2(localOffset) * worldRotation + worldPosition;

drawCircle(pos, radius);

This seems to be a totally different way than the implementation above.

 

Is there a nice way to change the polygon drawing to use this way - so that it uses a rotated position and of course, includes the vertex rotation as well ?

 

It must be really easy, but right now i dont see it at all... 

Share this post


Link to post
Share on other sites
Advertisement

Maybe one shape is a polygon and another is a circle - so its a combined thing.


But they're still individual shapes.


I'm not really sure what your question is, but you may want to structure your hierarchies like this:

A shape has its local transformation relative to the rigid body world transform that is attatched to it;
A rigid body stores its world center of mass and world rotation (world transform) and it can have 0...n shapes;

Then you loop through a rigid body shape list and render each shape as below:

ShapeWorldTransform = BodyWorldTransform * ShapeLocalTransform;
RenderShapeAt(ShapeWorldTransform);

And hopefully answering the question: You usually don't need to transform each local vertex on the CPU. I suggest to read the graphics API documentation you're using and check how to send local vertices and matrices to the GPU for it automatically transform the local vertices into world-space after you make a draw call. Edited by Irlan Robson

Share this post


Link to post
Share on other sites

To ensure I never got confused I decided this the pipeline of transformations is:

 

model -> local -> world

 

Bodies are stored in world space. Shapes are stored in model space, and fixtures (or colliders) are stored in local space. For simple shapes like circles I just store them directly in local space. It only makes sense to store models that are complicated in model space, that way the data does not need to be duplicated each time a shape referencing a single model appears.

 

Edit: IIRC Box2D stores everything in local space. When you pass Box2D vertices for a shape, even AABBs, the vertices are copied into local space. This makes for a lot of wasted memory in a lot of tile-style games where AABBs are all over everywhere.

Edited by Randy Gaul

Share this post


Link to post
Share on other sites

What i mean with local space is the space relative to the body position / rotation.

 

The center of mass is a separeted vector which is defined relative to the bodies position - which is in most cases equals zero and it will be only used in contact preparation (calculating rA and rB).

 

A shape has its local transformation relative to the rigid body world transform that is attatched to it;

A rigid body stores its world center of mass and world rotation (world transform) and it can have 0...n shapes;

 

Then you loop through a rigid body shape list and render each shape as above:

 

ShapeWorldTransform = BodyWorldTransform * ShapeLocalTransform;

RenderShapeAt(ShapeWorldTransform);

 

And for the (not-so-related with math/physics) question: You usually don't need to transform each local vertex on the CPU. I suggest to read the graphics API documentation you're using and check how to send local vertices and matrices to the GPU for it automatically transform the local vertices into world-space after you make a draw call.

 

 

My structure is already defined like this, but i dont use any graphics API at all - its just plain pixels and i do the transform myself.

But it seems combining the translation and rotation into a 3x3 matrix should be better anyway... so i can really just do "worldTransform * localTransform".

Share this post


Link to post
Share on other sites

It was so simple...

		Mat2f worldRot = new Mat2f().setFromAngle(body.rotation);
		Vec2f worldPos = body.pos;
		
		Mat2f localRot = new Mat2f().setFromAngle(shape.localRotation);
		Vec2f localPos = shape.localPos;
		
		Mat2f finalRotation = new Mat2f(worldRot).mult(localRot);
		Vec2f finalPos = new Vec2f(localPos).mult(worldRot).add(worldPos);
		
		VertexBasedShape vbs = (VertexBasedShape) shape;
		int numVerts = vbs.getVertexCount();
		Vec2f[] localVertices = vbs.getLocalVertices();
		for (int i = 0; i < numVerts; i++) {
			Vec2f p0 = new Vec2f(localVertices[i]).mult(finalRotation).add(finalPos);
			Vec2f p1 = new Vec2f(localVertices[i < numVerts - 1 ? i + 1 : 0]).mult(finalRotation).add(finalPos);
			drawLine(p0.x, p0.y, p1.x, p1.y, color);
		}

Problem solved.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!