예제 #1
0
    //-----------------------------------------------------------------------
    void
    MeshInformer::getEntityTriangles(const Entity* entity,
                                     std::vector<Vector3>& vertices,
                                     std::vector<size_t>& indices,
                                     std::vector<size_t>* indexOffsets)
    {
        size_t numVertices = 0, numIndices = 0;
        getEntityStatistics(entity, numVertices, numIndices);

        size_t vertex_offset = vertices.size();
        size_t index_offset = indices.size();

        vertices.resize(vertex_offset + numVertices);
        indices.resize(index_offset + numIndices);

        // Software blended vertex data available only if animation enabled, and software animation are
        // used by internally engine, or user requested software animation.
		bool useBlended = entity->_isAnimated() &&
            (!entity->isHardwareAnimationEnabled() || entity->getSoftwareAnimationRequests() > 0);

        // Use skinned vertex data only if blended data available and skeleton animation enabled.
        bool useSkinned = useBlended && entity->_isSkeletonAnimated();

        Vector3* pVertices = &vertices[0];
        size_t* pIndices = &indices[0];
        size_t shared_vertex_offset = vertex_offset;
        bool added_shared_vertex = false;

        size_t numSubEntities = entity->getNumSubEntities();
        for (size_t i = 0; i < numSubEntities; ++i)
        {
            SubEntity* subEntity = entity->getSubEntity(i);
            if (!subEntity->isVisible())
            {
                // Skip non-visible sub-entity
                continue;
            }

            SubMesh* subMesh = subEntity->getSubMesh();

            if (indexOffsets)
            {
                indexOffsets->push_back(index_offset);
            }

            if (subMesh->operationType == RenderOperation::OT_TRIANGLE_LIST ||
                subMesh->operationType == RenderOperation::OT_TRIANGLE_STRIP ||
                subMesh->operationType == RenderOperation::OT_TRIANGLE_FAN)
            {
                size_t current_vertex_offset;
                if (subMesh->useSharedVertices)
                {
                    if (!added_shared_vertex)
                    {
                        size_t vertexCount = getVertices(pVertices + vertex_offset,
                            useSkinned ? entity->_getSkelAnimVertexData()
                                :
                            useBlended && subMesh->parent->getSharedVertexDataAnimationType() != VAT_NONE ? entity->_getSoftwareVertexAnimVertexData()
                                :
                            subMesh->parent->sharedVertexData);
                        shared_vertex_offset = vertex_offset;
                        vertex_offset += vertexCount;
                        added_shared_vertex = true;
                    }

                    current_vertex_offset = shared_vertex_offset;
                }
                else
                {
                    size_t vertexCount = getVertices(pVertices + vertex_offset,
                        useSkinned ? subEntity->_getSkelAnimVertexData()
                            :
                        useBlended && subMesh->getVertexAnimationType() != VAT_NONE ? subEntity->_getSoftwareVertexAnimVertexData()
                            :
                        subMesh->vertexData);
                    current_vertex_offset = vertex_offset;
                    vertex_offset += vertexCount;
                }

                size_t index_count = getTriangles(pIndices + index_offset, subMesh->indexData, current_vertex_offset, subMesh->operationType);
                index_offset += index_count;
            }
        }
    }
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);
		}
	}
}
예제 #3
0
파일: main.cpp 프로젝트: OGRECave/ogre
void XMLToBinary(XmlOptions opts)
{
    // Read root element and decide from there what type
    String response;
    TiXmlDocument* doc = new TiXmlDocument(opts.source);
    // Some double-parsing here but never mind
    if (!doc->LoadFile())
    {
        cout << "Unable to open file " << opts.source << " - fatal error." << endl;
        delete doc;
        exit (1);
    }
    TiXmlElement* root = doc->RootElement();
    if (!stricmp(root->Value(), "mesh"))
    {
        delete doc;
        MeshPtr newMesh = MeshManager::getSingleton().createManual("conversion",
                          ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        VertexElementType colourElementType;
        if (opts.d3d)
            colourElementType = VET_COLOUR_ARGB;
        else
            colourElementType = VET_COLOUR_ABGR;

        xmlMeshSerializer->importMesh(opts.source, colourElementType, newMesh.getPointer());

        // Re-jig the buffers?
        // Make sure animation types are up to date first
        newMesh->_determineAnimationTypes();
        if (opts.reorganiseBuffers)
        {
            logMgr->logMessage("Reorganising vertex buffers to automatic layout...");
            // Shared geometry
            if (newMesh->sharedVertexData)
            {
                // Automatic
                VertexDeclaration* newDcl =
                    newMesh->sharedVertexData->vertexDeclaration->getAutoOrganisedDeclaration(
                        newMesh->hasSkeleton(), newMesh->hasVertexAnimation(), newMesh->getSharedVertexDataAnimationIncludesNormals());
                if (*newDcl != *(newMesh->sharedVertexData->vertexDeclaration))
                {
                    // Usages don't matter here since we're onlly exporting
                    BufferUsageList bufferUsages;
                    for (size_t u = 0; u <= newDcl->getMaxSource(); ++u)
                        bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY);
                    newMesh->sharedVertexData->reorganiseBuffers(newDcl, bufferUsages);
                }
            }
            // Dedicated geometry
            Mesh::SubMeshIterator smIt = newMesh->getSubMeshIterator();
            while (smIt.hasMoreElements())
            {
                SubMesh* sm = smIt.getNext();
                if (!sm->useSharedVertices)
                {
                    const bool hasVertexAnim = sm->getVertexAnimationType() != Ogre::VAT_NONE;

                    // Automatic
                    VertexDeclaration* newDcl =
                        sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(
                            newMesh->hasSkeleton(), hasVertexAnim, sm->getVertexAnimationIncludesNormals());
                    if (*newDcl != *(sm->vertexData->vertexDeclaration))
                    {
                        // Usages don't matter here since we're onlly exporting
                        BufferUsageList bufferUsages;
                        for (size_t u = 0; u <= newDcl->getMaxSource(); ++u)
                            bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY);
                        sm->vertexData->reorganiseBuffers(newDcl, bufferUsages);
                    }
                }
            }

        }

        if( opts.mergeTexcoordResult != opts.mergeTexcoordToDestroy )
        {
            newMesh->mergeAdjacentTexcoords( uint16(opts.mergeTexcoordResult), uint16(opts.mergeTexcoordToDestroy) );
        }

        if (opts.nuextremityPoints)
        {
            Mesh::SubMeshIterator smIt = newMesh->getSubMeshIterator();
            while (smIt.hasMoreElements())
            {
                SubMesh* sm = smIt.getNext();
                sm->generateExtremes (opts.nuextremityPoints);
            }
        }

        meshSerializer->exportMesh(newMesh.getPointer(), opts.dest, opts.endian);

        // Clean up the conversion mesh
        MeshManager::getSingleton().remove("conversion");
    }
    else if (!stricmp(root->Value(), "skeleton"))
    {
        delete doc;
        SkeletonPtr newSkel = SkeletonManager::getSingleton().create("conversion",
                              ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        xmlSkeletonSerializer->importSkeleton(opts.source, newSkel.getPointer());
        if (opts.optimiseAnimations)
        {
            newSkel->optimiseAllAnimations();
        }
        skeletonSerializer->exportSkeleton(newSkel.getPointer(), opts.dest, SKELETON_VERSION_LATEST, opts.endian);

        // Clean up the conversion skeleton
        SkeletonManager::getSingleton().remove("conversion");
    }
    else
    {
        delete doc;
    }

}