Beispiel #1
0
        public VBIB(IKeyValueCollection data) : this()
        {
            var vertexBuffers = data.GetArray("m_vertexBuffers");

            foreach (var vb in vertexBuffers)
            {
                var vertexBuffer = BufferDataFromDATA(vb);

                var decompressedSize = vertexBuffer.ElementCount * vertexBuffer.ElementSizeInBytes;
                if (vertexBuffer.Data.Length != decompressedSize)
                {
                    vertexBuffer.Data = MeshOptimizerVertexDecoder.DecodeVertexBuffer((int)vertexBuffer.ElementCount, (int)vertexBuffer.ElementSizeInBytes, vertexBuffer.Data);
                }
                VertexBuffers.Add(vertexBuffer);
            }
            var indexBuffers = data.GetArray("m_indexBuffers");

            foreach (var ib in indexBuffers)
            {
                var indexBuffer = BufferDataFromDATA(ib);

                var decompressedSize = indexBuffer.ElementCount * indexBuffer.ElementSizeInBytes;
                if (indexBuffer.Data.Length != decompressedSize)
                {
                    indexBuffer.Data = MeshOptimizerIndexDecoder.DecodeIndexBuffer((int)indexBuffer.ElementCount, (int)indexBuffer.ElementSizeInBytes, indexBuffer.Data);
                }

                IndexBuffers.Add(indexBuffer);
            }
        }
        public static IEnumerable <Animation> FromData(IKeyValueCollection animationData, IKeyValueCollection decodeKey)
        {
            var animArray = animationData.GetArray <IKeyValueCollection>("m_animArray");

            if (animArray.Length == 0)
            {
                Console.WriteLine("Empty animation file found.");
                return(Enumerable.Empty <Animation>());
            }

            var decoderArray = MakeDecoderArray(animationData.GetArray("m_decoderArray"));
            var segmentArray = animationData.GetArray("m_segmentArray");

            var animations = new List <Animation>();

            foreach (var anim in animArray)
            {
                // Here be dragons. Animation decoding is complicated, and we have not
                // fully figured it out, especially all of the decoder types.
                // If an animation decoder throws, this prevents the model from loading or exporting,
                // so we catch all exceptions here and skip over the animation.
                // Obviously we want to properly support animation decoding, but we are not there yet.
                try
                {
                    animations.Add(new Animation(anim, decodeKey, decoderArray, segmentArray));
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine(e);
                }
            }

            return(animations);
        }
Beispiel #3
0
        private static OnDiskBufferData BufferDataFromDATA(IKeyValueCollection data)
        {
            OnDiskBufferData buffer = new OnDiskBufferData();

            buffer.ElementCount       = data.GetUInt32Property("m_nElementCount");
            buffer.ElementSizeInBytes = data.GetUInt32Property("m_nElementSizeInBytes");

            buffer.InputLayoutFields = new List <RenderInputLayoutField>();

            var inputLayoutFields = data.GetArray("m_inputLayoutFields");

            foreach (var il in inputLayoutFields)
            {
                RenderInputLayoutField attrib = new RenderInputLayoutField();

                //null-terminated string
                attrib.SemanticName     = System.Text.Encoding.UTF8.GetString(il.GetArray <byte>("m_pSemanticName")).TrimEnd((char)0);
                attrib.SemanticIndex    = il.GetInt32Property("m_nSemanticIndex");
                attrib.Format           = (DXGI_FORMAT)il.GetUInt32Property("m_Format");
                attrib.Offset           = il.GetUInt32Property("m_nOffset");
                attrib.Slot             = il.GetInt32Property("m_nSlot");
                attrib.SlotType         = (RenderSlotType)il.GetUInt32Property("m_nSlotType");
                attrib.InstanceStepRate = il.GetInt32Property("m_nInstanceStepRate");

                buffer.InputLayoutFields.Add(attrib);
            }

            buffer.Data = data.GetArray <byte>("m_pData");

            return(buffer);
        }
        public PositionOffset(IKeyValueCollection keyValues)
        {
            if (keyValues.ContainsKey("m_OffsetMin"))
            {
                var vectorValues = keyValues.GetArray <double>("m_OffsetMin");
                offsetMin = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }

            if (keyValues.ContainsKey("m_OffsetMax"))
            {
                var vectorValues = keyValues.GetArray <double>("m_OffsetMax");
                offsetMax = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }
        }
        public static IEnumerable <Animation> FromData(IKeyValueCollection animationData, IKeyValueCollection decodeKey)
        {
            var animArray = animationData.GetArray <IKeyValueCollection>("m_animArray");

            if (animArray.Length == 0)
            {
                Console.WriteLine("Empty animation file found.");
                return(Enumerable.Empty <Animation>());
            }

            var decoderArray = MakeDecoderArray(animationData.GetArray("m_decoderArray"));
            var segmentArray = animationData.GetArray("m_segmentArray");

            return(animArray.Select(anim => new Animation(anim, decodeKey, decoderArray, segmentArray)));
        }
Beispiel #6
0
        public RandomColor(IKeyValueCollection keyValues)
        {
            random = new Random();

            if (keyValues.ContainsKey("m_ColorMin"))
            {
                var vectorValues = keyValues.GetArray <long>("m_ColorMin");
                colorMin = new Vector3(vectorValues[0], vectorValues[1], vectorValues[2]) / 255f;
            }

            if (keyValues.ContainsKey("m_ColorMax"))
            {
                var vectorValues = keyValues.GetArray <long>("m_ColorMax");
                colorMax = new Vector3(vectorValues[0], vectorValues[1], vectorValues[2]) / 255f;
            }
        }
        public static IVectorProvider GetVectorProvider(this IKeyValueCollection keyValues, string propertyName)
        {
            var property = keyValues.GetProperty <object>(propertyName);

            if (property is IKeyValueCollection numberProviderParameters && numberProviderParameters.ContainsKey("m_nType"))
            {
                var type = numberProviderParameters.GetProperty <string>("m_nType");
                switch (type)
                {
                case "PVEC_TYPE_LITERAL":
                    return(new LiteralVectorProvider(numberProviderParameters.GetArray <double>("m_vLiteralValue")));

                default:
                    if (numberProviderParameters.ContainsKey("m_vLiteralValue"))
                    {
                        Console.Error.WriteLine($"Vector provider of type {type} is not directly supported, but it has m_vLiteralValue.");
                        return(new LiteralVectorProvider(numberProviderParameters.GetArray <double>("m_vLiteralValue")));
                    }

                    throw new InvalidCastException($"Could not create vector provider of type {type}.");
                }
            }

            return(new LiteralVectorProvider(keyValues.GetArray <double>(propertyName)));
        }
        /// <summary>
        /// Construct the Armature object from mesh skeleton KV data.
        /// </summary>
        private Skeleton(IKeyValueCollection skeletonData, ILookup <long, int> remapTable)
        {
            var boneNames     = skeletonData.GetArray <string>("m_boneName");
            var boneParents   = skeletonData.GetIntegerArray("m_nParent");
            var boneFlags     = skeletonData.GetIntegerArray("m_nFlag");
            var bonePositions = skeletonData.GetArray("m_bonePosParent", v => v.ToVector3());
            var boneRotations = skeletonData.GetArray("m_boneRotParent", v => v.ToQuaternion());

            if (boneNames.Length > 0 && remapTable.Any())
            {
                AnimationTextureSize = remapTable.Select(g => g.Max()).Max() + 1;
            }

            // Initialise bone array
            Bones = new Bone[boneNames.Length];

            //Add all bones to the list
            for (var i = 0; i < boneNames.Length; i++)
            {
                if ((boneFlags[i] & BoneUsedByVertexLod0) != BoneUsedByVertexLod0)
                {
                    continue;
                }

                var name = boneNames[i];

                var position = bonePositions[i];
                var rotation = boneRotations[i];

                // Create bone
                var bone = new Bone(name, remapTable[i].ToList(), position, rotation);

                if (boneParents[i] != -1)
                {
                    bone.SetParent(Bones[boneParents[i]]);
                    Bones[boneParents[i]].AddChild(bone);
                }

                Bones[i] = bone;
            }

            FindRoots();
        }
Beispiel #9
0
        public InitialVelocityNoise(IKeyValueCollection keyValues)
        {
            if (keyValues.ContainsKey("m_vecOutputMin"))
            {
                var vectorValues = keyValues.GetArray <double>("m_vecOutputMin");
                outputMin = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }

            if (keyValues.ContainsKey("m_vecOutputMax"))
            {
                var vectorValues = keyValues.GetArray <double>("m_vecOutputMax");
                outputMax = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }

            if (keyValues.ContainsKey("m_flNoiseScale"))
            {
                noiseScale = keyValues.GetFloatProperty("m_flNoiseScale");
            }
        }
Beispiel #10
0
        public BasicMovement(IKeyValueCollection keyValues)
        {
            if (keyValues.ContainsKey("m_Gravity"))
            {
                var vectorValues = keyValues.GetArray <double>("m_Gravity");
                gravity = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }

            if (keyValues.ContainsKey("m_fDrag"))
            {
                drag = keyValues.GetFloatProperty("m_fDrag");
            }
        }
Beispiel #11
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>());
        }
Beispiel #12
0
        /// <summary>
        /// Construct the Armature object from mesh skeleton KV data.
        /// </summary>
        public void ConstructFromNTRO(IKeyValueCollection skeletonData, Dictionary <long, int> remapTable)
        {
            var boneNames     = skeletonData.GetArray <string>("m_boneName");
            var boneParents   = skeletonData.GetIntegerArray("m_nParent");
            var bonePositions = skeletonData.GetArray("m_bonePosParent", v => v.ToVector3());
            var boneRotations = skeletonData.GetArray("m_boneRotParent", v => v.ToQuaternion());

            // Initialise bone array
            Bones = new Bone[boneNames.Length];

            //Add all bones to the list
            for (var i = 0; i < boneNames.Length; i++)
            {
                var name = boneNames[i];

                var position = bonePositions[i];
                var rotation = boneRotations[i];

                // Create bone
                var index = remapTable.ContainsKey(i) ? remapTable[i] : -1;
                var bone  = new Bone(name, index, position, rotation);

                if (boneParents[i] != -1)
                {
                    bone.SetParent(Bones[boneParents[i]]);
                    Bones[boneParents[i]].AddChild(bone);
                }

                Bones[i] = bone;
            }

            FindRoots();

            // Figure out the index of the last bone so we dont have to do that every draw call
            LastBone = Bones.Length > 0 ? Bones.Max(b => b.Index) : -1;
        }
        public OffsetVectorToVector(IKeyValueCollection keyValues)
        {
            if (keyValues.ContainsKey("m_nFieldInput"))
            {
                inputField = (ParticleField)keyValues.GetIntegerProperty("m_nFieldInput");
            }

            if (keyValues.ContainsKey("m_nFieldOutput"))
            {
                outputField = (ParticleField)keyValues.GetIntegerProperty("m_nFieldOutput");
            }

            if (keyValues.ContainsKey("m_vecOutputMin"))
            {
                var vectorValues = keyValues.GetArray <double>("m_vecOutputMin");
                offsetMin = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }

            if (keyValues.ContainsKey("m_vecOutputMax"))
            {
                var vectorValues = keyValues.GetArray <double>("m_vecOutputMax");
                offsetMax = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }
        }
Beispiel #14
0
        public CreateWithinSphere(IKeyValueCollection keyValues)
        {
            random = new Random();

            if (keyValues.ContainsKey("m_fRadiusMin"))
            {
                radiusMin = keyValues.GetFloatProperty("m_fRadiusMin");
            }

            if (keyValues.ContainsKey("m_fRadiusMax"))
            {
                radiusMax = keyValues.GetFloatProperty("m_fRadiusMax");
            }

            if (keyValues.ContainsKey("m_fSpeedMin"))
            {
                speedMin = keyValues.GetFloatProperty("m_fSpeedMin");
            }

            if (keyValues.ContainsKey("m_fSpeedMax"))
            {
                speedMax = keyValues.GetFloatProperty("m_fSpeedMax");
            }

            if (keyValues.ContainsKey("m_LocalCoordinateSystemSpeedMin"))
            {
                var vectorValues = keyValues.GetArray <double>("m_LocalCoordinateSystemSpeedMin");
                localCoordinateSystemSpeedMin = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }

            if (keyValues.ContainsKey("m_LocalCoordinateSystemSpeedMax"))
            {
                var vectorValues = keyValues.GetArray <double>("m_LocalCoordinateSystemSpeedMax");
                localCoordinateSystemSpeedMax = new Vector3((float)vectorValues[0], (float)vectorValues[1], (float)vectorValues[2]);
            }
        }
Beispiel #15
0
        public static byte[] Decode(byte[] data, IKeyValueCollection sourceMap)
        {
            var mapping = sourceMap.GetArray("DBITSLC", kvArray => (kvArray.GetInt32Property("0"), kvArray.GetInt32Property("1"), kvArray.GetInt32Property("2")));

            var output = new List <IEnumerable <byte> >();

            var currentCol  = 0;
            var currentLine = 1;

            for (var i = 0; i < mapping.Length - 1; i++)
            {
                var(startIndex, sourceLine, sourceColumn) = mapping[i];
                var(nextIndex, _, _) = mapping[i + 1];

                // Prepend newlines if they are in front of this chunk according to sourceLineByteIndices
                if (currentLine < sourceLine)
                {
                    output.Add(Enumerable.Repeat(Encoding.UTF8.GetBytes("\n")[0], sourceLine - currentLine));
                    currentCol  = 0;
                    currentLine = sourceLine;
                }
                else if (sourceLine < currentLine)
                {
                    // Referring back to an object higher in hierarchy, also add newline here
                    output.Add(Enumerable.Repeat(Encoding.UTF8.GetBytes("\n")[0], 1));
                    currentCol = 0;
                    currentLine++;
                }

                // Prepend spaces until we catch up to the index we need to be at
                if (currentCol < sourceColumn)
                {
                    output.Add(Enumerable.Repeat(Encoding.UTF8.GetBytes(" ")[0], sourceColumn - currentCol));
                    currentCol = sourceColumn;
                }

                // Copy destination
                var length = nextIndex - startIndex;
                output.Add(data.Skip(startIndex).Take(length));
                currentCol += length;
            }

            output.Add(Enumerable.Repeat(Encoding.UTF8.GetBytes("\n")[0], 1));
            output.Add(data.Skip(mapping[mapping.Length - 1].Item1));

            return(output.SelectMany(_ => _).ToArray());
        }
Beispiel #16
0
        public ColorInterpolate(IKeyValueCollection keyValues)
        {
            if (keyValues.ContainsKey("m_ColorFade"))
            {
                var vectorValues = keyValues.GetArray <long>("m_ColorFade");
                colorFade = new Vector3(vectorValues[0], vectorValues[1], vectorValues[2]) / 255f;
            }

            if (keyValues.ContainsKey("m_flFadeStartTime"))
            {
                fadeStartTime = keyValues.GetFloatProperty("m_flFadeStartTime");
            }

            if (keyValues.ContainsKey("m_flFadeEndTime"))
            {
                fadeEndTime = keyValues.GetFloatProperty("m_flFadeEndTime");
            }
        }
Beispiel #17
0
        public Particle(IKeyValueCollection baseProperties)
        {
            if (baseProperties.ContainsKey("m_ConstantColor"))
            {
                var vectorValues = baseProperties.GetArray <long>("m_ConstantColor");
                ConstantColor = new Vector3(vectorValues[0], vectorValues[1], vectorValues[2]) / 255f;
            }

            if (baseProperties.ContainsKey("m_flConstantRadius"))
            {
                ConstantRadius = baseProperties.GetFloatProperty("m_flConstantRadius");
            }

            if (baseProperties.ContainsKey("m_flConstantLifespan"))
            {
                ConstantLifetime = baseProperties.GetFloatProperty("m_flConstantLifespan");
            }

            Init();
        }
Beispiel #18
0
 public IEnumerable <string> GetAnimationArray()
 => data.GetArray <string>("m_localHAnimArray").Where(a => a != null);
Beispiel #19
0
 public static T[] GetArray <T>(this IKeyValueCollection collection, string name, Func <IKeyValueCollection, T> mapper)
 => collection.GetArray <IKeyValueCollection>(name)
 .Select(mapper)
 .ToArray();
        /// <summary>
        /// Read segment.
        /// </summary>
        private void ReadSegment(long frame, IKeyValueCollection segment, IKeyValueCollection decodeKey, AnimDecoderType[] decoderArray, ref Frame outFrame)
        {
            // Clamp the frame number to be between 0 and the maximum frame
            frame = frame < 0 ? 0 : frame;
            frame = frame >= FrameCount ? FrameCount - 1 : frame;

            var localChannel = segment.GetIntegerProperty("m_nLocalChannel");
            var dataChannel  = decodeKey.GetArray("m_dataChannelArray")[localChannel];
            var boneNames    = dataChannel.GetArray <string>("m_szElementNameArray");

            var channelAttribute = dataChannel.GetProperty <string>("m_szVariableName");

            // Read container
            var container = segment.GetArray <byte>("m_container");

            using (var containerReader = new BinaryReader(new MemoryStream(container)))
            {
                var elementIndexArray = dataChannel.GetIntegerArray("m_nElementIndexArray");
                var elementBones      = new int[decodeKey.GetProperty <int>("m_nChannelElements")];
                for (var i = 0; i < elementIndexArray.Length; i++)
                {
                    elementBones[elementIndexArray[i]] = i;
                }

                // Read header
                var decoder     = decoderArray[containerReader.ReadInt16()];
                var cardinality = containerReader.ReadInt16();
                var numBones    = containerReader.ReadInt16();
                var totalLength = containerReader.ReadInt16();

                // Read bone list
                var elements = new List <int>();
                for (var i = 0; i < numBones; i++)
                {
                    elements.Add(containerReader.ReadInt16());
                }

                // Skip data to find the data for the current frame.
                // Structure is just | Bone 0 - Frame 0 | Bone 1 - Frame 0 | Bone 0 - Frame 1 | Bone 1 - Frame 1|
                if (containerReader.BaseStream.Position + (decoder.Size() * frame * numBones) < containerReader.BaseStream.Length)
                {
                    containerReader.BaseStream.Position += decoder.Size() * frame * numBones;
                }

                // Read animation data for all bones
                for (var element = 0; element < numBones; element++)
                {
                    // Get the bone we are reading for
                    var bone = elementBones[elements[element]];

                    // Look at the decoder to see what to read
                    switch (decoder)
                    {
                    case AnimDecoderType.CCompressedStaticFullVector3:
                    case AnimDecoderType.CCompressedFullVector3:
                    case AnimDecoderType.CCompressedDeltaVector3:
                        outFrame.SetAttribute(boneNames[bone], channelAttribute, new Vector3(
                                                  containerReader.ReadSingle(),
                                                  containerReader.ReadSingle(),
                                                  containerReader.ReadSingle()));
                        break;

                    case AnimDecoderType.CCompressedAnimVector3:
                    case AnimDecoderType.CCompressedStaticVector3:
                        outFrame.SetAttribute(boneNames[bone], channelAttribute, new Vector3(
                                                  ReadHalfFloat(containerReader),
                                                  ReadHalfFloat(containerReader),
                                                  ReadHalfFloat(containerReader)));
                        break;

                    case AnimDecoderType.CCompressedAnimQuaternion:
                    case AnimDecoderType.CCompressedFullQuaternion:
                    case AnimDecoderType.CCompressedStaticQuaternion:
                        outFrame.SetAttribute(boneNames[bone], channelAttribute, ReadQuaternion(containerReader));
                        break;

#if DEBUG
                    default:
                        if (channelAttribute != "data")
                        {
                            Console.WriteLine($"Unhandled animation bone decoder type '{decoder}'");
                        }

                        break;
#endif
                    }
                }
            }
        }
        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 + ")");
            }

            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].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 (!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_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);
        }
    }
        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);
        }
Beispiel #23
0
 public static ulong[] GetUnsignedIntegerArray(this IKeyValueCollection collection, string name)
 => collection.GetArray <object>(name)
 .Select(Convert.ToUInt64)
 .ToArray();
Beispiel #24
0
 public static IKeyValueCollection[] GetArray(this IKeyValueCollection collection, string name)
 => collection.GetArray <IKeyValueCollection>(name);