1
\$\begingroup\$

I'm recently learning entity component systems, and started implementing it into my test engine, however I'm having an issue integrating this with scene-graph, which I'm trying for the first time.

All my entities have a TransformComponent which transforms the entity in the scene, with it's position, rotation and scale. This is how I'm doing this:

transform.reset();

Entity entity = this.entity;

while (entity != null)
{
    if (!lockScale) transform.scale(entity.scale);
    if (!lockRotation) transform.rotate(Vector3.AXIS_Z, entity.rotation);
    if (!lockPosition) transform.translate(entity.position);

    entity = entity.parent;
}

The TransformComponent is present for all the entities, and hence it cannot be removed from the entity, I restrict it.

Now I have another component, called as CollisionComponent which contains the polygon, and a callback when a collision occurs, along with a collision tag. It updates the polygon position upon update:

polygon.setPosition(entity.position);
polygon.setRotation(entity.rotation);
polygon.setScale(entity.scale);

This is working for all the entities that are in the scene root, they are displayed at their correct positions, and also the collisions are working. The issue starts with the entity's children if they are present.

I have attached a child entity with position set to (0, 50) whose coordinate system is local to the parent entity system. But here, the graphics work correctly, on rotating the parent, the children rotate too due to the transform matrix, but the polygon stays at the local position.

The solution that I'm thinking now is to make the entity positions in global coordinate system, even if they are in the children of an entity, and have the transform change correctly even when the parent moves.

How can I do that?

\$\endgroup\$
1
\$\begingroup\$

I found my issue after getting some sleep, I forgot to take care of the parents in the CollisionComponent. All I had to do is to iterate up in the entity heirarchy chain (scene graph nodes) and apply the parent transforms to the polygon.

// Get some temporary Vector objects to work from the object pool
Vector2 tPosition = Vector2.REUSABLE_STACK.pop();
Vector2 tScale = Vector2.REUSABLE_STACK.pop();

// The temporary rotation variable
float rotation = 0;

// Set the entity properties into the temporary ones
tPosition.set(entity.position);
tScale.set(entity.scale);
rotation += entity.rotation;

// Get the parent of this entity
Entity parent = entity.parent;

// Iterate while the parent is not null and apply it's transforms
while (parent != null)
{
    rotation += parent.rotation;
    tScale.scale(parent.scale.x, parent.scale.y);
    tPosition.rotate(parent.rotation).add(parent.position);

    parent = parent.parent;
}

// Apply the transforms into the polygon
polygon.setCenter(tPosition);
polygon.setScale(tScale);
polygon.setRotation(rotation);

// Push back the temporary vectors into the object pool
Vector2.REUSABLE_STACK.push(tPosition);
Vector2.REUSABLE_STACK.push(tScale);

And this is how it looks in the screenshot:

Test Screenshot

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.