Reorder actor, bad way ?

Started by
7 comments, last by Alundra 10 years, 4 months ago

Hi all,

The goal is to have 0 recursion and keep the array linear to load/save hierarchy.

One way I have is to have a ReorderActor function in SceneManager :


void CSceneManager::ReorderActor( IActor* Parent, IActor* Child )
{
  // Find the child actor in this scene manager.
  for( UInt32 i = 0; i < m_ActorArray.GetSize(); ++i )
  {
    // Check if the child actor is found.
    if( m_ActorArray[ i ] == Child )
    {
      m_ActorArray.Remove( i );
      break;
    }
  }

  // Find the parent actor in this scene manager.
  for( UInt32 i = 0; i < m_ActorArray.GetSize(); ++i )
  {
    // Check if the parent actor is found.
    if( m_ActorArray[ i ] == Parent )
    {
      m_ActorArray.InsertBefore( Child, i + 1 );
      break;
    }
  }
}

IActor stores a pointer of the scene manager he is affected and in AddChild/RemoveChild he calls this function.

Now the question is : Is this way a good way or should be avoided ?

Thanks for the help

Advertisement

Now the question is : Is this way a good way or should be avoided ?

There are 2 main reasons why this is not a good way.

  1. An actor should never know what a scene manager is. A scene manager is what it is because by definition it exists above and beyond any object in the scene. It knows what scene objects are, they don’t know what a manager is.
  2. You are trying to solve a problem that doesn’t exist.

Without more information on what you are trying to do and why, I can only assume a few things.

  1. You want to avoid recursion because it can be costly, at least more than it needs to be.
    • The hierarchy rarely goes deep enough for the cost to matter.
    • Recursion is avoided by the use of explicit stacks, not by mangling your design.
  2. You want to avoid recursion because you want to iterate over the objects linearly for better rendering performance or etc.
    • A problem that doesn’t exist. The hierarchy and the array of objects stored in the scene manager are 2 entirely unrelated constructs. The hierarchy is called a “scene graph” and it describes the parent/child relationship between actors. It is not used for rendering and it has nothing to do with the scene manager. The scene manager, without knowing anything about what is a parent or child at all, keeps a linear array of objects over which it can iterate linearly in constant time for any operation that demands it; recursion does not exist in the scene manager.

If my #2 assumption is correct, then you need to read this.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Thanks for the answer and the link, I like your website, I missed this update.

The probleme is not the rendering since it's just a for loop so the order is not important, data is split on component.

The problem is the update because the transform is saved in each actor and if a parent is after a child the update is not correct.

The second probleme is to save/load, I have to save the hierarchy at the end of the file, list of index parent_index + child_count + child_indices.

The problem is the update because the transform is saved in each actor and if a parent is after a child the update is not correct.

When a parent transform is modified all children are marked as dirty (and so is the parent).
Any access to the world transform of any dirtied entity/actor causes that world transform to be updated prior to being returned. The order of applying transforms does not matter; you can never access any actor’s world transform in an out-of-date fashion.

The second probleme is to save/load, I have to save the hierarchy at the end of the file, list of index parent_index + child_count + child_indices.

This is usually done by giving each actor/entity a unique ID and for each actor you save you also save the ID’s of its children. A parent index is useless information, and again the order of the objects in the file has no meaning.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

When a parent transform is modified all children are marked as dirty (and so is the parent).
Any access to the world transform of any dirtied entity/actor causes that world transform to be updated prior to being returned. The order of applying transforms does not matter; you can never access any actor’s world transform in an out-of-date fashion.

Does that mean it's better to update all children in the update function of each actor and change the boolean NeedTransformUpdate like that the for loop in update of scene manager does nothing because it was already updated ? But, that can cause multiple update because if a child is before the parent, that will update the child, the parent will be updated and change the state of children to NeedUpdate and update again.

This is usually done by giving each actor/entity a unique ID and for each actor you save you also save the ID’s of its children. A parent index is useless information, and again the order of the objects in the file has no meaning.

I don't see very well how that can work really to save ID and use them in load function. I'm a bit lost on this one.

But, that can cause multiple update

How often do you need world positions of parents outside of the final updating phase where all object world positions are calculated?
If a knife if a child of a skeleton hand joint, it never really cares about its parent’s world position, and by the time it is thrown it has already lost its parent.
A guy on a horse or in the seat of a car doesn’t care what the world position of the horse or car is. He is just along for the ride.

If you have an exceptional use-case, you don’t need to worry about one possible extra update per frame.


I don't see very well how that can work really to save ID and use them in load function. I'm a bit lost on this one.

Why would indices be better than an ID?
Both require the same exact set of objects. Indices require a specific loading order while ID’s do not. Simple load everything, then add things as children as needed.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Simple load everything, then add things as children as needed.

This is what I actually do but using indices at the end of the read of scene, this is why I don't understand the ID stuff :


// Read the hierarchy.
for( UInt32 n = 0; n < NumActor; ++n )
{
  // Child count.
  UInt32 ChildCount;
  File.Read( &ChildCount, sizeof( UInt32 ) );

  // Each child.
  for( UInt32 c = 0; c < ChildCount; ++c )
  {
    // Child index.
    UInt32 ChildIndex;
    File.Read( &ChildIndex, sizeof( UInt32 ) );

    // Add the child.
    m_ActorArray[ n ]->AddChild( m_ActorArray[ ChildIndex ] );
  }
}

But, using a linear array that can be avoided I guess because that cause to store useless stuff.

I guess the point is it is simply flawed logic to rely in the order in which entities appear in the scene manager’s array, and as I already stated the scene manager’s array is completely and entirely separate from the child/parent relationship that exists within the actor system (again, actor system, not scene manager system).

I am running out of ways to say this.

There is absolutely no relationship at all in any way possible within this universe that the parent/child system is related to the scene manager and its array of actors that compose the game world.

So it’s not that it’s a bad idea to store indices, it’s that it’s impossible. It can’t happen.

  1. If the scene manager is unrelated to the parent/child system, how can it convert a parent or child into an index?
  2. If the actors know nothing about the scene manager (as I said before), how can they convert an parent or child into an index?

No conversion is possible.

An ID system is one possible way around this, but you are free to make any method you want, except for an index system.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

There is absolutely no relationship at all in any way possible within this universe that the parent/child system is related to the scene manager and its array of actors that compose the game world.

It's nice to listen that because I've always used an array of child in actor who is pointer of actor stored in the scene manager array, the scene manager doesn't know that.

Ok so the only way to kill this hierarchy at the end of file is to use ID system.

Thanks for the help

This topic is closed to new replies.

Advertisement