//----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- MeshInfo::MeshInfo (const String& meshName, MeshSurfaceDistribution distribution, const Quaternion& orientation, const Vector3& scale) : mDistribution(distribution) { Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load(meshName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); getMeshInformation(mesh, Vector3::ZERO, orientation, scale); }
/* Creates a list of triangles and allocating all the vertexs from a mesh * Requires: * @cont The Vertex container where it will been put the vertexs * @mesh The mesh to extract the triangles * @triangles The list to be filled with the triangles * Returns: * true on success * false otherwise */ bool Util::getTrianglesFromMesh(PolyStructsContainer<sm::Vertex *> &cont, PolyStructsContainer<Triangle *> &triangles, Ogre::MeshPtr mesh) { ASSERT(!mesh.isNull()); if(!cont.isEmpty()){ debug("Warning: Not an empty container\n"); } if(!triangles.isEmpty()){ debug("Warning, triangles is not empty\n"); ASSERT(false); } size_t vertex_count,index_count; Ogre::Vector3* vertices = 0; long unsigned* indices = 0; getMeshInformation(mesh.get(),vertex_count,vertices,index_count,indices); // TODO: hacer esta funcion mas rapida, estamos buscando para cada vector // el vertice asociado. Es lento // here we will map Ogre::Vector3[i] -> Vertex* std::vector<sm::Vertex *> vertexMap; vertexMap.resize(vertex_count); // fills the map of vertexs sm::Vertex *v = 0; for(size_t i = 0; i < vertex_count; ++i){ v = findVertex(cont.getObjs(), vertices[i]); if(!v){ // create a new vertex and put it in the container v = new sm::Vertex(vertices[i].x, vertices[i].z); cont.addObj(v); } // associate the vec to the vertex vertexMap[i] = v; } // now we have to create the triangles for(size_t i = 0; i < index_count; i += 3){ triangles.addObj(new Triangle(vertexMap[indices[i]], vertexMap[indices[i+1]], vertexMap[indices[i+2]])); } delete []vertices; delete []indices; return true; }
void OgreWidget::addMeshInformation(Ogre::Entity* entity, Ogre::SceneNode* node) { MeshInformation* mi = new MeshInformation; mi->sceneNode = node; getMeshInformation( entity->getMesh(), mi->vertex_count, mi->vertices, mi->index_count, mi->indices, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale() ); mi->aabb = entity->getBoundingBox(); mi->aabb.transform(node->_getFullTransform()); mi->valid = true; mEntities.insert(entity, mi); }
ECBody& ECScene::spawnMesh( const std::string& Name, const double& mass, const chrono::ChVector<>& position, const chrono::ChVector<>& size, const chrono::ChQuaternion<>& rotation, const std::string& FileName, const bool& fixed) { ECBody& _ret = createBody(Name); chrono::ChSharedPtr<chrono::ChTriangleMeshShape> _mesh(new chrono::ChTriangleMeshShape); _mesh->SetName(FileName); _mesh->SetScale(size); _ret->SetRot(rotation); _ret->SetPos(position); _ret->SetMass(mass); _ret->GetAssets().push_back(_mesh); Ogre::Entity* l_pEntity = m_pSceneManager->createEntity(FileName); Ogre::MeshPtr l_pMesh = l_pEntity->getMesh(); size_t l_vertex_count, l_index_count; Ogre::Vector3* l_pvertices; unsigned long* l_pindices; chrono::geometry::ChTriangleMeshConnected l_triangle_mesh; getMeshInformation(l_pMesh.getPointer(), l_vertex_count, l_pvertices, l_index_count, l_pindices, Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY, Ogre::Vector3::UNIT_SCALE); for (unsigned int i = 0; i < l_index_count; i+=3) { l_triangle_mesh.addTriangle( chrono::ChVector<>( // Vertex 0 (double) l_pvertices[l_pindices[i]].x, // Index I.x (double) l_pvertices[l_pindices[i]].y, // Index I.y (double) l_pvertices[l_pindices[i]].z // Index I.z ) * size, chrono::ChVector<>( // Vertex 1 (double) l_pvertices[l_pindices[i+1]].x, // Index I+1.x (double) l_pvertices[l_pindices[i+1]].y, // Index I+1.y (double) l_pvertices[l_pindices[i+1]].z // Index I+1.z ) * size, chrono::ChVector<>( // Vertex 2 (double) l_pvertices[l_pindices[i+2]].x, // Index I+2.x (double) l_pvertices[l_pindices[i+2]].y, // Index I+2.y (double) l_pvertices[l_pindices[i+2]].z // Index I+2.z ) * size ); } m_pSceneManager->destroyEntity(l_pEntity); delete[] l_pvertices; delete[] l_pindices; _ret->GetCollisionModel()->ClearModel(); _ret->GetCollisionModel()->AddTriangleMesh(l_triangle_mesh, true, false, chrono::ChVector<>(), chrono::QUNIT); _ret->GetCollisionModel()->BuildModel(); _ret->SetCollide(true); _ret->SetBodyFixed(fixed); _ret.refresh(); return _ret; }
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; } }