Пример #1
0
        private static void LoadEntities(NTROValue lump, Renderer.Renderer renderer, string path, Package package)
        {
            var reference = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value;

            if (reference == null)
            {
                return;
            }

            var newResource = FileExtensions.LoadFileByAnyMeansNecessary(reference.Name + "_c", path, package);

            if (newResource == null)
            {
                Console.WriteLine("unable to load entity lump " + reference.Name + "_c");

                return;
            }

            var entityLump = newResource.Blocks[BlockType.DATA] as EntityLump;

            var childLumps = (NTROArray)entityLump.Output["m_childLumps"];

            foreach (var lump2 in childLumps)
            {
                var lol = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value;

                // TODO: Should be controlled in UI with world layers
                if (lol.Name.Contains("_destruction"))
                {
                    continue;
                }

                LoadEntities(lump2, renderer, path, package);
            }

            foreach (var entity in entityLump.Datas)
            {
                var scale     = string.Empty;
                var position  = string.Empty;
                var angles    = string.Empty;
                var model     = string.Empty;
                var skin      = string.Empty;
                var colour    = new byte[0];
                var classname = string.Empty;
                var name      = string.Empty;

                foreach (var property in entity)
                {
                    //metadata
                    switch (property.Item2)
                    {
                    case 3368008710:     //World Model
                        model = property.Item3 as string;
                        break;

                    case 3827302934:     //Position
                        position = property.Item3 as string;
                        break;

                    case 3130579663:     //Angles
                        angles = property.Item3 as string;
                        break;

                    case 432137260:     //Scale
                        scale = property.Item3 as string;
                        break;

                    case 2020856412:     //Skin
                        skin = property.Item3 as string;
                        break;

                    case 588463423:     //Colour
                        colour = property.Item3 as byte[];
                        break;

                    case 3323665506:     //Classname
                        classname = property.Item3 as string;
                        break;

                    case 1094168427:
                        name = property.Item3 as string;
                        break;
                    }
                }

                if (scale == string.Empty || position == string.Empty || angles == string.Empty)
                {
                    continue;
                }

                var isCamera =
                    classname == "info_player_start" ||
                    classname == "worldspawn" ||
                    classname == "sky_camera" ||
                    classname == "point_devshot_camera" ||
                    classname == "point_camera";

                if (!isCamera && model == string.Empty)
                {
                    continue;
                }

                var scaleMatrix = Matrix4.CreateScale(ParseCoordinates(scale));

                var positionVector = ParseCoordinates(position);
                var positionMatrix = Matrix4.CreateTranslation(positionVector);

                var pitchYawRoll = ParseCoordinates(angles);
                var rollMatrix   = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(pitchYawRoll.Z)); // Roll
                var pitchMatrix  = Matrix4.CreateRotationY(MathHelper.DegreesToRadians(pitchYawRoll.X)); // Pitch
                var yawMatrix    = Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(pitchYawRoll.Y)); // Yaw

                var rotationMatrix       = rollMatrix * pitchMatrix * yawMatrix;
                var transformationMatrix = scaleMatrix * rotationMatrix * positionMatrix;

                if (isCamera)
                {
                    if (classname == "worldspawn")
                    {
                        renderer.SetDefaultWorldCamera(positionVector);
                    }
                    else
                    {
                        renderer.AddCamera(name == string.Empty ? $"{classname} #{anonymousCameraCount++}" : name, transformationMatrix);
                    }

                    continue;
                }

                var objColor = Vector4.One;

                // Parse colour if present
                if (colour.Length == 4)
                {
                    for (var i = 0; i < 4; i++)
                    {
                        objColor[i] = colour[i] / 255.0f;
                    }
                }

                var newEntity = FileExtensions.LoadFileByAnyMeansNecessary(model + "_c", path, package);
                if (newEntity == null)
                {
                    Console.WriteLine($"unable to load entity {model}_c");

                    continue;
                }

                var entityModel = new Model(newEntity);
                entityModel.LoadMeshes(renderer, path, transformationMatrix, objColor, package, skin);
            }
        }
Пример #2
0
        private void ReadFieldIntrospection(ResourceIntrospectionManifest.ResourceDiskStruct.Field field, ref NTROStruct structEntry)
        {
            var count   = (uint)field.Count;
            var pointer = false; // TODO: get rid of this

            if (count == 0)
            {
                count = 1;
            }

            long prevOffset = 0;

            if (field.Indirections.Count > 0)
            {
                // TODO
                if (field.Indirections.Count > 1)
                {
                    throw new NotImplementedException("More than one indirection, not yet handled.");
                }

                // TODO
                if (field.Count > 0)
                {
                    throw new NotImplementedException("Indirection.Count > 0 && field.Count > 0");
                }

                var indirection = field.Indirections[0]; // TODO: depth needs fixing?

                var offset = Reader.ReadUInt32();

                if (indirection == 0x03)
                {
                    pointer = true;

                    if (offset == 0)
                    {
                        structEntry.Add(field.FieldName, new NTROValue <byte?>(field.Type, null, true)); //being byte shouldn't matter

                        return;
                    }

                    prevOffset = Reader.BaseStream.Position;

                    Reader.BaseStream.Position += offset - 4;
                }
                else if (indirection == 0x04)
                {
                    count = Reader.ReadUInt32();

                    prevOffset = Reader.BaseStream.Position;

                    if (count > 0)
                    {
                        Reader.BaseStream.Position += offset - 8;
                    }
                }
                else
                {
                    throw new NotImplementedException(string.Format("Unknown indirection. ({0})", indirection));
                }
            }

            //if (pointer)
            //{
            //    Writer.Write("{0} {1}* = (ptr) ->", ValveDataType(field.Type), field.FieldName);
            //}
            if (field.Count > 0 || field.Indirections.Count > 0)
            {
                if (field.Type == DataType.Byte)
                {
                    //special case for byte arrays for faster access
                    var ntroValues = new NTROValue <byte[]>(field.Type, Reader.ReadBytes((int)count), pointer);
                    structEntry.Add(field.FieldName, ntroValues);
                }
                else
                {
                    var ntroValues = new NTROArray(field.Type, (int)count, pointer, field.Indirections.Count > 0);

                    for (var i = 0; i < count; i++)
                    {
                        ntroValues[i] = ReadField(field, pointer);
                    }

                    structEntry.Add(field.FieldName, ntroValues);
                }
            }
            else
            {
                for (var i = 0; i < count; i++)
                {
                    structEntry.Add(field.FieldName, ReadField(field, pointer));
                }
            }

            if (prevOffset > 0)
            {
                Reader.BaseStream.Position = prevOffset;
            }
        }
Пример #3
0
        private static void LoadEntities(NTROValue lump, Renderer.Renderer renderer, string path, Package package)
        {
            var reference = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value;

            if (reference == null)
            {
                return;
            }

            var newResource = FileExtensions.LoadFileByAnyMeansNecessary(reference.Name + "_c", path, package);

            if (newResource == null)
            {
                Console.WriteLine("unable to load entity lump " + reference.Name + "_c");

                return;
            }

            var entityLump = newResource.Blocks[BlockType.DATA] as EntityLump;

            var childLumps = (NTROArray)entityLump.Output["m_childLumps"];

            foreach (var lump2 in childLumps)
            {
                var lol = ((NTROValue <ResourceExtRefList.ResourceReferenceInfo>)lump).Value;

                // TODO: Should be controlled in UI with world layers
                if (lol.Name.Contains("_destruction"))
                {
                    continue;
                }

                LoadEntities(lump2, renderer, path, package);
            }

            foreach (var entity in entityLump.Datas)
            {
                var scale     = string.Empty;
                var position  = string.Empty;
                var angles    = string.Empty;
                var model     = string.Empty;
                var skin      = string.Empty;
                var colour    = new byte[0];
                var classname = string.Empty;
                var name      = string.Empty;

                foreach (var property in entity)
                {
                    //metadata
                    switch (property.Item2)
                    {
                    case 3368008710:     //World Model
                        model = property.Item3 as string;
                        break;

                    case 3827302934:     //Position
                        position = property.Item3 as string;
                        break;

                    case 3130579663:     //Angles
                        angles = property.Item3 as string;
                        break;

                    case 432137260:     //Scale
                        scale = property.Item3 as string;
                        break;

                    case 2020856412:     //Skin
                        skin = property.Item3 as string;
                        break;

                    case 588463423:     //Colour
                        colour = property.Item3 as byte[];
                        break;

                    case 3323665506:     //Classname
                        classname = property.Item3 as string;
                        break;

                    case 1094168427:
                        name = property.Item3 as string;
                        break;
                    }
                }

                if (scale == string.Empty || position == string.Empty || angles == string.Empty)
                {
                    continue;
                }

                if (classname == "point_camera" || classname == "vr_teleport_marker" || model != string.Empty)
                {
                    var scaleMatrix    = Matrix4.CreateScale(ParseCoordinates(scale));
                    var positionMatrix = Matrix4.CreateTranslation(ParseCoordinates(position));

                    var rotationVector = ParseCoordinates(angles);
                    var rotationMatrix = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(rotationVector.Z));
                    rotationMatrix *= Matrix4.CreateRotationY(MathHelper.DegreesToRadians(rotationVector.X));
                    rotationMatrix *= Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(rotationVector.Y));

                    var megaMatrix = scaleMatrix * rotationMatrix * positionMatrix;

                    var objColor = Vector4.One;
                    // Parse colour if present
                    if (colour.Length == 4)
                    {
                        for (var i = 0; i < 4; i++)
                        {
                            objColor[i] = colour[i] / 255.0f;
                        }
                    }

                    //This model is hardcoded into the FGD
                    if (classname == "vr_teleport_marker")
                    {
                        model = "models/effects/teleport/teleport_marker.vmdl";
                    }

                    if (classname == "point_camera")
                    {
                        renderer.AddCamera(name == string.Empty ? $"Camera {anonymousCameraCount++}" : name, megaMatrix);
                    }
                    else
                    {
                        var newEntity = FileExtensions.LoadFileByAnyMeansNecessary(model + "_c", path, package);
                        if (newEntity == null)
                        {
                            Console.WriteLine("unable to load entity " + model + "_c");

                            continue;
                        }

                        var entityModel = new Model(newEntity);
                        entityModel.LoadMeshes(renderer, path, megaMatrix, objColor, package, skin);
                    }
                }
            }
        }