Exemplo n.º 1
0
 public static void Write(this BinaryWriter writer, RealPoint3d point)
 {
     // Write a RealPoint3d object to the stream.
     writer.Write(point.x);
     writer.Write(point.y);
     writer.Write(point.z);
 }
Exemplo n.º 2
0
        public void Read(EndianReader reader)
        {
            Translations = new RealPoint3d[FrameCount];
            Rotations    = new RealEulerAngles3d[FrameCount];

            for (int i = 0; i < FrameCount; i++)
            {
                var yaw = 0f;
                var x   = reader.ReadSingle();
                var y   = reader.ReadSingle();
                var z   = 0f;

                switch (Type)
                {
                case AnimationMovementDataType.DxDyDyaw:
                    yaw = reader.ReadSingle();
                    break;

                case AnimationMovementDataType.DxDyDzDyaw:
                    z   = reader.ReadSingle();
                    yaw = reader.ReadSingle();
                    break;
                }

                Translations[i] = new RealPoint3d(x * 100f, y * 100f, z * 100f);
                Rotations[i]    = new RealEulerAngles3d(Angle.FromRadians(yaw), Angle.FromRadians(0f), Angle.FromRadians(0f));
            }
        }
Exemplo n.º 3
0
 private void AddPrematchCamera(RealPoint3d position, RealEulerAngles3d rotation)
 {
     Scnr.CutsceneCameraPoints.Add(new CutsceneCameraPoint()
     {
         Position    = position,
         Orientation = rotation,
         Flags       = CutsceneCameraPointFlags.PrematchCameraHack,
         Name        = "prematch_camera",
     });
 }
Exemplo n.º 4
0
        public static RealPoint3d ReadRealPoint3d(this BinaryReader reader)
        {
            // Read a RealPoint3d object from the stream.
            RealPoint3d point = new RealPoint3d();

            point.x = reader.ReadSingle();
            point.y = reader.ReadSingle();
            point.z = reader.ReadSingle();

            return(point);
        }
Exemplo n.º 5
0
        public void SetFieldValue(object owner, object value = null, object definition = null)
        {
            if (Loading || owner == null)
            {
                return;
            }

            if (value == null)
            {
                if (!float.TryParse(xTextBox.Text, out var x) ||
                    !float.TryParse(yTextBox.Text, out var y) ||
                    !float.TryParse(zTextBox.Text, out var z))
                {
                    return;
                }

                value = new RealPoint3d(x, y, z);
            }

            Field.SetValue(owner, value);
        }
Exemplo n.º 6
0
            private void AddRespawnPoint(RealPoint3d position, RealEulerAngles3d rotation)
            {
                var instance = new SceneryInstance();

                instance.PaletteIndex = (short)Scnr.SceneryPalette.Count;
                instance.NameIndex    = -1;
                instance.Position     = position;
                instance.Rotation     = rotation;
                instance.ObjectType   = new ScenarioObjectType()
                {
                    Halo3ODST = GameObjectTypeHalo3ODST.Scenery
                };
                instance.Source          = ScenarioInstance.SourceValue.Editor;
                instance.BspPolicy       = ScenarioInstance.BspPolicyValue.Default;
                instance.OriginBspIndex  = 0;
                instance.AllowedZoneSets = (1 << 0);
                instance.Team            = SceneryInstance.TeamValue.Neutral;
                Scnr.Scenery.Add(instance);

                Scnr.SceneryPalette.Add(new ScenarioPaletteEntry()
                {
                    Object = CacheContext.GetTag(@"objects\multi\spawning\respawn_point_invisible.scenery")
                });
            }
Exemplo n.º 7
0
        public RenderObject(D3DDevice device, HaloOnlineCacheContext cacheContext, GameObject definition, RealPoint3d position, RealEulerAngles3d rotation)
        {
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }
            else if (cacheContext == null)
            {
                throw new ArgumentNullException(nameof(cacheContext));
            }
            else if (definition == null)
            {
                throw new ArgumentNullException(nameof(definition));
            }

            Device       = device;
            CacheContext = cacheContext;
            Object       = definition;

            Position = position;
            Rotation = rotation;
            UpdateTransform();

            using (var cacheStream = CacheContext.OpenTagCacheRead())
            {
                if (Object.Model == null)
                {
                    throw new NullReferenceException(nameof(Object.Model));
                }

                Model = CacheContext.Deserialize <Model>(new TagSerializationContext(cacheStream, CacheContext, Object.Model));

                if (Model.RenderModel == null)
                {
                    throw new NullReferenceException(nameof(Model.RenderModel));
                }

                RenderModel = CacheContext.Deserialize <RenderModel>(new TagSerializationContext(cacheStream, CacheContext, Model.RenderModel));

                if (Model.Variants == null || Model.Variants.Count == 0)
                {
                    var modelVariant = new Model.Variant
                    {
                        Name    = CacheContext.GetStringId("default"),
                        Regions = new List <Model.Variant.Region>()
                    };

                    foreach (var region in RenderModel.Regions)
                    {
                        var modelRegion = new Model.Variant.Region
                        {
                            Name = region.Name,
                            RenderModelRegionIndex = (sbyte)RenderModel.Regions.IndexOf(region),
                            Permutations           = new List <Model.Variant.Region.Permutation>()
                        };

                        foreach (var permutation in region.Permutations)
                        {
                            modelRegion.Permutations.Add(new Model.Variant.Region.Permutation
                            {
                                Name = modelVariant.Name,
                                RenderModelPermutationIndex = (sbyte)region.Permutations.IndexOf(permutation)
                            });
                        }

                        modelVariant.Regions.Add(modelRegion);
                    }

                    Model.Variants = new List <Model.Variant> {
                        modelVariant
                    };
                }

                Materials = new List <RenderMaterial>();

                foreach (var material in RenderModel.Materials)
                {
                    Materials.Add(new RenderMaterial(device, CacheContext, material));
                }

                if (RenderModel.Geometry.Resource == null)
                {
                    throw new NullReferenceException(nameof(RenderModel.Geometry.Resource));
                }

                RenderGeometryResource = CacheContext.Deserialize <RenderGeometryApiResourceDefinition>(RenderModel.Geometry.Resource);

                using (var resourceStream = new MemoryStream())
                    using (var reader = new BinaryReader(resourceStream))
                    {
                        CacheContext.ExtractResource(RenderModel.Geometry.Resource, resourceStream);

                        VertexBuffers = new Dictionary <int, VertexBuffer>();
                        IndexBuffers  = new Dictionary <int, IndexBuffer>();

                        var compression = RenderModel.Geometry.Compression[0];

                        foreach (var mesh in RenderModel.Geometry.Meshes)
                        {
                            var renderVertex = VertexDefinition.Get(mesh.Type);
                            var streamTypes  = renderVertex.GetStreamTypes();

                            foreach (var streamEntry in streamTypes)
                            {
                                var vertexBufferIndex = mesh.VertexBufferIndices[streamEntry.Key];

                                if (vertexBufferIndex == ushort.MaxValue || VertexBuffers.ContainsKey(vertexBufferIndex))
                                {
                                    continue;
                                }

                                var vbDef = RenderGeometryResource.VertexBuffers[vertexBufferIndex].Definition;

                                var vb     = new VertexBuffer(streamEntry.Value, vbDef.Data.Size, device, Usage.DoNotClip, renderVertex.GetStreamFormat(streamEntry.Key), Pool.Managed);
                                var vbData = vb.Lock(0, vbDef.Data.Size, LockFlags.None);

                                resourceStream.Position = vbDef.Data.Address.Offset;

                                var vertices = Array.CreateInstance(streamEntry.Value, vbDef.Count);

                                for (var i = 0; i < vbDef.Count; i++)
                                {
                                    var handle = GCHandle.Alloc(reader.ReadBytes(Marshal.SizeOf(streamEntry.Value)), GCHandleType.Pinned);
                                    var vertex = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), streamEntry.Value);

                                    var positionField = streamEntry.Value.GetField("Position");

                                    if (positionField != null)
                                    {
                                        var xyz = (Vector3)positionField.GetValue(vertex);

                                        positionField.SetValue(vertex, new Vector3(
                                                                   xyz.X * compression.X.Length + compression.X.Lower,
                                                                   xyz.Y * compression.Y.Length + compression.Y.Lower,
                                                                   xyz.Z * compression.Z.Length + compression.Z.Lower));
                                    }

                                    var texcoordField = streamEntry.Value.GetField("Texcoord");

                                    if (texcoordField != null)
                                    {
                                        var uv = (Vector2)texcoordField.GetValue(vertex);

                                        texcoordField.SetValue(vertex, new Vector2(
                                                                   uv.X * compression.U.Length + compression.U.Lower,
                                                                   uv.Y * compression.V.Length + compression.V.Lower));
                                    }

                                    vertices.SetValue(vertex, i);

                                    handle.Free();
                                }

                                vbData.Write(vertices);
                                vb.Unlock();

                                VertexBuffers[vertexBufferIndex] = vb;
                            }

                            foreach (var indexBufferIndex in mesh.IndexBufferIndices)
                            {
                                if (indexBufferIndex == ushort.MaxValue || IndexBuffers.ContainsKey(indexBufferIndex))
                                {
                                    continue;
                                }

                                var ibDef = RenderGeometryResource.IndexBuffers[indexBufferIndex].Definition;

                                switch (ibDef.Format)
                                {
                                case IndexBufferFormat.PointList:
                                    mesh.IndexBufferType = TagPrimitiveType.PointList;
                                    break;

                                case IndexBufferFormat.LineList:
                                    mesh.IndexBufferType = TagPrimitiveType.LineList;
                                    break;

                                case IndexBufferFormat.LineStrip:
                                    mesh.IndexBufferType = TagPrimitiveType.LineStrip;
                                    break;

                                case IndexBufferFormat.TriangleList:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleList;
                                    break;

                                case IndexBufferFormat.TriangleFan:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleFan;
                                    break;

                                case IndexBufferFormat.TriangleStrip:
                                    mesh.IndexBufferType = TagPrimitiveType.TriangleStrip;
                                    break;
                                }

                                var ib     = new IndexBuffer(device, ibDef.Data.Size, Usage.DoNotClip, Pool.Managed, true);
                                var ibData = ib.Lock(0, ibDef.Data.Size, LockFlags.None);

                                resourceStream.Position = ibDef.Data.Address.Offset;

                                var indices = new ushort[ibDef.Data.Size / 2];

                                for (var i = 0; i < ibDef.Data.Size / 2; i++)
                                {
                                    indices[i] = reader.ReadUInt16();
                                }

                                ibData.Write(indices);
                                ib.Unlock();

                                IndexBuffers[indexBufferIndex] = ib;
                            }
                        }
                    }
            }
        }
Exemplo n.º 8
0
        public object ParseArgs(Type type, TagFieldInfo info, List <string> args)
        {
            var    input  = args[0];
            object output = null;

            if (type == typeof(byte))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!byte.TryParse(input, out byte value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(sbyte))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!sbyte.TryParse(input, out sbyte value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(short))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!short.TryParse(input, out short value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(ushort))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!ushort.TryParse(input, out ushort value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(int))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!int.TryParse(input, out int value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(uint))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!uint.TryParse(input, out uint value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(long))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!long.TryParse(input, out long value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(ulong))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!ulong.TryParse(input, out ulong value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(float))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!float.TryParse(input, out float value))
                {
                    return(false);
                }
                output = value;
            }
            else if (type == typeof(string))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                output = input;
            }
            else if (type == typeof(CachedTagInstance))
            {
                if (args.Count != 1 || !CacheContext.TryGetTag(input, out var tag))
                {
                    return(false);
                }
                output = tag;
            }
            else if (type == typeof(Tag))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!CacheContext.TryParseGroupTag(args[0], out var result))
                {
                    Console.WriteLine($"Invalid tag group specifier: {args[0]}");
                    return(false);
                }
                output = result;
            }
            else if (type == typeof(StringId))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                output = CacheContext.GetStringId(input);
            }
            else if (type == typeof(Angle))
            {
                if (args.Count != 1)
                {
                    return(false);
                }
                if (!float.TryParse(input, out float value))
                {
                    return(false);
                }
                output = Angle.FromDegrees(value);
            }
            else if (type == typeof(RealEulerAngles2d))
            {
                if (args.Count != 2)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float yaw) ||
                    !float.TryParse(args[1], out float pitch))
                {
                    return(false);
                }
                output = new RealEulerAngles2d(
                    Angle.FromDegrees(yaw),
                    Angle.FromDegrees(pitch));
            }
            else if (type == typeof(RealEulerAngles3d))
            {
                if (args.Count != 3)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float yaw) ||
                    !float.TryParse(args[1], out float pitch) ||
                    !float.TryParse(args[2], out float roll))
                {
                    return(false);
                }
                output = new RealEulerAngles3d(
                    Angle.FromDegrees(yaw),
                    Angle.FromDegrees(pitch),
                    Angle.FromDegrees(roll));
            }
            else if (type == typeof(RealPoint2d))
            {
                if (args.Count != 2)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float x) ||
                    !float.TryParse(args[1], out float y))
                {
                    return(false);
                }
                output = new RealPoint2d(x, y);
            }
            else if (type == typeof(RealPoint3d))
            {
                if (args.Count != 3)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float x) ||
                    !float.TryParse(args[1], out float y) ||
                    !float.TryParse(args[2], out float z))
                {
                    return(false);
                }
                output = new RealPoint3d(x, y, z);
            }
            else if (type == typeof(RealVector2d))
            {
                if (args.Count != 2)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float i) ||
                    !float.TryParse(args[1], out float j))
                {
                    return(false);
                }
                output = new RealVector2d(i, j);
            }
            else if (type == typeof(RealVector3d))
            {
                if (args.Count != 3)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float i) ||
                    !float.TryParse(args[1], out float j) ||
                    !float.TryParse(args[2], out float k))
                {
                    return(false);
                }
                output = new RealVector3d(i, j, k);
            }
            else if (type == typeof(RealQuaternion))
            {
                if (args.Count != 4)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float i) ||
                    !float.TryParse(args[1], out float j) ||
                    !float.TryParse(args[2], out float k) ||
                    !float.TryParse(args[3], out float w))
                {
                    return(false);
                }
                output = new RealQuaternion(i, j, k, w);
            }
            else if (type == typeof(RealPlane2d))
            {
                if (args.Count != 3)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float i) ||
                    !float.TryParse(args[1], out float j) ||
                    !float.TryParse(args[2], out float d))
                {
                    return(false);
                }
                output = new RealPlane2d(i, j, d);
            }
            else if (type == typeof(RealPlane3d))
            {
                if (args.Count != 4)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float i) ||
                    !float.TryParse(args[1], out float j) ||
                    !float.TryParse(args[2], out float k) ||
                    !float.TryParse(args[3], out float d))
                {
                    return(false);
                }
                output = new RealPlane3d(i, j, k, d);
            }
            else if (type.IsEnum)
            {
                if (args.Count != 1)
                {
                    return(false);
                }

                var query = args[0];

                object found;

                try
                {
                    found = Enum.Parse(type, query);
                }
                catch
                {
                    found = null;
                }

                var names = Enum.GetNames(type).ToList();

                if (found == null)
                {
                    var nameLow  = query.ToLower();
                    var namesLow = names.Select(i => i.ToLower()).ToList();

                    found = namesLow.Find(n => n == nameLow);

                    if (found == null)
                    {
                        var nameSnake  = query.ToSnakeCase();
                        var namesSnake = names.Select(i => i.ToSnakeCase()).ToList();
                        found = namesSnake.Find(n => n == nameSnake);

                        if (found == null)
                        {
                            Console.WriteLine("Invalid {0} enum option: {1}", type.Name, args[0]);
                            Console.WriteLine("");

                            Console.WriteLine("Valid options:");
                            foreach (var name in Enum.GetNames(type))
                            {
                                var fieldName         = $"{type.FullName}.{name}".Replace("+", ".");
                                var documentationNode = EditTagContextFactory.Documentation.SelectSingleNode($"//member[starts-with(@name, 'F:{fieldName}')]");

                                Console.WriteLine("\t{0} {1}", name,
                                                  documentationNode != null ?
                                                  $":: {documentationNode.FirstChild.InnerText.Replace("\r\n", "").TrimStart().TrimEnd()}" :
                                                  "");
                            }
                            Console.WriteLine();

                            return(false);
                        }
                        else
                        {
                            found = Enum.Parse(type, names[namesSnake.IndexOf((string)found)]);
                        }
                    }
                    else
                    {
                        found = Enum.Parse(type, names[namesLow.IndexOf((string)found)]);
                    }
                }

                output = found;
            }
            else if (type == typeof(Bounds <>))
            {
                var rangeType = type.GenericTypeArguments[0];
                var argCount  = RangeArgCount(rangeType);

                var min = ParseArgs(rangeType, null, args.Take(argCount).ToList());

                if (min.Equals(false))
                {
                    return(false);
                }

                var max = ParseArgs(rangeType, null, args.Skip(argCount).Take(argCount).ToList());

                if (max.Equals(false))
                {
                    return(false);
                }

                output = Activator.CreateInstance(type, new object[] { min, max });
            }
            else if (type.IsArray)
            {
                if (info?.FieldType == typeof(byte[]) && info?.Attribute.Length == 0)
                {   // tag_data field
                    if (args.Count != 1)
                    {
                        return(false);
                    }
                    if (input.Length % 2 != 0)
                    {
                        return(false);
                    }

                    List <byte> bytes = new List <byte>();

                    for (int i = 0; i < input.Length; i = i + 2)
                    {
                        bytes.Add(Convert.ToByte(input.Substring(i, 2), 16));
                    }

                    output = bytes.ToArray();
                }
                else
                {
                    if (info == null || args.Count != info.Attribute.Length)
                    {
                        return(false);
                    }

                    var elementType = info.FieldType.GetElementType();
                    var values      = Array.CreateInstance(elementType, info.Attribute.Length);

                    for (var i = 0; i < info.Attribute.Length; i++)
                    {
                        values.SetValue(Convert.ChangeType(ParseArgs(elementType, null, new List <string> {
                            args[i]
                        }), elementType), i);
                    }

                    return(values);
                }
            }
            else if (type == typeof(RealRgbColor))
            {
                if (args.Count != 3)
                {
                    return(false);
                }
                if (!float.TryParse(args[0], out float i) ||
                    !float.TryParse(args[1], out float j) ||
                    !float.TryParse(args[2], out float k))
                {
                    return(false);
                }
                output = new RealRgbColor(i, j, k);
            }
            else if (type == typeof(ArgbColor))
            {
                if (args.Count != 4)
                {
                    return(false);
                }
                if (!byte.TryParse(args[0], out byte i) ||
                    !byte.TryParse(args[1], out byte j) ||
                    !byte.TryParse(args[2], out byte k) ||
                    !byte.TryParse(args[3], out byte w))
                {
                    return(false);
                }
                output = new ArgbColor(i, j, k, w);
            }
            else if (type == typeof(Bounds <Angle>))
            {
                if (args.Count != 2)
                {
                    return(false);
                }

                if (!float.TryParse(args[0], out float i) ||
                    !float.TryParse(args[1], out float j))
                {
                    return(false);
                }

                output = new Bounds <Angle> {
                    Lower = Angle.FromDegrees(i), Upper = Angle.FromDegrees(j)
                };
            }
            else if (type == typeof(PageableResource))
            {
                if (args.Count < 1 || args.Count > 2)
                {
                    return(false);
                }

                if (args.Count == 1)
                {
                    switch (args[0].ToLower())
                    {
                    case "null":
                        output = null;
                        break;

                    default:
                        output = new FileInfo(args[0]);
                        if (!((FileInfo)output).Exists)
                        {
                            throw new FileNotFoundException(args[0]);
                        }
                        break;
                    }
                }
                else if (args.Count == 2)
                {
                    var resourceLocation = ResourceLocation.None;

                    switch (args[0].ToSnakeCase())
                    {
                    case "resources":
                        resourceLocation = ResourceLocation.Resources;
                        break;

                    case "textures":
                        resourceLocation = ResourceLocation.Textures;
                        break;

                    case "textures_b":
                        resourceLocation = ResourceLocation.TexturesB;
                        break;

                    case "audio":
                        resourceLocation = ResourceLocation.Audio;
                        break;

                    case "resources_b":
                        resourceLocation = ResourceLocation.ResourcesB;
                        break;

                    case "render_models" when CacheContext.Version >= CacheVersion.HaloOnline235640:
                        resourceLocation = ResourceLocation.RenderModels;
                        break;

                    case "lightmaps" when CacheContext.Version >= CacheVersion.HaloOnline235640:
                        resourceLocation = ResourceLocation.Lightmaps;
                        break;

                    default:
                        throw new FormatException($"Invalid resource location: {args[0]}");
                    }

                    var resourceFile = new FileInfo(args[1]);

                    if (!resourceFile.Exists)
                    {
                        throw new FileNotFoundException(args[1]);
                    }

                    output = (resourceLocation, resourceFile);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else
            {
                Console.WriteLine($"ERROR: Not Implemented.");
                return(false);
                // throw new NotImplementedException();
            }

            return(output);
        }
Exemplo n.º 9
0
 private void SerializePoint(IDataBlock block, RealPoint3d point)
 {
     block.Writer.Write(point.X);
     block.Writer.Write(point.Y);
     block.Writer.Write(point.Z);
 }
Exemplo n.º 10
0
        public override object Execute(List <string> args)
        {
            if (args.Count != 1)
            {
                return(false);
            }

            var file = new FileInfo(args[0]);

            if (!file.Directory.Exists)
            {
                file.Directory.Create();
            }

            using (var writer = new StreamWriter(file.Create()))
            {
                var baseVertex = 0;

                foreach (var region in Definition.Regions)
                {
                    var regionName = Cache.StringTable.GetString(region.Name);

                    foreach (var permutation in region.Permutations)
                    {
                        var permutationName = Cache.StringTable.GetString(permutation.Name);

                        foreach (var collisionBsp in permutation.Bsps)
                        {
                            var offset = new RealPoint3d();

                            for (var i = 0; i < collisionBsp.Geometry.Vertices.Count; i++)
                            {
                                var v = offset + collisionBsp.Geometry.Vertices[i].Point;
                                writer.WriteLine($"v {v.X} {v.Z} {v.Y}");
                            }

                            writer.WriteLine($"g {regionName}:{permutationName}");

                            for (var i = 0; i < collisionBsp.Geometry.Surfaces.Count; i++)
                            {
                                var surface = collisionBsp.Geometry.Surfaces[i];
                                var edge    = collisionBsp.Geometry.Edges[surface.FirstEdge];

                                writer.Write("f");

                                while (true)
                                {
                                    if (edge.LeftSurface == i)
                                    {
                                        writer.Write($" {baseVertex + edge.StartVertex + 1}");

                                        if (edge.ForwardEdge == surface.FirstEdge)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            edge = collisionBsp.Geometry.Edges[edge.ForwardEdge];
                                        }
                                    }
                                    else if (edge.RightSurface == i)
                                    {
                                        writer.Write($" {baseVertex + edge.EndVertex + 1}");

                                        if (edge.ReverseEdge == surface.FirstEdge)
                                        {
                                            break;
                                        }
                                        else
                                        {
                                            edge = collisionBsp.Geometry.Edges[edge.ReverseEdge];
                                        }
                                    }
                                }

                                writer.WriteLine();
                            }

                            baseVertex += collisionBsp.Geometry.Vertices.Count;
                        }
                    }
                }
            }

            return(true);
        }
Exemplo n.º 11
0
        public RenderModel GenerateGen3RenderModel(GameCache cache)
        {
            RenderModel mode = new RenderModel();

            mode.Name = AddStringId(cache, Name);

            // set materials
            mode.Materials = new List <RenderMaterial>();
            for (int i = 0; i < Materials.Count; i++)
            {
                mode.Materials.Add(new RenderMaterial());
                Console.WriteLine($"Render material {i} is {Materials[i].Name}");
            }

            // set nodes
            mode.Nodes = new List <RenderModel.Node>();
            mode.RuntimeNodeOrientations = new List <RenderModel.RuntimeNodeOrientation>();

            for (int i = 0; i < Nodes.Count; i++)
            {
                var node = Nodes[i];
                var quat = node.Rotation.Normalize();

                float sqw = quat.W * quat.W;
                float sqx = quat.I * quat.I;
                float sqy = quat.J * quat.J;
                float sqz = quat.K * quat.K;
                // use quaternion -> rotation matrix instead later on
                RealVector3d inverseForward = new RealVector3d((sqx - sqy - sqz + sqw), 2.0f * (quat.I * quat.J - quat.K * quat.W), 2.0f * (quat.I * quat.K + quat.J * quat.W));
                RealVector3d inverseLeft    = new RealVector3d(2.0f * (quat.I * quat.J + quat.K * quat.W), (-sqx + sqy - sqz + sqw), 2.0f * (quat.J * quat.K - quat.I * quat.W));
                RealVector3d inverseUp      = new RealVector3d(2.0f * (quat.I * quat.K - quat.J * quat.W), 2.0f * (quat.J * quat.K + quat.I * quat.W), (-sqx - sqy + sqz + sqw));

                mode.Nodes.Add(new RenderModel.Node
                {
                    Name               = AddStringId(cache, node.Name),
                    ParentNode         = (short)node.ParentNodeIndex,
                    FirstChildNode     = (short)node.FirstChildNodeIndex,
                    NextSiblingNode    = (short)node.NextSiblingNodeIndex,
                    Flags              = RenderModel.NodeFlags.None,
                    DefaultTranslation = node.Translation,
                    DefaultRotation    = node.Rotation,
                    DefaultScale       = node.Scale,

                    InverseForward  = inverseForward,
                    InverseLeft     = inverseLeft,
                    InverseUp       = inverseUp,
                    InversePosition = -1 * node.Translation,

                    DistanceFromParent = i == 0 ? 0.0f : RealPoint3d.Distance(node.Translation - Nodes[node.ParentNodeIndex].Translation)
                });



                mode.RuntimeNodeOrientations.Add(new RenderModel.RuntimeNodeOrientation
                {
                    Rotation    = node.Rotation,
                    Scale       = node.Scale,
                    Translation = node.Translation
                });
            }

            // set lighting

            mode.UnknownSHProbes = new List <RenderModel.UnknownSHProbe>();
            mode.SHBlue          = DefaultLighting.SHBlue;
            mode.SHRed           = DefaultLighting.SHRed;
            mode.SHGreen         = DefaultLighting.SHGreen;
            foreach (var lightProbe in LightProbes)
            {
                mode.UnknownSHProbes.Add(new RenderModel.UnknownSHProbe
                {
                    Position     = lightProbe.Position,
                    Coefficients = lightProbe.Coefficients
                });
            }

            // set permutations\region\meshes\markers
            mode.Regions = new List <RenderModel.Region>();
            foreach (var bmfRegion in Regions)
            {
                var newRegion = new RenderModel.Region
                {
                    Name         = AddStringId(cache, bmfRegion.Name),
                    Permutations = new List <RenderModel.Region.Permutation>()
                };
                mode.Regions.Add(newRegion);
            }

            mode.Geometry = new RenderGeometry();

            mode.Geometry.Meshes = new List <Mesh>();

            foreach (var bmfMesh in Meshes)
            {
                Mesh newMesh = new Mesh();

                // add new permutation
                mode.Regions[bmfMesh.RegionIndex].Permutations.Append(new RenderModel.Region.Permutation
                {
                    Name      = AddStringId(cache, bmfMesh.Name),
                    MeshCount = 1,
                    MeshIndex = (short)mode.Geometry.Meshes.Count
                });
            }

            return(mode);
        }