addObject, setParent and setting the localOrientation of the parent trouble

Hi all,

I’m running into some performance trouble using lots of dynamic objects as a child of an object.

I use the following code:

newObj = scene.addObject(prefab, cursor)

then I set the parent:

obj.setParent(self.scene.objects["Globe"])

This works wonderfully… however I need to rotate the Globe object and use:

globeObj.localOrientation = someNewQuaternion

However this is really slow. It takes 40 ms to set the orientation.

Anybody clues why or what to do about it?

Rg,

Arnaud

The orientation is a matrix. If you apply a lisz or a quaternation it needs to be converted first. Mabe this conversion needs that time. But i can’t tell.

Just to add to that I expect this to be caused by the scenegraph of the game engine. I’ve been reading the source and I expect that it’s caused by iterating through the child list:

in SG_Node.cpp:

void SG_Node::UpdateWorldData(double time, bool parentUpdated)
{
    //if (!GetSGParent())
    //    return;

    if (UpdateSpatialData(GetSGParent(),time,parentUpdated))
        // to update the 
        ActivateUpdateTransformCallback();

    // The node is updated, remove it from the update list
    Delink();

    // update children's worlddata
    for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
    {
        (*it)->UpdateWorldData(time, parentUpdated);
    }
}

In my case the NodeList contains some 1500 items.

I’d hoped the scenegraph to do this a bit more efficient but here lacks my understanding of scenegraphs.

1500 objects are quite a lot.

Hi Monster,

Just noticed your reply too late. I’ve tried setting the orientation as a matrix but it doens’t matter. I also traced that in the source of BGE. The first thing the BGE does is convert the parameter (Quaternion, Euler etc) to a 3x3 rotation matrix before continuing. So it is better to supply the parameter directly and not convert it to a matrix in python since than it will be converted by BGE, purely in C.

1500 objects is indeed a lot but without parenting it performs perfectly. It’s just that parenting makes it slow :frowning:

Just to add to this. A friend compared it with Unity3D. Good to know it’s also crippling Unity. :slight_smile: Although not as bad as Blender.

This could be a thing to enhance even further in Blender. I’m not sure how yet but scenegraph parsing is one of those tasks which could be enhanced using threads or some more clever math.

in the SG_Node class:

void SG_Node::UpdateWorldData(double time, bool parentUpdated)
{
    //if (!GetSGParent())
    //    return;

    if (UpdateSpatialData(GetSGParent(),time,parentUpdate  d))
        // to update the 
        ActivateUpdateTransformCallback();

    // The node is updated, remove it from the update list
    Delink();

    // update children's worlddata
    for (NodeList::iterator it = m_children.begin();it!=m_children.end();++it)
    {
        (*it)->UpdateWorldData(time, parentUpdated);
    }
}

That could be divided over cpu’s or even the gpu. Can’t tell if this could be done threadsafe just like that but perhaps it can. Since a tree of objects always has just one parent there’s never data memory mixing. So the tree can be parsed safely. Every child will be calling this function it self. The ActivateUpdateTransformCallback() calls the update function which is set as a callback but I can’t find just yet what function this is. Oh well, just a thought, perhaps someone with more insight in the scenegraph knows better.

Hmm, I do not think that threads are the solution. It looks more like a design issue. But I can’t tell what it is.
This might be worth a bug in the bugtracker.