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); } }
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))); }
private static void Save_Node(Kn5Writer writer, Kn5Node node) { writer.Write(node); foreach (var t in node.Children) { Save_Node(writer, t); } }
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; } }
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))); }
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); } }
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; }
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(); } }
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; }
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(); } }
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); }
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); }
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); }
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; } }
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; } }
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 }
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; } }
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)); }
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 }
public string GetObjectPath([NotNull] Kn5Node node) { return(GetObjectPath(RootNode, node)); }
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; }
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)); }
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; } }
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); }
/// <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); }
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; } }
public static Kn5 CreateEmpty() { return(new Kn5 { RootNode = Kn5Node.CreateBaseNode("Root") }); }