Ogre3d: iterating through childnode error

2019-07-25 03:33发布

问题:

I have a city node which houses many building nodes, each of these I wish to grant a new child-node. which tells the house what role and sign they have/role. Which can later be used for other functions. for now all get the same .mesh (will later make a sign) to identify which house is what. it shall be randomly assigned. If I try to run this I get the following error. I am very new to ogre , which adds to some weird code

int CityManager::assignBuildingRole(Ogre::SceneNode * _cityNode, int _numberOfBuildings)
{
    std::stringstream nodename("buildingRoleNode");
    Ogre::SceneNode::ChildNodeIterator cNode = _cityNode->getChildIterator();
    std::vector <Ogre::SceneNode*> detachable;
    while (cNode.hasMoreElements()) {
        detachable.push_back((Ogre::SceneNode *)cNode.getNext());
    }
        for (int i = 0; i < detachable.size(); i++) {
            nodename << childIteration << "_" << parentIteration << "_" << i;
            switch (rand() % 5) // assign building random proffessions by giving them a rolenode
            {
            case 0:
                _roleNode = ( Ogre::SceneNode *)cNode.getNext()->createChild(nodename.str());
                _signEntity = manager->createEntity("Barrel.mesh");
                _roleNode->attachObject(_signEntity);
                break;
            case 1:
                _roleNode = (Ogre::SceneNode *)cNode.getNext()->createChild(nodename.str());
                _signEntity = manager->createEntity("Barrel.mesh");
                _roleNode->attachObject(_signEntity);
                break;
            case 2:
                _roleNode = (Ogre::SceneNode *)cNode.getNext()->createChild(nodename.str());
                _signEntity = manager->createEntity("Barrel.mesh");
                _roleNode->attachObject(_signEntity);
                break;
            case 3:
                _roleNode = (Ogre::SceneNode *)cNode.getNext()->createChild(nodename.str());
                _signEntity = manager->createEntity("Barrel.mesh");
                _roleNode->attachObject(_signEntity);
                break;
            case 4:
                _roleNode = (Ogre::SceneNode *)cNode.getNext()->createChild(nodename.str());
                _signEntity = manager->createEntity("Barrel.mesh");
                _roleNode->attachObject(_signEntity);
                break;
            default:
                break;
            }
        }

    return role;
}

回答1:

Calling getNext on ChildNodeIterator will not only retrieve the next element but advance to the next element, too. See its description in documentation

So what you do is iterating over the children of _cityNode and store every child in your detachable vector.

while (cNode.hasMoreElements()) {
  detachable.push_back((Ogre::SceneNode *)cNode.getNext());
}

After these lines your cNode points to end of children list (specifically after the last element, as end() in std::map which is the underlying data type)

If you are trying to iterate it further you'll get an error.

You can either use detachable for the next iteration (I guess that's why you created it)

_roleNode = detachable[i]->createChild(nodename.str());

or do the child creation in your while loop and don't use detachable at all.

while (cNode.hasMoreElements()) {
  Ogre::SceneNode* curr = (Ogre::SceneNode *)cNode.getNext();
  switch (rand() % 5)
  {
  case 0:
    _roleNode = curr->createChild(nodename.str());
    _signEntity = manager->createEntity("Barrel.mesh");
    _roleNode->attachObject(_signEntity);
    break;
  /* ... */
  default:
    break;
  }
}