Exemple #1
0
void DumpNodes(std::stringstream &ss, Ogre::Node *n, int level)
{
	for (int i = 0; i < level; i++)
	{
		ss << " ";
	}

	ss << "SceneNode: " << n->getName() << std::endl;

	Ogre::SceneNode::ObjectIterator object_it = ((Ogre::SceneNode *)n)->getAttachedObjectIterator();
	Ogre::Node::ChildNodeIterator node_it = n->getChildIterator();

	Ogre::MovableObject *m;

	while (object_it.hasMoreElements())
	{
		for (int i = 0; i < level + 2; i++)
		{
			ss << " ";
		}

		m = object_it.getNext();
		ss << m->getMovableType() << ": " << m->getName() << std::endl;
	}

	while (node_it.hasMoreElements())
	{
		DumpNodes(ss, node_it.getNext(), level + 2);
	}
}
Exemple #2
0
//!
//! 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);
        }
    }
}
Exemple #3
0
	//该函数不支持多线程
	string BaseManager::pickMovableObject( int x,int y ){
		//如果相同的帧同时相同的x,y就直接返回结果
		if( mPickFrameCount == getFrameCount() && 
			mPickX == x && mPickY == y ){
			return mPickName;
		}

		mRay = mCamera->getCameraToViewportRay(
				(Ogre::Real)x/(Ogre::Real)mWindow->getWidth(),
				(Ogre::Real)y/(Ogre::Real)mWindow->getHeight()
				);

		mSceneQuery->setRay( mRay );

		//距离排序
		mSceneQuery->setSortByDistance(true);
		Ogre::RaySceneQueryResult result = mSceneQuery->execute();

		//execute不能执行像素级的查询,它仅仅是和包围盒进行比较
		//可以考虑使用渲染到纹理,使用1x1的纹理来对查询结果进行像素级别的查询
		//这里使用逐个求交点的办法
		Ogre::MovableObject* pmo = nullptr;
		Ogre::Real dis;
		for( size_t i = 0;i < result.size();++i ){
			if( result[i].movable && 
				result[i].movable->isVisible() &&  //不可见的
				result[i].movable->isInScene() ){ //不在场景中的
				mIntersect = false;
				result[i].movable->visitRenderables(this);
				if( mIntersect ){
					//考虑到同一帧中间有多个地方的代码需要调用该函数
					//这样使用内存换速度
					if( !pmo || dis>mIntersectDistance ){
						dis = mIntersectDistance;
						pmo = result[i].movable;
					}				
				}
			}
		}

		if( pmo ){
			mPickX = x;
			mPickY = y;
			mPickFrameCount = getFrameCount();
			mPickName = pmo->getName();
			return mPickName;
		}
		//返回一个空字串表示没有
		return "";
	}
	void RenderBoxWrap::removeNode(Ogre::SceneNode* _node)
	{
		//System::Console::WriteLine("remove node {0}", gcnew System::String(_node->getName().c_str()));

		while(_node->numAttachedObjects() != 0)
		{
			Ogre::MovableObject* object = _node->getAttachedObject(0);

			removeEntity(object->getName());
		}

		while (_node->numChildren() != 0)
		{
			Ogre::SceneNode* forDelete = (Ogre::SceneNode*)_node->getChild(0);

			removeNode(forDelete);
		}

		_node->getParentSceneNode()->removeAndDestroyChild(_node->getName());
	}
	bool CollisionTools::raycast(const Ogre::Ray &ray, Ogre::Vector3 &result,Ogre::MovableObject* &target,float &closest_distance, const Ogre::uint32 queryMask)
	{
		target = NULL;

		// check we are initialised
		if (mRaySceneQuery != NULL)
		{
			// create a query object
			mRaySceneQuery->setRay(ray);
			mRaySceneQuery->setSortByDistance(true);
			mRaySceneQuery->setQueryMask(queryMask);
			// execute the query, returns a vector of hits
			if (mRaySceneQuery->execute().size() <= 0)
			{
				// raycast did not hit an objects bounding box
				return (false);
			}
		}
		else
		{
			//LOG_ERROR << "Cannot raycast without RaySceneQuery instance" << ENDLOG;
			return (false);
		}

		// at this point we have raycast to a series of different objects bounding boxes.
		// we need to test these different objects to see which is the first polygon hit.
		// there are some minor optimizations (distance based) that mean we wont have to
		// check all of the objects most of the time, but the worst case scenario is that
		// we need to test every triangle of every object.
		//Ogre::Ogre::Real closest_distance = -1.0f;
		closest_distance = -1.0f;
		Ogre::Vector3 closest_result;
		Ogre::RaySceneQueryResult &query_result = mRaySceneQuery->getLastResults();

#if 0
		for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++)
		{
			const Ogre::RaySceneQueryResultEntry& result = query_result[qr_idx];
			Ogre::Real distance = result.distance;
			Ogre::MovableObject* movable = static_cast<Ogre::MovableObject*>(result.movable);
			Ogre::SceneQuery::WorldFragment* worldFragment = result.worldFragment;

			if (movable)
			{
				const Ogre::String& type = movable->getMovableType();
				const Ogre::String& name = movable->getName();
				const Ogre::String& parentName = movable->getParentNode()->getName();
				Ogre::uint32 flag = movable->getQueryFlags();  

				if (type.compare("Entity") == 0)
				{
					Ogre::Entity* ent =  (Ogre::Entity*)movable;
				}

				std::ostrstream oss;
				oss<<"name:"<<name<<" distance:"<< distance <<" type:"<<type<<" flag:"<<flag<<" parent:"<<parentName<<std::endl;
				OutputDebugString(oss.str() );
			}
		}

#endif

		for (size_t qr_idx = 0; qr_idx < query_result.size(); qr_idx++)
		{
			// stop checking if we have found a raycast hit that is closer
			// than all remaining entities
			if ((closest_distance >= 0.0f) &&
				(closest_distance < query_result[qr_idx].distance))
			{
				break;
			}

			// only check this result if its a hit against an entity
			if ((query_result[qr_idx].movable != NULL)  &&
				(query_result[qr_idx].movable->getMovableType().compare("Entity") == 0))
			{
				// get the entity to check
				Ogre::MovableObject *pentity = static_cast<Ogre::MovableObject*>(query_result[qr_idx].movable);

				// mesh data to retrieve
				size_t vertex_count;
				size_t index_count;
				Ogre::Vector3 *vertices = NULL;
				Ogre::uint32 *indices = NULL;

				// get the mesh information
				GetMeshInformation(((Ogre::Entity*)pentity)->getMesh(), vertex_count, vertices, index_count, indices,
					pentity->getParentNode()->_getDerivedPosition(),
					pentity->getParentNode()->_getDerivedOrientation(),
					pentity->getParentNode()->_getDerivedScale());

				// test for hitting individual triangles on the mesh
				bool new_closest_found = false;
				for (size_t i = 0; i < index_count; i += 3)
				{
					// check for a hit against this triangle
					std::pair<bool, Ogre::Real> hit = Ogre::Math::intersects(ray, vertices[indices[i]],
						vertices[indices[i+1]], vertices[indices[i+2]], true, false);

					// if it was a hit check if its the closest
					if (hit.first)
					{
						if ((closest_distance < 0.0f) ||
							(hit.second < closest_distance))
						{
							// this is the closest so far, save it off
							closest_distance = hit.second;
							new_closest_found = true;
						}
					}
				}

				// free the verticies and indicies memory
				delete  vertices;
				delete  indices;

				// if we found a new closest raycast for this object, update the
				// closest_result before moving on to the next object.
				if (new_closest_found)
				{
					target = pentity;
					closest_result = ray.getPoint(closest_distance);
				}
			}
		}

		// return the result
		if (closest_distance >= 0.0f)
		{
			// raycast success
			result = closest_result;
			return (true);
		}
		else
		{
			// raycast failed
			return (false);
		}
	}
Exemple #6
0
void OgreInfo::diagnose(std::ostream& outputStream)
{
	Ogre::SceneManagerEnumerator::SceneManagerIterator sceneManagerI = Ogre::Root::getSingleton().getSceneManagerIterator();
	while (sceneManagerI.hasMoreElements()) {
		Ogre::SceneManager* sceneManager = sceneManagerI.getNext();
		outputStream << "Scenemanager(" << sceneManager->getTypeName() << ") " << sceneManager->getName() << std::endl;
		outputStream << " Number of scene nodes: " << countNodes(sceneManager->getRootSceneNode()) << std::endl;
		outputStream << " Movable objects:" << std::endl;
		unsigned int movableObjectCounter = 0;
		Ogre::Root::MovableObjectFactoryIterator movableObjectFactoryI = Ogre::Root::getSingleton().getMovableObjectFactoryIterator();
		while (movableObjectFactoryI.hasMoreElements()) {
			Ogre::MovableObjectFactory* factory = movableObjectFactoryI.getNext();
			std::string type(factory->getType());
			{
				Ogre::SceneManager::MovableObjectIterator I = sceneManager->getMovableObjectIterator(type);
				while (I.hasMoreElements()) {
					movableObjectCounter++;
					Ogre::MovableObject* movable = I.getNext();
					if (movable->getMovableType() == "Light") {
						Ogre::Light* light = static_cast<Ogre::Light*> (movable);
						outputStream << "  * Light " << light->getName() << "(" << (light->isInScene() ? "in scene" : "not in scene") << ")" << std::endl;
						outputStream << "   Pos: " << light->getDerivedPosition() << std::endl;
						outputStream << "   Direction: " << light->getDerivedDirection() << std::endl;

					} else {
						std::stringstream ssPosAndOrientation;
						if (movable->getParentSceneNode() && movable->isInScene()) {
							ssPosAndOrientation << " pos: " << movable->getParentSceneNode()->getPosition() << " orientation: " << movable->getParentSceneNode()->getOrientation();
						}
						outputStream << "  * " << type << " " << movable->getName() << "(" << (movable->isInScene() ? "in scene" : "not in scene") << ")" << ssPosAndOrientation.str() << std::endl;
						//					outputStream << "  Pos: " << light->getDerivedPosition() << std::endl;
						//					outputStream << "  Direction: " << light->getDerivedDirection() << std::endl;
					}
				}
			}
		}

		outputStream << " Number of movable objects: " << movableObjectCounter << std::endl;

		outputStream << " Cameras:" << std::endl;
		{
			Ogre::SceneManager::CameraIterator I = sceneManager->getCameraIterator();
			while (I.hasMoreElements()) {
				Ogre::Camera* camera = I.getNext();
				outputStream << "  Camera " << camera->getName() << "(" << (camera->isInScene() ? "in scene" : "not in scene") << ")" << std::endl;
				outputStream << "  Pos: " << camera->getDerivedPosition() << std::endl;
				outputStream << "  Direction: " << camera->getDerivedDirection() << std::endl;
				outputStream << "  Clip distances: " << camera->getNearClipDistance() << " - " << camera->getFarClipDistance() << std::endl;
			}
		}

	}

	size_t resourceMemoryUsage = 0;
	outputStream << "Resource Managers:" << std::endl;
	Ogre::ResourceGroupManager::ResourceManagerIterator I = Ogre::ResourceGroupManager::getSingleton().getResourceManagerIterator();
	while (I.hasMoreElements()) {
		std::string name = I.peekNextKey();
		Ogre::ResourceManager* manager = I.getNext();
		outputStream << " Resource Manager: " << name << std::endl;
		if (manager->getMemoryBudget() == std::numeric_limits<size_t>::max()) {
			outputStream << "  Memory budget: not set" << std::endl;
		} else {
			outputStream << "  Memory budget: " << manager->getMemoryBudget() << " bytes" << std::endl;
		}
		outputStream << "  Memory usage:  " << manager->getMemoryUsage() << " bytes" << std::endl;
		resourceMemoryUsage += manager->getMemoryUsage();

		Ogre::ResourceManager::ResourceMapIterator resourceI = manager->getResourceIterator();
		if (resourceI.hasMoreElements()) {
			outputStream << "  Resources: " << std::endl;
			int resourceCount = 0;
			int loadedResourceCount = 0;
			while (resourceI.hasMoreElements()) {
				Ogre::ResourcePtr resource = resourceI.getNext();
				if (resource->isLoaded()) {
					std::string reloadable = resource->isReloadable() ? " reloadable" : "";
					outputStream << "   " << resource->getName() << " ( " << resource->getSize() << " bytes)" << reloadable;
					Ogre::Texture* texture = dynamic_cast<Ogre::Texture*>(resource.get());
					if (texture) {
						outputStream << texture->getWidth() << "x" << texture->getHeight() << " ";
					}
					outputStream << std::endl;
					loadedResourceCount++;
				}
				resourceCount++;
			}
			outputStream << "  Total number of resources: " << resourceCount << std::endl;
			outputStream << "  Number of loaded resources: " << loadedResourceCount << std::endl;
		}
	}

	outputStream << "Total memory usage for all resource manager: " << resourceMemoryUsage << " bytes" << std::endl;

	outputStream << std::flush;
}
Ogre::String ObjectControl::mouseDragged (QPoint lastPos,QPoint currPos,float w,float h) 
{
	using namespace Ogre;

	float RatioX = float(lastPos.x())/w;
	float RatioY = float(lastPos.y())/h;

	Ray mouseRay = mCamera->getCameraToViewportRay(RatioX,RatioY);
	mRaySceneQuery->setRay(mouseRay);
	mRaySceneQuery->setSortByDistance(true);
	mRaySceneQuery->setQueryMask(DUMMY_PLANE);
	mRaySceneQuery->setQueryTypeMask(SceneManager::ENTITY_TYPE_MASK);
	RaySceneQueryResult &result = mRaySceneQuery->execute();

	Ogre::MovableObject *closestObject = NULL;
	Real closestDistance = 100000;

	Ogre::RaySceneQueryResult::iterator rayIterator= result.begin();

	for( rayIterator; rayIterator != result.end(); rayIterator++ ) 
	{
		if ( (*rayIterator).movable !=NULL && closestDistance>(*rayIterator).distance )
		{
			closestObject = ( *rayIterator ).movable;
			Ogre::String name = closestObject->getName();

			Ogre::Vector3 newpos	= Ogre::Vector3::ZERO;
			float rotateFactor		= 0.0f;
			float scaleFactor		= 0.0f;

			switch( currntOperation )
			{
				//==== 處理物體平移 ====//
				case MoveX:
					if ( name != "dummy_plane_y" ) continue;
					newpos = mouseRay.getPoint((*rayIterator).distance);
					node->setPosition(newpos.x,node->getPosition().y,node->getPosition().z);
					break;
				case MoveY:
					if( name == "dummy_plane_y" ) continue; 
					newpos = mouseRay.getPoint((*rayIterator).distance);
					node->setPosition(node->getPosition().x,newpos.y-node->_getWorldAABB().getHalfSize().y,node->getPosition().z);
					break;
				case MoveZ:
					if( name != "dummy_plane_y" ) continue; 
					newpos = mouseRay.getPoint((*rayIterator).distance);
					node->setPosition(node->getPosition().x,node->getPosition().y,newpos.z);				
					break;

				//==== 處理物體旋轉 ====//
				case RotateX:
					rotateFactor = 1*(currPos.y()-lastPos.y());
					node->pitch(Ogre::Degree(rotateFactor),Node::TS_WORLD);
					break;
				case RotateY:
					rotateFactor = 1*(currPos.x()-lastPos.x());
					node->yaw(Ogre::Degree(rotateFactor),Node::TS_WORLD);
					break;
				case RotateZ:
					rotateFactor = 1*(currPos.y()-lastPos.y());
					node->roll(Ogre::Degree(rotateFactor),Node::TS_WORLD);
					break;

				//==== 處理物體縮放 ====//
				case ScaleX:
					scaleFactor = 1+0.001*(currPos.x()-lastPos.x());
					node->scale(scaleFactor,1,1);
					break;
				case ScaleY:
					scaleFactor = 1-0.001*(currPos.y()-lastPos.y());
					node->scale(1,scaleFactor,1);
					break;
				case ScaleZ:
					scaleFactor = 1+0.001*(currPos.x()-lastPos.x());
					node->scale(1,1,scaleFactor);
					break;
				case ScaleXYZ:
					scaleFactor = 1+0.001*(currPos.x()-lastPos.x());
					node->scale(scaleFactor,scaleFactor,scaleFactor);
					break;
			}

			update();
		}	
	}
	mRaySceneQuery->clearResults();

	return (node==NULL)?"":node->getName();
}