Beispiel #1
0
        private void ExportIni_Node(IniFile iniFile, string parentName, Kn5Node node, int priority = 0) {
            var name = node == RootNode ? parentName : parentName + "_" + node.Name;

            var section = iniFile["model_FBX: " + name];
            section.Set("ACTIVE", node.Active);
            section.Set("PRIORITY", priority);

            if (node.NodeClass == Kn5NodeClass.Base) {
                if (IsMultiMaterial(node)) {
                    var p = node.Children.Count;
                    foreach (var child in node.Children) {
                        ExportIni_Node(iniFile, name, child, --p);
                    }
                } else {
                    foreach (var child in node.Children) {
                        if (node == RootNode && child.NodeClass == Kn5NodeClass.Mesh) {
                            ExportIni_TrackNode(iniFile, name, child);
                        } else {
                            ExportIni_Node(iniFile, name, child);
                        }
                    }
                }
            } else {
                section.Set("VISIBLE", node.IsVisible);
                section.Set("TRANSPARENT", node.IsTransparent);
                section.Set("CAST_SHADOWS", node.CastShadows);
                section.Set("LOD_IN", node.LodIn);
                section.Set("LOD_OUT", node.LodOut);
                section.Set("RENDERABLE", node.IsRenderable);
            }
        }
Beispiel #2
0
 private static bool IsMultiMaterial(Kn5Node node)
 {
     return(node.NodeClass == Kn5NodeClass.Base &&
            node.Children.Any() &&
            node.Children.All(x => x.NodeClass == Kn5NodeClass.Mesh) &&
            Enumerable.Range(0, node.Children.Count).All(x => node.Children.Any(y => y.Name == node.Name + "_SUB" + x)));
 }
Beispiel #3
0
 private static void Save_Node(Kn5Writer writer, Kn5Node node)
 {
     writer.Write(node);
     foreach (var t in node.Children)
     {
         Save_Node(writer, t);
     }
 }
Beispiel #4
0
 public Kn5RenderableList(Kn5Node node, DeviceContextHolder holder)
         : base(node.Name, Kn5RenderableObject.FlipByX ? node.Transform.ToMatrixFixX() : node.Transform.ToMatrix(),
                 node.Children.Select(x => Kn5Converter.Convert(x, holder))) {
     OriginalNode = node;
     if (IsEnabled && (!OriginalNode.Active || OriginalNode.Name == "COCKPIT_LR" || OriginalNode.Name == "STEER_LR" ||
             OriginalNode.Name == "CINTURE_ON" || OriginalNode.Name.StartsWith("DAMAGE_GLASS"))) {
         IsEnabled = false;
     }
 }
Beispiel #5
0
        private static bool IsMultiMaterial(Kn5Node node)
        {
            if (!OptionJoinToMultiMaterial || node.NodeClass != Kn5NodeClass.Base || !node.Children.Any())
            {
                return(false);
            }
            var regex = new Regex($@"^{Regex.Escape(node.Name)}_SUB\d+$", RegexOptions.Compiled);

            return(node.Children.All(x => x.NodeClass == Kn5NodeClass.Mesh && regex.IsMatch(x.Name)));
        }
Beispiel #6
0
        private void ExportCollada_Node(XmlWriter xml, Kn5Node node)
        {
            var boneNames = node.Children.SelectManyRecursive(x => x.Children)
                            .Where(x => x.NodeClass == Kn5NodeClass.SkinnedMesh)
                            .SelectMany(x => x.Bones.Select(y => y.Name))
                            .ToList();

            foreach (var t in node.Children)
            {
                ExportCollada_NodeSub(xml, boneNames, t);
            }
        }
Beispiel #7
0
        private static bool FixLrHrNodes_HasParentWithName(Kn5Node rootNode, Kn5Node node, string name) {
            if (rootNode.NodeClass != Kn5NodeClass.Base) return false;

            foreach (var subNode in rootNode.Children) {
                if (subNode.Name == name) {
                    return FixLrHrNodes_HasChild(subNode, node);
                } else if (FixLrHrNodes_HasParentWithName(subNode, node, name)){
                    return true;
                }
            }

            return false;
        }
Beispiel #8
0
        public static IRenderableObject Convert(Kn5Node node, DeviceContextHolder holder) {
            switch (node.NodeClass) {
                case Kn5NodeClass.Base:
                    return new Kn5RenderableList(node, holder);

                case Kn5NodeClass.Mesh:
                case Kn5NodeClass.SkinnedMesh:
                    return new Kn5RenderableObject(node, holder);

                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
Beispiel #9
0
        public int RemoveAllByName(Kn5Node node, string name) {
            var result = 0;
            for (var i = 0; i < node.Children.Count; i++) {
                var child = node.Children[i];
                if (child.Name == name) {
                    node.Children.Remove(child);
                    result++;
                } else if (child.NodeClass == Kn5NodeClass.Base) {
                    result += RemoveAllByName(child, name);
                }
            }

            return result;
        }
Beispiel #10
0
        public void Write(Kn5Node node) {
            Write(node.NodeClass);
            Write(node.Name);
            Write(node.Children.Count);
            Write(node.Active);

            switch (node.NodeClass) {
                case Kn5NodeClass.Base:
                    Write(node.Transform);
                    break;

                case Kn5NodeClass.Mesh:
                    Write(node.CastShadows);
                    Write(node.IsVisible);
                    Write(node.IsTransparent);

                    Write(node.Vertices.Length);
                    for (var i = 0; i < node.Vertices.Length; i++) {
                        Write(node.Vertices[i].Co);
                        Write(node.Vertices[i].Normal);
                        Write(node.Vertices[i].Uv);
                        Write(node.Vertices[i].Tangent);
                    }

                    Write(node.Indices.Length);
                    foreach (var t in node.Indices) {
                        Write(t);
                    }

                    Write(node.MaterialId);
                    Write(node.Layer);
                    
                    Write(node.LodIn);
                    Write(node.LodOut);
                    
                    Write(node.BoundingSphereCenter);
                    Write(node.BoundingSphereRadius);

                    Write(node.IsRenderable);
                    break;

                case Kn5NodeClass.SkinnedMesh:
                    throw new NotImplementedException();
            }
        }
Beispiel #11
0
        private void ExportIni_Node(IniFile iniFile, string parentName, Kn5Node node, int priority = 0)
        {
            var name = node == RootNode ? parentName : parentName + "_" + node.Name;

            var section = iniFile["model_FBX: " + name];

            section.Set("ACTIVE", node.Active);
            section.Set("PRIORITY", priority);

            if (node.NodeClass == Kn5NodeClass.Base)
            {
                if (IsMultiMaterial(node))
                {
                    var p = node.Children.Count;
                    foreach (var child in node.Children)
                    {
                        ExportIni_Node(iniFile, name, child, --p);
                    }
                }
                else
                {
                    foreach (var child in node.Children)
                    {
                        if (node == RootNode && child.NodeClass == Kn5NodeClass.Mesh)
                        {
                            ExportIni_TrackNode(iniFile, name, child);
                        }
                        else
                        {
                            ExportIni_Node(iniFile, name, child);
                        }
                    }
                }
            }
            else
            {
                section.Set("VISIBLE", node.IsVisible);
                section.Set("TRANSPARENT", node.IsTransparent);
                section.Set("CAST_SHADOWS", node.CastShadows);
                section.Set("LOD_IN", node.LodIn);
                section.Set("LOD_OUT", node.LodOut);
                section.Set("RENDERABLE", node.IsRenderable);
            }
        }
Beispiel #12
0
        private string GetObjectPath([NotNull] Kn5Node parent, [NotNull] Kn5Node node)
        {
            if (parent.Children.IndexOf(node) != -1)
            {
                return(node.Name);
            }

            for (var i = 0; i < parent.Children.Count; i++)
            {
                var child = parent.Children[i];
                var v     = GetObjectPath(child, node);
                if (v != null)
                {
                    return(child.Name + '\\' + v);
                }
            }

            return(null);
        }
Beispiel #13
0
        private void ExportIni_TrackNode(IniFile iniFile, string parentName, Kn5Node node)
        {
            var name = node == RootNode ? parentName : parentName + "_" + node.Name;

            var section = iniFile["model_FBX: " + name];

            section.Set("ACTIVE", node.Active);
            section.Set("PRIORITY", 0);

            section = iniFile["model_FBX: " + name + "_" + node.Name];
            section.Set("ACTIVE", true);
            section.Set("PRIORITY", 0);
            section.Set("VISIBLE", node.IsVisible);
            section.Set("TRANSPARENT", node.IsTransparent);
            section.Set("CAST_SHADOWS", node.CastShadows);
            section.Set("LOD_IN", node.LodIn);
            section.Set("LOD_OUT", node.LodOut);
            section.Set("RENDERABLE", node.IsRenderable);
        }
Beispiel #14
0
        public int RemoveAllByName(Kn5Node node, string name)
        {
            var result = 0;

            for (var i = 0; i < node.Children.Count; i++)
            {
                var child = node.Children[i];
                if (child.Name == name)
                {
                    node.Children.Remove(child);
                    result++;
                }
                else if (child.NodeClass == Kn5NodeClass.Base)
                {
                    result += RemoveAllByName(child, name);
                }
            }

            return(result);
        }
Beispiel #15
0
        private void ExportCollada_MeshWrapper(XmlWriter xml, Kn5Node node)
        {
            switch (node.NodeClass)
            {
            case Kn5NodeClass.Base:
                if (IsMultiMaterial(node))
                {
                    ExportCollada_Mesh(xml, node.Name, node.Children);
                }
                else
                {
                    foreach (var child in node.Children)
                    {
                        ExportCollada_MeshWrapper(xml, child);
                    }
                }
                break;

            case Kn5NodeClass.Mesh:
            case Kn5NodeClass.SkinnedMesh:
                ExportCollada_Mesh(xml, node.Name, new [] { node });
                break;
            }
        }
Beispiel #16
0
        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;
            }
        }
Beispiel #17
0
        private void ExportCollada_NodeSub(XmlWriter xml, IReadOnlyList<string> boneNames, Kn5Node node) {
            xml.WriteStartElement("node");
            xml.WriteAttributeStringSafe("id", node.Name);
            xml.WriteAttributeStringSafe("sid", node.Name);
            xml.WriteAttributeStringSafe("name", node.Name);

            xml.WriteAttributeString("layer", node.Active ? "Visible" : "Hidden");
            xml.WriteAttributeString("type", node.NodeClass == Kn5NodeClass.Base && boneNames.Contains(node.Name) ? "JOINT" : "NODE");

            if (node.Children?.FirstOrDefault()?.NodeClass != Kn5NodeClass.SkinnedMesh) {
                xml.WriteElement("matrix",
                        "sid", "transform",
                        node.NodeClass == Kn5NodeClass.Base ? XmlWriterExtension.MatrixToCollada(node.Transform) : "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0");
            }

            if (IsMultiMaterial(node) && node.Children != null) {
                xml.WriteStartElement("instance_geometry");
                xml.WriteAttributeStringSafe("url", $"#{node.Name}-mesh");
                ExportCollada_NodeSub_BindMaterial(xml, node.Children.Select(x => x.MaterialId).ToArray());
                xml.WriteEndElement();
            } else {
                ExportCollada_NodeSub_Inner(xml, boneNames, node);
            }

            xml.WriteEndElement(); // node
        }
Beispiel #18
0
        private void ExportCollada_NodeSub_Inner(XmlWriter xml, IReadOnlyList<string> boneNames, Kn5Node node) {
            switch (node.NodeClass) {
                case Kn5NodeClass.Base:
                    if (node.Children.Count == 1 && node.Children[0].NodeClass != Kn5NodeClass.Base) {
                        ExportCollada_NodeSub_Inner(xml, boneNames, node.Children[0]);
                    } else {
                        foreach (var t in node.Children) {
                            ExportCollada_NodeSub(xml, boneNames, t);
                        }
                    }
                    break;

                case Kn5NodeClass.Mesh:
                    xml.WriteStartElement("instance_geometry");
                    xml.WriteAttributeStringSafe("url", $"#{node.Name}-mesh");
                    ExportCollada_NodeSub_BindMaterial(xml, node.MaterialId);
                    xml.WriteEndElement();
                    break;

                case Kn5NodeClass.SkinnedMesh:
                    xml.WriteStartElement("instance_controller");
                    xml.WriteAttributeStringSafe("url", $"#{node.Name}Controller");
                    ExportCollada_NodeSub_BindMaterial(xml, node.MaterialId);

                    foreach (var bone in node.Bones) {
                        xml.WriteElementString("skeleton", $"#{bone.Name}");
                    }

                    xml.WriteEndElement(); // instance_controller
                    break;
            }
        }
Beispiel #19
0
 private void ExportCollada_Node(XmlWriter xml, Kn5Node node) {
     var boneNames = node.Children.SelectManyRecursive(x => x.Children)
                         .Where(x => x.NodeClass == Kn5NodeClass.SkinnedMesh)
                         .SelectMany(x => x.Bones.Select(y => y.Name))
                         .ToList();
     foreach (var t in node.Children) {
         ExportCollada_NodeSub(xml, boneNames, t);
     }
 }
Beispiel #20
0
        private void ExportCollada_MeshWrapper(XmlWriter xml, Kn5Node node) {
            switch (node.NodeClass) {
                case Kn5NodeClass.Base:
                    if (IsMultiMaterial(node)) {
                        ExportCollada_Mesh(xml, node.Name, node.Children);
                    } else {
                        foreach (var child in node.Children) {
                            ExportCollada_MeshWrapper(xml, child);
                        }
                    }
                    break;

                case Kn5NodeClass.Mesh:
                case Kn5NodeClass.SkinnedMesh:
                    ExportCollada_Mesh(xml, node.Name, new [] { node });
                    break;
            }
        }
Beispiel #21
0
 private static bool IsMultiMaterial(Kn5Node node) {
     return node.NodeClass == Kn5NodeClass.Base &&
             node.Children.Any() &&
             node.Children.All(x => x.NodeClass == Kn5NodeClass.Mesh) &&
             Enumerable.Range(0, node.Children.Count).All(x => node.Children.Any(y => y.Name == node.Name + "_SUB" + x));
 }
Beispiel #22
0
        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;
            }

        }
Beispiel #23
0
        private void ExportCollada_NodeSub(XmlWriter xml, IReadOnlyList <string> boneNames, Kn5Node node)
        {
            xml.WriteStartElement("node");
            xml.WriteAttributeStringSafe("id", node.Name);
            xml.WriteAttributeStringSafe("sid", node.Name);
            xml.WriteAttributeStringSafe("name", node.Name);

            xml.WriteAttributeString("layer", node.Active ? "Visible" : "Hidden");
            xml.WriteAttributeString("type", node.NodeClass == Kn5NodeClass.Base && boneNames.Contains(node.Name) ? "JOINT" : "NODE");

            if (node.Children?.FirstOrDefault()?.NodeClass != Kn5NodeClass.SkinnedMesh)
            {
                xml.WriteElement("matrix",
                                 "sid", "transform",
                                 node.NodeClass == Kn5NodeClass.Base ? XmlWriterExtension.MatrixToCollada(node.Transform) : "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0");
            }

            if (IsMultiMaterial(node) && node.Children != null)
            {
                xml.WriteStartElement("instance_geometry");
                xml.WriteAttributeStringSafe("url", $"#{node.Name}-mesh");
                ExportCollada_NodeSub_BindMaterial(xml, node.Children.Select(x => x.MaterialId).ToArray());
                xml.WriteEndElement();
            }
            else
            {
                ExportCollada_NodeSub_Inner(xml, boneNames, node);
            }

            xml.WriteEndElement(); // node
        }
Beispiel #24
0
 public string GetObjectPath([NotNull] Kn5Node node)
 {
     return(GetObjectPath(RootNode, node));
 }
Beispiel #25
0
        public Kn5Node ReadNode() {
            var nodeClass = ReadNodeClass();
            var nodeName = ReadString();
            var nodeChildren = ReadInt32();
            var nodeActive = ReadBoolean();

            var node = new Kn5Node {
                NodeClass = nodeClass,
                Name = nodeName,
                Children = new List<Kn5Node>(nodeChildren),
                Active = nodeActive
            };

            switch (node.NodeClass) {
                case Kn5NodeClass.Base:
                    node.Transform = ReadMatrix();
                    break;

                case Kn5NodeClass.Mesh:
                    node.CastShadows = ReadBoolean();
                    node.IsVisible = ReadBoolean();
                    node.IsTransparent = ReadBoolean();
            
                    node.Vertices = new Kn5Node.Vertice[ReadUInt32()];
                    for (var i = 0; i < node.Vertices.Length; i++) {
                        // 44 bytes per vertice
                        node.Vertices[i] = new Kn5Node.Vertice {
                            Co = ReadSingle3D(),
                            Normal = ReadSingle3D(),
                            Uv = ReadSingle2D(),
                            Tangent = ReadSingle3D()
                        };
                    }
            
                    node.Indices = new ushort[ReadUInt32()];
                    for (var i = 0; i < node.Indices.Length; i++) {
                        node.Indices[i] = ReadUInt16();
                    }
            
                    node.MaterialId = ReadUInt32();
                    node.Layer = ReadUInt32();
                    
                    node.LodIn = ReadSingle();
                    node.LodOut = ReadSingle();
                    
                    node.BoundingSphereCenter = ReadSingle3D();
                    node.BoundingSphereRadius = ReadSingle();

                    node.IsRenderable = ReadBoolean();
                    break;

                case Kn5NodeClass.SkinnedMesh:
                    node.CastShadows = ReadBoolean();
                    node.IsVisible = ReadBoolean();
                    node.IsTransparent = ReadBoolean();
            
                    node.Bones = new Kn5Node.Bone[ReadUInt32()];
                    for (var i = 0; i < node.Bones.Length; i++) {
                        node.Bones[i] = new Kn5Node.Bone {
                            Name = ReadString(),
                            Transform = ReadMatrix()
                        };
                    }
            
                    node.Vertices = new Kn5Node.Vertice[ReadUInt32()];
                    node.VerticeWeights = new Kn5Node.VerticeWeight[node.Vertices.Length];
                    for (var i = 0; i < node.Vertices.Length; i++) {
                        // 76 bytes per vertice
                        node.Vertices[i] = new Kn5Node.Vertice {
                            Co = ReadSingle3D(),
                            Normal = ReadSingle3D(),
                            Uv = ReadSingle2D(),
                            Tangent = ReadSingle3D()
                        };

                        node.VerticeWeights[i] = new Kn5Node.VerticeWeight {
                            Weights = ReadSingle4D(),
                            Indices = ReadSingle4D()
                        };
                    }
            
                    node.Indices = new ushort[ReadUInt32()];
                    for (var i = 0; i < node.Indices.Length; i++) {
                        node.Indices[i] = ReadUInt16();
                    }

                    node.MaterialId = ReadUInt32();
                    node.Layer = ReadUInt32();
                    
                    ReadBytes(8); // the only mistery left?
                    node.IsRenderable = true;
                    break;
            }

            return node;
        }
Beispiel #26
0
 private static bool FixLrHrNodes_HasChild(Kn5Node node, Kn5Node child) {
     if (node.NodeClass != Kn5NodeClass.Base) return false;
     return node.Children.Contains(child) || node.Children.Any(subNode => FixLrHrNodes_HasChild(subNode, child));
 }
Beispiel #27
0
        private void ExportCollada_NodeSub_Inner(XmlWriter xml, IReadOnlyList <string> boneNames, Kn5Node node)
        {
            switch (node.NodeClass)
            {
            case Kn5NodeClass.Base:
                if (node.Children.Count == 1 && node.Children[0].NodeClass != Kn5NodeClass.Base)
                {
                    ExportCollada_NodeSub_Inner(xml, boneNames, node.Children[0]);
                }
                else
                {
                    foreach (var t in node.Children)
                    {
                        ExportCollada_NodeSub(xml, boneNames, t);
                    }
                }
                break;

            case Kn5NodeClass.Mesh:
                xml.WriteStartElement("instance_geometry");
                xml.WriteAttributeStringSafe("url", $"#{node.Name}-mesh");
                ExportCollada_NodeSub_BindMaterial(xml, node.MaterialId);
                xml.WriteEndElement();
                break;

            case Kn5NodeClass.SkinnedMesh:
                xml.WriteStartElement("instance_controller");
                xml.WriteAttributeStringSafe("url", $"#{node.Name}Controller");
                ExportCollada_NodeSub_BindMaterial(xml, node.MaterialId);

                foreach (var bone in node.Bones)
                {
                    xml.WriteElementString("skeleton", $"#{bone.Name}");
                }

                xml.WriteEndElement();     // instance_controller
                break;
            }
        }
Beispiel #28
0
        private void ExportIni_TrackNode(IniFile iniFile, string parentName, Kn5Node node) {
            var name = node == RootNode ? parentName : parentName + "_" + node.Name;

            var section = iniFile["model_FBX: " + name];
            section.Set("ACTIVE", node.Active);
            section.Set("PRIORITY", 0);

            section = iniFile["model_FBX: " + name + "_" + node.Name];
            section.Set("ACTIVE", true);
            section.Set("PRIORITY", 0);
            section.Set("VISIBLE", node.IsVisible);
            section.Set("TRANSPARENT", node.IsTransparent);
            section.Set("CAST_SHADOWS", node.CastShadows);
            section.Set("LOD_IN", node.LodIn);
            section.Set("LOD_OUT", node.LodOut);
            section.Set("RENDERABLE", node.IsRenderable);
        }
Beispiel #29
0
        public Kn5Node ReadNode()
        {
            var nodeClass    = ReadNodeClass();
            var nodeName     = ReadString();
            var nodeChildren = ReadInt32();
            var nodeActive   = ReadBoolean();

            var node = new Kn5Node {
                NodeClass = nodeClass,
                Name      = nodeName,
                Children  = new List <Kn5Node>(nodeChildren),
                Active    = nodeActive
            };

            switch (node.NodeClass)
            {
            case Kn5NodeClass.Base:
                node.Transform = ReadMatrix();
                break;

            case Kn5NodeClass.Mesh:
                node.CastShadows   = ReadBoolean();
                node.IsVisible     = ReadBoolean();
                node.IsTransparent = ReadBoolean();

                node.Vertices = new Kn5Node.Vertice[ReadUInt32()];
                for (var i = 0; i < node.Vertices.Length; i++)
                {
                    // 44 bytes per vertice
                    node.Vertices[i] = new Kn5Node.Vertice {
                        Co      = ReadSingle3D(),
                        Normal  = ReadSingle3D(),
                        Uv      = ReadSingle2D(),
                        Tangent = ReadSingle3D()
                    };
                }

                var indicesCount = ReadUInt32();
                node.Indices = new ushort[indicesCount];
                for (var i = 0; i < node.Indices.Length; i++)
                {
                    node.Indices[i] = ReadUInt16();
                }

                node.MaterialId = ReadUInt32();
                node.Layer      = ReadUInt32();

                node.LodIn  = ReadSingle();
                node.LodOut = ReadSingle();

                node.BoundingSphereCenter = ReadSingle3D();
                node.BoundingSphereRadius = ReadSingle();

                node.IsRenderable = ReadBoolean();
                break;

            case Kn5NodeClass.SkinnedMesh:
                node.CastShadows   = ReadBoolean();
                node.IsVisible     = ReadBoolean();
                node.IsTransparent = ReadBoolean();

                node.Bones = new Kn5Node.Bone[ReadUInt32()];
                for (var i = 0; i < node.Bones.Length; i++)
                {
                    node.Bones[i] = new Kn5Node.Bone {
                        Name      = ReadString(),
                        Transform = ReadMatrix()
                    };
                }

                node.Vertices       = new Kn5Node.Vertice[ReadUInt32()];
                node.VerticeWeights = new Kn5Node.VerticeWeight[node.Vertices.Length];
                for (var i = 0; i < node.Vertices.Length; i++)
                {
                    // 76 bytes per vertice
                    node.Vertices[i] = new Kn5Node.Vertice {
                        Co      = ReadSingle3D(),
                        Normal  = ReadSingle3D(),
                        Uv      = ReadSingle2D(),
                        Tangent = ReadSingle3D()
                    };

                    node.VerticeWeights[i] = new Kn5Node.VerticeWeight {
                        Weights = ReadSingle4D(),

                        // Yes! Those are floats!
                        Indices = ReadSingle4D()
                    };
                }

                node.Indices = new ushort[ReadUInt32()];
                for (var i = 0; i < node.Indices.Length; i++)
                {
                    node.Indices[i] = ReadUInt16();
                }

                node.MaterialId = ReadUInt32();
                node.Layer      = ReadUInt32();

                node.MisteryBytes = ReadBytes(8);     // the only mistery left?
                node.IsRenderable = true;
                break;
            }

            return(node);
        }
Beispiel #30
0
        /// <summary>
        /// Only hierarchy, without meshes or bones.
        /// </summary>
        public Kn5Node ReadNodeHierarchy()
        {
            var nodeClass    = ReadNodeClass();
            var nodeName     = ReadString();
            var nodeChildren = ReadInt32();
            var nodeActive   = ReadBoolean();

            var node = new Kn5Node {
                NodeClass = nodeClass,
                Name      = nodeName,
                Children  = new List <Kn5Node>(nodeChildren),
                Active    = nodeActive
            };

            switch (node.NodeClass)
            {
            case Kn5NodeClass.Base:
                node.Transform = ReadMatrix();
                break;

            case Kn5NodeClass.Mesh:
                node.CastShadows   = ReadBoolean();
                node.IsVisible     = ReadBoolean();
                node.IsTransparent = ReadBoolean();

                node.Vertices = new Kn5Node.Vertice[0];
                node.Indices  = new ushort[0];

                Skip((int)(44 * ReadUInt32()));
                Skip((int)(2 * ReadUInt32()));

                node.MaterialId = ReadUInt32();
                node.Layer      = ReadUInt32();

                node.LodIn  = ReadSingle();
                node.LodOut = ReadSingle();

                node.BoundingSphereCenter = ReadSingle3D();
                node.BoundingSphereRadius = ReadSingle();

                node.IsRenderable = ReadBoolean();
                break;

            case Kn5NodeClass.SkinnedMesh:
                node.CastShadows   = ReadBoolean();
                node.IsVisible     = ReadBoolean();
                node.IsTransparent = ReadBoolean();

                node.Bones          = new Kn5Node.Bone[0];
                node.Vertices       = new Kn5Node.Vertice[0];
                node.VerticeWeights = new Kn5Node.VerticeWeight[0];
                node.Indices        = new ushort[0];

                var bones = ReadUInt32();
                for (var i = 0; i < bones; i++)
                {
                    SkipString();
                    Skip(64);
                }

                Skip((int)(76 * ReadUInt32()));
                Skip((int)(2 * ReadUInt32()));

                node.MaterialId = ReadUInt32();
                node.Layer      = ReadUInt32();

                node.MisteryBytes = ReadBytes(8);     // the only mistery left?
                node.IsRenderable = true;
                break;
            }

            return(node);
        }
Beispiel #31
0
        public void Write(Kn5Node node)
        {
            Write(node.NodeClass);
            Write(node.Name);
            Write(node.Children.Count);
            Write(node.Active);

            switch (node.NodeClass)
            {
            case Kn5NodeClass.Base:
                Write(node.Transform);
                break;

            case Kn5NodeClass.Mesh:
                Write(node.CastShadows);
                Write(node.IsVisible);
                Write(node.IsTransparent);

                Write(node.Vertices.Length);
                for (var i = 0; i < node.Vertices.Length; i++)
                {
                    var v = node.Vertices[i];
                    Write(v.Position);
                    Write(v.Normal);
                    Write(v.TexC);
                    Write(v.TangentU);
                }

                Write(node.Indices.Length);
                foreach (var t in node.Indices)
                {
                    Write(t);
                }

                Write(node.MaterialId);
                Write(node.Layer);

                Write(node.LodIn);
                Write(node.LodOut);

                Write(node.BoundingSphereCenter);
                Write(node.BoundingSphereRadius);

                Write(node.IsRenderable);
                break;

            case Kn5NodeClass.SkinnedMesh:
                Write(node.CastShadows);
                Write(node.IsVisible);
                Write(node.IsTransparent);

                Write(node.Bones.Length);
                for (var i = 0; i < node.Bones.Length; i++)
                {
                    var b = node.Bones[i];
                    Write(b.Name);
                    Write(b.Transform);
                }

                Write(node.Vertices.Length);
                for (var i = 0; i < node.Vertices.Length; i++)
                {
                    var v = node.Vertices[i];
                    Write(v.Position);
                    Write(v.Normal);
                    Write(v.TexC);
                    Write(v.TangentU);

                    var w = node.VerticeWeights[i];
                    Write(w.Weights);
                    Write(w.Indices);
                }

                Write(node.Indices.Length);
                foreach (var t in node.Indices)
                {
                    Write(t);
                }

                Write(node.MaterialId);
                Write(node.Layer);
                Write(node.MisteryBytes ?? new byte[8]);
                break;
            }
        }
Beispiel #32
0
 public static Kn5 CreateEmpty()
 {
     return(new Kn5 {
         RootNode = Kn5Node.CreateBaseNode("Root")
     });
 }