void OgreWidget::mouseSelect(QPoint const & pos, bool multiple) { /* Apercu de ce que pourrait donner d'une selection par volume. Ogre::Real x = pos.x() / (float)width(); Ogre::Real y = pos.y() / (float)height(); Ogre::Ray ray = m_camera->getCamera()->getCameraToViewportRay(x, y); Ogre::RaySceneQuery * query = m_sceneManager->createRayQuery(ray); Ogre::RaySceneQueryResult & queryResult = query->execute(); Ogre::RaySceneQueryResult::iterator queryResultIterator = queryResult.begin(); Ogre::PlaneBoundedVolume volume = m_camera->getCameraToViewportBoxVolume(); Ogre::PlaneBoundedVolumeListSceneQuery * query = m_sceneManager->createPlaneBoundedVolumeQuery(volume); Ogre::SceneQueryResult & queryResult = query->execute();*/ Ogre::Entity * selectedEntity = m_selectionBuffer->OnSelectionClick(pos.x(), pos.y()); if (selectedEntity) { Ogre::SceneNode * node = selectedEntity->getParentSceneNode(); while (node->getParentSceneNode() != m_sceneManager->getRootSceneNode()) node = node->getParentSceneNode(); selectItem(Ogre::any_cast<InstItem *>(node->getUserObjectBindings().getUserAny()), multiple); } else unselectItem(); }
InputGeometry::InputGeometry(std::vector<Ogre::Entity*> sourceMeshes,const Ogre::AxisAlignedBox& tileBounds) : _sourceMeshes(sourceMeshes), _numVertices(0), _numTriangles(0), _referenceNode(0), _boundMin(0), _boundMax(0), _normals(0), _vertices(0), _triangles(0) { if(sourceMeshes.empty()) { return; } Ogre::Entity* ent = sourceMeshes[0]; _referenceNode = ent->getParentSceneNode()->getCreator()->getRootSceneNode(); _boundMin = new float[3]; _boundMax = new float[3]; Utility::vector3_toFloatPtr(tileBounds.getMinimum(),_boundMin); Utility::vector3_toFloatPtr(tileBounds.getMaximum(),_boundMax); _convertOgreEntities(tileBounds); //eventually add _buildChunkyTriMesh() }
InputGeometry::InputGeometry(std::vector<Ogre::Entity*> sourceMeshes) : _sourceMeshes(sourceMeshes), _numVertices(0), _numTriangles(0), _referenceNode(0), _boundMin(0), _boundMax(0), _normals(0), _vertices(0), _triangles(0) { if(sourceMeshes.empty()) { return; } Ogre::Entity* tmpEnt = sourceMeshes[0]; _referenceNode = tmpEnt->getParentSceneNode()->getCreator()->getRootSceneNode(); _calculateExtents(); _convertOgreEntities(); //eventually add _buildChunkTriMesh }
void InputGeometry::_calculateExtents() { Ogre::Entity* ent = _sourceMeshes[0]; Ogre::AxisAlignedBox sourceMeshBB = ent->getBoundingBox(); Ogre::Matrix4 transform; transform = _referenceNode->_getFullTransform().inverse() * ent->getParentSceneNode()->_getFullTransform(); sourceMeshBB.transform(transform); Ogre::Vector3 min = sourceMeshBB.getMinimum(); Ogre::Vector3 max = sourceMeshBB.getMaximum(); for(auto itr = _sourceMeshes.begin(); itr != _sourceMeshes.end(); ++itr) { Ogre::Entity* tmpEnt = *itr; transform = _referenceNode->_getFullTransform().inverse() * tmpEnt->getParentSceneNode()->_getFullTransform(); sourceMeshBB = ent->getBoundingBox(); sourceMeshBB.transform(transform); Ogre::Vector3 min2 = sourceMeshBB.getMinimum(); if(min2.x < min.x) min.x = min2.x; if(min2.y < min.y) min.y = min2.y; if(min2.z < min.z) min.z = min2.z; Ogre::Vector3 max2 = sourceMeshBB.getMaximum(); if(max2.x > max.x) max.x = max2.x; if(max2.y > max.y) max.y = max2.y; if(max2.z > max.z) max.z = max2.z; } if(!_boundMin) { _boundMin = new float[3]; } if(!_boundMax) { _boundMax = new float[3]; } Utility::vector3_toFloatPtr(min,_boundMin); Utility::vector3_toFloatPtr(max,_boundMax); }
void ManipulatorObject::Serialize( rapidxml::xml_document<>* doc, rapidxml::xml_node<>* XMLNode ) { using namespace rapidxml; const String count = Ogre::StringConverter::toString(m_objects.size()); XMLNode->append_attribute(doc->allocate_attribute("count", doc->allocate_string(count.c_str()))); for (auto iter=m_objects.begin(); iter!=m_objects.end(); ++iter) { Ogre::Entity* pObj = iter->first; xml_node<>* objNode = doc->allocate_node(node_element, "entity"); //meshname const String& strMesh = pObj->getMesh()->getName(); objNode->append_attribute(doc->allocate_attribute("meshname", doc->allocate_string(strMesh.c_str()))); //add to navmesh const String& strIsNavMesh = Ogre::StringConverter::toString((iter->second)->m_bAddToNavmesh); objNode->append_attribute(doc->allocate_attribute("isnavmesh", doc->allocate_string(strIsNavMesh.c_str()))); //is building const String& strIsBuilding = Ogre::StringConverter::toString((iter->second)->m_bIsBuilding); objNode->append_attribute(doc->allocate_attribute("isbuilding", doc->allocate_string(strIsBuilding.c_str()))); //building name if(strIsBuilding == "true") objNode->append_attribute(doc->allocate_attribute("buildingname", doc->allocate_string((iter->second)->m_buildingName.c_str()))); //is resource const String& strIsResource = Ogre::StringConverter::toString((iter->second)->m_bIsResource); objNode->append_attribute(doc->allocate_attribute("isresource", doc->allocate_string(strIsResource.c_str()))); //position String strPos = Ogre::StringConverter::toString(pObj->getParentSceneNode()->_getDerivedPosition()); objNode->append_attribute(doc->allocate_attribute("position", doc->allocate_string(strPos.c_str()))); //orientation String strOrient = Ogre::StringConverter::toString(pObj->getParentSceneNode()->_getDerivedOrientation()); objNode->append_attribute(doc->allocate_attribute("orientation", doc->allocate_string(strOrient.c_str()))); //scale String strScale = Ogre::StringConverter::toString(pObj->getParentSceneNode()->_getDerivedScale()); objNode->append_attribute(doc->allocate_attribute("scale", doc->allocate_string(strScale.c_str()))); XMLNode->append_node(objNode); } }
void SoundEditAction::_onEnd(const Point& pt, bool canceled) { if (!canceled) { Ogre::Vector3 normal; if (mSceneManipulator->getTerrainIntersects(pt, mCreatePos, &normal, true) && mSoundMovingEntity && mSoundNode) { // Permanent it to final scene mSceneManipulator->_fireUIChanged(static_cast<void*>(&mCreatePos), UIC_SOUNDEDIT); Ogre::SceneManager* sceneManager = mSceneManipulator->getSceneManager(); Ogre::Entity* entity = sceneManager->createEntity("SoundEntity" + Ogre::StringConverter::toString(mNextNameIndex++), "axes.mesh"); mSoundNode->createChildSceneNode()->attachObject(entity); entity->getParentSceneNode()->setPosition(mCreatePos); entity->getParentSceneNode()->setScale(10,10,10); mSoundEntities.push_back(entity); } } }
void SoundEditAction::_createSoundEntity(int gridX, int gridZ) { if (!mFirstInit) _createIndicatorInstance(); WX::TerrainData* terrainData = mSceneManipulator->getTerrainData(); std::pair<Real, Real> worldPos = terrainData->gridToWorld(gridX, gridZ); Real worldHeight = terrainData->getHeightAt(worldPos.first, worldPos.second); Ogre::SceneManager* sceneManager = mSceneManipulator->getSceneManager(); Ogre::Entity* entity = sceneManager->createEntity("SoundEntity" + Ogre::StringConverter::toString(mNextNameIndex++), "axes.mesh"); mSoundNode->createChildSceneNode()->attachObject(entity); entity->getParentSceneNode()->setPosition(worldPos.first, worldHeight, worldPos.second); entity->getParentSceneNode()->setVisible(mShowSoundEntity); entity->getParentSceneNode()->setScale(10,10,10); mSoundEntities.push_back(entity); }
void SelectionBox::performSelection(std::list<AgentId> &selection, Ogre::Camera *mCamera) { if((mRight - mLeft) * (mBottom - mTop) < 0.0001) return; float left = (mLeft + 1.f) / 2.f; float right = (mRight + 1.f) / 2.f; float top = (1.f - mBottom) / 2.f; float bottom = (1.f - mTop) / 2.f; Ogre::Ray topLeft = mCamera->getCameraToViewportRay(left, top); Ogre::Ray topRight = mCamera->getCameraToViewportRay(right, top); Ogre::Ray bottomLeft = mCamera->getCameraToViewportRay(left, bottom); Ogre::Ray bottomRight = mCamera->getCameraToViewportRay(right, bottom); // These planes have now defined an "open box" which extends to infinity in front of the camera. You can think of // the rectangle we drew with the mouse as being the termination point of the box just in front of the camera. Ogre::PlaneBoundedVolume vol; const Ogre::Real min = .1, max = 500; vol.planes.push_back(Ogre::Plane(topLeft.getPoint(min), topRight.getPoint(min), bottomRight.getPoint(min))); // front plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), topLeft.getPoint(max), topRight.getPoint(max))); // top plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), bottomLeft.getPoint(max), topLeft.getPoint(max))); // left plane vol.planes.push_back(Ogre::Plane(bottomLeft.getOrigin(), bottomRight.getPoint(max), bottomLeft.getPoint(max))); // bottom plane vol.planes.push_back(Ogre::Plane(topRight.getOrigin(), topRight.getPoint(max), bottomRight.getPoint(max))); // right plane Ogre::PlaneBoundedVolumeList volList; volList.push_back(vol); mVolQuery->setVolumes(volList); Ogre::SceneQueryResult result = mVolQuery->execute(); // Finally we need to handle the results of the query. First we will deselect all previously selected objects, // then we will select all objects which were found by the query. std::list<Ogre::SceneNode *> nodes; Ogre::SceneQueryResultMovableList::iterator iter; for(iter = result.movables.begin(); iter != result.movables.end(); ++iter) { Ogre::MovableObject *movable = *iter; if(movable->getMovableType().compare("Entity") == 0) { Ogre::Entity *pentity = static_cast<Ogre::Entity *>(movable); nodes.push_back(pentity->getParentSceneNode()); } } mEngine->level()->getAgentsIdsFromSceneNodes(nodes, selection); }
// Manage physics from this loop // Please don't alter the Ogre scene manager directly. Instead use the designated methods (setPositionX, setPositionY, setPositionZ, setRoll, setPitch, setYaw, animate) void loop(Ogre::SceneManager* smgr){ int dir = 1; int timeStep = 10; while(true){ // If the message array has any elements, the render loop is applying changes from physics loop // If so, abort this timestep if((*::message).size() == 1){ continue; } Sleep(timeStep); Ogre::SceneManager::MovableObjectIterator iterator = smgr->getMovableObjectIterator("Entity"); while(iterator.hasMoreElements()){ // If the message array has any elements, the render loop is applying changes from physics loop // If so, abort this timestep if((*::message).size() == 1){ continue; } Ogre::Entity* entity = static_cast<Ogre::Entity*>(iterator.getNext()); // <>< <>< Make the cute fishy swim <>< <>< // This only moves fish if(entity->hasAnimationState("swim")){ Ogre::SceneNode* sceneNode = entity->getParentSceneNode(); // Update position Ogre::Vector3 pos = sceneNode->getPosition(); if(pos.x > 120){ dir = -1; setYaw(entity, 180); } if(pos.x < -120){ dir = 1; setYaw(entity, 180); } setPositionX(entity, sceneNode->getPosition().x + dir); animate(entity, "swim"); } } } }
Ogre::Entity* OGRE3DPointRenderable::fetchEntity(const Ogre::String& name) { Ogre::Entity* entity = NULL; if (Ogre::StringUtil::endsWith(name, ".mesh")) // Is it a mesh? { entity = mRenderSystem->getSceneManager()->createEntity(mRenderSystem->getUniqueName("Entity"), name); } else if (mRenderSystem->getSceneManager()->hasEntity(name)) // Could it be an entity? { entity = mRenderSystem->getSceneManager()->getEntity(name); if (entity->isAttached()) entity->getParentSceneNode()->detachObject(entity); } else // It must be a mesh. { entity = mRenderSystem->getSceneManager()->createEntity(mRenderSystem->getUniqueName("Entity"), name); } return entity; }
//get stuff void EntityMovementReaction::setUserData(void* data) { Ogre::Entity* mEntity = (Ogre::Entity*) data; node = mEntity->getParentSceneNode(); }
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; }
void RenderedTexture::renderTextures() { //Set up RTT texture Ogre::TexturePtr renderTexture; if (renderTexture.isNull()) { renderTexture = Ogre::TextureManager::getSingleton().createManual( getUniqueID("RenderedEntityMaterial"), "EntityRenderer", Ogre::TEX_TYPE_2D, textureSize, textureSize, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET, 0); } renderTexture->setNumMipmaps(0); //Set up render target Ogre::RenderTexture* renderTarget = renderTexture->getBuffer()->getRenderTarget(); renderTarget->setAutoUpdated(false); //Set up camera Ogre::SceneNode* camNode = sceneMgr->getSceneNode("EntityRenderer::cameraNode"); Ogre::Camera* renderCamera = sceneMgr->createCamera(getUniqueID("EntityRendererCam")); camNode->attachObject(renderCamera); renderCamera->setLodBias(1000.0f); Ogre::Viewport* renderViewport = renderTarget->addViewport(renderCamera); renderViewport->setOverlaysEnabled(false); renderViewport->setClearEveryFrame(true); renderViewport->setShadowsEnabled(false); renderViewport->setBackgroundColour(Ogre::ColourValue(0.0f, 0.0f, 0.0f, 0.0f)); //Set up scene node Ogre::SceneNode* node = sceneMgr->getSceneNode("EntityRenderer::renderNode"); Ogre::SceneNode* oldSceneNode = entity->getParentSceneNode(); if (oldSceneNode) oldSceneNode->detachObject(entity); node->attachObject(entity); node->setPosition(-entityCenter); //Set up camera FOV const Ogre::Real objDist = entityRadius * 100; const Ogre::Real nearDist = objDist - (entityRadius + 1); const Ogre::Real farDist = objDist + (entityRadius + 1); renderCamera->setAspectRatio(1.0f); renderCamera->setFOVy(Ogre::Math::ATan(2.0 * entityRadius / objDist)); renderCamera->setNearClipDistance(nearDist); renderCamera->setFarClipDistance(farDist); //Disable mipmapping (without this, masked textures look bad) Ogre::MaterialManager* mm = Ogre::MaterialManager::getSingletonPtr(); Ogre::FilterOptions oldMinFilter = mm->getDefaultTextureFiltering(Ogre::FT_MIN); Ogre::FilterOptions oldMagFilter = mm->getDefaultTextureFiltering(Ogre::FT_MAG); Ogre::FilterOptions oldMipFilter = mm->getDefaultTextureFiltering(Ogre::FT_MIP); mm->setDefaultTextureFiltering(Ogre::FO_POINT, Ogre::FO_LINEAR,Ogre:: FO_NONE); //Disable fog Ogre::FogMode oldFogMode = sceneMgr->getFogMode(); Ogre::ColourValue oldFogColor = sceneMgr->getFogColour(); Ogre::Real oldFogDensity = sceneMgr->getFogDensity(); Ogre::Real oldFogStart = sceneMgr->getFogStart(); Ogre::Real oldFogEnd = sceneMgr->getFogEnd(); sceneMgr->setFog(Ogre::FOG_NONE); // Get current status of the queue mode Ogre::SceneManager::SpecialCaseRenderQueueMode OldSpecialCaseRenderQueueMode = sceneMgr->getSpecialCaseRenderQueueMode(); //Only render the entity sceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_INCLUDE); sceneMgr->addSpecialCaseRenderQueue(renderQueueGroup); Ogre::uint8 oldRenderQueueGroup = entity->getRenderQueueGroup(); entity->setRenderQueueGroup(renderQueueGroup); bool oldVisible = entity->getVisible(); entity->setVisible(true); float oldMaxDistance = entity->getRenderingDistance(); entity->setRenderingDistance(0); //Calculate the filename hash used to uniquely identity this render std::string strKey = entityKey; char key[32] = {0}; Ogre::uint32 i = 0; for (std::string::const_iterator it = entityKey.begin(); it != entityKey.end(); ++it) { key[i] ^= *it; i = (i+1) % sizeof(key); } for (i = 0; i < sizeof(key); ++i) key[i] = (key[i] % 26) + 'A'; Ogre::ResourceGroupManager::getSingleton().addResourceLocation( GetUserDir().string(), "FileSystem", "BinFolder"); std::string fileNamePNG = "Rendered." + std::string(key, sizeof(key)) + '.' + Ogre::StringConverter::toString(textureSize) + ".png"; //Attempt to load the pre-render file if allowed bool needsRegen = false; if (!needsRegen) { try{ texture = Ogre::TextureManager::getSingleton().load( fileNamePNG, "BinFolder", Ogre::TEX_TYPE_2D, 0); } catch (...) { needsRegen = true; } } if (needsRegen) { //If this has not been pre-rendered, do so now //Position camera camNode->setPosition(0, 0, 0); // TODO camNode->setOrientation(Quaternion(yaw, Vector3::UNIT_Y) * Quaternion(-pitch, Vector3::UNIT_X)); camNode->translate(Ogre::Vector3(0, 0, objDist), Ogre::Node::TS_LOCAL); renderTarget->update(); //Save RTT to file renderTarget->writeContentsToFile((GetUserDir() / fileNamePNG).string()); //Load the render into the appropriate texture view texture = Ogre::TextureManager::getSingleton().load(fileNamePNG, "BinFolder", Ogre::TEX_TYPE_2D, 0); ggTexture = ClientUI::GetTexture(GetUserDir() / fileNamePNG); } entity->setVisible(oldVisible); entity->setRenderQueueGroup(oldRenderQueueGroup); entity->setRenderingDistance(oldMaxDistance); sceneMgr->removeSpecialCaseRenderQueue(renderQueueGroup); // Restore original state sceneMgr->setSpecialCaseRenderQueueMode(OldSpecialCaseRenderQueueMode); //Re-enable mipmapping mm->setDefaultTextureFiltering(oldMinFilter, oldMagFilter, oldMipFilter); //Re-enable fog sceneMgr->setFog(oldFogMode, oldFogColor, oldFogDensity, oldFogStart, oldFogEnd); //Delete camera renderTarget->removeViewport(0); renderCamera->getSceneManager()->destroyCamera(renderCamera); //Delete scene node node->detachAllObjects(); if (oldSceneNode) oldSceneNode->attachObject(entity); //Delete RTT texture assert(!renderTexture.isNull()); std::string texName2(renderTexture->getName()); renderTexture.setNull(); if (Ogre::TextureManager::getSingletonPtr()) Ogre::TextureManager::getSingleton().remove(texName2); }
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; }
Ogre::Entity* RaycastToPolygon( const Ogre::Real& x, const Ogre::Real& y, Ogre::RaySceneQuery* Query, Ogre::Camera* Camera ) { Ogre::Ray MouseRay = Camera->getCameraToViewportRay( x, y ); Query->setRay( MouseRay ); Query->setSortByDistance( true ); Ogre::RaySceneQueryResult& QueryResult = Query->execute(); if( QueryResult.size() == 0 ) { return NULL; } // 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 ClosestDistance = -1.0f; Ogre::Entity* ClosestResult; for( size_t QRIndex = 0; QRIndex < QueryResult.size(); QRIndex++ ) { // stop checking if we have found a raycast hit that is closer // than all remaining entities if( ( ClosestDistance >= 0.0f ) && ( ClosestDistance < QueryResult[QRIndex].distance ) ) break; // only check this result if its a hit against an entity if( ( QueryResult[QRIndex].movable != NULL ) && ( QueryResult[QRIndex].movable->getMovableType().compare("Entity") == 0 ) && QueryResult[QRIndex].movable->getName() != OVISE_SelectionBoxName ) { // get the entity to check Ogre::Entity* PEntity = static_cast<Ogre::Entity*>(QueryResult[QRIndex].movable); // mesh data to retrieve size_t VertexCount; size_t IndexCount; Ogre::Vector3* Vertices; unsigned long* Indices; // get the mesh information GetMeshInformation( PEntity->getMesh(), VertexCount, Vertices, IndexCount, Indices, PEntity->getParentSceneNode()->_getDerivedPosition(), PEntity->getParentSceneNode()->_getDerivedOrientation(), PEntity->getParentSceneNode()->_getDerivedScale() ); // test for hitting individual triangles on the mesh bool NewClosestFound = false; if( IndexCount == 0 ) // no triangles, e.g. pointcloud { NewClosestFound = true; ClosestDistance = QueryResult[QRIndex].distance; } else { for( int i = 0; i < static_cast<int>(IndexCount); i += 3 ) { // check for a hit against this triangle std::pair<bool, Ogre::Real> Hit = Ogre::Math::intersects( MouseRay, 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( ( ClosestDistance < 0.0f ) || ( Hit.second < ClosestDistance ) ) { // this is the closest so far, save it off ClosestDistance = Hit.second; NewClosestFound = 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( NewClosestFound ) ClosestResult = PEntity; } } if( ClosestDistance < 0.0f ) { // raycast failed ClosestResult = NULL; } return ClosestResult; }
void InputGeometry::_convertOgreEntities() { int numNodes = _sourceMeshes.size(); size_t* meshVertexCount = new size_t[numNodes]; size_t* meshIndexCount = new size_t[numNodes]; Ogre::Vector3** meshVertices = new Ogre::Vector3*[numNodes]; unsigned long** meshIndices = new unsigned long*[numNodes]; _numVertices = 0; _numTriangles = 0; size_t i = 0; // used as additional incrementer for(auto itr = _sourceMeshes.begin(); itr != _sourceMeshes.end(); ++itr) { Ogre::MeshPtr meshPtr = (*itr)->getMesh(); GraphicsManager::getMeshInformation(&meshPtr, meshVertexCount[i], meshVertices[i], meshIndexCount[i], meshIndices[i]); _numVertices += meshVertexCount[i]; _numTriangles += meshIndexCount[i]; i++; } _vertices = new float[_numVertices * 3]; _triangles = new int[_numTriangles]; //Triangles in Recast = Indices in Ogre //Triangle array is indices, number of triangles is actual number of triangles _numTriangles = _numTriangles / 3; // indices / 3 int vertsIndex = 0,prevVerticesCount = 0,prevIndexCountTotal = 0; i = 0; for(auto itr = _sourceMeshes.begin(); itr != _sourceMeshes.end(); ++itr) { Ogre::Entity* ent = *itr; Ogre::Matrix4 transform = _referenceNode->_getFullTransform().inverse() * ent->getParentSceneNode()->_getFullTransform(); Ogre::Vector3 vertexPos; for(size_t j = 0; j < meshVertexCount[i]; j++) { vertexPos = transform * meshVertices[i][j]; _vertices[vertsIndex + 0] = vertexPos.x; _vertices[vertsIndex + 1] = vertexPos.y; _vertices[vertsIndex + 2] = vertexPos.z; vertsIndex += 3; } for(size_t j = 0; j < meshIndexCount[i]; j++) { _triangles[prevIndexCountTotal + j] = meshIndices[i][j] + prevVerticesCount; } prevIndexCountTotal += meshIndexCount[i]; prevVerticesCount += meshVertexCount[i]; i++; } delete[] meshIndices[0]; delete[] meshVertices[0]; delete[] meshIndices; delete[] meshVertices; delete[] meshVertexCount; delete[] meshIndexCount; _normals = new float[_numTriangles * 3]; for(int i = 0; i< _numTriangles * 3; i += 3) { const float* v0 = &_vertices[_triangles[i] * 3]; const float* v1 = &_vertices[_triangles[i+1] * 3]; const float* v2 = &_vertices[_triangles[i+2] * 3]; //std::cout << *v0 << "," << *v1 << "," << *v2 << std::endl; float e0[3],e1[3]; for(int j = 0; j < 3; j++) { e0[j] = (v1[j] - v0[j]); e1[j] = (v2[j] - v0[j]); } float* n = &_normals[i]; n[0] = ((e0[1]*e1[2]) - (e0[2]*e1[1])); n[1] = ((e0[2]*e1[0]) - (e0[0]*e1[2])); n[2] = ((e0[0]*e1[1]) - (e0[1]*e1[0])); float d = sqrtf(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); if (d > 0) { d = 1.0f/d; n[0] *= d; n[1] *= d; n[2] *= d; } } }