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; }