void OLMeshTracker::UpdateSubNodes(Ogre::Node* regionNode, Ogre::Node* node, bool recurse, Ogre::MeshPtr meshP) { if (recurse && node->numChildren() > 0) { // if node has more children nodes, visit them recursivily Ogre::SceneNode::ChildNodeIterator nodeChildIterator = node->getChildIterator(); while (nodeChildIterator.hasMoreElements()) { Ogre::Node* nodeChild = nodeChildIterator.getNext(); // 'false' causes it to not visit sub-children which are included in parent and pos relative to parent UpdateSubNodes(regionNode, nodeChild, true, meshP); } } // children taken care of... check for attached objects to this node Ogre::SceneNode* snode = (Ogre::SceneNode*)node; Ogre::SceneNode::ObjectIterator snodeObjectIterator = snode->getAttachedObjectIterator(); while (snodeObjectIterator.hasMoreElements()) { Ogre::MovableObject* snodeObject = snodeObjectIterator.getNext(); if (snodeObject->getMovableType() == "Entity") { Ogre::Entity* snodeEntity = (Ogre::Entity*)snodeObject; Ogre::MeshPtr entityMesh = snodeEntity->getMesh(); if (entityMesh == meshP) { snode->needUpdate(true); // LG::Log("OLMeshTracker::UpdateSubNodes: setting node update for %s", snode->getName().c_str()); } } } return; }
//! //! Returns the first movable object of the given type name contained in //! the given scene node. //! //! \param sceneNode The scene node to find the first object in. //! \param typeName The name of the type of objects to look for. //! \return The first movable object of the given type name contained in the given scene node. //! Ogre::MovableObject * OgreTools::findFirstObject ( Ogre::SceneNode *sceneNode, const QString &typeName ) { // make sure the given scene node is valid if (!sceneNode) { Log::error("The given scene node is invalid.", "OgreTools::findFirstObject"); return 0; } // iterate over the list of attached objects Ogre::SceneNode::ObjectIterator objectIterator = sceneNode->getAttachedObjectIterator(); while (objectIterator.hasMoreElements()) { Ogre::MovableObject *movableObject = objectIterator.getNext(); if (movableObject && QString::compare(movableObject->getMovableType().c_str(), typeName) == 0) return movableObject; } // iterate over the list of child nodes Ogre::SceneNode::ChildNodeIterator childIter = sceneNode->getChildIterator(); while( childIter.hasMoreElements() ) { Ogre::SceneNode *childSceneNode = (Ogre::SceneNode *) childIter.getNext(); return findFirstObject(childSceneNode, typeName); } return 0; }
void MergeBounds(Ogre::SceneNode* node, Ogre::SceneNode* rootNode, const Ogre::Matrix4& parentTransform, Ogre::AxisAlignedBox& aabb) { // Get this nodes current transform Ogre::Matrix4 currentTransform = parentTransform; if (node != rootNode) { Ogre::Matrix4 localTransform(node->getOrientation()); localTransform.setTrans(node->getPosition()); currentTransform = currentTransform * localTransform; } // Merge this nodes objects Ogre::SceneNode::ObjectIterator object = node->getAttachedObjectIterator(); while (object.hasMoreElements()) { Ogre::AxisAlignedBox localAABB = object.getNext()->getBoundingBox(); localAABB.transform(currentTransform); aabb.merge(localAABB); } // Iterate through all children and call this function on them Ogre::SceneNode::ChildNodeIterator child = node->getChildIterator(); while (child.hasMoreElements()) { MergeBounds(static_cast<Ogre::SceneNode*>(child.getNext()), rootNode, currentTransform, aabb); } }
void OLMeshTracker::UpdateSceneNodesForMesh(Ogre::MeshPtr meshP) { Ogre::SceneNode* nodeRoot = LG::RendererOgre::Instance()->m_sceneMgr->getRootSceneNode(); if (nodeRoot == NULL) return; // Hanging off the root node will be a node for each 'region'. A region has // terrain and then content nodes Ogre::SceneNode::ChildNodeIterator rootChildIterator = nodeRoot->getChildIterator(); while (rootChildIterator.hasMoreElements()) { Ogre::Node* nodeRegion = rootChildIterator.getNext(); // a region node has the nodes of its contents. UpdateSubNodes(nodeRegion, nodeRegion, true, meshP); } return; }
//! //! Creates a deep copy of the given scene node. //! //! \param sceneNode The scene node to copy. //! \param sceneNodeCopy The scene node to add the copied objects to (will be created if 0). //! \param namePrefix The prefix to use for names of copied objects. //! \param sceneManager The scene manager to use for creating the object. //! void OgreTools::deepCopySceneNode ( Ogre::SceneNode *sceneNode, Ogre::SceneNode *&sceneNodeCopy, const QString &namePrefix, Ogre::SceneManager *sceneManager /* = 0 */ ) { // make sure the given scene node is valid if (!sceneNode) { Log::error("The given scene node is invalid.", "OgreTools::deepCopySceneNode"); return; } // make sure a valid scene manager is available if (!sceneManager) sceneManager = sceneNode->getCreator(); if (!sceneManager) { Log::error("No valid scene manager available.", "OgreTools::deepCopySceneNode"); return; } // create the target scene node if it doesn't exist yet if (!sceneNodeCopy) { QString sceneNodeCopyName = QString("%1_%2Copy").arg(namePrefix).arg(sceneNode->getName().c_str()); sceneNodeCopy = copySceneNode(sceneNode, sceneNodeCopyName, sceneManager); if (!sceneNodeCopy) { Log::error("The scene node could not be copied.", "OgreTools::deepCopySceneNode"); return; } } // iterate over the list of attached objects Ogre::SceneNode::ObjectIterator objectIterator = sceneNode->getAttachedObjectIterator(); while (objectIterator.hasMoreElements()) { Ogre::MovableObject *movableObject = objectIterator.getNext(); if (movableObject) { QString entityCopyName = QString("%1_%2Copy").arg(namePrefix).arg(movableObject->getName().c_str()); Ogre::MovableObject *movableObjectCopy = cloneMovableObject(movableObject, entityCopyName, sceneManager); if (movableObjectCopy) sceneNodeCopy->attachObject(movableObjectCopy); } } // iterate over the list of child nodes Ogre::SceneNode::ChildNodeIterator childNodeIterator = sceneNode->getChildIterator(); while (childNodeIterator.hasMoreElements() ) { Ogre::SceneNode *childSceneNode = (Ogre::SceneNode *) childNodeIterator.getNext(); QString childSceneNodeCopyName = QString("%1_%2Copy").arg(namePrefix).arg(childSceneNode->getName().c_str()); Ogre::SceneNode *childSceneNodeCopy = copySceneNode(childSceneNode, childSceneNodeCopyName, sceneManager); if (childSceneNodeCopy) { sceneNodeCopy->addChild(childSceneNodeCopy); deepCopySceneNode(childSceneNode, childSceneNodeCopy, namePrefix, sceneManager); } } }
void CSVRender::Object::clearSceneNode (Ogre::SceneNode *node) { for (Ogre::SceneNode::ObjectIterator iter = node->getAttachedObjectIterator(); iter.hasMoreElements(); ) { Ogre::MovableObject* object = dynamic_cast<Ogre::MovableObject*> (iter.getNext()); node->getCreator()->destroyMovableObject (object); } for (Ogre::SceneNode::ChildNodeIterator iter = node->getChildIterator(); iter.hasMoreElements(); ) { Ogre::SceneNode* childNode = dynamic_cast<Ogre::SceneNode*> (iter.getNext()); clearSceneNode (childNode); node->getCreator()->destroySceneNode (childNode); } }
void DestroyAllAttachedMovableObjects(Ogre::SceneNode* i_pSceneNode ) { if (!i_pSceneNode ) return; // Destroy all the attached objects Ogre::SceneNode::ObjectIterator itObject = i_pSceneNode->getAttachedObjectIterator(); while (itObject.hasMoreElements() ) { Ogre::MovableObject* pObject = static_cast<Ogre::MovableObject*>(itObject.getNext()); i_pSceneNode->getCreator()->destroyMovableObject(pObject); } // Recurse to child SceneNodes Ogre::SceneNode::ChildNodeIterator itChild = i_pSceneNode->getChildIterator(); while (itChild.hasMoreElements() ) { Ogre::SceneNode* pChildNode = static_cast<Ogre::SceneNode*>(itChild.getNext()); DestroyAllAttachedMovableObjects(pChildNode); } }
/// From http://www.ogre3d.org/forums/viewtopic.php?f=2&t=53647 inline void destroyAllAttachedMovableObjects(Ogre::SceneNode *node) { if(!node) return; // Destroy all the attached objects Ogre::SceneNode::ObjectIterator itObject = node->getAttachedObjectIterator(); // FIXME segmentation fault while (itObject.hasMoreElements()) node->getCreator()->destroyMovableObject(itObject.getNext()); // Recurse to child SceneNodes Ogre::SceneNode::ChildNodeIterator itChild = node->getChildIterator(); while ( itChild.hasMoreElements() ) { Ogre::SceneNode* pChildNode = boost::polymorphic_cast<Ogre::SceneNode*>(itChild.getNext()); destroyAllAttachedMovableObjects(pChildNode); } }
//! //! Remove and destroy this scene children. //! \param The scenenode to be destroyed //! void Model2SceneNode::resizeNodes( Ogre::SceneNode* i_pSceneNode ) { if ( !i_pSceneNode || i_pSceneNode->numChildren() == 0 ) return; // Destroy all the attached objects Ogre::SceneNode::ObjectIterator itObject = i_pSceneNode->getAttachedObjectIterator(); // Recurse to child SceneNodes Ogre::SceneNode::ChildNodeIterator itChild = i_pSceneNode->getChildIterator(); while ( itChild.hasMoreElements() ) { Ogre::SceneNode* pChildNode = static_cast<Ogre::SceneNode*>(itChild.getNext()); // obtain the OGRE scene manager Ogre::SceneManager *sceneManager = OgreManager::getSceneManager(); if (pChildNode != m_sceneNode) pChildNode->setScale(m_size); } }
//----------------------------------------------------------------------- void SceneDecoratorExtern::_notifyStop (void) { if (mSubnode && mParentTechnique->getParentSystem()) { Ogre::SceneNode* sceneNode = mParentTechnique->getParentSystem()->getParentSceneNode(); Ogre::SceneNode::ChildNodeIterator it = sceneNode->getChildIterator(); unsigned int i = 0; while (it.hasMoreElements()) { Ogre::SceneNode* child = static_cast<Ogre::SceneNode*>(it.getNext()); if (child == mSubnode) { mSubnode->detachAllObjects(); sceneNode->removeAndDestroyChild(i); mSubnode = 0; } ++i; } destroyEntity(); } }
/* Removes all the entities of a sceneNode (recursively) */ void Util::removeAllEntities(Ogre::SceneNode *node) { ASSERT(node); // Destroy all the attached objects Ogre::SceneNode::ObjectIterator itObject = node->getAttachedObjectIterator(); while (itObject.hasMoreElements()) { Ogre::MovableObject* pObject = static_cast<Ogre::MovableObject*> (itObject.getNext()); node->getCreator()->destroyMovableObject(pObject); } // Recurse to child SceneNodes Ogre::SceneNode::ChildNodeIterator itChild = node->getChildIterator(); while (itChild.hasMoreElements()) { Ogre::SceneNode* pChildNode = static_cast<Ogre::SceneNode*> (itChild.getNext()); removeAllEntities(pChildNode); } }
// BETWEEN FRAME OPERATION void VisCalcFrustDist::calculateEntityVisibility(Ogre::Node* regionNode, Ogre::Node* node, bool recurse) { if (recurse && node->numChildren() > 0) { // if node has more children nodes, visit them recursivily Ogre::SceneNode::ChildNodeIterator nodeChildIterator = node->getChildIterator(); while (nodeChildIterator.hasMoreElements()) { Ogre::Node* nodeChild = nodeChildIterator.getNext(); // 'false' causes it to not visit sub-children which are included in parent and pos relative to parent calculateEntityVisibility(regionNode, nodeChild, false); visChildren++; } } visNodes++; // children taken care of... check fo attached objects to this node Ogre::SceneNode* snode = (Ogre::SceneNode*)node; // the camera needs to be made relative to the region // Ogre::Vector3 relCameraPos = LG::RendererOgre::Instance()->m_camera->getPosition() - regionNode->getPosition(); // float snodeDistance = LG::RendererOgre::Instance()->m_camera->getPosition().distance(snode->_getWorldAABB().getCenter()); // float snodeDistance = relCameraPos.distance(snode->getPosition()); float snodeDistance = LG::RendererOgre::Instance()->m_camera->getDistanceFromCamera(regionNode, snode->getPosition()); Ogre::SceneNode::ObjectIterator snodeObjectIterator = snode->getAttachedObjectIterator(); while (snodeObjectIterator.hasMoreElements()) { Ogre::MovableObject* snodeObject = snodeObjectIterator.getNext(); if (snodeObject->getMovableType() == "Entity") { visEntities++; Ogre::Entity* snodeEntity = (Ogre::Entity*)snodeObject; // check it's visibility if it's not world geometry (terrain and ocean) if ((snodeEntity->getQueryFlags() & Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK) == 0) { // computation if it should be visible // Note: this call is overridden by derived classes that do fancier visibility rules bool shouldBeVisible = this->CalculateVisibilityImpl(LG::RendererOgre::Instance()->m_camera, snodeEntity, snodeDistance); if (snodeEntity->isVisible()) { // we currently think this object is visible. make sure it should stay that way if (shouldBeVisible) { // it should stay visible visVisToVis++; } else { // not visible any more... make invisible nad unload it` /* Ogre::Vector3 cPos = LG::RendererOgre::Instance()->m_camera->getPosition(); Ogre::Vector3 rPos = regionNode->getPosition(); Ogre::Vector3 sPos = snode->getPosition(); LG::Log("VisToInVis: cPos=<%f,%f,%f>, rPos=<%f,%f,%f>, sPos(%s)=<%f,%f,%f>, d=%f", cPos.x, cPos.y, cPos.z, rPos.x, rPos.y, rPos.z, snode->getName().c_str(), sPos.x, sPos.y, sPos.z, snodeDistance); */ snodeEntity->setVisible(false); snode->needUpdate(true); visVisToInvis++; if (!snodeEntity->getMesh().isNull()) { queueMeshUnload(snodeEntity->getMesh()); } } } else { // the entity currently thinks it's not visible. // check to see if it should be visible by checking a fake bounding box if (shouldBeVisible) { // it should become visible again if (!snodeEntity->getMesh().isNull()) { // queueMeshLoad(snodeEntity, snodeEntity->getMesh()); LG::OLMeshTracker::Instance()->MakeLoaded(snodeEntity->getMesh()->getName(), Ogre::String(""), Ogre::String("visible"), snodeEntity); } // snodeEntity->setVisible(true); // must happen after mesh loaded visInvisToVis++; } else { visInvisToInvis++; } } } } } }
//! //! Deletes a whole scene node tree (including attached objects). //! //! \param sceneNode The scene node containing the tree to delete. //! \param sceneManager The scene manager to use for destroying the scene node. //! \param deleteRoot Flag to control whether to delete the given scene node. //! void OgreTools::deepDeleteSceneNode ( Ogre::SceneNode *sceneNode, Ogre::SceneManager *sceneManager /* = 0 */, bool deleteRoot /* = false */ ) { // make sure the given scene node is valid if (!sceneNode) { Log::error("The given scene node is invalid.", "OgreTools::deepDeleteSceneNode"); return; } // make sure a valid scene manager is available if (!sceneManager) sceneManager = sceneNode->getCreator(); if (!sceneManager) { Log::error("No valid scene manager available.", "OgreTools::deepDeleteSceneNode"); return; } // iterate over the list of attached objects Ogre::SceneNode::ObjectIterator objectIterator = sceneNode->getAttachedObjectIterator(); while (objectIterator.hasMoreElements()) { Ogre::MovableObject *movableObject = objectIterator.getNext(); sceneNode->detachObject(movableObject); Ogre::SceneManager *movableSceneManager = movableObject->_getManager(); if (!movableSceneManager) { Log::error("The Ogre scene manager could not be obtained.", "OgreTools::deepDeleteSceneNode"); return; } Ogre::Any customData = movableObject->getUserAny(); if (!customData.isEmpty()) { OgreContainer *ogreContainer = Ogre::any_cast<OgreContainer *>(customData); if (ogreContainer) { delete ogreContainer; ogreContainer = 0; } } movableSceneManager->destroyMovableObject(movableObject); } // iterate over the list of child nodes Ogre::SceneNode::ChildNodeIterator childNodeIterator = sceneNode->getChildIterator(); while (childNodeIterator.hasMoreElements()) { Ogre::SceneNode *childSceneNode = dynamic_cast<Ogre::SceneNode *>(childNodeIterator.getNext()); if (childSceneNode) { Ogre::Any customData = childSceneNode->getUserAny(); if (!customData.isEmpty()) { OgreContainer *ogreContainer = Ogre::any_cast<OgreContainer *>(customData); if (ogreContainer) { delete ogreContainer; ogreContainer = 0; } else { CameraInfo *cameraInfo = Ogre::any_cast<CameraInfo *>(customData); if (cameraInfo) { delete cameraInfo; cameraInfo = 0; } } } deepDeleteSceneNode(childSceneNode, sceneManager); } } // destroy all child nodes of the given scene node sceneNode->removeAndDestroyAllChildren(); // check if the given scene node should be destroyed as well if (deleteRoot) { Ogre::Any customData = sceneNode->getUserAny(); if (!customData.isEmpty()) { OgreContainer *ogreContainer = Ogre::any_cast<OgreContainer *>(customData); if (ogreContainer) { delete ogreContainer; ogreContainer = 0; } else { CameraInfo *cameraInfo = Ogre::any_cast<CameraInfo *>(customData); if (cameraInfo) { delete cameraInfo; cameraInfo = 0; } } } sceneManager->destroySceneNode(sceneNode); } }