예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        private static void PrintInclude(IKeyValueCollection node, IndentedTextWriter writer)
        {
            var reference = node.GetSubCollection("child");

            writer.Write($"<include src=");
            PrintAttributeOrReferenceValue(reference, writer);
            writer.WriteLine(" />");
        }
예제 #5
0
        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>());
        }
예제 #6
0
        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);
        }
예제 #9
0
 public IKeyValueCollection GetDecodeKey()
 => data.GetSubCollection("m_decodeKey");