Process order of mounted objects and all children (+ fix)
by Ken Pajala · in Torque Game Builder · 09/20/2006 (5:08 pm) · 7 replies
The problem is, if you have an object that has other objects mounted to it, then mount that parent object to another object, then the grandchildren don't get their process order updated.
It's easier to explain by example. Imagine this:
create object A
create object B
create object C
Now within the scenegraph, the objects are processed in order ABC.
mount A to C
mount B to C
Now objects are processed in order CBA (since the parent has to move before the children can be updated).
create object D
Now objects are processed in order CBAD. So far so good.
mount C to D
Now objects are processed in order BADC. Ack! The children of C are processed before C since only C was moved to be after D. This means that A and B will update their physics based on information about C that is a frame out of date.
Fortunately this is easy to fix:
and
edit: fixed problem where recursively fixing children of children could cause problems
That does it.
::ken::
It's easier to explain by example. Imagine this:
create object A
create object B
create object C
Now within the scenegraph, the objects are processed in order ABC.
mount A to C
mount B to C
Now objects are processed in order CBA (since the parent has to move before the children can be updated).
create object D
Now objects are processed in order CBAD. So far so good.
mount C to D
Now objects are processed in order BADC. Ack! The children of C are processed before C since only C was moved to be after D. This means that A and B will update their physics based on information about C that is a frame out of date.
Fortunately this is easy to fix:
t2dSceneObject::mount () {
...
processLinkAfter( pSceneObject2D ); // After this line
// Ensure all children are after parent.
updateChildrenLinkOrder ();
...
}and
//-----------------------------------------------------------------------------
// Ensure all children are after parent.
//-----------------------------------------------------------------------------
bool t2dSceneObject::updateChildrenLinkOrder( void )
{
t2dSceneObject* pSceneObject2D = getSceneGraph()->getProcessHead()->getProcessNext();
t2dSceneObject* nextSceneObject2D;
bool changedOrder = false;
bool childrenChanged = false;
while (pSceneObject2D != this && pSceneObject2D != getSceneGraph()->getProcessHead()) {
// get next before order is changed
nextSceneObject2D = pSceneObject2D->getProcessNext();
if (pSceneObject2D->mpMountedTo == this) {
changedOrder = true;
// Unlink from Process.
pSceneObject2D->processUnLink();
// Insert after parent.
pSceneObject2D->processLinkAfter( this );
// restore mpMountedTo which was initialized in processUnLink()
pSceneObject2D->mpMountedTo = this;
// make sure all of pSceneObject2D's children are fixed too
childrenChanged = pSceneObject2D->updateChildrenLinkOrder ();
if (childrenChanged) {
// then the process order may have changed so we need to start over
nextSceneObject2D = getSceneGraph()->getProcessHead()->getProcessNext();
}
}
pSceneObject2D = nextSceneObject2D;
}
return changedOrder;
}edit: fixed problem where recursively fixing children of children could cause problems
That does it.
::ken::
#2
06/03/2008 (6:21 am)
:: Happy ::
#3
09/24/2008 (10:21 pm)
Discussion of rigid-mount issue (in 1.7.4 they don't stay rigid) moved here.
#4
Sorry but this is the first time I've seen there is a problem with rigid-mounts. I'm at work at the moment so I'll download those links when I get back home and will look at the problem. I obviously cannot promise a new release but I can offer you an official fix for any problem I find.
Also, this thread isn't about rigid-mounting so your post is completely off-topic. Do you have an existing post somewhere that we could move this to. Perhaps you could generate a new post and delete this one.
Can you do that and send me a link to it to melv (dot) may (at) gmail [dot) com?
Thanks.
Melv.
09/25/2008 (2:47 am)
Kalle,Sorry but this is the first time I've seen there is a problem with rigid-mounts. I'm at work at the moment so I'll download those links when I get back home and will look at the problem. I obviously cannot promise a new release but I can offer you an official fix for any problem I find.
Also, this thread isn't about rigid-mounting so your post is completely off-topic. Do you have an existing post somewhere that we could move this to. Perhaps you could generate a new post and delete this one.
Can you do that and send me a link to it to melv (dot) may (at) gmail [dot) com?
Thanks.
Melv.
#6
05/31/2012 (5:33 pm)
I'd like to note that this is still an issue in 1.7.6, I was having a problem where objects mounted rigidly onto another object which was in turn mounted onto the player lagged noticeably behind. This fix worked thankfully, but it sounded like this wasn't an ideal solution.
#7
06/10/2012 (4:24 pm)
Wouldn't it work with getAllMountedChildren() instead of reiterating from processHead?
Associate Melv May
I can confirm that you are most correct in that the process order of children can become incorrect with respect to the object they're mounted to.
Your solution above seems sound but I'm really worried about the amount of time it could potentially take especially as people do some pretty heavy mounting / dismounting and expect it to be very quick. Saying that we're only shifting pointers here so it should be fast but some peoples scenes are massive.
I'm thinking that a modification to allow a parent to keep track of its mounted children is called for. At least in this way an object can determine a graph of objects needed to be processed in one go without having to (potentially) repeatedly parse the process list.
I might even look for edge-cases where you're mounting an object (with its own children) to a parent that doesn't have any (yet). In this case the parents process order can be shifted thereby negating the need to parse the mount tree. Stuff like that.
Again, thanks for bringing this one to my attention and sorry for the *ahem* delay in fixing it.
The bug report reference is "TGB-89".
Melv.