AcTools.Kn5File.Kn5.ExportCollada_Mesh C# (CSharp) Method

ExportCollada_Mesh() private method

private ExportCollada_Mesh ( XmlWriter xml, string name, IReadOnlyList unsorted ) : void
xml XmlWriter
name string
unsorted IReadOnlyList
return void
        private void ExportCollada_Mesh(XmlWriter xml, string name, IReadOnlyList<Kn5Node> unsorted) {
            xml.WriteStartElement("geometry");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh");
            xml.WriteAttributeStringSafe("name", name);

            xml.WriteStartElement("mesh");

            var nodes = unsorted.Count == 1 ? unsorted :
                    unsorted.OrderBy(x => int.Parse(x.Name.Split(new[] { "_SUB" }, StringSplitOptions.None).Last())).ToList();

            /* coordinates */
            var vertexCount = nodes.Sum(x => x.Vertices.Length);
            xml.WriteStartElement("source");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh-positions");
            xml.WriteStartElement("float_array");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh-positions-array");
            xml.WriteAttributeString("count", vertexCount * 3);
            xml.WriteString(nodes.SelectMany(x => x.Vertices).SelectMany(x => x.Co).JoinToString(" "));
            xml.WriteEndElement(); // float_array

            xml.WriteStartElement("technique_common");
            xml.WriteStartElement("accessor");
            xml.WriteAttributeStringSafe("source", $"#{name}-mesh-positions-array");
            xml.WriteAttributeString("count", vertexCount);
            xml.WriteAttributeString("stride", 3);

            xml.WriteElement("param",
                    "name", "X",
                    "type", "float");
            xml.WriteElement("param",
                    "name", "Y",
                    "type", "float");
            xml.WriteElement("param",
                    "name", "Z",
                    "type", "float");

            xml.WriteEndElement(); // accessor
            xml.WriteEndElement(); // technique_common
            xml.WriteEndElement(); // source

            /* normals */
            xml.WriteStartElement("source");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh-normals");
            xml.WriteStartElement("float_array");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh-normals-array");
            xml.WriteAttributeString("count", vertexCount * 3);
            xml.WriteString(nodes.SelectMany(x => x.Vertices).SelectMany(x => x.Normal).JoinToString(" "));
            xml.WriteEndElement(); // float_array

            xml.WriteStartElement("technique_common");
            xml.WriteStartElement("accessor");
            xml.WriteAttributeStringSafe("source", $"#{name}-mesh-normals-array");
            xml.WriteAttributeString("count", vertexCount);
            xml.WriteAttributeString("stride", "3");
            
            xml.WriteElement("param",
                    "name", "X",
                    "type", "float");
            xml.WriteElement("param",
                    "name", "Y",
                    "type", "float");
            xml.WriteElement("param",
                    "name", "Z",
                    "type", "float");

            xml.WriteEndElement(); // accessor
            xml.WriteEndElement(); // technique_common
            xml.WriteEndElement(); // source

            /* uv */
            xml.WriteStartElement("source");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh-map-0");
            xml.WriteStartElement("float_array");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh-map-0-array");
            xml.WriteAttributeString("count", vertexCount * 2);
            xml.WriteString(nodes.SelectMany(x => x.Vertices).SelectMany(x => new[] { x.Uv[0], -x.Uv[1] }).JoinToString(" "));
            xml.WriteEndElement(); // float_array

            xml.WriteStartElement("technique_common");
            xml.WriteStartElement("accessor");
            xml.WriteAttributeStringSafe("source", $"#{name}-mesh-map-0-array");
            xml.WriteAttributeString("count", vertexCount);
            xml.WriteAttributeString("stride", 2);

            xml.WriteElement("param",
                    "name", "S",
                    "type", "float");
            xml.WriteElement("param",
                    "name", "T",
                    "type", "float");

            xml.WriteEndElement(); // accessor
            xml.WriteEndElement(); // technique_common
            xml.WriteEndElement(); // source

            /* vertices */
            xml.WriteStartElement("vertices");
            xml.WriteAttributeStringSafe("id", $"{name}-mesh-vertices");
            xml.WriteElement("input",
                    "semantic", "POSITION",
                    "source", $"#{name}-mesh-positions");
            xml.WriteEndElement();

            /* triangles */
            var offset = 0;
            foreach (var node in nodes) {
                xml.WriteStartElement("triangles");
                xml.WriteAttributeStringSafe("original_node", $"{node.Name}");
                xml.WriteAttributeStringSafe("material", $"{Materials.Values.ElementAt((int)node.MaterialId).Name}-material");
                xml.WriteAttributeString("count", node.Indices.Length / 3);

                xml.WriteElement("input",
                        "semantic", "VERTEX",
                        "source", $"#{name}-mesh-vertices",
                        "offset", 0);
                xml.WriteElement("input",
                        "semantic", "NORMAL",
                        "source", $"#{name}-mesh-normals",
                        "offset", 1);
                xml.WriteElement("input",
                        "semantic", "TEXCOORD",
                        "source", $"#{name}-mesh-map-0",
                        "offset", 2,
                        "set", 0);

                var inner = offset;
                xml.WriteElementString("p", node.Indices.SelectMany(x => new[] { x + inner, x + inner, x + inner }).JoinToString(" "));
                xml.WriteEndElement(); // triangles

                offset += node.Vertices.Length;
            }
            
            xml.WriteEndElement(); // mesh
            xml.WriteEndElement(); // geometry
        }