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)); } }
private void AddPrematchCamera(RealPoint3d position, RealEulerAngles3d rotation) { Scnr.CutsceneCameraPoints.Add(new CutsceneCameraPoint() { Position = position, Orientation = rotation, Flags = CutsceneCameraPointFlags.PrematchCameraHack, Name = "prematch_camera", }); }
public void SetFieldValue(object owner, object value = null, object definition = null) { if (Loading || owner == null) { return; } if (value == null) { if (!float.TryParse(yawTextBox.Text, out var yaw) || !float.TryParse(pitchTextBox.Text, out var pitch) || !float.TryParse(rollTextBox.Text, out var roll)) { return; } value = new RealEulerAngles3d(Angle.FromDegrees(yaw), Angle.FromDegrees(pitch), Angle.FromDegrees(roll)); } Field.SetValue(owner, value); }
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") }); }
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; } } } } }
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); }
private void SerializeEulerAngles(IDataBlock block, RealEulerAngles3d angles) { block.Writer.Write(angles.Yaw.Radians); block.Writer.Write(angles.Pitch.Radians); block.Writer.Write(angles.Roll.Radians); }