Saturday, March 12, 2016

javascript - Efficiently calculate 2d world position based on parent(s) recursively


I am writing a small 2d html5 game engine in javascript that relies on the concept of a hierarchy. The scene is the root node or entity, and its children make up the game objects. These children can have other children, recursively. Every entity has a relative position and an absolute position. By relative, I mean in object space, and by absolute, I mean in world space - based on its own and its parents' transformations.


To calculate the world position of an entity, all I have to do is apply its transformations (translation, rotation and scale), and that of its parent, and of its parent's parent, to its local/relative position up until the root entity of the hierarchy.


The problem I'm having is when to calculate this the most efficient way. Should I calculate the world position every time I get its worldX or worldY properties? What about every time the position, scale or rotation properties of the entity or any of its parents are set? Or is there a completely different way?


Note: along with knowing an entity's world location, I also need to know its world bounding box.



Answer



The way this is typically handled is with a dirty flag.


Each object stores both its current local transformation/bounds, and a net transformation/bounds according to its whole parent hierarchy (eg. a single composed local-to-world matrix and worldspace bounding box).



To avoid updating all of this transformation/bounds data more often than we need to, we allow it to go out of date, and mark stale data with a flag.


When we change an aspect of an object's transformation, we mark its transformation/bounds data "dirty" (and propagate this down to any child objects not already marked dirty).


If we change it again and it's already dirty, we're done, and don't need to do any extra calculations.


When we want to use an object's transformation/bounds data (eg. to check its final position in the world), we check if it's been marked "dirty."




  • If so, we go up the hierarchy to the last dirty parent, and re-calculate the transformation & bounds data down the chain from there, clearing the dirty flags as we go.




  • If not, we can use the object's net transformation & bounds data as-is, without extra computation or walking of the parent hierarchy.





This approach saves repeated calculations when we mix changes to the transformations and use of those transformations/bounds, walking the hierarchy and re-computing net transforms & bounds just once between a set of changes and the next use of that data.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...