xmlNode* FArchiveXML::WriteGeometryMesh(FCDObject* object, xmlNode* parentNode) { FCDGeometryMesh* geometryMesh = (FCDGeometryMesh*)object; xmlNode* meshNode = NULL; if (geometryMesh->IsConvex() && !geometryMesh->GetConvexHullOf().empty()) { meshNode = AddChild(parentNode, DAE_CONVEX_MESH_ELEMENT); FUSStringBuilder convexHullOfName(geometryMesh->GetConvexHullOf()); AddAttribute(meshNode, DAE_CONVEX_HULL_OF_ATTRIBUTE, convexHullOfName); } else { meshNode = AddChild(parentNode, DAE_MESH_ELEMENT); // Write out the sources for (size_t i = 0; i < geometryMesh->GetSourceCount(); ++i) { FArchiveXML::LetWriteObject(geometryMesh->GetSource(i), meshNode); } // Write out the <vertices> element xmlNode* verticesNode = AddChild(meshNode, DAE_VERTICES_ELEMENT); xmlNode* verticesInputExtraNode = NULL,* verticesInputExtraTechniqueNode = NULL; for (size_t i = 0; i < geometryMesh->GetVertexSourceCount(); ++i) { FCDGeometrySource* source = geometryMesh->GetVertexSource(i); const char* semantic = FUDaeGeometryInput::ToString(source->GetType()); AddInput(verticesNode, source->GetDaeId(), semantic); if (geometryMesh->GetPolygonsCount() > 0) { FCDGeometryPolygons* firstPolys = geometryMesh->GetPolygons(0); FCDGeometryPolygonsInput* input = firstPolys->FindInput(source); FUAssert(input != NULL, continue); if (input->GetSet() != -1) { // We are interested in the set information, so if it is available, export it as an extra. if (verticesInputExtraNode == NULL) { verticesInputExtraNode = FUXmlWriter::CreateNode(DAE_EXTRA_ELEMENT); verticesInputExtraTechniqueNode = FUXmlWriter::AddChild(verticesInputExtraNode, DAE_TECHNIQUE_ELEMENT); FUXmlWriter::AddAttribute(verticesInputExtraTechniqueNode, DAE_PROFILE_ATTRIBUTE, DAE_FCOLLADA_PROFILE); } AddInput(verticesInputExtraTechniqueNode, source->GetDaeId(), semantic, -1, input->GetSet()); } } } if (verticesInputExtraNode != NULL) AddChild(verticesNode, verticesInputExtraNode); FUSStringBuilder verticesNodeId(geometryMesh->GetDaeId()); verticesNodeId.append("-vertices"); AddAttribute(verticesNode, DAE_ID_ATTRIBUTE, verticesNodeId); // Write out the polygons for (size_t i = 0; i < geometryMesh->GetPolygonsCount(); ++i) { FArchiveXML::LetWriteObject(geometryMesh->GetPolygons(i), meshNode); } }
bool CheckGeometryMesh(FULogFile& fileOut, FCDGeometryMesh* mesh) { // Verify the mesh and its sources PassIf(mesh->GetSourceCount() == 3); FCDGeometrySource* posSource = NULL,* colorSource = NULL,* dummySource = NULL; for (size_t i = 0; i < 3; ++i) { FCDGeometrySource* source = mesh->GetSource(i); FailIf(source == NULL); switch (source->GetType()) { case FUDaeGeometryInput::POSITION: posSource = source; PassIf(source->GetName() == FC("TestPositionSource")); break; case FUDaeGeometryInput::COLOR: colorSource = source; PassIf(source->GetName() == FC("TestColorSource")); break; case FUDaeGeometryInput::EXTRA: dummySource = source; PassIf(source->GetName() == FC("TestDummySource")); break; default: Fail; break; } } FailIf(posSource == NULL || colorSource == NULL || dummySource == NULL); PassIf(IsEquivalent(posSource->GetData(), posSource->GetDataCount(), positionData, 12)); PassIf(posSource->GetStride() == 3); PassIf(IsEquivalent(colorSource->GetData(), colorSource->GetDataCount(), colorData, 12)); PassIf(colorSource->GetStride() == 4); PassIf(IsEquivalent(dummySource->GetData(), dummySource->GetDataCount(), dummyData, 10)); PassIf(dummySource->GetStride() == 3); PassIf(CheckExtraTree(fileOut, dummySource->GetExtra(), false)); // Find the non-empty polygon set and verify that one of the polygon set is, in fact, empty. FCDGeometryPolygons* polys1 = NULL,* polysEmpty = NULL; for (size_t i = 0; i < mesh->GetPolygonsCount(); ++i) { FCDGeometryPolygons* p = mesh->GetPolygons(i); if (p->GetFaceCount() == 0) { PassIf(polysEmpty == NULL); polysEmpty = p; } else { PassIf(polys1 == NULL); polys1 = p; } CheckExtraTree(fileOut, p->GetExtra(), true); } PassIf(polys1 != NULL && polysEmpty != NULL); // Check that we have the wanted tetrahedron in the non-empty polygon set. PassIf(polys1->GetFaceCount() == 4); PassIf(polys1->GetHoleCount() == 0); PassIf(polys1->GetFaceVertexCount(0) == 3 && polys1->GetFaceVertexCount(1) == 3 && polys1->GetFaceVertexCount(2) == 3 && polys1->GetFaceVertexCount(3) == 3); FCDGeometryPolygonsInput* posInput = polys1->FindInput(posSource); FailIf(posInput == NULL || posInput->GetIndexCount() != 12); FCDGeometryPolygonsInput* colorInput = polys1->FindInput(colorSource); FailIf(colorInput == NULL || colorInput == posInput || colorInput->GetIndexCount() != 12); PassIf(IsEquivalent(posInput->GetIndices(), 12, positionIndices, 12)); PassIf(IsEquivalent(colorInput->GetIndices(), 12, colorIndices, 12)); return true; }
xmlNode* FArchiveXML::WriteGeometrySource(FCDObject* object, xmlNode* parentNode) { FCDGeometrySource* geometrySource = (FCDGeometrySource*)object; xmlNode* sourceNode = NULL; // Export the source directly, using the correct parameters and the length factor FloatList& sourceData = geometrySource->GetSourceData().GetDataList(); uint32 stride = geometrySource->GetStride(); switch (geometrySource->GetType()) { case FUDaeGeometryInput::POSITION: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::XYZW); break; case FUDaeGeometryInput::NORMAL: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::XYZW); break; case FUDaeGeometryInput::GEOTANGENT: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::XYZW); break; case FUDaeGeometryInput::GEOBINORMAL: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::XYZW); break; case FUDaeGeometryInput::TEXCOORD: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::STPQ); break; case FUDaeGeometryInput::TEXTANGENT: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::XYZW); break; case FUDaeGeometryInput::TEXBINORMAL: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::XYZW); break; case FUDaeGeometryInput::UV: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::XYZW); break; case FUDaeGeometryInput::COLOR: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, FUDaeAccessor::RGBA); break; case FUDaeGeometryInput::EXTRA: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, NULL); break; case FUDaeGeometryInput::UNKNOWN: sourceNode = AddSourceFloat(parentNode, geometrySource->GetDaeId(), sourceData, stride, NULL); break; case FUDaeGeometryInput::VERTEX: // Refuse to export these sources default: break; } if (!geometrySource->GetName().empty()) { AddAttribute(sourceNode, DAE_NAME_ATTRIBUTE, geometrySource->GetName()); } if (geometrySource->GetExtra() != NULL) { FArchiveXML::WriteTechniquesFCDExtra(geometrySource->GetExtra(), sourceNode); } for (size_t i = 0; i < geometrySource->GetAnimatedValues().size(); ++i) { FArchiveXML::WriteAnimatedValue(geometrySource->GetAnimatedValues()[i], sourceNode, ""); } return sourceNode; }