//----------------------------------------------------------------------- bool HardwareSkinningFactory::extractSkeletonData(const Entity* pEntity, size_t subEntityIndex, ushort& boneCount, ushort& weightCount) { bool isValidData = false; boneCount = 0; weightCount = 0; //Check if we have pose animation which the HS sub render state does not //know how to handle bool hasVertexAnim = pEntity->getMesh()->hasVertexAnimation(); //gather data on the skeleton if (!hasVertexAnim && pEntity->hasSkeleton()) { //get weights count MeshPtr pMesh = pEntity->getMesh(); RenderOperation ro; SubMesh* pSubMesh = pMesh->getSubMesh(subEntityIndex); pSubMesh->_getRenderOperation(ro,0); //get the largest bone assignment boneCount = ushort(std::max(pMesh->sharedBlendIndexToBoneIndexMap.size(), pSubMesh->blendIndexToBoneIndexMap.size())); //go over vertex deceleration //check that they have blend indices and blend weights const VertexElement* pDeclWeights = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS,0); const VertexElement* pDeclIndexes = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES,0); if ((pDeclWeights != NULL) && (pDeclIndexes != NULL)) { isValidData = true; switch (pDeclWeights->getType()) { case VET_FLOAT1: weightCount = 1; break; case VET_USHORT2_NORM: case VET_FLOAT2: weightCount = 2; break; case VET_FLOAT3: weightCount = 3; break; case VET_USHORT4_NORM: case VET_UBYTE4_NORM: case VET_FLOAT4: weightCount = 4; break; default: isValidData = false; break; } } } return isValidData; }
//----------------------------------------------------------------------- void Node::getRenderOperation(RenderOperation& op) { SubMesh* pSubMesh = 0; MeshPtr pMesh = MeshManager::getSingleton().getByName("axes.mesh"); if (pMesh.isNull()) { pMesh = MeshManager::getSingleton().load("axes.mesh", ResourceGroupManager::BOOTSTRAP_RESOURCE_GROUP_NAME); } pSubMesh = pMesh->getSubMesh(0); pSubMesh->_getRenderOperation(op); }
void MeshSerializerTests::assertMeshClone(Mesh* a, Mesh* b, MeshVersion version /*= MESH_VERSION_LATEST*/) { // TODO: Compare skeleton // TODO: Compare animations // TODO: Compare pose animations // CPPUNIT_ASSERT(a->getGroup() == b->getGroup()); // CPPUNIT_ASSERT(a->getName() == b->getName()); #ifndef OGRE_TEST_XMLSERIALIZER // XML serializer fails on these! CPPUNIT_ASSERT(isEqual(a->getBoundingSphereRadius(), b->getBoundingSphereRadius())); CPPUNIT_ASSERT(isEqual(a->getBounds().getMinimum(), b->getBounds().getMinimum())); CPPUNIT_ASSERT(isEqual(a->getBounds().getMaximum(), b->getBounds().getMaximum())); #else StringStream str; Real val1 = a->getBoundingSphereRadius(); Real val2 = b->getBoundingSphereRadius(); Real diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); if (diff > 1.1) { str << "bound sphere diff: " << diff << std::endl; } val1 = a->getBounds().getMinimum().length(); val2 = b->getBounds().getMinimum().length(); diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); if (diff > 1.1) { str << "bound min diff: " << diff << std::endl; } val1 = a->getBounds().getMaximum().length(); val2 = b->getBounds().getMaximum().length(); diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); if (diff > 1.1) { str << "bound max diff: " << diff << std::endl; } if (!str.str().empty()) { StringStream str2; str2 << std::endl << "Mesh name: " << b->getName() << std::endl; str2 << str.str(); std::cout << str2.str(); // OutputDebugStringA(str2.str().c_str()); } #endif /* ifndef OGRE_TEST_XMLSERIALIZER */ // AutobuildEdgeLists is not saved to mesh file. You need to set it after loading a mesh! // CPPUNIT_ASSERT(a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()); CPPUNIT_ASSERT(isHashMapClone(a->getSubMeshNameMap(), b->getSubMeshNameMap())); assertVertexDataClone(a->sharedVertexData, b->sharedVertexData); CPPUNIT_ASSERT(a->getCreator() == b->getCreator()); CPPUNIT_ASSERT(a->getIndexBufferUsage() == b->getIndexBufferUsage()); CPPUNIT_ASSERT(a->getSharedVertexDataAnimationIncludesNormals() == b->getSharedVertexDataAnimationIncludesNormals()); CPPUNIT_ASSERT(a->getSharedVertexDataAnimationType() == b->getSharedVertexDataAnimationType()); CPPUNIT_ASSERT(a->getVertexBufferUsage() == b->getVertexBufferUsage()); CPPUNIT_ASSERT(a->hasVertexAnimation() == b->hasVertexAnimation()); #ifndef OGRE_TEST_XMLSERIALIZER CPPUNIT_ASSERT(a->isEdgeListBuilt() == b->isEdgeListBuilt()); // <== OgreXMLSerializer is doing post processing to generate edgelists! #endif // !OGRE_TEST_XMLSERIALIZER if ((a->getNumLodLevels() > 1 || b->getNumLodLevels() > 1) && ((version < MESH_VERSION_1_8 || (!isLodMixed(a) && !isLodMixed(b))) && // mixed lod only supported in v1.10+ (version < MESH_VERSION_1_4 || (a->getLodStrategy() == DistanceLodStrategy::getSingletonPtr() && b->getLodStrategy() == DistanceLodStrategy::getSingletonPtr())))) { // Lod Strategy only supported in v1.41+ CPPUNIT_ASSERT(a->getNumLodLevels() == b->getNumLodLevels()); CPPUNIT_ASSERT(a->hasManualLodLevel() == b->hasManualLodLevel()); CPPUNIT_ASSERT(a->getLodStrategy() == b->getLodStrategy()); int numLods = a->getNumLodLevels(); for (int i = 0; i < numLods; i++) { if (version != MESH_VERSION_1_0 && a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()) { assertEdgeDataClone(a->getEdgeList(i), b->getEdgeList(i)); } else if (a->getLodLevel(i).edgeData != NULL && b->getLodLevel(i).edgeData != NULL) { assertEdgeDataClone(a->getLodLevel(i).edgeData, b->getLodLevel(i).edgeData); } assertLodUsageClone(a->getLodLevel(i), b->getLodLevel(i)); } } CPPUNIT_ASSERT(a->getNumSubMeshes() == b->getNumSubMeshes()); int numLods = std::min(a->getNumLodLevels(), b->getNumLodLevels()); int numSubmeshes = a->getNumSubMeshes(); for (int i = 0; i < numSubmeshes; i++) { SubMesh* aSubmesh = a->getSubMesh(i); SubMesh* bSubmesh = b->getSubMesh(i); CPPUNIT_ASSERT(aSubmesh->getMaterialName() == bSubmesh->getMaterialName()); CPPUNIT_ASSERT(aSubmesh->isMatInitialised() == bSubmesh->isMatInitialised()); CPPUNIT_ASSERT(aSubmesh->useSharedVertices == bSubmesh->useSharedVertices); CPPUNIT_ASSERT(aSubmesh->getVertexAnimationIncludesNormals() == bSubmesh->getVertexAnimationIncludesNormals()); CPPUNIT_ASSERT(aSubmesh->getVertexAnimationType() == bSubmesh->getVertexAnimationType()); CPPUNIT_ASSERT(aSubmesh->getTextureAliasCount() == bSubmesh->getTextureAliasCount()); CPPUNIT_ASSERT(isContainerClone(aSubmesh->blendIndexToBoneIndexMap, bSubmesh->blendIndexToBoneIndexMap)); // TODO: Compare getBoneAssignments and getTextureAliases for (int n = 0; n < numLods; n++) { if (a->_isManualLodLevel(n)) { continue; } RenderOperation aop, bop; aSubmesh->_getRenderOperation(aop, n); bSubmesh->_getRenderOperation(bop, n); assertIndexDataClone(aop.indexData, bop.indexData); assertVertexDataClone(aop.vertexData, bop.vertexData); CPPUNIT_ASSERT(aop.operationType == bop.operationType); CPPUNIT_ASSERT(aop.useIndexes == bop.useIndexes); } } }