-
-
Notifications
You must be signed in to change notification settings - Fork 108
Transform and area recalculation
We want to avoid superfluous recalculation of world areas:
- Fixed tiles' world areas never change.
- Only when objects move, rotate or scale does their world area change.
- When a level moves, all tiles, even fixed ones, need their world area recalculated.
Basically, an area needs it's world area updated if:
- The shape, area offset or scale changes.
- The transform of the object changes.
- The transform of an ancestor changes.
There are several ways to implement this, but all come with pros and cons:
- Always recalculate.
- Recalculate in fixed points in the pipeline, allow the user to update manually.
- Use dirty flags.
This is how it works now, worldArea() just transforms the local area using the transform.
- The world area is always up-to-date.
- If the world area didn't change, we do unnecessary calculations.
We recalculate between update and draw. This way draw has the newest world area when clipping. If the area participates in the physics step(s), it is updated when moved during physics. So update also gets the updated world area. For the edge case where someone changes something in update and expects to retrieve the updated word area, a custom refresh flag can be passed to worldArea().
- The world area is always up-to-date for most uses.
- When doing out of the ordinary things, the user can force recalculation.
- ??
When the transform changes, or any aspect of the area, set the world area to dirty. When the world area is requested, update it before returning if dirty.
- The world area will be up-to-date when the local transform or area has changed.
- The world area will be stale if one or more of the ancestor transforms have changed.
Theoretically it is possible to set the dirty flag on all descendants when some aspect of the transform or area changes, however this may impair performance (think a level rotating with 256 tiles).
One might think that another solution is to check not only the object's dirty flag, but ancestors' flags as well. But this won't work as you can only update local flags, so you basically you would update your world area, but the ancestor flag stays dirty, so next time you'll update your world area again, even though it didn't change. You would have to update all dirty ancestors as well in order to clear all their flags, even if you have no use of their world area.
