/// <summary> /// Initializes a new instance of the <see cref="Skeleton"/> class. /// </summary> public Skeleton(IKeyValueCollection modelData) { Bones = new Bone[0]; Roots = new List <Bone>(); // Check if there is any skeleton data present at all if (!modelData.ContainsKey("m_modelSkeleton")) { Console.WriteLine("No skeleton data found."); } // Get the remap table and invert it for our construction method var remapTable = modelData.GetIntegerArray("m_remappingTable"); var invMapTable = new Dictionary <long, int>(); for (var i = 0; i < remapTable.Length; i++) { if (!invMapTable.ContainsKey(remapTable[i])) { invMapTable.Add(remapTable[i], i); } } // Construct the armature from the skeleton KV ConstructFromNTRO(modelData.GetSubCollection("m_modelSkeleton"), invMapTable); }
/// <summary> /// Initializes a new instance of the <see cref="Skeleton"/> class. /// </summary> public static Skeleton FromModelData(IKeyValueCollection modelData, int meshIndex) { // Check if there is any skeleton data present at all if (!modelData.ContainsKey("m_modelSkeleton")) { Console.WriteLine("No skeleton data found."); } // Get the remap table and invert it for our construction method var remapTable = modelData.GetIntegerArray("m_remappingTable"); var remapTableStarts = modelData.GetIntegerArray("m_remappingTableStarts"); var start = (int)remapTableStarts[meshIndex]; var end = meshIndex < remapTableStarts.Length - 1 ? (int)remapTableStarts[meshIndex + 1] : remapTable.Length; var invMapTable = remapTable.Skip(start).Take(end - start) .Select((mapping, index) => (mapping, index)) .ToLookup(mi => mi.mapping, mi => mi.index); // Construct the armature from the skeleton KV return(new Skeleton(modelData.GetSubCollection("m_modelSkeleton"), invMapTable)); }
/// <summary> /// Initializes a new instance of the <see cref="Skeleton"/> class. /// </summary> public Skeleton(IKeyValueCollection modelData) { // Check if there is any skeleton data present at all if (!modelData.ContainsKey("m_modelSkeleton")) { Console.WriteLine("No skeleton data found."); } // Get the remap table and invert it for our construction method var remapTable = modelData.GetIntegerArray("m_remappingTable"); var start = 0; var end = remapTable.Length; var remapTableStarts = modelData.GetIntegerArray("m_remappingTableStarts"); // we only use lod 1 if (remapTableStarts.Length > 1) { start = (int)remapTableStarts[0]; end = (int)remapTableStarts[1]; } var invMapTable = remapTable.Skip(start).Take(end - start) .Select((mapping, index) => (mapping, index)) .ToLookup(mi => mi.mapping, mi => mi.index); if (invMapTable.Any()) { AnimationTextureSize = invMapTable.Select(g => g.Max()).Max() + 1; } // Construct the armature from the skeleton KV ConstructFromNTRO(modelData.GetSubCollection("m_modelSkeleton"), invMapTable); }
private static void PrintInclude(IKeyValueCollection node, IndentedTextWriter writer) { var reference = node.GetSubCollection("child"); writer.Write($"<include src="); PrintAttributeOrReferenceValue(reference, writer); writer.WriteLine(" />"); }
private static IEnumerable <IKeyValueCollection> SubNodes(IKeyValueCollection node) { if (node.ContainsKey("vecChildren")) { return(node.GetArray("vecChildren")); } if (node.ContainsKey("child")) { return(new[] { node.GetSubCollection("child") }); } return(Array.Empty <IKeyValueCollection>()); }
public static string Print(IKeyValueCollection layoutRoot) { using var writer = new IndentedTextWriter(); writer.WriteLine("<!-- xml reconstructed by ValveResourceFormat: https://vrf.steamdb.info/ -->"); var root = layoutRoot.GetSubCollection("m_AST")?.GetSubCollection("m_pRoot"); if (root == default) { throw new Exception("Unknown LaCo format, unable to format to XML"); } PrintNode(root, writer); return(writer.ToString()); }
private DrawCall CreateDrawCall(IKeyValueCollection objectDrawCall, VBIB vbib, GPUMeshBuffers gpuMeshBuffers, IDictionary <string, bool> shaderArguments, RenderMaterial material) { var drawCall = new DrawCall(); switch (objectDrawCall.GetProperty <string>("m_nPrimitiveType")) { case "RENDER_PRIM_TRIANGLES": drawCall.PrimitiveType = PrimitiveType.Triangles; break; default: throw new Exception("Unknown PrimitiveType in drawCall! (" + objectDrawCall.GetProperty <string>("m_nPrimitiveType") + ")"); } drawCall.Material = material; // Add shader parameters from material to the shader parameters from the draw call var combinedShaderParameters = shaderArguments .Concat(material.Material.GetShaderArguments()) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Load shader drawCall.Shader = guiContext.ShaderLoader.LoadShader(drawCall.Material.Material.ShaderName, combinedShaderParameters); //Bind and validate shader GL.UseProgram(drawCall.Shader.Program); var indexBufferObject = objectDrawCall.GetSubCollection("m_indexBuffer"); var indexBuffer = default(DrawBuffer); indexBuffer.Id = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_hBuffer")); indexBuffer.Offset = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_nBindOffsetBytes")); drawCall.IndexBuffer = indexBuffer; var indexElementSize = vbib.IndexBuffers[(int)drawCall.IndexBuffer.Id].Size; //drawCall.BaseVertex = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nBaseVertex")); //drawCall.VertexCount = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nVertexCount")); drawCall.StartIndex = Convert.ToUInt32(objectDrawCall.GetProperty <object>("m_nStartIndex")) * indexElementSize; drawCall.IndexCount = Convert.ToInt32(objectDrawCall.GetProperty <object>("m_nIndexCount")); if (objectDrawCall.ContainsKey("m_vTintColor")) { var tintColor = objectDrawCall.GetSubCollection("m_vTintColor").ToVector3(); drawCall.TintColor = new OpenTK.Vector3(tintColor.X, tintColor.Y, tintColor.Z); } if (!drawCall.Material.Textures.ContainsKey("g_tTintMask")) { drawCall.Material.Textures.Add("g_tTintMask", MaterialLoader.CreateSolidTexture(1f, 1f, 1f)); } if (!drawCall.Material.Textures.ContainsKey("g_tNormal")) { drawCall.Material.Textures.Add("g_tNormal", MaterialLoader.CreateSolidTexture(0.5f, 1f, 0.5f)); } if (indexElementSize == 2) { //shopkeeper_vr drawCall.IndexType = DrawElementsType.UnsignedShort; } else if (indexElementSize == 4) { //glados drawCall.IndexType = DrawElementsType.UnsignedInt; } else { throw new Exception("Unsupported index type"); } var m_vertexBuffers = objectDrawCall.GetSubCollection("m_vertexBuffers"); var m_vertexBuffer = m_vertexBuffers.GetSubCollection("0"); // TODO: Not just 0 var vertexBuffer = default(DrawBuffer); vertexBuffer.Id = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_hBuffer")); vertexBuffer.Offset = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_nBindOffsetBytes")); drawCall.VertexBuffer = vertexBuffer; drawCall.VertexArrayObject = guiContext.MeshBufferCache.GetVertexArrayObject( vbib, drawCall.Shader, drawCall.VertexBuffer.Id, drawCall.IndexBuffer.Id); return(drawCall); }
private DrawCall CreateDrawCall(IKeyValueCollection objectDrawCall, VBIB vbib, IDictionary <string, bool> shaderArguments, RenderMaterial material) { var drawCall = new DrawCall(); string primitiveType = objectDrawCall.GetProperty <object>("m_nPrimitiveType") switch { string primitiveTypeString => primitiveTypeString, byte primitiveTypeByte => (primitiveTypeByte == 5) ? "RENDER_PRIM_TRIANGLES" : ("UNKNOWN_" + primitiveTypeByte), _ => throw new NotImplementedException("Unknown PrimitiveType in drawCall!") }; switch (primitiveType) { case "RENDER_PRIM_TRIANGLES": drawCall.PrimitiveType = PrimitiveType.Triangles; break; default: throw new NotImplementedException("Unknown PrimitiveType in drawCall! (" + primitiveType + ")"); } SetupDrawCallMaterial(drawCall, shaderArguments, material); var indexBufferObject = objectDrawCall.GetSubCollection("m_indexBuffer"); var indexBuffer = default(DrawBuffer); indexBuffer.Id = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_hBuffer")); indexBuffer.Offset = Convert.ToUInt32(indexBufferObject.GetProperty <object>("m_nBindOffsetBytes")); drawCall.IndexBuffer = indexBuffer; var indexElementSize = vbib.IndexBuffers[(int)drawCall.IndexBuffer.Id].ElementSizeInBytes; //drawCall.BaseVertex = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nBaseVertex")); //drawCall.VertexCount = Convert.ToUInt32(objectDrawCall.GetProperty<object>("m_nVertexCount")); drawCall.StartIndex = Convert.ToUInt32(objectDrawCall.GetProperty <object>("m_nStartIndex")) * indexElementSize; drawCall.IndexCount = Convert.ToInt32(objectDrawCall.GetProperty <object>("m_nIndexCount")); if (objectDrawCall.ContainsKey("m_vTintColor")) { var tintColor = objectDrawCall.GetSubCollection("m_vTintColor").ToVector3(); drawCall.TintColor = new OpenTK.Vector3(tintColor.X, tintColor.Y, tintColor.Z); } if (indexElementSize == 2) { //shopkeeper_vr drawCall.IndexType = DrawElementsType.UnsignedShort; } else if (indexElementSize == 4) { //glados drawCall.IndexType = DrawElementsType.UnsignedInt; } else { throw new Exception("Unsupported index type"); } var m_vertexBuffer = objectDrawCall.GetArray("m_vertexBuffers")[0]; // TODO: Not just 0 var vertexBuffer = default(DrawBuffer); vertexBuffer.Id = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_hBuffer")); vertexBuffer.Offset = Convert.ToUInt32(m_vertexBuffer.GetProperty <object>("m_nBindOffsetBytes")); drawCall.VertexBuffer = vertexBuffer; drawCall.VertexArrayObject = guiContext.MeshBufferCache.GetVertexArrayObject( vbib, drawCall.Shader, drawCall.VertexBuffer.Id, drawCall.IndexBuffer.Id); return(drawCall); }
public IKeyValueCollection GetDecodeKey() => data.GetSubCollection("m_decodeKey");