//------------------------------------------------------------------------------------------------ void StaticMeshToShapeConverter::addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform) { // Each entity added need to reset size and radius // next time getRadius and getSize are asked, they're computed. mBounds = Ogre::Vector3(-1,-1,-1); mBoundRadius = -1; //_entity = entity; //_node = (SceneNode*)(_entity->getParentNode()); mTransform = transform; if (mesh->hasSkeleton ()) Ogre::LogManager::getSingleton().logMessage("MeshToShapeConverter::addMesh : Mesh " + mesh->getName () + " as skeleton but added to trimesh non animated"); if (mesh->sharedVertexData) { VertexIndexToShape::addStaticVertexData (mesh->sharedVertexData); } for(unsigned int i = 0;i < mesh->getNumSubMeshes();++i) { Ogre::SubMesh *sub_mesh = mesh->getSubMesh(i); if (!sub_mesh->useSharedVertices) { VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount); VertexIndexToShape::addStaticVertexData (sub_mesh->vertexData); } else { VertexIndexToShape::addIndexData (sub_mesh->indexData); } } }
std::pair<int, int> MeshUtils::getMeshCount(const Ogre::MeshPtr& mesh) { size_t vertex_count = 0; size_t index_count = 0; bool added_shared = false; for (int j = 0; j < mesh->getNumSubMeshes(); j++) { Ogre::SubMesh* submesh = mesh->getSubMesh(j); // VertexData* vertex_data = submesh->vertexData; // IndexData* index_data = submesh->indexData; // We only need to add the shared vertices once if (submesh->useSharedVertices) { if (!added_shared) { vertex_count += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertex_count += submesh->vertexData->vertexCount; } // Add the indices index_count += submesh->indexData->indexCount; } return std::make_pair(vertex_count, index_count); }
void LodInputBuffer::fillBuffer( Ogre::MeshPtr mesh ) { meshName = mesh->getName(); boundingSphereRadius = mesh->getBoundingSphereRadius(); bool sharedVerticesAdded = false; unsigned short submeshCount = mesh->getNumSubMeshes(); submesh.resize(submeshCount); for (unsigned short i = 0; i < submeshCount; i++) { const SubMesh* ogresubmesh = mesh->getSubMesh(i); LodInputBuffer::Submesh& outsubmesh = submesh[i]; outsubmesh.indexBuffer.fillBuffer(ogresubmesh->indexData); outsubmesh.useSharedVertexBuffer = ogresubmesh->useSharedVertices; if (!outsubmesh.useSharedVertexBuffer) { outsubmesh.vertexBuffer.fillBuffer(ogresubmesh->vertexData); } else if (!sharedVerticesAdded) { sharedVerticesAdded = true; sharedVertexBuffer.fillBuffer(mesh->sharedVertexData); } } }
//------------------------------------------------------------------------------------------------ void AnimatedMeshToShapeConverter::addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform) { // Each entity added need to reset size and radius // next time getRadius and getSize are asked, they're computed. mBounds = Ogre::Vector3(-1.0f , -1.0f, -1.0f); mBoundRadius = -1.0f; //_entity = entity; //_node = (SceneNode*)(_entity->getParentNode()); mTransform = transform; assert(mesh->hasSkeleton()); if (mesh->sharedVertexData) { VertexIndexToShape::addAnimatedVertexData(mesh->sharedVertexData, NULL, &mesh->sharedBlendIndexToBoneIndexMap); } for (unsigned int i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh *sub_mesh = mesh->getSubMesh(i); if (!sub_mesh->useSharedVertices) { VertexIndexToShape::addIndexData(sub_mesh->indexData, mVertexCount); VertexIndexToShape::addAnimatedVertexData(sub_mesh->vertexData, NULL, &sub_mesh->blendIndexToBoneIndexMap); } else { VertexIndexToShape::addIndexData(sub_mesh->indexData); } } }
//--------------------------------------------------------------------- void MeshElement::setMaterialName(const String &name) { mMaterialName = name; if (mEntity) { // if this is "none",we will use the origin material of the mesh if (mMaterialName == "none") { if ( false == mMeshName.empty() ) { Ogre::MeshPtr currentMesh = Ogre::MeshManager::getSingleton().getByName(mMeshName); for ( unsigned short i=0; i<currentMesh->getNumSubMeshes(); ++i ) { mEntity->getSubEntity(i)->setMaterialName( currentMesh->getSubMesh(i)->getMaterialName() ); } } } else mEntity->setMaterialName(mMaterialName); } }
void Utils::GetMeshInformation( const Ogre::MeshPtr mesh, size_t &vertexCount, Ogre::Vector3* &vertices, size_t &indexCount, unsigned* &indices) { bool addShared = false; size_t currentOffset = 0; size_t shared_offset = 0; size_t nextOffset = 0; size_t indexOffset = 0; vertexCount = indexCount = 0; for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); if(submesh->useSharedVertices) { if( !addShared ) { vertexCount += mesh->sharedVertexData->vertexCount; addShared = true; } } else { vertexCount += submesh->vertexData->vertexCount; } indexCount += submesh->indexData->indexCount; } vertices = new Ogre::Vector3[vertexCount]; indices = new unsigned[indexCount]; addShared = false; for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertexData = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !addShared)) { if(submesh->useSharedVertices) { addShared = true; shared_offset = currentOffset; } const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float* pReal; for( size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[currentOffset + j] = pt; } vbuf->unlock(); nextOffset += vertexData->vertexCount; } Ogre::IndexData* indexData = submesh->indexData; size_t numTris = indexData->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : currentOffset; if ( use32bitindexes ) { for ( size_t k = 0; k < numTris*3; ++k) { indices[indexOffset++] = pLong[k] + static_cast<unsigned long>(offset); } } else { for ( size_t k = 0; k < numTris*3; ++k) { indices[indexOffset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset); } } ibuf->unlock(); currentOffset = nextOffset; } }
void PhysicsManager::getMeshInformation(Ogre::MeshPtr mesh,size_t &vertex_count,Vector3* &vertices, size_t &index_count, unsigned* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient,const Ogre::Vector3 &scale) { vertex_count = index_count = 0; bool added_shared = false; size_t current_offset = vertex_count; size_t shared_offset = vertex_count; size_t next_offset = vertex_count; size_t index_offset = index_count; size_t prev_vert = vertex_count; size_t prev_ind = index_count; // Calculate how many vertices and indices we're going to need for(int i = 0;i < mesh->getNumSubMeshes();i++) { SubMesh* submesh = mesh->getSubMesh(i); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if(!added_shared) { VertexData* vertex_data = mesh->sharedVertexData; vertex_count += vertex_data->vertexCount; added_shared = true; } } else { VertexData* vertex_data = submesh->vertexData; vertex_count += vertex_data->vertexCount; } // Add the indices Ogre::IndexData* index_data = submesh->indexData; index_count += index_data->indexCount; } // Allocate space for the vertices and indices vertices = new Vector3[vertex_count]; indices = new unsigned[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for(int i = 0;i < mesh->getNumSubMeshes();i++) { SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::Real* pReal; for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Vector3 pt; pt.x = (*pReal++); pt.y = (*pReal++); pt.z = (*pReal++); pt = (orient * (pt * scale)) + position; vertices[current_offset + j].x = pt.x; vertices[current_offset + j].y = pt.y; vertices[current_offset + j].z = pt.z; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; unsigned short* pShort; unsigned int* pInt; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); if (use32bitindexes) pInt = static_cast<unsigned int*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); else pShort = static_cast<unsigned short*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); for(size_t k = 0; k < numTris; ++k) { size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset; unsigned int vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 0] = vindex + offset; vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 1] = vindex + offset; vindex = use32bitindexes? *pInt++ : *pShort++; indices[index_offset + 2] = vindex + offset; index_offset += 3; } ibuf->unlock(); current_offset = next_offset; } }
void Renderer::FindClosestPolygon(Ogre::Entity* entity, float& closestDistance, Ogre::Vector3& position, Ogre::Vector3& normal) { closestDistance = std::numeric_limits<float>::max(); // default value (means // nothing detected) // Get transformation Ogre::SceneNode* parentNode = entity->getParentSceneNode(); Ogre::Vector3 parentPos; Ogre::Quaternion parentOrientation; Ogre::Vector3 parentScale; if (parentNode) { parentPos = parentNode->_getDerivedPosition(); parentOrientation = parentNode->_getDerivedOrientation(); parentScale = parentNode->_getDerivedScale(); } else { parentPos = Ogre::Vector3::ZERO; parentOrientation = Ogre::Quaternion::IDENTITY; parentScale = Ogre::Vector3::UNIT_SCALE; } // Handle animated entities bool isAnimated = entity->hasSkeleton(); if (isAnimated) { entity->addSoftwareAnimationRequest(false); entity->_updateAnimation(); } // Loop through each submesh Ogre::MeshPtr mesh = entity->getMesh(); for (uint i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); // Ignore anything that isn't a triangle List if (subMesh->operationType != Ogre::RenderOperation::OT_TRIANGLE_LIST) continue; // Get the vertex data Ogre::VertexData* vertexData; if (subMesh->useSharedVertices) { if (isAnimated) vertexData = entity->_getSkelAnimVertexData(); else vertexData = mesh->sharedVertexData; } else { if (isAnimated) vertexData = entity->getSubEntity(i)->_getSkelAnimVertexData(); else vertexData = subMesh->vertexData; } // Get the size of one vertex const Ogre::VertexElement* posEl = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vBuff = vertexData->vertexBufferBinding->getBuffer(posEl->getSource()); uint vertexSize = vBuff->getVertexSize(); // Save pointer to first vertex short* pVertex = (short*)vBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); short* pStartVertex = pVertex; // Get the index buffer // If it is null then skip as it must be a point cloud Ogre::HardwareIndexBufferSharedPtr iBuff = subMesh->indexData->indexBuffer; if (iBuff.isNull()) continue; uint* pLong = (uint*)iBuff->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); uint16_t* pShort = (uint16_t*)pLong; // Look through each vertex and check each triangle with the ray Ogre::Vector3 vertexPos; Ogre::Vector3 vertex1; Ogre::Vector3 vertex2; float* pReal; uint index; for (uint k = 0; k < subMesh->indexData->indexCount; k++) { // Read index value if (iBuff->getType() == Ogre::HardwareIndexBuffer::IT_32BIT) // if 32bit indexes { index = (uint)pLong[k]; } else { index = (uint)pShort[k]; } // Read referenced vertex pVertex = pStartVertex + (vertexSize * index); // calculate pointer posEl->baseVertexPointerToElement(pVertex, &pReal); // read vertex vertexPos = Ogre::Vector3(pReal[0], pReal[1], pReal[2]); // read position values // Apply world transformations if (parentNode) vertexPos = (parentOrientation * (vertexPos * parentScale)) + parentPos; // Figure out triangle and calculate the distance if it's the closest switch (k % 3) { case 0: vertex1 = vertexPos; break; case 1: vertex2 = vertexPos; break; case 2: RayToTriangleCheck(vertex1, vertex2, vertexPos, closestDistance, position, normal); break; default: break; } } iBuff->unlock(); vBuff->unlock(); } if (isAnimated) { entity->removeSoftwareAnimationRequest(false); } }
//----------------------------------------------------------------------- void MeshInfo::getMeshInformation( Ogre::MeshPtr mesh, const Vector3 &position, const Quaternion &orient, const Vector3 &scale) { size_t vertexCount = 0; size_t indexCount = 0; Vector3* vertices = 0; Vector3* normals; unsigned long* indices = 0; bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; // Calculate how many vertices and indices we're going to need for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh( i ); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if( !added_shared ) { vertexCount += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertexCount += submesh->vertexData->vertexCount; } // Add the indices indexCount += submesh->indexData->indexCount; } // Allocate space for the vertices and indices vertices = new Vector3[vertexCount]; normals = new Vector3[vertexCount]; indices = new unsigned long[indexCount]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); const Ogre::VertexElement* normalElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_NORMAL); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float* pReal; for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; normalElem->baseVertexPointerToElement(vertex, &pReal); Vector3 nt(pReal[0], pReal[1], pReal[2]); normals[current_offset + j] = nt; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset; size_t numTrisMultThree = numTris*3; if ( use32bitindexes ) { for ( size_t k = 0; k < numTrisMultThree; ++k) { indices[index_offset++] = pLong[k] + static_cast<unsigned long>(offset); } } else { for ( size_t k = 0; k < numTrisMultThree; ++k) { indices[index_offset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset); } } ibuf->unlock(); current_offset = next_offset; } // Create triangles from the retrieved data for (size_t k = 0; k < indexCount-1; k+=3) { Triangle t; t.v1 = vertices [indices[k]]; t.vn1 = normals [indices[k]]; t.v2 = vertices [indices[k+1]]; t.vn2 = normals [indices[k+1]]; t.v3 = vertices [indices[k+2]]; t.vn3 = normals [indices[k+2]]; t.calculateSquareSurface(); t.calculateSurfaceNormal(); t.calculateEdgeNormals(); _triangles.push_back(t); } // Delete intermediate arrays delete [] indices; delete [] normals; delete [] vertices; // Sort the triangle on their size, if needed (only if a gaussian random number generator // function is used to perform a random lookup of a triangle) if (mDistribution == MSD_HOMOGENEOUS) sort(_triangles.begin(), _triangles.end(), SortDescending()); else if (mDistribution == MSD_HETEROGENEOUS_1) sort(_triangles.begin(), _triangles.end(), SortAscending()); }
CompoundCollisionShape* CollisionShapeManager::PerformConvexDecomposition(const String& Name, Graphics::Mesh* ObjectMesh, Whole Depth, Real CPercent, Real PPercent, Boole UseAllSubmeshes) { //new submesh friendly code Ogre::MeshPtr myMesh = ObjectMesh->_GetInternalMesh(); Ogre::SubMesh* subMesh = NULL; Ogre::IndexData* indexData = NULL; Ogre::VertexData* vertexData = NULL; Boole use32bitindexes = false; unsigned int currtriCount = 0; unsigned int triCount = 0; unsigned int vCount = 0; unsigned int iCount = 0; Whole VertPrevSize = 0; Whole IndiPrevSize = 0; Boole SharedVerts = myMesh->getSubMesh(0)->useSharedVertices; Whole* VertPerSubMesh = NULL; if(UseAllSubmeshes) { VertPerSubMesh = new Whole[myMesh->getNumSubMeshes()]; for( Whole X = 0 ; X < myMesh->getNumSubMeshes() ; X++ ) { vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(X)->vertexData->vertexCount; iCount += myMesh->getSubMesh(X)->indexData->indexCount; VertPerSubMesh[X] = SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(X)->vertexData->vertexCount; } }else{ vCount += SharedVerts ? myMesh->sharedVertexData->vertexCount : myMesh->getSubMesh(0)->vertexData->vertexCount; iCount += myMesh->getSubMesh(0)->indexData->indexCount; } Ogre::Vector3* vertices = new Ogre::Vector3[vCount]; unsigned int* indices = new unsigned int[iCount]; for( unsigned short int SubMeshIndex = 0 ; SubMeshIndex < myMesh->getNumSubMeshes() ; SubMeshIndex++ ) { if( !UseAllSubmeshes && (SubMeshIndex > 0) ) break; if( SharedVerts && (SubMeshIndex > 0) ) break; subMesh = myMesh->getSubMesh(SubMeshIndex); indexData = subMesh->indexData; vertexData = SharedVerts ? myMesh->sharedVertexData : myMesh->getSubMesh(SubMeshIndex)->vertexData; const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vBuffer = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); Ogre::HardwareIndexBufferSharedPtr iBuffer = indexData->indexBuffer; currtriCount=indexData->indexCount/3; triCount+=(indexData->indexCount/3); unsigned char* vertex = static_cast<unsigned char*>(vBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); float* pReal = NULL; for( size_t j = 0 ; j < vertexData->vertexCount ; j++, vertex += vBuffer->getVertexSize() ) { posElem->baseVertexPointerToElement(vertex, &pReal); vertices[j + VertPrevSize].x = *pReal++; vertices[j + VertPrevSize].y = *pReal++; vertices[j + VertPrevSize].z = *pReal++; } vBuffer->unlock(); size_t index_offset = 0; use32bitindexes = (iBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(iBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); if( use32bitindexes ) { for (size_t k = 0; k < currtriCount*3; ++k) { if(SubMeshIndex > 0 && VertPerSubMesh) { indices[index_offset+IndiPrevSize] = pLong[k] + VertPerSubMesh[SubMeshIndex]; }else{ indices[index_offset+IndiPrevSize] = pLong[k]; } index_offset++; } }else{ for( size_t k = 0 ; k < currtriCount * 3 ; ++k ) { if(SubMeshIndex > 0 && VertPerSubMesh) { indices[index_offset+IndiPrevSize] = (static_cast<unsigned long>(pShort[k])) + VertPerSubMesh[SubMeshIndex]; }else{ indices[index_offset+IndiPrevSize] = static_cast<unsigned long>(pShort[k]); } index_offset++; } } iBuffer->unlock(); VertPrevSize += vertexData->vertexCount; IndiPrevSize += indexData->indexCount; } ConvexDecomposition::DecompDesc desc; desc.mVcount = vertexData->vertexCount; desc.mTcount = triCount; desc.mVertices = &vertices[0].x; desc.mIndices = &indices[0]; unsigned int maxv = 16; float skinWidth = 0.0; desc.mDepth = Depth; desc.mCpercent = CPercent; desc.mPpercent = PPercent; desc.mMaxVertices = maxv; desc.mSkinWidth = skinWidth; Internal::MezzConvexDecomposition decomp; desc.mCallback = &decomp; ConvexBuilder cb(desc.mCallback); cb.process(desc); CompoundCollisionShape* compound = new CompoundCollisionShape(Name); btTransform trans; trans.setIdentity(); for (int i=0;i<decomp.m_convexShapes.size();i++) { std::stringstream namestream; namestream << Name << "Child" << i; Vector3 centroid(decomp.m_convexCentroids[i]); ConvexHullCollisionShape* convexShape = new ConvexHullCollisionShape(namestream.str(),decomp.m_convexShapes[i]); compound->AddChildShape(convexShape,centroid); } delete[] vertices; delete[] indices; delete[] VertPerSubMesh; return compound; }
//--------------------------------------------------------------------- void OptimiseTool::processMesh(Ogre::MeshPtr mesh) { bool rebuildEdgeList = false; // Shared geometry if (mesh->sharedVertexData) { print("Optimising mesh shared vertex data..."); setTargetVertexData(mesh->sharedVertexData); for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { SubMesh* sm = mesh->getSubMesh(i); if (sm->useSharedVertices) { addIndexData(sm->indexData); } } if (optimiseGeometry()) { if (mesh->getSkeletonName() != StringUtil::BLANK) { print(" fixing bone assignments..."); Mesh::BoneAssignmentIterator currentIt = mesh->getBoneAssignmentIterator(); Mesh::VertexBoneAssignmentList newList = getAdjustedBoneAssignments(currentIt); mesh->clearBoneAssignments(); for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin(); bi != newList.end(); ++bi) { mesh->addBoneAssignment(bi->second); } } for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { SubMesh* sm = mesh->getSubMesh(i); if (mesh->getSkeletonName() != StringUtil::BLANK) { print(" fixing bone assignments..."); Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator(); Mesh::VertexBoneAssignmentList newList = getAdjustedBoneAssignments(currentIt); sm->clearBoneAssignments(); for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin(); bi != newList.end(); ++bi) { sm->addBoneAssignment(bi->second); } } if (sm->useSharedVertices) { fixLOD(sm->mLodFaceList); } } rebuildEdgeList = true; } } // Dedicated geometry for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { SubMesh* sm = mesh->getSubMesh(i); if (!sm->useSharedVertices) { print("Optimising submesh " + StringConverter::toString(i) + " dedicated vertex data "); setTargetVertexData(sm->vertexData); addIndexData(sm->indexData); if (optimiseGeometry()) { if (mesh->getSkeletonName() != StringUtil::BLANK) { print(" fixing bone assignments..."); Mesh::BoneAssignmentIterator currentIt = sm->getBoneAssignmentIterator(); Mesh::VertexBoneAssignmentList newList = getAdjustedBoneAssignments(currentIt); sm->clearBoneAssignments(); for (Mesh::VertexBoneAssignmentList::iterator bi = newList.begin(); bi != newList.end(); ++bi) { sm->addBoneAssignment(bi->second); } } fixLOD(sm->mLodFaceList); rebuildEdgeList = true; } } } if (rebuildEdgeList && mesh->isEdgeListBuilt()) { // force rebuild of edge list mesh->freeEdgeList(); mesh->buildEdgeList(); } }
Mesh loadMesh(const std::string& meshName) { Mesh result; bool addedShared = false; size_t currentOffset = 0; size_t sharedOffset = 0; size_t nextOffset = 0; size_t indexOffset = 0; const v3 scale = v3::UNIT_SCALE; const v3 position = v3::ZERO; const qv4 orientation = qv4::IDENTITY; Ogre::MeshManager* mm = Ogre::MeshManager::getSingletonPtr(); if (! mm) { initOgreForMeshLoading(); mm = Ogre::MeshManager::getSingletonPtr(); } Ogre::MeshPtr mesh = mm->load(meshName, "General"); // Calculate how many result.mVertices and result.mIndices we're going to need for (unsigned short i=0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); // We only need to add the shared result.mVertices once if (subMesh->useSharedVertices) { if (!addedShared) { result.mVertexCount += mesh->sharedVertexData->vertexCount; addedShared = true; } } else { result.mVertexCount += subMesh->vertexData->vertexCount; } result.mIndexCount += subMesh->indexData->indexCount; } result.mVertices.reset(new v3[result.mVertexCount]); result.mIndices.reset(new u32[result.mIndexCount]); addedShared = false; // Run through the sub-meshes again, adding the data into the arrays for (unsigned short i=0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* subMesh = mesh->getSubMesh(i); Ogre::VertexData* vertexData = subMesh->useSharedVertices ? mesh->sharedVertexData : subMesh->vertexData; if((!subMesh->useSharedVertices) || (subMesh->useSharedVertices && !addedShared)) { if(subMesh->useSharedVertices) { addedShared = true; sharedOffset = currentOffset; } const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be compiled/typedefed as double: float* pReal; for( size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); v3 pt(pReal[0], pReal[1], pReal[2]); result.mVertices[currentOffset + j] = (orientation * (pt * scale)) + position; } vbuf->unlock(); nextOffset += vertexData->vertexCount; } Ogre::IndexData* index_data = subMesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); unsigned long* pLong = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (subMesh->useSharedVertices)? sharedOffset : currentOffset; if (use32bitindexes) { for (size_t k = 0; k < numTris*3; ++k) { result.mIndices[indexOffset++] = pLong[k] + static_cast<unsigned long>(offset); } } else { for (size_t k = 0; k < numTris*3; ++k) { result.mIndices[indexOffset++] = static_cast<unsigned long>(pShort[k]) + static_cast<unsigned long>(offset); } } ibuf->unlock(); currentOffset = nextOffset; } return result; }
OgreNewt::ConvexCollisionPtr PhysicsRagDoll::RagBone::_makeConvexHull(OgreNewt::World* world, Ogre::MeshPtr mesh, Ogre::Real minWeight) { std::vector< Ogre::Vector3 > vertexVector; // for this bone, gather all of the vertices linked to it, and make an individual convex hull. std::string boneName = mOgreBone->getName(); unsigned int boneIndex = mOgreBone->getHandle(); Ogre::Matrix4 invMatrix; invMatrix.makeInverseTransform(-mOgreBone->_getBindingPoseInversePosition(), Ogre::Vector3::UNIT_SCALE / mOgreBone->_getBindingPoseInverseScale(), mOgreBone->_getBindingPoseInverseOrientation().Inverse()); unsigned int num_sub = mesh->getNumSubMeshes(); for (unsigned int i = 0; i < num_sub; i++) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::SubMesh::BoneAssignmentIterator bai = submesh->getBoneAssignmentIterator(); Ogre::VertexDeclaration* v_decl; const Ogre::VertexElement* p_elem; float* v_Posptr; size_t v_count; Ogre::VertexData* v_data = NULL; if (submesh->useSharedVertices) { v_data = mesh->sharedVertexData; v_count = v_data->vertexCount; v_decl = v_data->vertexDeclaration; p_elem = v_decl->findElementBySemantic(Ogre::VES_POSITION); } else { v_data = submesh->vertexData; v_count = v_data->vertexCount; v_decl = v_data->vertexDeclaration; p_elem = v_decl->findElementBySemantic(Ogre::VES_POSITION); } size_t start = v_data->vertexStart; //pointer Ogre::HardwareVertexBufferSharedPtr v_sptr = v_data->vertexBufferBinding->getBuffer(p_elem->getSource()); unsigned char* v_ptr = static_cast<unsigned char*>(v_sptr->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned char* v_offset; while (bai.hasMoreElements()) { Ogre::VertexBoneAssignment vba = bai.getNext(); if (vba.boneIndex == boneIndex) { //found a vertex that is attached to this bone. if (vba.weight >= minWeight) { //get offset to Position data! v_offset = v_ptr + (vba.vertexIndex * v_sptr->getVertexSize()); p_elem->baseVertexPointerToElement(v_offset, &v_Posptr); Ogre::Vector3 vert; vert.x = *v_Posptr; v_Posptr++; vert.y = *v_Posptr; v_Posptr++; vert.z = *v_Posptr; // apply transformation in to local space. vert = invMatrix * vert; vertexVector.push_back(vert); Ogre::LogManager::getSingletonPtr()->logMessage(" vertex found! id:"+Ogre::StringConverter::toString(vba.vertexIndex)); } } } v_sptr->unlock(); } // okay, we have gathered all verts for this bone. make a convex hull! unsigned int numVerts = vertexVector.size(); Ogre::Vector3* verts = new Ogre::Vector3[ numVerts ]; unsigned int j = 0; while (!vertexVector.empty()) { verts[j] = vertexVector.back(); vertexVector.pop_back(); j++; } ////////////////////////////////////////////////////////////////////////////////// OgreNewt::ConvexCollisionPtr col; if (numVerts > 0) col = OgreNewt::ConvexCollisionPtr(new OgreNewt::CollisionPrimitives::ConvexHull(world, verts, numVerts, 0)); delete []verts; return col; }
PhysicsObject* PhysicsMgr::createConvexHull(String meshname,Ogre::Vector3 pos,Ogre::Vector3 scale) { bool newshape = false; size_t vertex_count; float* vertices; size_t index_count; vertex_count = index_count = 0; bool added_shared = false; size_t current_offset = vertex_count; size_t shared_offset = vertex_count; size_t next_offset = vertex_count; size_t index_offset = index_count; size_t prev_vert = vertex_count; size_t prev_ind = index_count; std::vector<Ogre::Vector3> vertVect; btConvexShape *convexShape; //btShapeHull* hull; if(meshname=="CUBE"||meshname=="BOX") { return createCube(scale,pos); } if(mShapes.find(meshname)==mShapes.end()) { newshape = true; Ogre::MeshPtr mesh = Ogre::MeshManager::getSingletonPtr()->load(meshname,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // Calculate how many vertices and indices we're going to need for(int i = 0;i < mesh->getNumSubMeshes();i++) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if(!added_shared) { Ogre::VertexData* vertex_data = mesh->sharedVertexData; vertex_count += vertex_data->vertexCount; added_shared = true; } } else { Ogre::VertexData* vertex_data = submesh->vertexData; vertex_count += vertex_data->vertexCount; } // Add the indices Ogre::IndexData* index_data = submesh->indexData; index_count += index_data->indexCount; } // Allocate space for the vertices and indices int a = vertex_count; vertices = new float[vertex_count*3]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for(int i = 0;i < mesh->getNumSubMeshes();i++) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); Ogre::Real* pReal; for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt; pt.x = (*pReal++); pt.y = (*pReal++); pt.z = (*pReal++); bool skip = false; // ignore duped verts for(unsigned int i=0;i<vertVect.size();++i) { if(vertVect[i]==pt) { skip = true; //std::cout<<"IGNORED!\n"; } } // skipping duped verts caused some kind of f-up, TOBEFIXED eventually if(!skip) { vertices[current_offset + (j*3)] = pt.x*0.92f; vertices[current_offset + (j*3) + 1] = pt.y*0.92f; vertices[current_offset + (j*3) + 2] = pt.z*0.92f; vertVect.push_back(pt); } } vbuf->unlock(); next_offset += vertex_data->vertexCount; } } convexShape = new btConvexHullShape(static_cast<btScalar*>(vertices),vertVect.size(),3*sizeof(btScalar)); //create a hull approximation btConvexShape *finalShape = 0; //std::cout<<"size: "<<vertVect.size()<<"\n"; // seemed kinda iffy? //if(vertVect.size()>75) //{ // hull = new btShapeHull(convexShape); // btScalar margin = convexShape->getMargin(); // hull->buildHull(margin); // //btConvexHullShape* simplifiedConvexShape = new btConvexHullShape(hull->getVertexPointer(),hull->numVertices()); // // btConvexHullShape* simplifiedConvexShape = new btConvexHullShape(); // for (int i=0;i<hull->numVertices();i++) // { // btVector3 vect = hull->getVertexPointer()[i]*0.9; // std::cout<<"Vert: "<<vect.x()<<" "<<vect.y()<<" "<<vect.z()<<"\n"; // simplifiedConvexShape->addPoint(vect); // } // mShapes[meshname] = (simplifiedConvexShape); // finalShape = simplifiedConvexShape; //} //else //{ mShapes[meshname] = (convexShape); finalShape = convexShape; //} } //finalShape->setMargin(0.f); btVector3 localInertia(0,0,0); mShapes[meshname]->calculateLocalInertia(180.f,localInertia); btRigidBody* actor = new btRigidBody(180.f,0,mShapes[meshname],localInertia); actor->setWorldTransform(btTransform(btQuaternion::getIdentity(),btVector3(pos.x,pos.y,pos.z))); actor->setRestitution(0.f); actor->setFriction(0.8f); //actor->setAnisotropicFriction(btVector3(0.3f,0.3f,0.3f)); actor->setDamping(0.2f,0.7f); dynamic_cast<btDiscreteDynamicsWorld*>(mDynamicsWorld)->addRigidBody(actor,COLLISION_GROUP_1,COLLISION_GROUP_1); mObjects.push_back(new PhysicsObject(actor,mDynamicsWorld)); if(newshape) { delete[] vertices; //if(vertVect.size()>75) //{ // delete hull; // delete convexShape; //} } return mObjects[mObjects.size()-1]; }
// Get the mesh information for the given mesh. // Code found on this forum link: http://www.ogre3d.org/wiki/index.php/RetrieveVertexData void CollisionTools::GetMeshInformation(const Ogre::MeshPtr mesh, size_t &vertex_count, Ogre::Vector3* &vertices, size_t &index_count, Ogre::uint32* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient, const Ogre::Vector3 &scale) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; vertex_count = index_count = 0; // Calculate how many vertices and indices we're going to need for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh( i ); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if( !added_shared ) { vertex_count += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertex_count += submesh->vertexData->vertexCount; } // Add the indices index_count += submesh->indexData->indexCount; } // Allocate space for the vertices and indices vertices = new Ogre::Vector3[vertex_count]; indices = new Ogre::uint32[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Ogre::Real will // be comiled/typedefed as double: // Ogre::Ogre::Real* pOgre::Real; float* pReal; for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); Ogre::uint32* pLong = static_cast<Ogre::uint32*>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong); size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset; if ( use32bitindexes ) { for ( size_t k = 0; k < numTris*3; ++k) { indices[index_offset++] = pLong[k] + static_cast<Ogre::uint32>(offset); } } else { for ( size_t k = 0; k < numTris*3; ++k) { indices[index_offset++] = static_cast<Ogre::uint32>(pShort[k]) + static_cast<Ogre::uint32>(offset); } } ibuf->unlock(); current_offset = next_offset; } }
//----------------------------------------------------------------------- void InstanceManager::unshareVertices(const Ogre::MeshPtr &mesh) { // Retrieve data to copy bone assignments const Mesh::VertexBoneAssignmentList& boneAssignments = mesh->getBoneAssignments(); Mesh::VertexBoneAssignmentList::const_iterator it = boneAssignments.begin(); Mesh::VertexBoneAssignmentList::const_iterator end = boneAssignments.end(); size_t curVertexOffset = 0; // Access shared vertices VertexData* sharedVertexData = mesh->sharedVertexData; for (size_t subMeshIdx = 0; subMeshIdx < mesh->getNumSubMeshes(); subMeshIdx++) { SubMesh *subMesh = mesh->getSubMesh(subMeshIdx); IndexData *indexData = subMesh->indexData; HardwareIndexBuffer::IndexType idxType = indexData->indexBuffer->getType(); IndicesMap indicesMap = (idxType == HardwareIndexBuffer::IT_16BIT) ? getUsedIndices<uint16>(indexData) : getUsedIndices<uint32>(indexData); VertexData *newVertexData = new VertexData(); newVertexData->vertexCount = indicesMap.size(); newVertexData->vertexDeclaration = sharedVertexData->vertexDeclaration->clone(); for (size_t bufIdx = 0; bufIdx < sharedVertexData->vertexBufferBinding->getBufferCount(); bufIdx++) { HardwareVertexBufferSharedPtr sharedVertexBuffer = sharedVertexData->vertexBufferBinding->getBuffer(bufIdx); size_t vertexSize = sharedVertexBuffer->getVertexSize(); HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer (vertexSize, newVertexData->vertexCount, sharedVertexBuffer->getUsage(), sharedVertexBuffer->hasShadowBuffer()); uint8 *oldLock = (uint8*)sharedVertexBuffer->lock(0, sharedVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY); uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL); IndicesMap::iterator indIt = indicesMap.begin(); IndicesMap::iterator endIndIt = indicesMap.end(); for (; indIt != endIndIt; ++indIt) { memcpy(newLock + vertexSize * indIt->second, oldLock + vertexSize * indIt->first, vertexSize); } sharedVertexBuffer->unlock(); newVertexBuffer->unlock(); newVertexData->vertexBufferBinding->setBinding(bufIdx, newVertexBuffer); } if (idxType == HardwareIndexBuffer::IT_16BIT) { copyIndexBuffer<uint16>(indexData, indicesMap); } else { copyIndexBuffer<uint32>(indexData, indicesMap); } // Store new attributes subMesh->useSharedVertices = false; subMesh->vertexData = newVertexData; // Transfer bone assignments to the submesh size_t offset = curVertexOffset + newVertexData->vertexCount; for (; it != end; ++it) { size_t vertexIdx = (*it).first; if (vertexIdx > offset) break; VertexBoneAssignment boneAssignment = (*it).second; boneAssignment.vertexIndex = static_cast<unsigned int>(boneAssignment.vertexIndex - curVertexOffset); subMesh->addBoneAssignment(boneAssignment); } curVertexOffset = newVertexData->vertexCount + 1; } // Release shared vertex data delete mesh->sharedVertexData; mesh->sharedVertexData = NULL; mesh->clearBoneAssignments(); }
void NxMeshManager::SetPivotTransform( Ogre::MeshPtr mesh, const Nx::Vector3 & Position, const Nx::Quaternion & Rotation, const Nx::Vector3 & Scale ) { //from mesh magick / mit licence Nx::Matrix4 transform = Nx::Matrix4::IDENTITY; Nx::Vector3 translate = Nx::Vector3::ZERO; // Apply current transform to the mesh, to get the bounding box to // base te translation on. AxisAlignedBox aabb = getMeshAabb( mesh, transform); //if (alignment == "left") //{ // translate = Vector3(-aabb.getMinimum().x, 0, 0); //} //else if (alignment == "center") //{ // translate = Vector3(-aabb.getCenter().x, 0, 0); //} //else if (alignment == "right") //{ // translate = Vector3(-aabb.getMaximum().x, 0, 0); //} //Position .. only support pivot down / centered //translate = Vector3(0, -aabb.getMinimum().y, 0);// pivot down translate = Position; transform = Nx::Matrix4::getTrans(translate) * transform; //rotation transform = Nx::Matrix4(Rotation) * transform; //scale transform = Nx::Matrix4::getScale(Scale) * transform; // Check whether we have to flip vertex winding. // We do have to, if we changed our right hand base. // We can test it by using the cross product from X and Y and see, if it is a non-negative // projection on Z. Actually it should be exactly Z, as we don't do non-uniform scaling yet, // but the test is cheap either way. Nx::Matrix3 m3; transform.extract3x3Matrix(m3); if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0) { LogMsg("SetPivotPosition : Flipping vertex winding ... " ); mFlipVertexWinding = true; } //mTransform = transform; NxMat4toOgre( mTransform, transform ) ; mBoundingBox.setNull(); if( mesh->sharedVertexData != NULL) { processVertexData( mesh->sharedVertexData); }else { LogMsg("mesh->sharedVertexData NULL"); } for( int i = 0; i < mesh->getNumSubMeshes(); i++ ) { SubMesh* submesh = mesh->getSubMesh(i); if( submesh->vertexData != NULL ) { LogMsg("SetPivotPosition : Processing vertex data ... " ); processVertexData(submesh->vertexData); }else { LogMsg("submesh->vertexData NULL"); } if (submesh->indexData != NULL) { LogMsg("SetPivotPosition : Processing Index data .." ); processIndexData(submesh->indexData); }else { LogMsg("submesh->indexData NULL"); } } //process pose for( unsigned short i = 0; i < mesh->getPoseCount(); ++i ) { Ogre::Pose * pose = mesh->getPose(i); Ogre::Matrix3 m3x3; mTransform.extract3x3Matrix(m3x3); Pose::VertexOffsetIterator it = pose->getVertexOffsetIterator(); while (it.hasMoreElements()) { Ogre::Vector3 offset = it.peekNextValue(); Ogre::Vector3 newOffset = m3x3 * offset; *it.peekNextValuePtr() = newOffset; it.moveNext(); } } mesh->_setBounds( mBoundingBox, false ); }
void PolyMousePicker::GetMeshInformation( Ogre::Entity *entity, size_t &vertex_count, Ogre::Vector3* &vertices, size_t &index_count, Ogre::uint32* &indices, const Ogre::Vector3 &position, const Ogre::Quaternion &orient, const Ogre::Vector3 &scale) { bool added_shared = false; size_t current_offset = 0; size_t shared_offset = 0; size_t next_offset = 0; size_t index_offset = 0; vertex_count = index_count = 0; Ogre::MeshPtr mesh = entity->getMesh(); bool useSoftwareBlendingVertices = entity->hasSkeleton(); if (useSoftwareBlendingVertices) { entity->_updateAnimation(); } // Calculate how many vertices and indices we're going to need for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh( i ); // We only need to add the shared vertices once if(submesh->useSharedVertices) { if( !added_shared ) { vertex_count += mesh->sharedVertexData->vertexCount; added_shared = true; } } else { vertex_count += submesh->vertexData->vertexCount; } // Add the indices index_count += submesh->indexData->indexCount; } // Allocate space for the vertices and indices vertices = new Ogre::Vector3[vertex_count]; indices = new Ogre::uint32[index_count]; added_shared = false; // Run through the submeshes again, adding the data into the arrays for ( unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { Ogre::SubMesh* submesh = mesh->getSubMesh(i); //---------------------------------------------------------------- // GET VERTEXDATA //---------------------------------------------------------------- Ogre::VertexData* vertex_data; //When there is animation: if(useSoftwareBlendingVertices) vertex_data = submesh->useSharedVertices ? entity->_getSkelAnimVertexData() : entity->getSubEntity(i)->_getSkelAnimVertexData(); else vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData; if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) { if(submesh->useSharedVertices) { added_shared = true; shared_offset = current_offset; } const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); unsigned char* vertex = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); // There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double // as second argument. So make it float, to avoid trouble when Ogre::Real will // be comiled/typedefed as double: // Ogre::Real* pReal; float* pReal; for( size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) { posElem->baseVertexPointerToElement(vertex, &pReal); Ogre::Vector3 pt(pReal[0], pReal[1], pReal[2]); vertices[current_offset + j] = (orient * (pt * scale)) + position; } vbuf->unlock(); next_offset += vertex_data->vertexCount; } Ogre::IndexData* index_data = submesh->indexData; size_t numTris = index_data->indexCount / 3; Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); void* hwBuf = ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY); size_t offset = (submesh->useSharedVertices)? shared_offset : current_offset; size_t index_start = index_data->indexStart; size_t last_index = numTris*3 + index_start; if (use32bitindexes) { Ogre::uint32* hwBuf32 = static_cast<Ogre::uint32*>(hwBuf); for (size_t k = index_start; k < last_index; ++k) { indices[index_offset++] = hwBuf32[k] + static_cast<Ogre::uint32>( offset ); } } else { Ogre::uint16* hwBuf16 = static_cast<Ogre::uint16*>(hwBuf); for (size_t k = index_start; k < last_index; ++k) { indices[ index_offset++ ] = static_cast<Ogre::uint32>( hwBuf16[k] ) + static_cast<Ogre::uint32>( offset ); } } ibuf->unlock(); current_offset = next_offset; } }