Пример #1
0
	Object* ObjectManager::collision(const Ogre::Vector3& fromPoint, const Ogre::Vector3& toPoint, 
		float collisionRadius, int queryMask)
	{
			Ogre::Entity* entity = mCollision->collidesWithObject(fromPoint, toPoint, collisionRadius, queryMask);
		if (entity && entity->isVisible())
			return getObject(entity->getName());

		return 0;
	}
Пример #2
0
	bool PlaypenApp::appFrameStarted(opal::real dt)
	{
		// Do per-frame application-specific things here.

		// Handle speech input.
		bool keepLooping = true;
		bool makeObject = false;
		std::string material;
		ObjectType type;
		std::string outputString;
		while (voce::getRecognizerQueueSize() > 0)
		{
			std::string s = voce::popRecognizedString();

			//// Check if the string contains 'quit'.
			//if (std::string::npos != s.rfind("quit"))
			//{
			//	keepLooping = false;
			//}

			// Check if we should reset.
			if (std::string::npos != s.rfind("reset"))
			{
				// Make sure the PhysicalCamera isn't grabbing anything.
				mPhysicalCamera->release();
				destroyAllPhysicalEntities();
				setupInitialPhysicalEntities();
				voce::synthesize("reset");
				return true;
			}

			// Check for material color.
			if (std::string::npos != s.rfind("yellow"))
			{
				outputString += "yellow";
				material = "Plastic/Yellow";
			}
			else if (std::string::npos != s.rfind("red"))
			{
				outputString += "red";
				material = "Plastic/Red";
			}
			else if (std::string::npos != s.rfind("blue"))
			{
				outputString += "blue";
				material = "Plastic/Blue";
			}
			else if (std::string::npos != s.rfind("green"))
			{
				outputString += "green";
				material = "Plastic/Green";
			}
			else if (std::string::npos != s.rfind("purple"))
			{
				outputString += "purple";
				material = "Plastic/Purple";
			}
			else if (std::string::npos != s.rfind("orange"))
			{
				outputString += "orange";
				material = "Plastic/Orange";
			}
			else
			{
				// Default to dark gray.
				material = "Plastic/DarkGray";
			}

			// Check for object type.
			if (std::string::npos != s.rfind("box"))
			{
				outputString += " box";
				type = OBJECT_TYPE_BOX;
				makeObject = true;
			}
			else if (std::string::npos != s.rfind("sphere"))
			{
				outputString += " sphere";
				type = OBJECT_TYPE_SPHERE;
				makeObject = true;
			}
			else if (std::string::npos != s.rfind("wall"))
			{
				outputString += " wall";
				type = OBJECT_TYPE_WALL;
				makeObject = true;
			}
			else if (std::string::npos != s.rfind("tower"))
			{
				outputString += " tower";
				type = OBJECT_TYPE_TOWER;
				makeObject = true;
			}
			else if (std::string::npos != s.rfind("character"))
			{
				outputString += " character";
				type = OBJECT_TYPE_RAGDOLL;
				makeObject = true;
			}

			if (makeObject)
			{
				voce::synthesize(outputString);
				createObject(material, type);
			}
		}

		// Update the grasping spring line.
		if (mPhysicalCamera->isGrasping())
		{
			Ogre::Entity* pickingSphere = 
				mSceneMgr->getEntity("pickingSphere");
			if (!pickingSphere->isVisible())
			{
				pickingSphere->setVisible(true);
			}

			Ogre::Entity* springLine = 
				mSceneMgr->getEntity("springLine");
			if (!springLine->isVisible())
			{
				springLine->setVisible(true);
			}

			opal::Point3r desiredPos = 
				mPhysicalCamera->getGraspGlobalPos();
			Ogre::Vector3 point0(desiredPos[0], desiredPos[1], desiredPos[2]);

			opal::Point3r attachPos = mPhysicalCamera->getAttachGlobalPos();
			Ogre::Vector3 point1(attachPos[0], attachPos[1], attachPos[2]);

			pickingSphere->getParentSceneNode()->setPosition(point1);

			Ogre::Vector3 lineVec = point0 - point1;
			if (!lineVec.isZeroLength())
			{
				Ogre::SceneNode* springLineNode = 
					springLine->getParentSceneNode();
				springLineNode->setPosition(0.5 * (point0 + point1));
				
				springLineNode->setDirection(lineVec);
				springLineNode->setScale(0.1, 0.1, lineVec.length());
			}
			else
			{
				springLine->setVisible(false);
			}
		}
		else
		{
			Ogre::Entity* pickingSphere = 
				mSceneMgr->getEntity("pickingSphere");
			if (pickingSphere->isVisible())
			{
				pickingSphere->setVisible(false);
			}

			Ogre::Entity* springLine = 
				mSceneMgr->getEntity("springLine");
			if (springLine->isVisible())
			{
				springLine->setVisible(false);
			}
		}

		// Return true to continue looping.
		return keepLooping;
	}
Пример #3
0
	bool PlaypenApp::appFrameStarted(opal::real dt)
	{
		// Do per-frame application-specific things here.

		// Update the grasping spring line.
		if (mPhysicalCamera->isGrasping())
		{
			Ogre::Entity* pickingSphere = 
				mSceneMgr->getEntity("pickingSphere");
			if (!pickingSphere->isVisible())
			{
				pickingSphere->setVisible(true);
			}

			Ogre::Entity* springLine = 
				mSceneMgr->getEntity("springLine");
			if (!springLine->isVisible())
			{
				springLine->setVisible(true);
			}

			opal::Point3r desiredPos = 
				mPhysicalCamera->getGraspGlobalPos();
			Ogre::Vector3 point0(desiredPos[0], desiredPos[1], desiredPos[2]);

			opal::Point3r attachPos = mPhysicalCamera->getAttachGlobalPos();
			Ogre::Vector3 point1(attachPos[0], attachPos[1], attachPos[2]);

			pickingSphere->getParentSceneNode()->setPosition(point1);

			Ogre::Vector3 lineVec = point0 - point1;
			if (!lineVec.isZeroLength())
			{
				Ogre::SceneNode* springLineNode = 
					springLine->getParentSceneNode();
				springLineNode->setPosition(0.5 * (point0 + point1));
				
				springLineNode->setDirection(lineVec, Ogre::Node::TS_WORLD);
				springLineNode->setScale(0.1, 0.1, lineVec.length());
			}
			else
			{
				springLine->setVisible(false);
			}
		}
		else
		{
			Ogre::Entity* pickingSphere = 
				mSceneMgr->getEntity("pickingSphere");
			if (pickingSphere->isVisible())
			{
				pickingSphere->setVisible(false);
			}

			Ogre::Entity* springLine = 
				mSceneMgr->getEntity("springLine");
			if (springLine->isVisible())
			{
				springLine->setVisible(false);
			}
		}

		// Return true to continue looping.
		return true;
	}
// 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++;
					}
				}
			}
		}
	}
}
Пример #5
0
void MeshCollisionDetector::testCollision(Ogre::Ray& ray, CollisionResult& result)
{

    // 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::Real closest_distance = -1.0f;
    Ogre::Vector3 closest_result = Ogre::Vector3::ZERO;
    const Model::Model::SubModelSet& submodels = mModel->getSubmodels();
    for (Model::Model::SubModelSet::const_iterator I = submodels.begin(); I != submodels.end(); ++I)
    {
        Ogre::Entity* pentity = (*I)->getEntity();
        if (pentity->isVisible() && pentity->getParentNode()) {
            // mesh data to retrieve
            size_t vertex_count;
            size_t index_count;
            Ogre::Vector3 *vertices;
            unsigned long *indices;

            // get the mesh information
            getMeshInformation(pentity->getMesh(), vertex_count, vertices, index_count, indices,
                               pentity->getParentNode()->_getDerivedPosition(),
                               pentity->getParentNode()->_getDerivedOrientation(),
                               pentity->getParentNode()->getScale());

            // test for hitting individual triangles on the mesh
            bool new_closest_found = false;
            for (int i = 0; i < static_cast<int>(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)
            {
                closest_result = ray.getPoint(closest_distance);
            }
        }
    }


    // return the result
    if (closest_distance >= 0.0f)
    {
        // raycast success
        result.collided = true;
        result.position = closest_result;
        result.distance = closest_distance;
    }
    else
    {
        // raycast failed
        result.collided = false;
    }
}