private void ExportCollada_Skinned(XmlWriter xml, Kn5Node node) {
switch (node.NodeClass) {
case Kn5NodeClass.Base:
foreach (var child in node.Children) {
ExportCollada_Skinned(xml, child);
}
break;
case Kn5NodeClass.Mesh:
return;
case Kn5NodeClass.SkinnedMesh:
xml.WriteStartElement("controller");
xml.WriteAttributeStringSafe("id", $"{node.Name}Controller");
xml.WriteStartElement("skin");
xml.WriteAttributeStringSafe("source", $"#{node.Name}-mesh");
// xml.WriteElementString("bind_shape_matrix", "1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1");
xml.WriteElementString("bind_shape_matrix", "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1");
// Joints
xml.WriteStartElement("source");
xml.WriteAttributeStringSafe("id", $"{node.Name}Controller-Joints");
xml.WriteStartElement("Name_array");
xml.WriteAttributeStringSafe("id", $"{node.Name}Controller-Joints-array");
xml.WriteAttributeString("count", node.Bones.Length);
xml.WriteString(node.Bones.Select(x => x.Name).JoinToString(" "));
xml.WriteEndElement(); // Name_array
xml.WriteStartElement("technique_common");
xml.WriteStartElement("accessor");
xml.WriteAttributeStringSafe("source", $"#{node.Name}Controller-Joints-array");
xml.WriteAttributeString("count", node.Bones.Length);
xml.WriteAttributeString("stride", 1);
xml.WriteStartElement("param");
xml.WriteAttributeString("name", "JOINT");
xml.WriteAttributeString("type", "name");
xml.WriteEndElement(); // param
xml.WriteEndElement(); // accessor
xml.WriteEndElement(); // technique_common
xml.WriteEndElement(); // source (Joints)
// Matrices
xml.WriteStartElement("source");
xml.WriteAttributeStringSafe("id", $"{node.Name}Controller-Matrices");
xml.WriteStartElement("float_array");
xml.WriteAttributeStringSafe("id", $"{node.Name}Controller-Matrices-array");
xml.WriteAttributeString("count", node.Bones.Length * 16);
xml.WriteString(node.Bones.Select(x => XmlWriterExtension.MatrixToCollada(x.Transform))
.JoinToString(" "));
xml.WriteEndElement(); // float_array
xml.WriteStartElement("technique_common");
xml.WriteStartElement("accessor");
xml.WriteAttributeStringSafe("source", $"#{node.Name}Controller-Matrices-array");
xml.WriteAttributeString("count", node.Bones.Length);
xml.WriteAttributeString("stride", 16);
xml.WriteStartElement("param");
xml.WriteAttributeString("name", "TRANSFORM");
xml.WriteAttributeString("type", "float4x4");
xml.WriteEndElement(); // param
xml.WriteEndElement(); // accessor
xml.WriteEndElement(); // technique_common
xml.WriteEndElement(); // source (Matrices)
// Weights
xml.WriteStartElement("source");
xml.WriteAttributeStringSafe("id", $"{node.Name}Controller-Weights");
xml.WriteStartElement("float_array");
xml.WriteAttributeStringSafe("id", $"{node.Name}Controller-Weights-array");
var weights = node.VerticeWeights.SelectMany(x => x.Weights.Where((y, i) => !Equals(x.Indices[i], -1f))).ToList();
xml.WriteAttributeString("count", weights.Count);
xml.WriteString(weights.JoinToString(" "));
xml.WriteEndElement(); // float_array
xml.WriteStartElement("technique_common");
xml.WriteStartElement("accessor");
xml.WriteAttributeStringSafe("source", $"#{node.Name}Controller-Weights-array");
xml.WriteAttributeString("count", weights.Count);
xml.WriteAttributeString("stride", 1);
xml.WriteStartElement("param");
xml.WriteAttributeString("name", "WEIGHT");
xml.WriteAttributeString("type", "float");
xml.WriteEndElement(); // param
xml.WriteEndElement(); // accessor
xml.WriteEndElement(); // technique_common
xml.WriteEndElement(); // source (Matrices)
xml.WriteStartElement("joints");
xml.WriteStartElement("input");
xml.WriteAttributeString("semantic", "JOINT");
xml.WriteAttributeStringSafe("source", $"#{node.Name}Controller-Joints");
xml.WriteEndElement(); // input
xml.WriteStartElement("input");
xml.WriteAttributeString("semantic", "INV_BIND_MATRIX");
xml.WriteAttributeStringSafe("source", $"#{node.Name}Controller-Matrices");
xml.WriteEndElement(); // input
xml.WriteEndElement(); // joints
xml.WriteStartElement("vertex_weights");
xml.WriteAttributeString("count", node.Vertices.Length);
xml.WriteStartElement("input");
xml.WriteAttributeString("semantic", "JOINT");
xml.WriteAttributeString("offset", 0);
xml.WriteAttributeStringSafe("source", $"#{node.Name}Controller-Joints");
xml.WriteEndElement(); // input
xml.WriteStartElement("input");
xml.WriteAttributeString("semantic", "WEIGHT");
xml.WriteAttributeString("offset", 1);
xml.WriteAttributeStringSafe("source", $"#{node.Name}Controller-Weights");
xml.WriteEndElement(); // input
xml.WriteElementString("vcount", node.VerticeWeights.Select(x => x.Weights.Where(y => !Equals(y, 0f)).Count()).JoinToString(" "));
var k = 0;
xml.WriteElementString("v", node.VerticeWeights.SelectMany(x =>
x.Indices.Where(y => !Equals(y, -1f)).SelectMany((y, i) => new[] { y, k++ })).JoinToString(" "));
xml.WriteEndElement(); // vertex_weights
xml.WriteEndElement(); // skin
xml.WriteEndElement(); // controller
break;
}
}