diff --git a/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs index 72fa115..6c211b4 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs @@ -327,8 +327,8 @@ namespace CodeWalker.GameFiles public BoundsStoreItem(Bounds b) { Name = 0; - Min = b.BoundingBoxMin; - Max = b.BoundingBoxMax; + Min = b.BoxMin; + Max = b.BoxMax; Layer = 0; } public BoundsStoreItem(BinaryReader br) diff --git a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs index d8f47b3..545e76f 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs @@ -11,6 +11,11 @@ namespace CodeWalker.GameFiles { public Bounds Bounds { get; set; } + + //used by the editor: + public bool HasChanged { get; set; } = false; + + public YbnFile() : base(null, GameFileType.Ybn) { } @@ -18,6 +23,14 @@ namespace CodeWalker.GameFiles { } + public void Load(byte[] data) + { + //direct load from a raw, compressed ybn file + + RpfFile.LoadResourceFile(this, data, 43); + + Loaded = true; + } public void Load(byte[] data, RpfFileEntry entry) { @@ -36,6 +49,7 @@ namespace CodeWalker.GameFiles Bounds = rd.ReadBlock(); + Bounds.OwnerYbn = this; Bounds.OwnerName = entry.Name; Loaded = true; diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs index 84ee29c..ce70644 100644 --- a/CodeWalker.Core/GameFiles/GameFileCache.cs +++ b/CodeWalker.Core/GameFiles/GameFileCache.cs @@ -3171,9 +3171,9 @@ namespace CodeWalker.GameFiles } public void TestYcds() { + bool savetest = false; var errorfiles = new List(); var errorentries = new List(); - foreach (RpfFile file in AllRpfs) { foreach (RpfEntry entry in file.AllEntries) @@ -3192,17 +3192,13 @@ namespace CodeWalker.GameFiles { errorfiles.Add(ycd1);//these ones have file corruption issues and won't load as resource... } - else + else if (savetest) { if (ycd1.ClipDictionary == null) { continue; } //var data1 = ycd1.Save(); - var t = true; - if (t)//just here to test loading only - { continue; } - var xml = YcdXml.GetXml(ycd1); var ycdX = XmlYcd.GetYcd(xml); var data = ycdX.Save(); @@ -3444,6 +3440,7 @@ namespace CodeWalker.GameFiles } public void TestYtds() { + bool savetest = false; var errorfiles = new List(); foreach (RpfFile file in AllRpfs) { @@ -3464,7 +3461,7 @@ namespace CodeWalker.GameFiles UpdateStatus("Error! " + ex.ToString()); errorfiles.Add(entry); } - if ((ytdfile != null) && (ytdfile.TextureDict != null)) + if (savetest && (ytdfile != null) && (ytdfile.TextureDict != null)) { var fentry = entry as RpfFileEntry; if (fentry == null) @@ -3519,6 +3516,7 @@ namespace CodeWalker.GameFiles } public void TestYbns() { + bool savetest = false; var errorfiles = new List(); foreach (RpfFile file in AllRpfs) { @@ -3539,7 +3537,7 @@ namespace CodeWalker.GameFiles UpdateStatus("Error! " + ex.ToString()); errorfiles.Add(entry); } - if ((ybn != null) && (ybn.Bounds != null)) + if (savetest && (ybn != null) && (ybn.Bounds != null)) { var fentry = entry as RpfFileEntry; if (fentry == null) @@ -3562,7 +3560,7 @@ namespace CodeWalker.GameFiles //quick check of roundtrip switch (ybn2.Bounds.Type) { - case 0: //return new BoundSphere(); + case BoundsType.Sphere: { var a = ybn.Bounds as BoundSphere; var b = ybn2.Bounds as BoundSphere; @@ -3570,7 +3568,7 @@ namespace CodeWalker.GameFiles { continue; } break; } - case 1: //return new BoundCapsule(); + case BoundsType.Capsule: { var a = ybn.Bounds as BoundCapsule; var b = ybn2.Bounds as BoundCapsule; @@ -3578,7 +3576,7 @@ namespace CodeWalker.GameFiles { continue; } break; } - case 3: //return new BoundBox(); + case BoundsType.Box: { var a = ybn.Bounds as BoundBox; var b = ybn2.Bounds as BoundBox; @@ -3586,7 +3584,7 @@ namespace CodeWalker.GameFiles { continue; } break; } - case 4: //return new BoundGeometry(); + case BoundsType.Geometry: { var a = ybn.Bounds as BoundGeometry; var b = ybn2.Bounds as BoundGeometry; @@ -3603,7 +3601,7 @@ namespace CodeWalker.GameFiles } break; } - case 8: //return new BoundBVH(); + case BoundsType.GeometryBVH: { var a = ybn.Bounds as BoundBVH; var b = ybn2.Bounds as BoundBVH; @@ -3622,7 +3620,7 @@ namespace CodeWalker.GameFiles } break; } - case 10: //return new BoundComposite(); + case BoundsType.Composite: { var a = ybn.Bounds as BoundComposite; var b = ybn2.Bounds as BoundComposite; @@ -3632,7 +3630,7 @@ namespace CodeWalker.GameFiles { } break; } - case 12: //return new BoundDisc(); + case BoundsType.Disc: { var a = ybn.Bounds as BoundDisc; var b = ybn2.Bounds as BoundDisc; @@ -3640,7 +3638,7 @@ namespace CodeWalker.GameFiles { continue; } break; } - case 13: //return new BoundCylinder(); + case BoundsType.Cylinder: { var a = ybn.Bounds as BoundCylinder; var b = ybn2.Bounds as BoundCylinder; @@ -3648,7 +3646,14 @@ namespace CodeWalker.GameFiles { continue; } break; } - case 15: //return null; //TODO: find out what this is! + case BoundsType.Cloth: + { + var a = ybn.Bounds as BoundCloth; + var b = ybn2.Bounds as BoundCloth; + if (b == null) + { continue; } + break; + } default: //return null; // throw new Exception("Unknown bound type"); break; } @@ -3669,6 +3674,7 @@ namespace CodeWalker.GameFiles } public void TestYdrs() { + bool savetest = false; var errorfiles = new List(); foreach (RpfFile file in AllRpfs) { @@ -3689,7 +3695,7 @@ namespace CodeWalker.GameFiles UpdateStatus("Error! " + ex.ToString()); errorfiles.Add(entry); } - if ((ydr != null) && (ydr.Drawable != null)) + if (savetest && (ydr != null) && (ydr.Drawable != null)) { var fentry = entry as RpfFileEntry; if (fentry == null) @@ -3722,6 +3728,7 @@ namespace CodeWalker.GameFiles } public void TestYdds() { + bool savetest = false; var errorfiles = new List(); foreach (RpfFile file in AllRpfs) { @@ -3742,7 +3749,7 @@ namespace CodeWalker.GameFiles UpdateStatus("Error! " + ex.ToString()); errorfiles.Add(entry); } - if ((ydd != null) && (ydd.DrawableDict != null)) + if (savetest && (ydd != null) && (ydd.DrawableDict != null)) { var fentry = entry as RpfFileEntry; if (fentry == null) @@ -3776,8 +3783,7 @@ namespace CodeWalker.GameFiles } public void TestYfts() { - bool savetest = true; - + bool savetest = false; var errorfiles = new List(); foreach (RpfFile file in AllRpfs) { @@ -3798,14 +3804,12 @@ namespace CodeWalker.GameFiles UpdateStatus("Error! " + ex.ToString()); errorfiles.Add(entry); } - if ((yft != null) && (yft.Fragment != null)) + if (savetest && (yft != null) && (yft.Fragment != null)) { var fentry = entry as RpfFileEntry; if (fentry == null) { continue; } //shouldn't happen - if (!savetest) continue; - var bytes = yft.Save(); diff --git a/CodeWalker.Core/GameFiles/Resources/Bounds.cs b/CodeWalker.Core/GameFiles/Resources/Bounds.cs index 64f7138..bea721c 100644 --- a/CodeWalker.Core/GameFiles/Resources/Bounds.cs +++ b/CodeWalker.Core/GameFiles/Resources/Bounds.cs @@ -97,6 +97,19 @@ namespace CodeWalker.GameFiles } } + public enum BoundsType : byte + { + Sphere = 0, + Capsule = 1, + Box = 3, + Geometry = 4, + GeometryBVH = 8, + Composite = 10, + Disc = 12, + Cylinder = 13, + Cloth = 15, + } + [TC(typeof(EXP))] public class Bounds : ResourceFileBase, IResourceXXSystemBlock { public override long BlockLength @@ -105,32 +118,54 @@ namespace CodeWalker.GameFiles } // structure data - public byte Type { get; set; } - public byte Unknown_11h { get; set; } - public ushort Unknown_12h { get; set; } - public float BoundingSphereRadius { get; set; } - public uint Unknown_18h { get; set; } - public uint Unknown_1Ch { get; set; } - public Vector3 BoundingBoxMax { get; set; } + public BoundsType Type { get; set; } + public byte Unknown_11h { get; set; } // 0x00000000 + public ushort Unknown_12h { get; set; } // 0x00000000 + public float SphereRadius { get; set; } + public uint Unknown_18h { get; set; } // 0x00000000 + public uint Unknown_1Ch { get; set; } // 0x00000000 + public Vector3 BoxMax { get; set; } public float Margin { get; set; } - public Vector3 BoundingBoxMin { get; set; } - public uint Unknown_3Ch { get; set; } - public Vector3 BoundingBoxCenter { get; set; } + public Vector3 BoxMin { get; set; } + public uint Unknown_3Ch { get; set; } = 1; //1, 2 (yft only) + public Vector3 BoxCenter { get; set; } public byte MaterialIndex { get; set; } public byte ProceduralId { get; set; } public byte RoomId_and_PedDensity { get; set; } //5bits for RoomID and then 3bits for PedDensity - public byte Unknown_4Fh { get; set; } //flags? (bit5 related to Unknown_5Ch, should be a flag called "Has PolyFlags")<-- i don't remember why i wrote this lol - public Vector3 Center { get; set; } + public byte UnkFlags { get; set; } // (bit5 related to PolyFlags, should be a flag called "Has PolyFlags")[check this?] + public Vector3 SphereCenter { get; set; } public byte PolyFlags { get; set; } public byte MaterialColorIndex { get; set; } - public ushort Unknown_5Eh { get; set; } - public float Unknown_60h { get; set; } - public float Unknown_64h { get; set; } - public float Unknown_68h { get; set; } - public float BoundingBoxVolume { get; set; } + public ushort Unknown_5Eh { get; set; } // 0x00000000 + public Vector3 Unknown_60h { get; set; } + public float Volume { get; set; } + public byte RoomId + { + get + { + return (byte)(RoomId_and_PedDensity & 0x1F); + } + set + { + RoomId_and_PedDensity = (byte)((RoomId_and_PedDensity & 0xE0) + (value & 0x1F)); + } + } + public byte PedDensity + { + get + { + return (byte)(RoomId_and_PedDensity >> 5); + } + set + { + RoomId_and_PedDensity = (byte)((RoomId_and_PedDensity & 0x1F) + ((value & 0x7) << 5)); + } + } + public bool HasChanged { get; set; } = false; public BoundComposite Parent { get; set; } + public YbnFile OwnerYbn { get; set; } public string OwnerName { get; set; } public string GetName() { @@ -143,6 +178,23 @@ namespace CodeWalker.GameFiles } return n; } + public string GetTitle() + { + var n = GetName(); + var t = Type.ToString(); + return t + ": " + n; + } + public YbnFile GetRootYbn() + { + var r = OwnerYbn; + var p = Parent; + while ((p != null) && (r == null)) + { + r = p.OwnerYbn; + p = p.Parent; + } + return r; + } public Matrix Transform { get; set; } = Matrix.Identity; //when it's the child of a bound composite public Matrix TransformInv { get; set; } = Matrix.Identity; @@ -199,29 +251,106 @@ namespace CodeWalker.GameFiles base.Read(reader, parameters); // read structure data - this.Type = reader.ReadByte(); + this.Type = (BoundsType)reader.ReadByte(); this.Unknown_11h = reader.ReadByte(); this.Unknown_12h = reader.ReadUInt16(); - this.BoundingSphereRadius = reader.ReadSingle(); + this.SphereRadius = reader.ReadSingle(); this.Unknown_18h = reader.ReadUInt32(); this.Unknown_1Ch = reader.ReadUInt32(); - this.BoundingBoxMax = reader.ReadStruct(); + this.BoxMax = reader.ReadVector3(); this.Margin = reader.ReadSingle(); - this.BoundingBoxMin = reader.ReadStruct(); + this.BoxMin = reader.ReadVector3(); this.Unknown_3Ch = reader.ReadUInt32(); - this.BoundingBoxCenter = reader.ReadStruct(); + this.BoxCenter = reader.ReadVector3(); this.MaterialIndex = reader.ReadByte(); this.ProceduralId = reader.ReadByte(); this.RoomId_and_PedDensity = reader.ReadByte(); - this.Unknown_4Fh = reader.ReadByte(); - this.Center = reader.ReadStruct(); + this.UnkFlags = reader.ReadByte(); + this.SphereCenter = reader.ReadVector3(); this.PolyFlags = reader.ReadByte(); this.MaterialColorIndex = reader.ReadByte(); this.Unknown_5Eh = reader.ReadUInt16(); - this.Unknown_60h = reader.ReadSingle(); - this.Unknown_64h = reader.ReadSingle(); - this.Unknown_68h = reader.ReadSingle(); - this.BoundingBoxVolume = reader.ReadSingle(); + this.Unknown_60h = reader.ReadVector3(); + this.Volume = reader.ReadSingle(); + + if (Unknown_11h != 0) + { } + if (Unknown_12h != 0) + { } + if (Unknown_18h != 0) + { } + if (Unknown_1Ch != 0) + { } + if (Unknown_5Eh != 0) + { } + + + switch (Unknown_3Ch) + { + case 1: + case 2: // only found in .yft + break; + default: + break; + } + switch (UnkFlags)//yeah it's probably flags + { + case 0://for all .ybn files + case 26: //v_corp_banktrolley.ydr + case 18: //v_corp_banktrolley.ydr + case 16: //v_corp_banktrolley.ydr + case 2: //v_corp_bk_bust.ydr + case 10: //v_corp_bk_bust.ydr + case 130://v_corp_bk_chair2.ydr + case 30: //v_corp_bk_flag.ydr + case 144://v_corp_bombbin.ydr + case 8: //v_corp_conftable2.ydr + case 12: //v_corp_conftable3.ydr + case 4: //v_corp_cubiclefd.ydr + case 22: //v_corp_hicksdoor.ydr + case 150://v_corp_hicksdoor.ydr + case 128://v_corp_officedesk003.ydr + case 24: //v_corp_potplant1.ydr + case 14: //v_ind_cm_aircomp.ydr + case 146://v_ind_rc_rubbish.ydr + case 134://v_ilev_bk_door.ydr + case 64: //v_ilev_carmod3lamp.ydr + case 28: //v_ilev_cbankvaulgate02.ydr + case 132://v_ilev_ch_glassdoor.ydr + case 6: //v_ilev_cs_door01.ydr + case 20: //v_ilev_fib_atrgl1s.ydr + case 94: //v_ilev_uvcheetah.ydr + case 148://v_serv_metro_elecpole_singlel.ydr + case 48: //v_serv_metro_statseat1.ydr + case 50: //v_serv_securitycam_03.ydr + case 80: //prop_bmu_02_ld.ydr + case 92: //prop_bmu_02_ld.ydr + case 82: //prop_roofvent_08a.ydr + case 1: //prop_portasteps_02.ydr + case 65: //prop_storagetank_01_cr.ydr + case 90: //prop_storagetank_01_cr.ydr + case 68: //prop_sub_frame_01a.ydr + case 66: //prop_ld_cable.ydr + case 78: //prop_ld_cable.ydr + case 72: //prop_snow_oldlight_01b.ydr + case 13: //prop_conslift_steps.ydr + case 86: //prop_scafold_01a.ydr + case 84: //prop_scafold_04a.ydr + case 76: //prop_fruitstand_b_nite.ydr + case 88: //prop_telegwall_01a.ydr + case 17: //prop_air_stair_04a_cr.ydr + case 196://prop_dock_rtg_ld.ydr + case 70: //prop_fnclink_02gate5.ydr + case 214://prop_facgate_04_l.ydr + case 198://prop_fncsec_01a.ydr + case 210://prop_rub_cardpile_01.yft + case 212://prop_streetlight_01b.yft + case 208://prop_streetlight_03e.yft + break; + default: + break; + } + } /// @@ -232,48 +361,46 @@ namespace CodeWalker.GameFiles base.Write(writer, parameters); // write structure data - writer.Write(this.Type); + writer.Write((byte)this.Type); writer.Write(this.Unknown_11h); writer.Write(this.Unknown_12h); - writer.Write(this.BoundingSphereRadius); + writer.Write(this.SphereRadius); writer.Write(this.Unknown_18h); writer.Write(this.Unknown_1Ch); - writer.Write(this.BoundingBoxMax); + writer.Write(this.BoxMax); writer.Write(this.Margin); - writer.Write(this.BoundingBoxMin); + writer.Write(this.BoxMin); writer.Write(this.Unknown_3Ch); - writer.Write(this.BoundingBoxCenter); + writer.Write(this.BoxCenter); writer.Write(this.MaterialIndex); writer.Write(this.ProceduralId); writer.Write(this.RoomId_and_PedDensity); - writer.Write(this.Unknown_4Fh); - writer.Write(this.Center); + writer.Write(this.UnkFlags); + writer.Write(this.SphereCenter); writer.Write(this.PolyFlags); writer.Write(this.MaterialColorIndex); writer.Write(this.Unknown_5Eh); writer.Write(this.Unknown_60h); - writer.Write(this.Unknown_64h); - writer.Write(this.Unknown_68h); - writer.Write(this.BoundingBoxVolume); + writer.Write(this.Volume); } public IResourceSystemBlock GetType(ResourceDataReader reader, params object[] parameters) { reader.Position += 16; - var type = reader.ReadByte(); + var type = (BoundsType)reader.ReadByte(); reader.Position -= 17; switch (type) { - case 0: return new BoundSphere(); - case 1: return new BoundCapsule(); - case 3: return new BoundBox(); - case 4: return new BoundGeometry(); - case 8: return new BoundBVH(); - case 10: return new BoundComposite(); - case 12: return new BoundDisc(); - case 13: return new BoundCylinder(); - case 15: return null; //TODO: find out what this is! + case BoundsType.Sphere: return new BoundSphere(); + case BoundsType.Capsule: return new BoundCapsule(); + case BoundsType.Box: return new BoundBox(); + case BoundsType.Geometry: return new BoundGeometry(); + case BoundsType.GeometryBVH: return new BoundBVH(); + case BoundsType.Composite: return new BoundComposite(); + case BoundsType.Disc: return new BoundDisc(); + case BoundsType.Cylinder: return new BoundCylinder(); + case BoundsType.Cloth: return new BoundCloth(); default: return null; // throw new Exception("Unknown bound type"); } } @@ -295,12 +422,12 @@ namespace CodeWalker.GameFiles { var res = new SpaceSphereIntersectResult(); var bsph = new BoundingSphere(); - bsph.Center = Center; - bsph.Radius = BoundingSphereRadius; + bsph.Center = SphereCenter; + bsph.Radius = SphereRadius; if (sph.Intersects(ref bsph)) { res.Hit = true; - res.Normal = Vector3.Normalize(sph.Center - Center); + res.Normal = Vector3.Normalize(sph.Center - SphereCenter); } return res; } @@ -308,8 +435,8 @@ namespace CodeWalker.GameFiles { var res = new SpaceRayIntersectResult(); var bsph = new BoundingSphere(); - bsph.Center = Center; - bsph.Radius = BoundingSphereRadius; + bsph.Center = SphereCenter; + bsph.Radius = SphereRadius; float testdist; if (ray.Intersects(ref bsph, out testdist) && (testdist < maxdist)) { @@ -317,7 +444,7 @@ namespace CodeWalker.GameFiles res.HitDist = testdist; res.HitBounds = this; res.Position = ray.Position + ray.Direction * testdist; - res.Normal = Vector3.Normalize(res.Position - Center); + res.Normal = Vector3.Normalize(res.Position - SphereCenter); res.Material.Type = MaterialIndex; } return res; @@ -361,9 +488,9 @@ namespace CodeWalker.GameFiles { var res = new SpaceSphereIntersectResult(); var bcap = new BoundingCapsule(); - var extent = new Vector3(0, BoundingSphereRadius - Margin, 0); - bcap.PointA = Center - extent; - bcap.PointB = Center + extent; + var extent = new Vector3(0, SphereRadius - Margin, 0); + bcap.PointA = SphereCenter - extent; + bcap.PointB = SphereCenter + extent; bcap.Radius = Margin; if (sph.Intersects(ref bcap, out res.Normal)) { @@ -375,9 +502,9 @@ namespace CodeWalker.GameFiles { var res = new SpaceRayIntersectResult(); var bcap = new BoundingCapsule(); - var extent = new Vector3(0, BoundingSphereRadius - Margin, 0); - bcap.PointA = Center - extent; - bcap.PointB = Center + extent; + var extent = new Vector3(0, SphereRadius - Margin, 0); + bcap.PointA = SphereCenter - extent; + bcap.PointB = SphereCenter + extent; bcap.Radius = Margin; float testdist; if (ray.Intersects(ref bcap, out testdist) && (testdist < maxdist)) @@ -397,19 +524,19 @@ namespace CodeWalker.GameFiles public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph) { var res = new SpaceSphereIntersectResult(); - var bbox = new BoundingBox(BoundingBoxMin, BoundingBoxMax); + var bbox = new BoundingBox(BoxMin, BoxMax); if (sph.Intersects(ref bbox)) { var sphmin = sph.Center - sph.Radius; var sphmax = sph.Center + sph.Radius; var n = Vector3.Zero; float eps = sph.Radius * 0.8f; - if (Math.Abs(sphmax.X - BoundingBoxMin.X) < eps) n -= Vector3.UnitX; - else if (Math.Abs(sphmin.X - BoundingBoxMax.X) < eps) n += Vector3.UnitX; - else if (Math.Abs(sphmax.Y - BoundingBoxMin.Y) < eps) n -= Vector3.UnitY; - else if (Math.Abs(sphmin.Y - BoundingBoxMax.Y) < eps) n += Vector3.UnitY; - else if (Math.Abs(sphmax.Z - BoundingBoxMin.Z) < eps) n -= Vector3.UnitZ; - else if (Math.Abs(sphmin.Z - BoundingBoxMax.Z) < eps) n += Vector3.UnitZ; + if (Math.Abs(sphmax.X - BoxMin.X) < eps) n -= Vector3.UnitX; + else if (Math.Abs(sphmin.X - BoxMax.X) < eps) n += Vector3.UnitX; + else if (Math.Abs(sphmax.Y - BoxMin.Y) < eps) n -= Vector3.UnitY; + else if (Math.Abs(sphmin.Y - BoxMax.Y) < eps) n += Vector3.UnitY; + else if (Math.Abs(sphmax.Z - BoxMin.Z) < eps) n -= Vector3.UnitZ; + else if (Math.Abs(sphmin.Z - BoxMax.Z) < eps) n += Vector3.UnitZ; else { n = Vector3.UnitZ; } //ray starts inside the box... res.Normal = Vector3.Normalize(n); @@ -420,19 +547,19 @@ namespace CodeWalker.GameFiles public override SpaceRayIntersectResult RayIntersect(ref Ray ray, float maxdist = float.MaxValue) { var res = new SpaceRayIntersectResult(); - var bbox = new BoundingBox(BoundingBoxMin, BoundingBoxMax); + var bbox = new BoundingBox(BoxMin, BoxMax); float testdist; if (ray.Intersects(ref bbox, out testdist) && (testdist < maxdist)) { const float eps = 0.002f; var n = Vector3.Zero; var hpt = ray.Position + ray.Direction * testdist; - if (Math.Abs(hpt.X - BoundingBoxMin.X) < eps) n = -Vector3.UnitX; - else if (Math.Abs(hpt.X - BoundingBoxMax.X) < eps) n = Vector3.UnitX; - else if (Math.Abs(hpt.Y - BoundingBoxMin.Y) < eps) n = -Vector3.UnitY; - else if (Math.Abs(hpt.Y - BoundingBoxMax.Y) < eps) n = Vector3.UnitY; - else if (Math.Abs(hpt.Z - BoundingBoxMin.Z) < eps) n = -Vector3.UnitZ; - else if (Math.Abs(hpt.Z - BoundingBoxMax.Z) < eps) n = Vector3.UnitZ; + if (Math.Abs(hpt.X - BoxMin.X) < eps) n = -Vector3.UnitX; + else if (Math.Abs(hpt.X - BoxMax.X) < eps) n = Vector3.UnitX; + else if (Math.Abs(hpt.Y - BoxMin.Y) < eps) n = -Vector3.UnitY; + else if (Math.Abs(hpt.Y - BoxMax.Y) < eps) n = Vector3.UnitY; + else if (Math.Abs(hpt.Z - BoxMin.Z) < eps) n = -Vector3.UnitZ; + else if (Math.Abs(hpt.Z - BoxMax.Z) < eps) n = Vector3.UnitZ; else { n = Vector3.UnitZ; } //ray starts inside the box... res.Hit = true; @@ -484,12 +611,12 @@ namespace CodeWalker.GameFiles //as a temporary hack, just use the sphere-sphere intersection //TODO: sphere-disc intersection var res = new SpaceSphereIntersectResult(); var bsph = new BoundingSphere(); - bsph.Center = Center; - bsph.Radius = BoundingSphereRadius; + bsph.Center = SphereCenter; + bsph.Radius = SphereRadius; if (sph.Intersects(ref bsph)) { res.Hit = true; - res.Normal = Vector3.Normalize(sph.Center - Center); + res.Normal = Vector3.Normalize(sph.Center - SphereCenter); } return res; } @@ -498,9 +625,9 @@ namespace CodeWalker.GameFiles var res = new SpaceRayIntersectResult(); var bcyl = new BoundingCylinder(); var size = new Vector3(Margin, 0, 0); - bcyl.PointA = Center - size; - bcyl.PointB = Center + size; - bcyl.Radius = BoundingSphereRadius; + bcyl.PointA = SphereCenter - size; + bcyl.PointB = SphereCenter + size; + bcyl.Radius = SphereRadius; Vector3 n; float testdist; if (ray.Intersects(ref bcyl, out testdist, out n) && (testdist < maxdist)) @@ -554,10 +681,10 @@ namespace CodeWalker.GameFiles //as a temporary hack, just use the sphere-capsule intersection //TODO: sphere-cylinder intersection var res = new SpaceSphereIntersectResult(); var bcap = new BoundingCapsule(); - var extent = (BoundingBoxMax - BoundingBoxMin).Abs(); + var extent = (BoxMax - BoxMin).Abs(); var size = new Vector3(0, extent.Y * 0.5f, 0); - bcap.PointA = Center - size; - bcap.PointB = Center + size; + bcap.PointA = SphereCenter - size; + bcap.PointB = SphereCenter + size; bcap.Radius = extent.X * 0.5f; if (sph.Intersects(ref bcap, out res.Normal)) { @@ -569,10 +696,10 @@ namespace CodeWalker.GameFiles { var res = new SpaceRayIntersectResult(); var bcyl = new BoundingCylinder(); - var extent = (BoundingBoxMax - BoundingBoxMin).Abs(); + var extent = (BoxMax - BoxMin).Abs(); var size = new Vector3(0, extent.Y * 0.5f, 0); - bcyl.PointA = Center - size; - bcyl.PointB = Center + size; + bcyl.PointA = SphereCenter - size; + bcyl.PointB = SphereCenter + size; bcyl.Radius = extent.X * 0.5f; Vector3 n; float testdist; @@ -588,6 +715,67 @@ namespace CodeWalker.GameFiles return res; } } + [TC(typeof(EXP))] public class BoundCloth : Bounds + { + //public override long BlockLength + //{ + // get { return 128; } + //} + + //// TODO! length currently unknown! + //public uint Unknown_70h { get; set; } + //public uint Unknown_74h { get; set; } + //public uint Unknown_78h { get; set; } + //public uint Unknown_7Ch { get; set; } + + + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + //// read structure data + //this.Unknown_70h = reader.ReadUInt32(); + //this.Unknown_74h = reader.ReadUInt32(); + //this.Unknown_78h = reader.ReadUInt32(); + //this.Unknown_7Ch = reader.ReadUInt32(); + + + // found in eg: + //dt1_16_build4_cloth11.yft + //dt1_16_build4_cloth12.yft + //dt1_16_build4_cloth8.yft + //dt1_16_build4_clothb.yft + //dt1_17_cloth1.yft + //dt1_17_cloth1b.yft + //dt1_17_cloth3.yft + //dt1_21_dtzz_cloth_a.yft + //dt1_21_dtzz_cloth_b.yft + //dt1_21_dtzz_cloth_bx.yft + //dt1_21_dtzz_cloth_c.yft + //dt1_21_dtzz_cloth_d.yft + } + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + //// write structure data + //writer.Write(this.Unknown_70h); + //writer.Write(this.Unknown_74h); + //writer.Write(this.Unknown_78h); + //writer.Write(this.Unknown_7Ch); + } + + public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph) + { + var res = new SpaceSphereIntersectResult(); //TODO... + return res; + } + public override SpaceRayIntersectResult RayIntersect(ref Ray ray, float maxdist = float.MaxValue) + { + var res = new SpaceRayIntersectResult(); //TODO... + return res; + } + } [TC(typeof(EXP))] public class BoundGeometry : Bounds { public override long BlockLength @@ -596,10 +784,11 @@ namespace CodeWalker.GameFiles } // structure data - public uint Unknown_70h { get; set; } - public uint Unknown_74h { get; set; } + public uint Unknown_70h { get; set; } // 0x00000000 + public uint Unknown_74h { get; set; } // 0x00000000 public ulong Unknown_78h_Pointer { get; set; } - public uint Unknown_80h { get; set; } + public ushort Unknown_80h { get; set; } // 0x0000 + public ushort Unknown_82h { get; set; } //des_.ydr's? some extra data to read..?? is this some extra poly count? public uint Count1 { get; set; } public ulong PolygonsPointer { get; set; } public Vector3 Quantum { get; set; } @@ -640,7 +829,7 @@ namespace CodeWalker.GameFiles public Vector3[] Vertices { get; set; } public uint[] Unknown_B8h_Data { get; set; } public uint[] Unknown_C0h_Data { get; set; } - public BoundUnknown1 Unknown_C8h_Data { get; set; } + public BoundGeomUnknown1 Unknown_C8h_Data { get; set; } public BoundMaterial_s[] Materials { get; set; } public BoundMaterialColour[] MaterialColours { get; set; } public byte[] PolygonMaterialIndices { get; set; } @@ -664,12 +853,13 @@ namespace CodeWalker.GameFiles this.Unknown_70h = reader.ReadUInt32(); this.Unknown_74h = reader.ReadUInt32(); this.Unknown_78h_Pointer = reader.ReadUInt64(); - this.Unknown_80h = reader.ReadUInt32(); + this.Unknown_80h = reader.ReadUInt16(); + this.Unknown_82h = reader.ReadUInt16(); this.Count1 = reader.ReadUInt32(); this.PolygonsPointer = reader.ReadUInt64(); - this.Quantum = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); - this.Unknown_9Ch = reader.ReadSingle();//.ReadUInt32(); - this.CenterGeom = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); + this.Quantum = reader.ReadVector3(); + this.Unknown_9Ch = reader.ReadSingle(); + this.CenterGeom = reader.ReadVector3(); this.Unknown_ACh = reader.ReadSingle(); this.VerticesPointer = reader.ReadUInt64(); this.Unknown_B8h_Pointer = reader.ReadUInt64(); @@ -722,7 +912,7 @@ namespace CodeWalker.GameFiles this.Unknown_C0h_Data = reader.ReadUintsAt(this.Unknown_C0h_Pointer, 8);//item counts if (this.Unknown_C0h_Data != null) { - this.Unknown_C8h_Data = reader.ReadBlockAt(this.Unknown_C8h_Pointer, this.Unknown_C0h_Data); + this.Unknown_C8h_Data = reader.ReadBlockAt(this.Unknown_C8h_Pointer, this.Unknown_C0h_Data); } this.Materials = reader.ReadStructsAt(this.MaterialsPointer, this.MaterialsCount); @@ -731,6 +921,22 @@ namespace CodeWalker.GameFiles this.PolygonMaterialIndices = reader.ReadBytesAt(this.PolygonMaterialIndicesPointer, (uint)PolygonsCount); + + + if (Unknown_9Ch != 0) + { } + if (Unknown_ACh != 0) + { } + + switch (Unknown_82h) + { + case 0: + case 1://ybns + break; + default://des_.ydr's? some extra data to read..?? is this some extra poly count? + break; + } + } private void ReadPolygons(ResourceDataReader reader) @@ -825,15 +1031,12 @@ namespace CodeWalker.GameFiles writer.Write(this.Unknown_74h); writer.Write(this.Unknown_78h_Pointer); writer.Write(this.Unknown_80h); + writer.Write(this.Unknown_82h); writer.Write(this.Count1); writer.Write(this.PolygonsPointer); - writer.Write(this.Quantum.X);// this.Unknown_90h); - writer.Write(this.Quantum.Y);// .Unknown_94h); - writer.Write(this.Quantum.Z);// .Unknown_98h); + writer.Write(this.Quantum); writer.Write(this.Unknown_9Ch); - writer.Write(this.CenterGeom.X);// .Unknown_A0h); - writer.Write(this.CenterGeom.Y);// .Unknown_A4h); - writer.Write(this.CenterGeom.Z);// .Unknown_A8h); + writer.Write(this.CenterGeom); writer.Write(this.Unknown_ACh); writer.Write(this.VerticesPointer); writer.Write(this.Unknown_B8h_Pointer); @@ -952,8 +1155,8 @@ namespace CodeWalker.GameFiles if (Polygons == null) { return res; } - box.Minimum = BoundingBoxMin; - box.Maximum = BoundingBoxMax; + box.Minimum = BoxMin; + box.Maximum = BoxMax; if (!sph.Intersects(ref box)) { return res; } @@ -969,8 +1172,8 @@ namespace CodeWalker.GameFiles if (Polygons == null) { return res; } - box.Minimum = BoundingBoxMin; - box.Maximum = BoundingBoxMax; + box.Minimum = BoxMin; + box.Maximum = BoxMax; float bvhboxhittest; if (!ray.Intersects(ref box, out bvhboxhittest)) { return res; } @@ -1187,213 +1390,472 @@ namespace CodeWalker.GameFiles res.Normal = n1; res.HitPolygon = polygon; res.HitBounds = this; - - byte matind = ((PolygonMaterialIndices != null) && (p < PolygonMaterialIndices.Length)) ? PolygonMaterialIndices[p] : (byte)0; - BoundMaterial_s mat = ((Materials != null) && (matind < Materials.Length)) ? Materials[matind] : new BoundMaterial_s(); - res.Material = mat; + res.Material = polygon?.Material ?? new BoundMaterial_s(); } res.TestedPolyCount++; } } } - - [TC(typeof(EXP))] public class BoundUnknown1 : ResourceSystemBlock + [TC(typeof(EXP))] public class BoundBVH : BoundGeometry { - public uint[][] Items { get; private set; } - - private ResourceSystemStructBlock[] ItemBlocks = null; - - public override long BlockLength { - get - { - return Items != null ? (Items.Length*8) : 0; //main pointer array has 8 items, 8 bytes each - } + get { return 336; } } - public BoundUnknown1() { } - public BoundUnknown1(uint[][] items) - { - Items = items; - } + // structure data + public ulong BvhPointer { get; set; } + public uint Unknown_138h { get; set; } // 0x00000000 + public uint Unknown_13Ch { get; set; } // 0x00000000 + public ushort Unknown_140h { get; set; } = 0xFFFF; // 0xFFFF + public ushort Unknown_142h { get; set; } // 0x0000 + public uint Unknown_144h { get; set; } // 0x00000000 + public uint Unknown_148h { get; set; } // 0x00000000 + public uint Unknown_14Ch { get; set; } // 0x00000000 + // reference data + public BVH BVH { get; set; } + + /// + /// Reads the data-block from a stream. + /// public override void Read(ResourceDataReader reader, params object[] parameters) { - if (parameters?.Length < 1) - { return; } //shouldn't happen! + base.Read(reader, parameters); - var itemcounts = (uint[])parameters[0]; - ulong ptr = (ulong)reader.Position; //pointer array pointer + // read structure data + this.BvhPointer = reader.ReadUInt64(); + this.Unknown_138h = reader.ReadUInt32(); + this.Unknown_13Ch = reader.ReadUInt32(); + this.Unknown_140h = reader.ReadUInt16(); + this.Unknown_142h = reader.ReadUInt16(); + this.Unknown_144h = reader.ReadUInt32(); + this.Unknown_148h = reader.ReadUInt32(); + this.Unknown_14Ch = reader.ReadUInt32(); - if (itemcounts != null) + // read reference data + if (this.BvhPointer > 65535) { - ulong[] ptrlist = reader.ReadUlongsAt(ptr, (uint)itemcounts.Length); - Items = new uint[itemcounts.Length][]; - for (int i = 0; i < itemcounts.Length; i++) - { - Items[i] = reader.ReadUintsAt(ptrlist[i], itemcounts[i]); - } + this.BVH = reader.ReadBlockAt( + this.BvhPointer // offset + ); + } + else + { + //this can happen in some ydr's for some reason } } + /// + /// Writes the data-block to a stream. + /// public override void Write(ResourceDataWriter writer, params object[] parameters) { + base.Write(writer, parameters); - //just write the pointer array. - if (ItemBlocks != null) - { - foreach (var item in ItemBlocks) - { - writer.Write((ulong)item.FilePosition); - } - } - + // update structure data + this.BvhPointer = (ulong)(this.BVH != null ? this.BVH.FilePosition : 0); + + // write structure data + writer.Write(this.BvhPointer); + writer.Write(this.Unknown_138h); + writer.Write(this.Unknown_13Ch); + writer.Write(this.Unknown_140h); + writer.Write(this.Unknown_142h); + writer.Write(this.Unknown_144h); + writer.Write(this.Unknown_148h); + writer.Write(this.Unknown_14Ch); } + /// + /// Returns a list of data blocks which are referenced by this block. + /// public override IResourceBlock[] GetReferences() { var list = new List(base.GetReferences()); - - var ilist = new List>(); - if (Items != null) - { - foreach (var item in Items) - { - var block = new ResourceSystemStructBlock(item); - ilist.Add(block); - list.Add(block); - } - } - ItemBlocks = ilist.ToArray(); - + if (BVH != null) list.Add(BVH); return list.ToArray(); } - } - [TC(typeof(EXP))] public struct BoundMaterial_s - { - public uint Data1; - public uint Data2; - #region Public Properties - public BoundsMaterialType Type + public void BuildBVH() { - get => (BoundsMaterialType)(Data1 & 0xFFu); - set => Data1 = ((Data1 & 0xFFFFFF00u) | ((byte)value & 0xFFu)); + } - public byte ProceduralId + + + public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph) { - get => (byte)((Data1 >> 8) & 0xFFu); - set => Data1 = ((Data1 & 0xFFFF00FFu) | ((value & 0xFFu) << 8)); - } + var res = new SpaceSphereIntersectResult(); + var box = new BoundingBox(); - public byte RoomId - { - get => (byte)((Data1 >> 16) & 0x1Fu); - set => Data1 = ((Data1 & 0xFFE0FFFFu) | ((value & 0x1Fu) << 16)); - } + if (Polygons == null) + { return res; } + if ((BVH?.Nodes?.data_items == null) || (BVH?.Trees?.data_items == null)) + { return res; } - public byte PedDensity - { - get => (byte)((Data1 >> 21) & 0x7u); - set => Data1 = ((Data1 & 0xFF1FFFFFu) | ((value & 0x7u) << 21)); - } + box.Minimum = BoxMin; + box.Maximum = BoxMax; + if (!sph.Intersects(ref box)) + { return res; } - //public byte Flags1 - //{ - // get => (byte)((Data1 >> 24) & 0xFFu); - // set => Data1 = ((Data1 & 0xFFFFFFu) | ((value & 0xFFu) << 24)); - //} - - //public byte Flags2 - //{ - // get => (byte)((Data2 >> 24) & 0xFFu); - // set => Data2 = ((Data2 & 0xFFFFFFu) | ((value & 0xFFu) << 24)); - //} - - public EBoundMaterialFlags Flags - { - get => (EBoundMaterialFlags)(((Data1 >> 24) & 0xFFu) | ((Data2 & 0xFFu) << 8)); - set + var q = BVH.Quantum.XYZ(); + var c = BVH.BoundingBoxCenter.XYZ(); + for (int t = 0; t < BVH.Trees.data_items.Length; t++) { - Data1 = (Data1 & 0x00FFFFFFu) | (((ushort)value & 0x00FFu) << 24); - Data2 = (Data2 & 0xFFFFFF00u) | (((ushort)value & 0xFF00u) >> 8); + var tree = BVH.Trees.data_items[t]; + box.Minimum = new Vector3(tree.MinX, tree.MinY, tree.MinZ) * q + c; + box.Maximum = new Vector3(tree.MaxX, tree.MaxY, tree.MaxZ) * q + c; + if (!sph.Intersects(ref box)) + { continue; } + + int nodeind = tree.NodeIndex1; + int lastind = tree.NodeIndex2; + while (nodeind < lastind) + { + var node = BVH.Nodes.data_items[nodeind]; + box.Minimum = new Vector3(node.MinX, node.MinY, node.MinZ) * q + c; + box.Maximum = new Vector3(node.MaxX, node.MaxY, node.MaxZ) * q + c; + bool nodehit = sph.Intersects(ref box); + bool nodeskip = !nodehit; + if (node.ItemCount <= 0) //intermediate node with child nodes + { + if (nodeskip) + { + nodeind += node.ItemId; //(child node count) + } + else + { + nodeind++; + } + } + else //leaf node, with polygons + { + if (!nodeskip) + { + var lastp = Math.Min(node.ItemId + node.ItemCount, (int)PolygonsCount); + + SphereIntersectPolygons(ref sph, ref res, node.ItemId, lastp); + + } + nodeind++; + } + res.TestedNodeCount++; + } } + + return res; } - public byte MaterialColorIndex + public override SpaceRayIntersectResult RayIntersect(ref Ray ray, float maxdist = float.MaxValue) { - get => (byte)((Data2 >> 8) & 0xFFu); - set => Data2 = ((Data2 & 0xFFFF00FFu) | (value & 0xFFu)); + var res = new SpaceRayIntersectResult(); + var box = new BoundingBox(); + + if (Polygons == null) + { return res; } + if ((BVH?.Nodes?.data_items == null) || (BVH?.Trees?.data_items == null)) + { return res; } + + box.Minimum = BoxMin; + box.Maximum = BoxMax; + float bvhboxhittest; + if (!ray.Intersects(ref box, out bvhboxhittest)) + { return res; } + if (bvhboxhittest > maxdist) + { return res; } //already a closer hit. + + res.HitDist = maxdist; + + var q = BVH.Quantum.XYZ(); + var c = BVH.BoundingBoxCenter.XYZ(); + for (int t = 0; t < BVH.Trees.data_items.Length; t++) + { + var tree = BVH.Trees.data_items[t]; + box.Minimum = new Vector3(tree.MinX, tree.MinY, tree.MinZ) * q + c; + box.Maximum = new Vector3(tree.MaxX, tree.MaxY, tree.MaxZ) * q + c; + if (!ray.Intersects(ref box, out bvhboxhittest)) + { continue; } + if (bvhboxhittest > res.HitDist) + { continue; } //already a closer hit. + + int nodeind = tree.NodeIndex1; + int lastind = tree.NodeIndex2; + while (nodeind < lastind) + { + var node = BVH.Nodes.data_items[nodeind]; + box.Minimum = new Vector3(node.MinX, node.MinY, node.MinZ) * q + c; + box.Maximum = new Vector3(node.MaxX, node.MaxY, node.MaxZ) * q + c; + bool nodehit = ray.Intersects(ref box, out bvhboxhittest); + bool nodeskip = !nodehit || (bvhboxhittest > res.HitDist); + if (node.ItemCount <= 0) //intermediate node with child nodes + { + if (nodeskip) + { + nodeind += node.ItemId; //(child node count) + } + else + { + nodeind++; + } + } + else //leaf node, with polygons + { + if (!nodeskip) + { + var lastp = Math.Min(node.ItemId + node.ItemCount, (int)PolygonsCount); + + RayIntersectPolygons(ref ray, ref res, node.ItemId, lastp); + + } + nodeind++; + } + res.TestedNodeCount++; + } + } + + return res; } - public ushort Unk4 - { - get => (ushort)((Data2 >> 16) & 0xFFFFu); - set => Data2 = ((Data2 & 0x0000FFFFu) | ((value & 0xFFFFu) << 16)); - } - - public override string ToString() - { - return Data1.ToString() + ", " + Data2.ToString() + ", " - + Type.ToString() + ", " + ProceduralId.ToString() + ", " + RoomId.ToString() + ", " + PedDensity.ToString() + ", " - + Flags.ToString() + ", " + MaterialColorIndex.ToString() + ", " + Unk4.ToString(); - } - - #endregion } - - [Flags] public enum EBoundMaterialFlags : ushort + [TC(typeof(EXP))] public class BoundComposite : Bounds { - NONE = 0, - FLAG_STAIRS = 1, - FLAG_NOT_CLIMBABLE = 1 << 1, - FLAG_SEE_THROUGH = 1 << 2, - FLAG_SHOOT_THROUGH = 1 << 3, - FLAG_NOT_COVER = 1 << 4, - FLAG_WALKABLE_PATH = 1 << 5, - FLAG_NO_CAM_COLLISION = 1 << 6, - FLAG_SHOOT_THROUGH_FX = 1 << 7, - FLAG_NO_DECAL = 1 << 8, - FLAG_NO_NAVMESH = 1 << 9, - FLAG_NO_RAGDOLL = 1 << 10, - FLAG_VEHICLE_WHEEL = 1 << 11, - FLAG_NO_PTFX = 1 << 12, - FLAG_TOO_STEEP_FOR_PLAYER = 1 << 13, - FLAG_NO_NETWORK_SPAWN = 1 << 14, - FLAG_NO_CAM_COLLISION_ALLOW_CLIPPING = 1 << 15, + public override long BlockLength + { + get { return 176; } + } + + // structure data + public ulong ChildrenPointer { get; set; } + public ulong ChildrenTransformation1Pointer { get; set; } + public ulong ChildrenTransformation2Pointer { get; set; } + public ulong ChildrenBoundingBoxesPointer { get; set; } + public ulong ChildrenFlags1Pointer { get; set; } + public ulong ChildrenFlags2Pointer { get; set; } + public ushort ChildrenCount1 { get; set; } + public ushort ChildrenCount2 { get; set; } + public uint Unknown_A4h { get; set; } // 0x00000000 + public ulong BVHPointer { get; set; } + + // reference data + public ResourcePointerArray64 Children { get; set; } + public Matrix[] ChildrenTransformation1 { get; set; } + public Matrix[] ChildrenTransformation2 { get; set; } + public AABB_s[] ChildrenBoundingBoxes { get; set; } + public BoundCompositeChildrenFlags[] ChildrenFlags1 { get; set; } + public BoundCompositeChildrenFlags[] ChildrenFlags2 { get; set; } + + public BVH BVH { get; set; } + + + private ResourceSystemStructBlock ChildrenTransformation1Block = null; + private ResourceSystemStructBlock ChildrenTransformation2Block = null; + private ResourceSystemStructBlock ChildrenBoundingBoxesBlock = null; + private ResourceSystemStructBlock ChildrenFlags1Block = null; + private ResourceSystemStructBlock ChildrenFlags2Block = null; + + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + // read structure data + this.ChildrenPointer = reader.ReadUInt64(); + this.ChildrenTransformation1Pointer = reader.ReadUInt64(); + this.ChildrenTransformation2Pointer = reader.ReadUInt64(); + this.ChildrenBoundingBoxesPointer = reader.ReadUInt64(); + this.ChildrenFlags1Pointer = reader.ReadUInt64(); + this.ChildrenFlags2Pointer = reader.ReadUInt64(); + this.ChildrenCount1 = reader.ReadUInt16(); + this.ChildrenCount2 = reader.ReadUInt16(); + this.Unknown_A4h = reader.ReadUInt32(); + this.BVHPointer = reader.ReadUInt64(); + + // read reference data + this.Children = reader.ReadBlockAt>( + this.ChildrenPointer, // offset + this.ChildrenCount1 + ); + + this.ChildrenTransformation1 = reader.ReadStructsAt(this.ChildrenTransformation1Pointer, this.ChildrenCount1); + this.ChildrenTransformation2 = reader.ReadStructsAt(this.ChildrenTransformation2Pointer, this.ChildrenCount1); + this.ChildrenBoundingBoxes = reader.ReadStructsAt(this.ChildrenBoundingBoxesPointer, this.ChildrenCount1); + this.ChildrenFlags1 = reader.ReadStructsAt(this.ChildrenFlags1Pointer, this.ChildrenCount1); + this.ChildrenFlags2 = reader.ReadStructsAt(this.ChildrenFlags2Pointer, this.ChildrenCount1); + + this.BVH = reader.ReadBlockAt( + this.BVHPointer // offset + ); + + + + + var childTransforms = ChildrenTransformation1 ?? ChildrenTransformation2; + if ((Children != null) && (Children.data_items != null)) + { + for (int i = 0; i < Children.data_items.Length; i++) + { + var child = Children.data_items[i]; + if (child != null) + { + child.Parent = this; + + var xform = ((childTransforms != null) && (i < childTransforms.Length)) ? childTransforms[i] : Matrix.Identity; + xform.Column4 = new Vector4(0.0f, 0.0f, 0.0f, 1.0f); + child.Transform = xform; + child.TransformInv = Matrix.Invert(xform); + } + } + } + + + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + // update structure data + this.ChildrenPointer = (ulong)(this.Children != null ? this.Children.FilePosition : 0); + this.ChildrenTransformation1Pointer = (ulong)(this.ChildrenTransformation1Block != null ? this.ChildrenTransformation1Block.FilePosition : 0); + this.ChildrenTransformation2Pointer = (ulong)(this.ChildrenTransformation2Block != null ? this.ChildrenTransformation2Block.FilePosition : 0); + this.ChildrenBoundingBoxesPointer = (ulong)(this.ChildrenBoundingBoxesBlock != null ? this.ChildrenBoundingBoxesBlock.FilePosition : 0); + this.ChildrenFlags1Pointer = (ulong)(this.ChildrenFlags1Block != null ? this.ChildrenFlags1Block.FilePosition : 0); + this.ChildrenFlags2Pointer = (ulong)(this.ChildrenFlags2Block != null ? this.ChildrenFlags2Block.FilePosition : 0); + this.ChildrenCount1 = (ushort)(this.Children != null ? this.Children.Count : 0); + this.ChildrenCount2 = (ushort)(this.Children != null ? this.Children.Count : 0); + this.BVHPointer = (ulong)(this.BVH != null ? this.BVH.FilePosition : 0); + + // write structure data + writer.Write(this.ChildrenPointer); + writer.Write(this.ChildrenTransformation1Pointer); + writer.Write(this.ChildrenTransformation2Pointer); + writer.Write(this.ChildrenBoundingBoxesPointer); + writer.Write(this.ChildrenFlags1Pointer); + writer.Write(this.ChildrenFlags2Pointer); + writer.Write(this.ChildrenCount1); + writer.Write(this.ChildrenCount2); + writer.Write(this.Unknown_A4h); + writer.Write(this.BVHPointer); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(base.GetReferences()); + if (Children != null) list.Add(Children); + if (ChildrenTransformation1 != null) + { + ChildrenTransformation1Block = new ResourceSystemStructBlock(ChildrenTransformation1); + list.Add(ChildrenTransformation1Block); + } + if (ChildrenTransformation2 != null) + { + ChildrenTransformation2Block = new ResourceSystemStructBlock(ChildrenTransformation2); + list.Add(ChildrenTransformation2Block); + } + if (ChildrenBoundingBoxes != null) + { + ChildrenBoundingBoxesBlock = new ResourceSystemStructBlock(ChildrenBoundingBoxes); + list.Add(ChildrenBoundingBoxesBlock); + } + if (ChildrenFlags1 != null) + { + ChildrenFlags1Block = new ResourceSystemStructBlock(ChildrenFlags1); + list.Add(ChildrenFlags1Block); + } + if (ChildrenFlags2 != null) + { + ChildrenFlags2Block = new ResourceSystemStructBlock(ChildrenFlags2); + list.Add(ChildrenFlags2Block); + } + if (BVH != null) list.Add(BVH); + return list.ToArray(); + } + + + + + + public void BuildBVH() + { + + } + + + + + public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph) + { + var res = new SpaceSphereIntersectResult(); + var tsph = sph; + + var compchilds = Children?.data_items; + if (compchilds == null) + { return res; } + + for (int i = 0; i < compchilds.Length; i++) + { + var c = compchilds[i]; + if (c == null) continue; + + tsph.Center = c.TransformInv.Multiply(sph.Center); + + var chit = c.SphereIntersect(ref tsph); + + chit.Normal = c.Transform.MultiplyRot(chit.Normal); + + res.TryUpdate(ref chit); + } + + return res; + } + + public override SpaceRayIntersectResult RayIntersect(ref Ray ray, float maxdist = float.MaxValue) + { + var res = new SpaceRayIntersectResult(); + res.HitDist = maxdist; + + var tray = ray; + + var compchilds = Children?.data_items; + if (compchilds == null) + { return res; } + + for (int i = 0; i < compchilds.Length; i++) + { + var c = compchilds[i]; + if (c == null) continue; + + tray.Position = c.TransformInv.Multiply(ray.Position); + tray.Direction = c.TransformInv.MultiplyRot(ray.Direction); + + var chit = c.RayIntersect(ref tray, res.HitDist); + + chit.Position = c.Transform.Multiply(chit.Position); + chit.Normal = c.Transform.MultiplyRot(chit.Normal); + + res.TryUpdate(ref chit); + } + + return res; + } + } - [TC(typeof(EXP))] public struct BoundMaterialColour - { - //public BoundsMaterialType Type { get; set; } - public byte R { get; set; } - public byte G { get; set; } - public byte B { get; set; } - public byte A { get; set; } //GIMS EVO saves this as "opacity" 0-100 - public override string ToString() - { - //return Type.ToString() + ", " + Unk0.ToString() + ", " + Unk1.ToString() + ", " + Unk2.ToString(); - return R.ToString() + ", " + G.ToString() + ", " + B.ToString() + ", " + A.ToString(); - } - } - [TC(typeof(EXP))] public struct BoundVertex_s - { - public short X { get; set; } - public short Y { get; set; } - public short Z { get; set; } - public BoundVertex_s(Vector3 v) - { - X = (short)v.X; - Y = (short)v.Y; - Z = (short)v.Z; - } - } + public enum BoundPolygonType : byte { @@ -1407,12 +1869,35 @@ namespace CodeWalker.GameFiles { public BoundPolygonType Type { get; set; } public BoundGeometry Owner { get; set; } //for browsing/editing convenience + public BoundMaterial_s Material + { + get + { + var matind = 0; + if ((Owner?.PolygonMaterialIndices != null) && (Index < Owner.PolygonMaterialIndices.Length)) + { + matind = Owner.PolygonMaterialIndices[Index]; + } + if ((Owner.Materials != null) && (matind < Owner.Materials.Length)) + { + return Owner.Materials[matind]; + } + return new BoundMaterial_s(); + } + } public int Index { get; set; } //for editing convenience, not stored public abstract Vector3 Scale { get; set; } public abstract Vector3 Position { get; set; } public abstract Quaternion Orientation { get; set; } public abstract void Read(byte[] bytes, int offset); public abstract void Write(BinaryWriter bw); + public virtual string Title + { + get + { + return Type.ToString() + " " + Index.ToString(); + } + } public override string ToString() { return Type.ToString(); @@ -1428,12 +1913,12 @@ namespace CodeWalker.GameFiles public short edgeIndex2 { get; set; } public short edgeIndex3 { get; set; } - public int vertIndex1 { get { return triIndex1 & 0x7FFF; } } - public int vertIndex2 { get { return triIndex2 & 0x7FFF; } } - public int vertIndex3 { get { return triIndex3 & 0x7FFF; } } - public bool vertFlag1 { get { return (triIndex1 & 0x8000) > 0; } } - public bool vertFlag2 { get { return (triIndex2 & 0x8000) > 0; } } - public bool vertFlag3 { get { return (triIndex3 & 0x8000) > 0; } } + public int vertIndex1 { get { return (triIndex1 & 0x7FFF); } } + public int vertIndex2 { get { return (triIndex2 & 0x7FFF); } } + public int vertIndex3 { get { return (triIndex3 & 0x7FFF); } } + public bool vertFlag1 { get { return (triIndex1 & 0x8000) > 0; } set { triIndex1 = (ushort)(vertIndex1 + (value ? 0x8000 : 0)); } } + public bool vertFlag2 { get { return (triIndex2 & 0x8000) > 0; } set { triIndex2 = (ushort)(vertIndex2 + (value ? 0x8000 : 0)); } } + public bool vertFlag3 { get { return (triIndex3 & 0x8000) > 0; } set { triIndex3 = (ushort)(vertIndex3 + (value ? 0x8000 : 0)); } } public Vector3 Vertex1 { @@ -1830,464 +2315,95 @@ namespace CodeWalker.GameFiles } } - [TC(typeof(EXP))] public class BoundBVH : BoundGeometry + [TC(typeof(EXP))] public struct BoundVertex_s { + public short X { get; set; } + public short Y { get; set; } + public short Z { get; set; } + + public BoundVertex_s(Vector3 v) + { + X = (short)v.X; + Y = (short)v.Y; + Z = (short)v.Z; + } + } + + [TC(typeof(EXP))] public class BoundGeomUnknown1 : ResourceSystemBlock + { + public uint[][] Items { get; private set; } + + private ResourceSystemStructBlock[] ItemBlocks = null; + + public override long BlockLength { - get { return 336; } + get + { + return Items != null ? (Items.Length*8) : 0; //main pointer array has 8 items, 8 bytes each + } } - // structure data - public ulong BvhPointer { get; set; } - public uint Unknown_138h { get; set; } // 0x00000000 - public uint Unknown_13Ch { get; set; } // 0x00000000 - public ushort Unknown_140h { get; set; } // 0xFFFF - public ushort Unknown_142h { get; set; } // 0x0000 - public uint Unknown_144h { get; set; } // 0x00000000 - public uint Unknown_148h { get; set; } // 0x00000000 - public uint Unknown_14Ch { get; set; } // 0x00000000 + public BoundGeomUnknown1() { } + public BoundGeomUnknown1(uint[][] items) + { + Items = items; + } - // reference data - public BVH BVH { get; set; } - - /// - /// Reads the data-block from a stream. - /// public override void Read(ResourceDataReader reader, params object[] parameters) { - base.Read(reader, parameters); + if (parameters?.Length < 1) + { return; } //shouldn't happen! - // read structure data - this.BvhPointer = reader.ReadUInt64(); - this.Unknown_138h = reader.ReadUInt32(); - this.Unknown_13Ch = reader.ReadUInt32(); - this.Unknown_140h = reader.ReadUInt16(); - this.Unknown_142h = reader.ReadUInt16(); - this.Unknown_144h = reader.ReadUInt32(); - this.Unknown_148h = reader.ReadUInt32(); - this.Unknown_14Ch = reader.ReadUInt32(); + var itemcounts = (uint[])parameters[0]; + ulong ptr = (ulong)reader.Position; //pointer array pointer - // read reference data - if (this.BvhPointer > 65535) + if (itemcounts != null) { - this.BVH = reader.ReadBlockAt( - this.BvhPointer // offset - ); - } - else - { - //this can happen in some ydr's for some reason + ulong[] ptrlist = reader.ReadUlongsAt(ptr, (uint)itemcounts.Length); + Items = new uint[itemcounts.Length][]; + for (int i = 0; i < itemcounts.Length; i++) + { + Items[i] = reader.ReadUintsAt(ptrlist[i], itemcounts[i]); + } } } - /// - /// Writes the data-block to a stream. - /// public override void Write(ResourceDataWriter writer, params object[] parameters) { - base.Write(writer, parameters); - // update structure data - this.BvhPointer = (ulong)(this.BVH != null ? this.BVH.FilePosition : 0); - - // write structure data - writer.Write(this.BvhPointer); - writer.Write(this.Unknown_138h); - writer.Write(this.Unknown_13Ch); - writer.Write(this.Unknown_140h); - writer.Write(this.Unknown_142h); - writer.Write(this.Unknown_144h); - writer.Write(this.Unknown_148h); - writer.Write(this.Unknown_14Ch); - } - - /// - /// Returns a list of data blocks which are referenced by this block. - /// - public override IResourceBlock[] GetReferences() - { - var list = new List(base.GetReferences()); - if (BVH != null) list.Add(BVH); - return list.ToArray(); - } - - - - - public void BuildBVH() - { - - } - - - - public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph) - { - var res = new SpaceSphereIntersectResult(); - var box = new BoundingBox(); - - if (Polygons == null) - { return res; } - if ((BVH?.Nodes?.data_items == null) || (BVH?.Trees?.data_items == null)) - { return res; } - - box.Minimum = BoundingBoxMin; - box.Maximum = BoundingBoxMax; - if (!sph.Intersects(ref box)) - { return res; } - - var q = BVH.Quantum.XYZ(); - var c = BVH.BoundingBoxCenter.XYZ(); - for (int t = 0; t < BVH.Trees.data_items.Length; t++) + //just write the pointer array. + if (ItemBlocks != null) { - var tree = BVH.Trees.data_items[t]; - box.Minimum = new Vector3(tree.MinX, tree.MinY, tree.MinZ) * q + c; - box.Maximum = new Vector3(tree.MaxX, tree.MaxY, tree.MaxZ) * q + c; - if (!sph.Intersects(ref box)) - { continue; } - - int nodeind = tree.NodeIndex1; - int lastind = tree.NodeIndex2; - while (nodeind < lastind) + foreach (var item in ItemBlocks) { - var node = BVH.Nodes.data_items[nodeind]; - box.Minimum = new Vector3(node.MinX, node.MinY, node.MinZ) * q + c; - box.Maximum = new Vector3(node.MaxX, node.MaxY, node.MaxZ) * q + c; - bool nodehit = sph.Intersects(ref box); - bool nodeskip = !nodehit; - if (node.ItemCount <= 0) //intermediate node with child nodes - { - if (nodeskip) - { - nodeind += node.ItemId; //(child node count) - } - else - { - nodeind++; - } - } - else //leaf node, with polygons - { - if (!nodeskip) - { - var lastp = Math.Min(node.ItemId + node.ItemCount, (int)PolygonsCount); - - SphereIntersectPolygons(ref sph, ref res, node.ItemId, lastp); - - } - nodeind++; - } - res.TestedNodeCount++; - } - } - - return res; - } - - public override SpaceRayIntersectResult RayIntersect(ref Ray ray, float maxdist = float.MaxValue) - { - var res = new SpaceRayIntersectResult(); - var box = new BoundingBox(); - - if (Polygons == null) - { return res; } - if ((BVH?.Nodes?.data_items == null) || (BVH?.Trees?.data_items == null)) - { return res; } - - box.Minimum = BoundingBoxMin; - box.Maximum = BoundingBoxMax; - float bvhboxhittest; - if (!ray.Intersects(ref box, out bvhboxhittest)) - { return res; } - if (bvhboxhittest > maxdist) - { return res; } //already a closer hit. - - res.HitDist = maxdist; - - var q = BVH.Quantum.XYZ(); - var c = BVH.BoundingBoxCenter.XYZ(); - for (int t = 0; t < BVH.Trees.data_items.Length; t++) - { - var tree = BVH.Trees.data_items[t]; - box.Minimum = new Vector3(tree.MinX, tree.MinY, tree.MinZ) * q + c; - box.Maximum = new Vector3(tree.MaxX, tree.MaxY, tree.MaxZ) * q + c; - if (!ray.Intersects(ref box, out bvhboxhittest)) - { continue; } - if (bvhboxhittest > res.HitDist) - { continue; } //already a closer hit. - - int nodeind = tree.NodeIndex1; - int lastind = tree.NodeIndex2; - while (nodeind < lastind) - { - var node = BVH.Nodes.data_items[nodeind]; - box.Minimum = new Vector3(node.MinX, node.MinY, node.MinZ) * q + c; - box.Maximum = new Vector3(node.MaxX, node.MaxY, node.MaxZ) * q + c; - bool nodehit = ray.Intersects(ref box, out bvhboxhittest); - bool nodeskip = !nodehit || (bvhboxhittest > res.HitDist); - if (node.ItemCount <= 0) //intermediate node with child nodes - { - if (nodeskip) - { - nodeind += node.ItemId; //(child node count) - } - else - { - nodeind++; - } - } - else //leaf node, with polygons - { - if (!nodeskip) - { - var lastp = Math.Min(node.ItemId + node.ItemCount, (int)PolygonsCount); - - RayIntersectPolygons(ref ray, ref res, node.ItemId, lastp); - - } - nodeind++; - } - res.TestedNodeCount++; - } - } - - return res; - } - - } - [TC(typeof(EXP))] public class BoundComposite : Bounds - { - public override long BlockLength - { - get { return 176; } - } - - // structure data - public ulong ChildrenPointer { get; set; } - public ulong ChildrenTransformation1Pointer { get; set; } - public ulong ChildrenTransformation2Pointer { get; set; } - public ulong ChildrenBoundingBoxesPointer { get; set; } - public ulong ChildrenFlags1Pointer { get; set; } - public ulong ChildrenFlags2Pointer { get; set; } - public ushort ChildrenCount1 { get; set; } - public ushort ChildrenCount2 { get; set; } - public uint Unknown_A4h { get; set; } // 0x00000000 - public ulong BVHPointer { get; set; } - - // reference data - public ResourcePointerArray64 Children { get; set; } - public Matrix[] ChildrenTransformation1 { get; set; } - public Matrix[] ChildrenTransformation2 { get; set; } - public AABB_s[] ChildrenBoundingBoxes { get; set; } - public BoundCompositeChildrenFlags[] ChildrenFlags1 { get; set; } - public BoundCompositeChildrenFlags[] ChildrenFlags2 { get; set; } - - public BVH BVH { get; set; } - - - private ResourceSystemStructBlock ChildrenTransformation1Block = null; - private ResourceSystemStructBlock ChildrenTransformation2Block = null; - private ResourceSystemStructBlock ChildrenBoundingBoxesBlock = null; - private ResourceSystemStructBlock ChildrenFlags1Block = null; - private ResourceSystemStructBlock ChildrenFlags2Block = null; - - - /// - /// Reads the data-block from a stream. - /// - public override void Read(ResourceDataReader reader, params object[] parameters) - { - base.Read(reader, parameters); - - // read structure data - this.ChildrenPointer = reader.ReadUInt64(); - this.ChildrenTransformation1Pointer = reader.ReadUInt64(); - this.ChildrenTransformation2Pointer = reader.ReadUInt64(); - this.ChildrenBoundingBoxesPointer = reader.ReadUInt64(); - this.ChildrenFlags1Pointer = reader.ReadUInt64(); - this.ChildrenFlags2Pointer = reader.ReadUInt64(); - this.ChildrenCount1 = reader.ReadUInt16(); - this.ChildrenCount2 = reader.ReadUInt16(); - this.Unknown_A4h = reader.ReadUInt32(); - this.BVHPointer = reader.ReadUInt64(); - - // read reference data - this.Children = reader.ReadBlockAt>( - this.ChildrenPointer, // offset - this.ChildrenCount1 - ); - - this.ChildrenTransformation1 = reader.ReadStructsAt(this.ChildrenTransformation1Pointer, this.ChildrenCount1); - this.ChildrenTransformation2 = reader.ReadStructsAt(this.ChildrenTransformation2Pointer, this.ChildrenCount1); - this.ChildrenBoundingBoxes = reader.ReadStructsAt(this.ChildrenBoundingBoxesPointer, this.ChildrenCount1); - this.ChildrenFlags1 = reader.ReadStructsAt(this.ChildrenFlags1Pointer, this.ChildrenCount1); - this.ChildrenFlags2 = reader.ReadStructsAt(this.ChildrenFlags2Pointer, this.ChildrenCount1); - - this.BVH = reader.ReadBlockAt( - this.BVHPointer // offset - ); - - - - - var childTransforms = ChildrenTransformation1 ?? ChildrenTransformation2; - if ((Children != null) && (Children.data_items != null)) - { - for (int i = 0; i < Children.data_items.Length; i++) - { - var child = Children.data_items[i]; - if (child != null) - { - child.Parent = this; - - var xform = ((childTransforms != null) && (i < childTransforms.Length)) ? childTransforms[i] : Matrix.Identity; - xform.Column4 = new Vector4(0.0f, 0.0f, 0.0f, 1.0f); - child.Transform = xform; - child.TransformInv = Matrix.Invert(xform); - } + writer.Write((ulong)item.FilePosition); } } - } - /// - /// Writes the data-block to a stream. - /// - public override void Write(ResourceDataWriter writer, params object[] parameters) - { - base.Write(writer, parameters); - - // update structure data - this.ChildrenPointer = (ulong)(this.Children != null ? this.Children.FilePosition : 0); - this.ChildrenTransformation1Pointer = (ulong)(this.ChildrenTransformation1Block != null ? this.ChildrenTransformation1Block.FilePosition : 0); - this.ChildrenTransformation2Pointer = (ulong)(this.ChildrenTransformation2Block != null ? this.ChildrenTransformation2Block.FilePosition : 0); - this.ChildrenBoundingBoxesPointer = (ulong)(this.ChildrenBoundingBoxesBlock != null ? this.ChildrenBoundingBoxesBlock.FilePosition : 0); - this.ChildrenFlags1Pointer = (ulong)(this.ChildrenFlags1Block != null ? this.ChildrenFlags1Block.FilePosition : 0); - this.ChildrenFlags2Pointer = (ulong)(this.ChildrenFlags2Block != null ? this.ChildrenFlags2Block.FilePosition : 0); - this.ChildrenCount1 = (ushort)(this.Children != null ? this.Children.Count : 0); - this.ChildrenCount2 = (ushort)(this.Children != null ? this.Children.Count : 0); - this.BVHPointer = (ulong)(this.BVH != null ? this.BVH.FilePosition : 0); - - // write structure data - writer.Write(this.ChildrenPointer); - writer.Write(this.ChildrenTransformation1Pointer); - writer.Write(this.ChildrenTransformation2Pointer); - writer.Write(this.ChildrenBoundingBoxesPointer); - writer.Write(this.ChildrenFlags1Pointer); - writer.Write(this.ChildrenFlags2Pointer); - writer.Write(this.ChildrenCount1); - writer.Write(this.ChildrenCount2); - writer.Write(this.Unknown_A4h); - writer.Write(this.BVHPointer); - } - - /// - /// Returns a list of data blocks which are referenced by this block. - /// public override IResourceBlock[] GetReferences() { var list = new List(base.GetReferences()); - if (Children != null) list.Add(Children); - if (ChildrenTransformation1 != null) + + var ilist = new List>(); + if (Items != null) { - ChildrenTransformation1Block = new ResourceSystemStructBlock(ChildrenTransformation1); - list.Add(ChildrenTransformation1Block); + foreach (var item in Items) + { + var block = new ResourceSystemStructBlock(item); + ilist.Add(block); + list.Add(block); + } } - if (ChildrenTransformation2 != null) - { - ChildrenTransformation2Block = new ResourceSystemStructBlock(ChildrenTransformation2); - list.Add(ChildrenTransformation2Block); - } - if (ChildrenBoundingBoxes != null) - { - ChildrenBoundingBoxesBlock = new ResourceSystemStructBlock(ChildrenBoundingBoxes); - list.Add(ChildrenBoundingBoxesBlock); - } - if (ChildrenFlags1 != null) - { - ChildrenFlags1Block = new ResourceSystemStructBlock(ChildrenFlags1); - list.Add(ChildrenFlags1Block); - } - if (ChildrenFlags2 != null) - { - ChildrenFlags2Block = new ResourceSystemStructBlock(ChildrenFlags2); - list.Add(ChildrenFlags2Block); - } - if (BVH != null) list.Add(BVH); + ItemBlocks = ilist.ToArray(); + return list.ToArray(); } - - - - - - public void BuildBVH() - { - - } - - - - - public override SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph) - { - var res = new SpaceSphereIntersectResult(); - var tsph = sph; - - var compchilds = Children?.data_items; - if (compchilds == null) - { return res; } - - for (int i = 0; i < compchilds.Length; i++) - { - var c = compchilds[i]; - if (c == null) continue; - - tsph.Center = c.TransformInv.Multiply(sph.Center); - - var chit = c.SphereIntersect(ref tsph); - - chit.Normal = c.Transform.MultiplyRot(chit.Normal); - - res.TryUpdate(ref chit); - } - - return res; - } - - public override SpaceRayIntersectResult RayIntersect(ref Ray ray, float maxdist = float.MaxValue) - { - var res = new SpaceRayIntersectResult(); - res.HitDist = maxdist; - - var tray = ray; - - var compchilds = Children?.data_items; - if (compchilds == null) - { return res; } - - for (int i = 0; i < compchilds.Length; i++) - { - var c = compchilds[i]; - if (c == null) continue; - - tray.Position = c.TransformInv.Multiply(ray.Position); - tray.Direction = c.TransformInv.MultiplyRot(ray.Direction); - - var chit = c.RayIntersect(ref tray, res.HitDist); - - chit.Position = c.Transform.Multiply(chit.Position); - chit.Normal = c.Transform.MultiplyRot(chit.Normal); - - res.TryUpdate(ref chit); - } - - return res; - } - } + [Flags] public enum EBoundCompositeFlags { NONE = 0, @@ -2324,7 +2440,6 @@ namespace CodeWalker.GameFiles MAP_STAIRS = 1 << 30, MAP_DEEP_SURFACE = 1 << 31, } - [TC(typeof(EXP))] public struct BoundCompositeChildrenFlags { public EBoundCompositeFlags Flags1 { get; set; } @@ -2336,6 +2451,7 @@ namespace CodeWalker.GameFiles } + [TC(typeof(EXP))] public class BVH : ResourceSystemBlock { public override long BlockLength @@ -2451,6 +2567,115 @@ namespace CodeWalker.GameFiles + + [Flags] public enum EBoundMaterialFlags : ushort + { + NONE = 0, + FLAG_STAIRS = 1, + FLAG_NOT_CLIMBABLE = 1 << 1, + FLAG_SEE_THROUGH = 1 << 2, + FLAG_SHOOT_THROUGH = 1 << 3, + FLAG_NOT_COVER = 1 << 4, + FLAG_WALKABLE_PATH = 1 << 5, + FLAG_NO_CAM_COLLISION = 1 << 6, + FLAG_SHOOT_THROUGH_FX = 1 << 7, + FLAG_NO_DECAL = 1 << 8, + FLAG_NO_NAVMESH = 1 << 9, + FLAG_NO_RAGDOLL = 1 << 10, + FLAG_VEHICLE_WHEEL = 1 << 11, + FLAG_NO_PTFX = 1 << 12, + FLAG_TOO_STEEP_FOR_PLAYER = 1 << 13, + FLAG_NO_NETWORK_SPAWN = 1 << 14, + FLAG_NO_CAM_COLLISION_ALLOW_CLIPPING = 1 << 15, + } + [TC(typeof(EXP))] public struct BoundMaterial_s + { + + public uint Data1; + public uint Data2; + + #region Public Properties + + public BoundsMaterialType Type + { + get => (BoundsMaterialType)(Data1 & 0xFFu); + set => Data1 = ((Data1 & 0xFFFFFF00u) | ((byte)value & 0xFFu)); + } + + public byte ProceduralId + { + get => (byte)((Data1 >> 8) & 0xFFu); + set => Data1 = ((Data1 & 0xFFFF00FFu) | ((value & 0xFFu) << 8)); + } + + public byte RoomId + { + get => (byte)((Data1 >> 16) & 0x1Fu); + set => Data1 = ((Data1 & 0xFFE0FFFFu) | ((value & 0x1Fu) << 16)); + } + + public byte PedDensity + { + get => (byte)((Data1 >> 21) & 0x7u); + set => Data1 = ((Data1 & 0xFF1FFFFFu) | ((value & 0x7u) << 21)); + } + + //public byte Flags1 + //{ + // get => (byte)((Data1 >> 24) & 0xFFu); + // set => Data1 = ((Data1 & 0xFFFFFFu) | ((value & 0xFFu) << 24)); + //} + + //public byte Flags2 + //{ + // get => (byte)((Data2 >> 24) & 0xFFu); + // set => Data2 = ((Data2 & 0xFFFFFFu) | ((value & 0xFFu) << 24)); + //} + + public EBoundMaterialFlags Flags + { + get => (EBoundMaterialFlags)(((Data1 >> 24) & 0xFFu) | ((Data2 & 0xFFu) << 8)); + set + { + Data1 = (Data1 & 0x00FFFFFFu) | (((ushort)value & 0x00FFu) << 24); + Data2 = (Data2 & 0xFFFFFF00u) | (((ushort)value & 0xFF00u) >> 8); + } + } + + public byte MaterialColorIndex + { + get => (byte)((Data2 >> 8) & 0xFFu); + set => Data2 = ((Data2 & 0xFFFF00FFu) | (value & 0xFFu)); + } + + public ushort Unk4 + { + get => (ushort)((Data2 >> 16) & 0xFFFFu); + set => Data2 = ((Data2 & 0x0000FFFFu) | ((value & 0xFFFFu) << 16)); + } + + public override string ToString() + { + return Data1.ToString() + ", " + Data2.ToString() + ", " + + Type.ToString() + ", " + ProceduralId.ToString() + ", " + RoomId.ToString() + ", " + PedDensity.ToString() + ", " + + Flags.ToString() + ", " + MaterialColorIndex.ToString() + ", " + Unk4.ToString(); + } + + #endregion + } + [TC(typeof(EXP))] public struct BoundMaterialColour + { + //public BoundsMaterialType Type { get; set; } + public byte R { get; set; } + public byte G { get; set; } + public byte B { get; set; } + public byte A { get; set; } //GIMS EVO saves this as "opacity" 0-100 + public override string ToString() + { + //return Type.ToString() + ", " + Unk0.ToString() + ", " + Unk1.ToString() + ", " + Unk2.ToString(); + return R.ToString() + ", " + G.ToString() + ", " + B.ToString() + ", " + A.ToString(); + } + } [TC(typeof(EXP))] public struct BoundsMaterialType { public byte Index { get; set; } @@ -2478,7 +2703,6 @@ namespace CodeWalker.GameFiles return new BoundsMaterialType() { Index = b }; } } - [TC(typeof(EXP))] public class BoundsMaterialData { public string Name { get; set; } @@ -2516,7 +2740,7 @@ namespace CodeWalker.GameFiles public static class BoundsMaterialTypes { private static Dictionary ColourDict; - private static List Materials; + public static List Materials; public static void Init(GameFileCache gameFileCache) { diff --git a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs index 2a92f68..f78a947 100644 --- a/CodeWalker.Core/GameFiles/Resources/ResourceData.cs +++ b/CodeWalker.Core/GameFiles/Resources/ResourceData.cs @@ -46,6 +46,8 @@ namespace CodeWalker.GameFiles private Stream systemStream; private Stream graphicsStream; + public RpfResourceFileEntry FileEntry { get; set; } + // this is a dictionary that contains all the resource blocks // which were read from this resource reader private Dictionary> blockPool; @@ -84,6 +86,7 @@ namespace CodeWalker.GameFiles public ResourceDataReader(RpfResourceFileEntry resentry, byte[] data, Endianess endianess = Endianess.LittleEndian) : base((Stream)null, endianess) { + FileEntry = resentry; var systemSize = resentry.SystemSize; var graphicsSize = resentry.GraphicsSize; diff --git a/CodeWalker.csproj b/CodeWalker.csproj index 812acf4..fcab0ca 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -140,6 +140,24 @@ + + Form + + + EditYbnBoundPolyPanel.cs + + + Form + + + EditYbnBoundsPanel.cs + + + Form + + + EditYbnPanel.cs + Form @@ -621,6 +639,15 @@ WorldForm.cs + + EditYbnBoundPolyPanel.cs + + + EditYbnBoundsPanel.cs + + + EditYbnPanel.cs + EditYtypMloEntSetPanel.cs diff --git a/Forms/ModelForm.cs b/Forms/ModelForm.cs index 55357c8..d60357d 100644 --- a/Forms/ModelForm.cs +++ b/Forms/ModelForm.cs @@ -686,7 +686,7 @@ namespace CodeWalker.Forms if (Ybn.Bounds != null) { - MoveCameraToView(Ybn.Bounds.BoundingBoxCenter, Ybn.Bounds.BoundingSphereRadius); + MoveCameraToView(Ybn.Bounds.SphereCenter, Ybn.Bounds.SphereRadius); } UpdateBoundsUI(ybn); diff --git a/Project/Panels/EditYbnBoundPolyPanel.Designer.cs b/Project/Panels/EditYbnBoundPolyPanel.Designer.cs new file mode 100644 index 0000000..1a61ca1 --- /dev/null +++ b/Project/Panels/EditYbnBoundPolyPanel.Designer.cs @@ -0,0 +1,926 @@ +namespace CodeWalker.Project.Panels +{ + partial class EditYbnBoundPolyPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EditYbnBoundPolyPanel)); + this.PolyTabControl = new System.Windows.Forms.TabControl(); + this.TriangleTabPage = new System.Windows.Forms.TabPage(); + this.SphereTabPage = new System.Windows.Forms.TabPage(); + this.CapsuleTabPage = new System.Windows.Forms.TabPage(); + this.BoxTabPage = new System.Windows.Forms.TabPage(); + this.CylinderTabPage = new System.Windows.Forms.TabPage(); + this.TriVertex3TextBox = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.TriVertex2TextBox = new System.Windows.Forms.TextBox(); + this.TriVertex1TextBox = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.TriAreaTextBox = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.TriEdge1UpDown = new System.Windows.Forms.NumericUpDown(); + this.label7 = new System.Windows.Forms.Label(); + this.TriEdge2UpDown = new System.Windows.Forms.NumericUpDown(); + this.label3 = new System.Windows.Forms.Label(); + this.TriEdge3UpDown = new System.Windows.Forms.NumericUpDown(); + this.label4 = new System.Windows.Forms.Label(); + this.TriFlag1CheckBox = new System.Windows.Forms.CheckBox(); + this.TriFlag2CheckBox = new System.Windows.Forms.CheckBox(); + this.TriFlag3CheckBox = new System.Windows.Forms.CheckBox(); + this.MaterialTabControl = new System.Windows.Forms.TabControl(); + this.MaterialTabPage = new System.Windows.Forms.TabPage(); + this.SphRadiusTextBox = new System.Windows.Forms.TextBox(); + this.SphPositionTextBox = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.label8 = new System.Windows.Forms.Label(); + this.CapRadiusTextBox = new System.Windows.Forms.TextBox(); + this.label9 = new System.Windows.Forms.Label(); + this.CapVertex2TextBox = new System.Windows.Forms.TextBox(); + this.CapVertex1TextBox = new System.Windows.Forms.TextBox(); + this.label10 = new System.Windows.Forms.Label(); + this.label12 = new System.Windows.Forms.Label(); + this.CylRadiusTextBox = new System.Windows.Forms.TextBox(); + this.label13 = new System.Windows.Forms.Label(); + this.CylVertex2TextBox = new System.Windows.Forms.TextBox(); + this.CylVertex1TextBox = new System.Windows.Forms.TextBox(); + this.label14 = new System.Windows.Forms.Label(); + this.label15 = new System.Windows.Forms.Label(); + this.BoxVertex4TextBox = new System.Windows.Forms.TextBox(); + this.label16 = new System.Windows.Forms.Label(); + this.BoxVertex3TextBox = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.BoxVertex2TextBox = new System.Windows.Forms.TextBox(); + this.BoxVertex1TextBox = new System.Windows.Forms.TextBox(); + this.label18 = new System.Windows.Forms.Label(); + this.label19 = new System.Windows.Forms.Label(); + this.MatTypeCombo = new System.Windows.Forms.ComboBox(); + this.label20 = new System.Windows.Forms.Label(); + this.MatUnkUpDown = new System.Windows.Forms.NumericUpDown(); + this.label21 = new System.Windows.Forms.Label(); + this.MatPedDensityUpDown = new System.Windows.Forms.NumericUpDown(); + this.label22 = new System.Windows.Forms.Label(); + this.MatRoomIDUpDown = new System.Windows.Forms.NumericUpDown(); + this.label23 = new System.Windows.Forms.Label(); + this.MatProceduralIDUpDown = new System.Windows.Forms.NumericUpDown(); + this.label24 = new System.Windows.Forms.Label(); + this.MatColourUpDown = new System.Windows.Forms.NumericUpDown(); + this.label25 = new System.Windows.Forms.Label(); + this.MatFlagsCheckedListBox = new System.Windows.Forms.CheckedListBox(); + this.PolyTabControl.SuspendLayout(); + this.TriangleTabPage.SuspendLayout(); + this.SphereTabPage.SuspendLayout(); + this.CapsuleTabPage.SuspendLayout(); + this.BoxTabPage.SuspendLayout(); + this.CylinderTabPage.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.TriEdge1UpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.TriEdge2UpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.TriEdge3UpDown)).BeginInit(); + this.MaterialTabControl.SuspendLayout(); + this.MaterialTabPage.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.MatUnkUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatPedDensityUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatRoomIDUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatProceduralIDUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatColourUpDown)).BeginInit(); + this.SuspendLayout(); + // + // PolyTabControl + // + this.PolyTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.PolyTabControl.Controls.Add(this.TriangleTabPage); + this.PolyTabControl.Controls.Add(this.SphereTabPage); + this.PolyTabControl.Controls.Add(this.CapsuleTabPage); + this.PolyTabControl.Controls.Add(this.BoxTabPage); + this.PolyTabControl.Controls.Add(this.CylinderTabPage); + this.PolyTabControl.Location = new System.Drawing.Point(0, 0); + this.PolyTabControl.Name = "PolyTabControl"; + this.PolyTabControl.SelectedIndex = 0; + this.PolyTabControl.Size = new System.Drawing.Size(564, 216); + this.PolyTabControl.TabIndex = 0; + // + // TriangleTabPage + // + this.TriangleTabPage.Controls.Add(this.TriFlag3CheckBox); + this.TriangleTabPage.Controls.Add(this.TriFlag2CheckBox); + this.TriangleTabPage.Controls.Add(this.TriFlag1CheckBox); + this.TriangleTabPage.Controls.Add(this.TriEdge3UpDown); + this.TriangleTabPage.Controls.Add(this.label4); + this.TriangleTabPage.Controls.Add(this.TriEdge2UpDown); + this.TriangleTabPage.Controls.Add(this.label3); + this.TriangleTabPage.Controls.Add(this.TriEdge1UpDown); + this.TriangleTabPage.Controls.Add(this.label7); + this.TriangleTabPage.Controls.Add(this.TriAreaTextBox); + this.TriangleTabPage.Controls.Add(this.label2); + this.TriangleTabPage.Controls.Add(this.TriVertex3TextBox); + this.TriangleTabPage.Controls.Add(this.label1); + this.TriangleTabPage.Controls.Add(this.TriVertex2TextBox); + this.TriangleTabPage.Controls.Add(this.TriVertex1TextBox); + this.TriangleTabPage.Controls.Add(this.label11); + this.TriangleTabPage.Controls.Add(this.label5); + this.TriangleTabPage.Location = new System.Drawing.Point(4, 22); + this.TriangleTabPage.Name = "TriangleTabPage"; + this.TriangleTabPage.Padding = new System.Windows.Forms.Padding(3); + this.TriangleTabPage.Size = new System.Drawing.Size(556, 190); + this.TriangleTabPage.TabIndex = 0; + this.TriangleTabPage.Text = "Triangle"; + this.TriangleTabPage.UseVisualStyleBackColor = true; + // + // SphereTabPage + // + this.SphereTabPage.Controls.Add(this.SphRadiusTextBox); + this.SphereTabPage.Controls.Add(this.SphPositionTextBox); + this.SphereTabPage.Controls.Add(this.label6); + this.SphereTabPage.Controls.Add(this.label8); + this.SphereTabPage.Location = new System.Drawing.Point(4, 22); + this.SphereTabPage.Name = "SphereTabPage"; + this.SphereTabPage.Padding = new System.Windows.Forms.Padding(3); + this.SphereTabPage.Size = new System.Drawing.Size(556, 190); + this.SphereTabPage.TabIndex = 1; + this.SphereTabPage.Text = "Sphere"; + this.SphereTabPage.UseVisualStyleBackColor = true; + // + // CapsuleTabPage + // + this.CapsuleTabPage.Controls.Add(this.CapRadiusTextBox); + this.CapsuleTabPage.Controls.Add(this.label9); + this.CapsuleTabPage.Controls.Add(this.CapVertex2TextBox); + this.CapsuleTabPage.Controls.Add(this.CapVertex1TextBox); + this.CapsuleTabPage.Controls.Add(this.label10); + this.CapsuleTabPage.Controls.Add(this.label12); + this.CapsuleTabPage.Location = new System.Drawing.Point(4, 22); + this.CapsuleTabPage.Name = "CapsuleTabPage"; + this.CapsuleTabPage.Size = new System.Drawing.Size(556, 190); + this.CapsuleTabPage.TabIndex = 2; + this.CapsuleTabPage.Text = "Capsule"; + this.CapsuleTabPage.UseVisualStyleBackColor = true; + // + // BoxTabPage + // + this.BoxTabPage.Controls.Add(this.BoxVertex4TextBox); + this.BoxTabPage.Controls.Add(this.label16); + this.BoxTabPage.Controls.Add(this.BoxVertex3TextBox); + this.BoxTabPage.Controls.Add(this.label17); + this.BoxTabPage.Controls.Add(this.BoxVertex2TextBox); + this.BoxTabPage.Controls.Add(this.BoxVertex1TextBox); + this.BoxTabPage.Controls.Add(this.label18); + this.BoxTabPage.Controls.Add(this.label19); + this.BoxTabPage.Location = new System.Drawing.Point(4, 22); + this.BoxTabPage.Name = "BoxTabPage"; + this.BoxTabPage.Size = new System.Drawing.Size(556, 190); + this.BoxTabPage.TabIndex = 3; + this.BoxTabPage.Text = "Box"; + this.BoxTabPage.UseVisualStyleBackColor = true; + // + // CylinderTabPage + // + this.CylinderTabPage.Controls.Add(this.CylRadiusTextBox); + this.CylinderTabPage.Controls.Add(this.label13); + this.CylinderTabPage.Controls.Add(this.CylVertex2TextBox); + this.CylinderTabPage.Controls.Add(this.CylVertex1TextBox); + this.CylinderTabPage.Controls.Add(this.label14); + this.CylinderTabPage.Controls.Add(this.label15); + this.CylinderTabPage.Location = new System.Drawing.Point(4, 22); + this.CylinderTabPage.Name = "CylinderTabPage"; + this.CylinderTabPage.Size = new System.Drawing.Size(556, 190); + this.CylinderTabPage.TabIndex = 4; + this.CylinderTabPage.Text = "Cylinder"; + this.CylinderTabPage.UseVisualStyleBackColor = true; + // + // TriVertex3TextBox + // + this.TriVertex3TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TriVertex3TextBox.Location = new System.Drawing.Point(92, 58); + this.TriVertex3TextBox.Name = "TriVertex3TextBox"; + this.TriVertex3TextBox.Size = new System.Drawing.Size(457, 20); + this.TriVertex3TextBox.TabIndex = 12; + this.TriVertex3TextBox.TextChanged += new System.EventHandler(this.TriVertex3TextBox_TextChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(37, 61); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(49, 13); + this.label1.TabIndex = 11; + this.label1.Text = "Vertex 3:"; + // + // TriVertex2TextBox + // + this.TriVertex2TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TriVertex2TextBox.Location = new System.Drawing.Point(92, 32); + this.TriVertex2TextBox.Name = "TriVertex2TextBox"; + this.TriVertex2TextBox.Size = new System.Drawing.Size(457, 20); + this.TriVertex2TextBox.TabIndex = 10; + this.TriVertex2TextBox.TextChanged += new System.EventHandler(this.TriVertex2TextBox_TextChanged); + // + // TriVertex1TextBox + // + this.TriVertex1TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TriVertex1TextBox.Location = new System.Drawing.Point(92, 6); + this.TriVertex1TextBox.Name = "TriVertex1TextBox"; + this.TriVertex1TextBox.Size = new System.Drawing.Size(457, 20); + this.TriVertex1TextBox.TabIndex = 8; + this.TriVertex1TextBox.TextChanged += new System.EventHandler(this.TriVertex1TextBox_TextChanged); + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(37, 35); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(49, 13); + this.label11.TabIndex = 9; + this.label11.Text = "Vertex 2:"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(37, 9); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(49, 13); + this.label5.TabIndex = 7; + this.label5.Text = "Vertex 1:"; + // + // TriAreaTextBox + // + this.TriAreaTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.TriAreaTextBox.Location = new System.Drawing.Point(92, 84); + this.TriAreaTextBox.Name = "TriAreaTextBox"; + this.TriAreaTextBox.Size = new System.Drawing.Size(457, 20); + this.TriAreaTextBox.TabIndex = 14; + this.TriAreaTextBox.TextChanged += new System.EventHandler(this.TriAreaTextBox_TextChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(54, 87); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(32, 13); + this.label2.TabIndex = 13; + this.label2.Text = "Area:"; + // + // TriEdge1UpDown + // + this.TriEdge1UpDown.Location = new System.Drawing.Point(92, 110); + this.TriEdge1UpDown.Maximum = new decimal(new int[] { + 32767, + 0, + 0, + 0}); + this.TriEdge1UpDown.Minimum = new decimal(new int[] { + 32767, + 0, + 0, + -2147483648}); + this.TriEdge1UpDown.Name = "TriEdge1UpDown"; + this.TriEdge1UpDown.Size = new System.Drawing.Size(89, 20); + this.TriEdge1UpDown.TabIndex = 16; + this.TriEdge1UpDown.ValueChanged += new System.EventHandler(this.TriEdge1UpDown_ValueChanged); + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(42, 112); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(44, 13); + this.label7.TabIndex = 15; + this.label7.Text = "Edge 1:"; + // + // TriEdge2UpDown + // + this.TriEdge2UpDown.Location = new System.Drawing.Point(92, 136); + this.TriEdge2UpDown.Maximum = new decimal(new int[] { + 32767, + 0, + 0, + 0}); + this.TriEdge2UpDown.Minimum = new decimal(new int[] { + 32767, + 0, + 0, + -2147483648}); + this.TriEdge2UpDown.Name = "TriEdge2UpDown"; + this.TriEdge2UpDown.Size = new System.Drawing.Size(89, 20); + this.TriEdge2UpDown.TabIndex = 18; + this.TriEdge2UpDown.ValueChanged += new System.EventHandler(this.TriEdge2UpDown_ValueChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(42, 138); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(44, 13); + this.label3.TabIndex = 17; + this.label3.Text = "Edge 2:"; + // + // TriEdge3UpDown + // + this.TriEdge3UpDown.Location = new System.Drawing.Point(92, 162); + this.TriEdge3UpDown.Maximum = new decimal(new int[] { + 32767, + 0, + 0, + 0}); + this.TriEdge3UpDown.Minimum = new decimal(new int[] { + 32767, + 0, + 0, + -2147483648}); + this.TriEdge3UpDown.Name = "TriEdge3UpDown"; + this.TriEdge3UpDown.Size = new System.Drawing.Size(89, 20); + this.TriEdge3UpDown.TabIndex = 20; + this.TriEdge3UpDown.ValueChanged += new System.EventHandler(this.TriEdge3UpDown_ValueChanged); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(42, 164); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(44, 13); + this.label4.TabIndex = 19; + this.label4.Text = "Edge 3:"; + // + // TriFlag1CheckBox + // + this.TriFlag1CheckBox.AutoSize = true; + this.TriFlag1CheckBox.Location = new System.Drawing.Point(224, 111); + this.TriFlag1CheckBox.Name = "TriFlag1CheckBox"; + this.TriFlag1CheckBox.Size = new System.Drawing.Size(55, 17); + this.TriFlag1CheckBox.TabIndex = 21; + this.TriFlag1CheckBox.Text = "Flag 1"; + this.TriFlag1CheckBox.UseVisualStyleBackColor = true; + this.TriFlag1CheckBox.CheckedChanged += new System.EventHandler(this.TriFlag1CheckBox_CheckedChanged); + // + // TriFlag2CheckBox + // + this.TriFlag2CheckBox.AutoSize = true; + this.TriFlag2CheckBox.Location = new System.Drawing.Point(224, 137); + this.TriFlag2CheckBox.Name = "TriFlag2CheckBox"; + this.TriFlag2CheckBox.Size = new System.Drawing.Size(55, 17); + this.TriFlag2CheckBox.TabIndex = 22; + this.TriFlag2CheckBox.Text = "Flag 2"; + this.TriFlag2CheckBox.UseVisualStyleBackColor = true; + this.TriFlag2CheckBox.CheckedChanged += new System.EventHandler(this.TriFlag2CheckBox_CheckedChanged); + // + // TriFlag3CheckBox + // + this.TriFlag3CheckBox.AutoSize = true; + this.TriFlag3CheckBox.Location = new System.Drawing.Point(224, 163); + this.TriFlag3CheckBox.Name = "TriFlag3CheckBox"; + this.TriFlag3CheckBox.Size = new System.Drawing.Size(55, 17); + this.TriFlag3CheckBox.TabIndex = 23; + this.TriFlag3CheckBox.Text = "Flag 3"; + this.TriFlag3CheckBox.UseVisualStyleBackColor = true; + this.TriFlag3CheckBox.CheckedChanged += new System.EventHandler(this.TriFlag3CheckBox_CheckedChanged); + // + // MaterialTabControl + // + this.MaterialTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.MaterialTabControl.Controls.Add(this.MaterialTabPage); + this.MaterialTabControl.Location = new System.Drawing.Point(0, 218); + this.MaterialTabControl.Name = "MaterialTabControl"; + this.MaterialTabControl.SelectedIndex = 0; + this.MaterialTabControl.Size = new System.Drawing.Size(564, 286); + this.MaterialTabControl.TabIndex = 1; + // + // MaterialTabPage + // + this.MaterialTabPage.Controls.Add(this.MatFlagsCheckedListBox); + this.MaterialTabPage.Controls.Add(this.MatColourUpDown); + this.MaterialTabPage.Controls.Add(this.label25); + this.MaterialTabPage.Controls.Add(this.MatUnkUpDown); + this.MaterialTabPage.Controls.Add(this.label21); + this.MaterialTabPage.Controls.Add(this.MatPedDensityUpDown); + this.MaterialTabPage.Controls.Add(this.label22); + this.MaterialTabPage.Controls.Add(this.MatRoomIDUpDown); + this.MaterialTabPage.Controls.Add(this.label23); + this.MaterialTabPage.Controls.Add(this.MatProceduralIDUpDown); + this.MaterialTabPage.Controls.Add(this.label24); + this.MaterialTabPage.Controls.Add(this.MatTypeCombo); + this.MaterialTabPage.Controls.Add(this.label20); + this.MaterialTabPage.Location = new System.Drawing.Point(4, 22); + this.MaterialTabPage.Name = "MaterialTabPage"; + this.MaterialTabPage.Padding = new System.Windows.Forms.Padding(3); + this.MaterialTabPage.Size = new System.Drawing.Size(556, 260); + this.MaterialTabPage.TabIndex = 0; + this.MaterialTabPage.Text = "Material"; + this.MaterialTabPage.UseVisualStyleBackColor = true; + // + // SphRadiusTextBox + // + this.SphRadiusTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.SphRadiusTextBox.Location = new System.Drawing.Point(92, 32); + this.SphRadiusTextBox.Name = "SphRadiusTextBox"; + this.SphRadiusTextBox.Size = new System.Drawing.Size(457, 20); + this.SphRadiusTextBox.TabIndex = 14; + this.SphRadiusTextBox.TextChanged += new System.EventHandler(this.SphRadiusTextBox_TextChanged); + // + // SphPositionTextBox + // + this.SphPositionTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.SphPositionTextBox.Location = new System.Drawing.Point(92, 6); + this.SphPositionTextBox.Name = "SphPositionTextBox"; + this.SphPositionTextBox.Size = new System.Drawing.Size(457, 20); + this.SphPositionTextBox.TabIndex = 12; + this.SphPositionTextBox.TextChanged += new System.EventHandler(this.SphPositionTextBox_TextChanged); + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(37, 35); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(43, 13); + this.label6.TabIndex = 13; + this.label6.Text = "Radius:"; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(37, 9); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(47, 13); + this.label8.TabIndex = 11; + this.label8.Text = "Position:"; + // + // CapRadiusTextBox + // + this.CapRadiusTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CapRadiusTextBox.Location = new System.Drawing.Point(92, 58); + this.CapRadiusTextBox.Name = "CapRadiusTextBox"; + this.CapRadiusTextBox.Size = new System.Drawing.Size(457, 20); + this.CapRadiusTextBox.TabIndex = 18; + this.CapRadiusTextBox.TextChanged += new System.EventHandler(this.CapRadiusTextBox_TextChanged); + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(37, 61); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(43, 13); + this.label9.TabIndex = 17; + this.label9.Text = "Radius:"; + // + // CapVertex2TextBox + // + this.CapVertex2TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CapVertex2TextBox.Location = new System.Drawing.Point(92, 32); + this.CapVertex2TextBox.Name = "CapVertex2TextBox"; + this.CapVertex2TextBox.Size = new System.Drawing.Size(457, 20); + this.CapVertex2TextBox.TabIndex = 16; + this.CapVertex2TextBox.TextChanged += new System.EventHandler(this.CapVertex2TextBox_TextChanged); + // + // CapVertex1TextBox + // + this.CapVertex1TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CapVertex1TextBox.Location = new System.Drawing.Point(92, 6); + this.CapVertex1TextBox.Name = "CapVertex1TextBox"; + this.CapVertex1TextBox.Size = new System.Drawing.Size(457, 20); + this.CapVertex1TextBox.TabIndex = 14; + this.CapVertex1TextBox.TextChanged += new System.EventHandler(this.CapVertex1TextBox_TextChanged); + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(37, 35); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(49, 13); + this.label10.TabIndex = 15; + this.label10.Text = "Vertex 2:"; + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(37, 9); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(49, 13); + this.label12.TabIndex = 13; + this.label12.Text = "Vertex 1:"; + // + // CylRadiusTextBox + // + this.CylRadiusTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CylRadiusTextBox.Location = new System.Drawing.Point(92, 58); + this.CylRadiusTextBox.Name = "CylRadiusTextBox"; + this.CylRadiusTextBox.Size = new System.Drawing.Size(457, 20); + this.CylRadiusTextBox.TabIndex = 24; + this.CylRadiusTextBox.TextChanged += new System.EventHandler(this.CylRadiusTextBox_TextChanged); + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Location = new System.Drawing.Point(37, 61); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(43, 13); + this.label13.TabIndex = 23; + this.label13.Text = "Radius:"; + // + // CylVertex2TextBox + // + this.CylVertex2TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CylVertex2TextBox.Location = new System.Drawing.Point(92, 32); + this.CylVertex2TextBox.Name = "CylVertex2TextBox"; + this.CylVertex2TextBox.Size = new System.Drawing.Size(457, 20); + this.CylVertex2TextBox.TabIndex = 22; + this.CylVertex2TextBox.TextChanged += new System.EventHandler(this.CylVertex2TextBox_TextChanged); + // + // CylVertex1TextBox + // + this.CylVertex1TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CylVertex1TextBox.Location = new System.Drawing.Point(92, 6); + this.CylVertex1TextBox.Name = "CylVertex1TextBox"; + this.CylVertex1TextBox.Size = new System.Drawing.Size(457, 20); + this.CylVertex1TextBox.TabIndex = 20; + this.CylVertex1TextBox.TextChanged += new System.EventHandler(this.CylVertex1TextBox_TextChanged); + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(37, 35); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(49, 13); + this.label14.TabIndex = 21; + this.label14.Text = "Vertex 2:"; + // + // label15 + // + this.label15.AutoSize = true; + this.label15.Location = new System.Drawing.Point(37, 9); + this.label15.Name = "label15"; + this.label15.Size = new System.Drawing.Size(49, 13); + this.label15.TabIndex = 19; + this.label15.Text = "Vertex 1:"; + // + // BoxVertex4TextBox + // + this.BoxVertex4TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BoxVertex4TextBox.Location = new System.Drawing.Point(92, 84); + this.BoxVertex4TextBox.Name = "BoxVertex4TextBox"; + this.BoxVertex4TextBox.Size = new System.Drawing.Size(457, 20); + this.BoxVertex4TextBox.TabIndex = 22; + this.BoxVertex4TextBox.TextChanged += new System.EventHandler(this.BoxVertex4TextBox_TextChanged); + // + // label16 + // + this.label16.AutoSize = true; + this.label16.Location = new System.Drawing.Point(37, 87); + this.label16.Name = "label16"; + this.label16.Size = new System.Drawing.Size(49, 13); + this.label16.TabIndex = 21; + this.label16.Text = "Vertex 4:"; + // + // BoxVertex3TextBox + // + this.BoxVertex3TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BoxVertex3TextBox.Location = new System.Drawing.Point(92, 58); + this.BoxVertex3TextBox.Name = "BoxVertex3TextBox"; + this.BoxVertex3TextBox.Size = new System.Drawing.Size(457, 20); + this.BoxVertex3TextBox.TabIndex = 20; + this.BoxVertex3TextBox.TextChanged += new System.EventHandler(this.BoxVertex3TextBox_TextChanged); + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(37, 61); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(49, 13); + this.label17.TabIndex = 19; + this.label17.Text = "Vertex 3:"; + // + // BoxVertex2TextBox + // + this.BoxVertex2TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BoxVertex2TextBox.Location = new System.Drawing.Point(92, 32); + this.BoxVertex2TextBox.Name = "BoxVertex2TextBox"; + this.BoxVertex2TextBox.Size = new System.Drawing.Size(457, 20); + this.BoxVertex2TextBox.TabIndex = 18; + this.BoxVertex2TextBox.TextChanged += new System.EventHandler(this.BoxVertex2TextBox_TextChanged); + // + // BoxVertex1TextBox + // + this.BoxVertex1TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BoxVertex1TextBox.Location = new System.Drawing.Point(92, 6); + this.BoxVertex1TextBox.Name = "BoxVertex1TextBox"; + this.BoxVertex1TextBox.Size = new System.Drawing.Size(457, 20); + this.BoxVertex1TextBox.TabIndex = 16; + this.BoxVertex1TextBox.TextChanged += new System.EventHandler(this.BoxVertex1TextBox_TextChanged); + // + // label18 + // + this.label18.AutoSize = true; + this.label18.Location = new System.Drawing.Point(37, 35); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(49, 13); + this.label18.TabIndex = 17; + this.label18.Text = "Vertex 2:"; + // + // label19 + // + this.label19.AutoSize = true; + this.label19.Location = new System.Drawing.Point(37, 9); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(49, 13); + this.label19.TabIndex = 15; + this.label19.Text = "Vertex 1:"; + // + // MatTypeCombo + // + this.MatTypeCombo.FormattingEnabled = true; + this.MatTypeCombo.Location = new System.Drawing.Point(92, 9); + this.MatTypeCombo.Name = "MatTypeCombo"; + this.MatTypeCombo.Size = new System.Drawing.Size(195, 21); + this.MatTypeCombo.TabIndex = 20; + this.MatTypeCombo.SelectedIndexChanged += new System.EventHandler(this.MatTypeCombo_SelectedIndexChanged); + // + // label20 + // + this.label20.AutoSize = true; + this.label20.Location = new System.Drawing.Point(39, 12); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(47, 13); + this.label20.TabIndex = 19; + this.label20.Text = "Material:"; + // + // MatUnkUpDown + // + this.MatUnkUpDown.Location = new System.Drawing.Point(92, 140); + this.MatUnkUpDown.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.MatUnkUpDown.Name = "MatUnkUpDown"; + this.MatUnkUpDown.Size = new System.Drawing.Size(64, 20); + this.MatUnkUpDown.TabIndex = 30; + this.MatUnkUpDown.ValueChanged += new System.EventHandler(this.MatUnkUpDown_ValueChanged); + // + // label21 + // + this.label21.AutoSize = true; + this.label21.Location = new System.Drawing.Point(56, 142); + this.label21.Name = "label21"; + this.label21.Size = new System.Drawing.Size(30, 13); + this.label21.TabIndex = 29; + this.label21.Text = "Unk:"; + // + // MatPedDensityUpDown + // + this.MatPedDensityUpDown.Location = new System.Drawing.Point(92, 114); + this.MatPedDensityUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.MatPedDensityUpDown.Name = "MatPedDensityUpDown"; + this.MatPedDensityUpDown.Size = new System.Drawing.Size(64, 20); + this.MatPedDensityUpDown.TabIndex = 28; + this.MatPedDensityUpDown.ValueChanged += new System.EventHandler(this.MatPedDensityUpDown_ValueChanged); + // + // label22 + // + this.label22.AutoSize = true; + this.label22.Location = new System.Drawing.Point(19, 116); + this.label22.Name = "label22"; + this.label22.Size = new System.Drawing.Size(67, 13); + this.label22.TabIndex = 27; + this.label22.Text = "Ped Density:"; + // + // MatRoomIDUpDown + // + this.MatRoomIDUpDown.Location = new System.Drawing.Point(92, 88); + this.MatRoomIDUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.MatRoomIDUpDown.Name = "MatRoomIDUpDown"; + this.MatRoomIDUpDown.Size = new System.Drawing.Size(64, 20); + this.MatRoomIDUpDown.TabIndex = 26; + this.MatRoomIDUpDown.ValueChanged += new System.EventHandler(this.MatRoomIDUpDown_ValueChanged); + // + // label23 + // + this.label23.AutoSize = true; + this.label23.Location = new System.Drawing.Point(34, 90); + this.label23.Name = "label23"; + this.label23.Size = new System.Drawing.Size(52, 13); + this.label23.TabIndex = 25; + this.label23.Text = "Room ID:"; + // + // MatProceduralIDUpDown + // + this.MatProceduralIDUpDown.Location = new System.Drawing.Point(92, 62); + this.MatProceduralIDUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.MatProceduralIDUpDown.Name = "MatProceduralIDUpDown"; + this.MatProceduralIDUpDown.Size = new System.Drawing.Size(64, 20); + this.MatProceduralIDUpDown.TabIndex = 24; + this.MatProceduralIDUpDown.ValueChanged += new System.EventHandler(this.MatProceduralIDUpDown_ValueChanged); + // + // label24 + // + this.label24.AutoSize = true; + this.label24.Location = new System.Drawing.Point(11, 64); + this.label24.Name = "label24"; + this.label24.Size = new System.Drawing.Size(75, 13); + this.label24.TabIndex = 23; + this.label24.Text = "Procedural ID:"; + // + // MatColourUpDown + // + this.MatColourUpDown.Location = new System.Drawing.Point(92, 36); + this.MatColourUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.MatColourUpDown.Name = "MatColourUpDown"; + this.MatColourUpDown.Size = new System.Drawing.Size(64, 20); + this.MatColourUpDown.TabIndex = 22; + this.MatColourUpDown.ValueChanged += new System.EventHandler(this.MatColourUpDown_ValueChanged); + // + // label25 + // + this.label25.AutoSize = true; + this.label25.Location = new System.Drawing.Point(6, 38); + this.label25.Name = "label25"; + this.label25.Size = new System.Drawing.Size(80, 13); + this.label25.TabIndex = 21; + this.label25.Text = "Material Colour:"; + // + // MatFlagsCheckedListBox + // + this.MatFlagsCheckedListBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.MatFlagsCheckedListBox.CheckOnClick = true; + this.MatFlagsCheckedListBox.FormattingEnabled = true; + this.MatFlagsCheckedListBox.Items.AddRange(new object[] { + "0 - Stairs", + "1 - Not Climbable", + "2 - See Through", + "3 - Shoot Through", + "4 - Not Cover", + "5 - Walkable Path", + "6 - No Cam Collision", + "7 - Shoot Through FX", + "8 - No Decal", + "9 - No Navmesh", + "10 - No Ragdoll", + "11 - Vehicle Wheel", + "12 - No PTFX", + "13 - Too Steep for Player", + "14 - No Network Spawn", + "15 - No Cam Collision Allow Clipping"}); + this.MatFlagsCheckedListBox.Location = new System.Drawing.Point(326, 9); + this.MatFlagsCheckedListBox.Name = "MatFlagsCheckedListBox"; + this.MatFlagsCheckedListBox.Size = new System.Drawing.Size(223, 244); + this.MatFlagsCheckedListBox.TabIndex = 31; + this.MatFlagsCheckedListBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.MatFlagsCheckedListBox_ItemCheck); + // + // EditYbnBoundPolyPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(565, 505); + this.Controls.Add(this.MaterialTabControl); + this.Controls.Add(this.PolyTabControl); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EditYbnBoundPolyPanel"; + this.Text = "EditYbnBoundPolyPanel"; + this.PolyTabControl.ResumeLayout(false); + this.TriangleTabPage.ResumeLayout(false); + this.TriangleTabPage.PerformLayout(); + this.SphereTabPage.ResumeLayout(false); + this.SphereTabPage.PerformLayout(); + this.CapsuleTabPage.ResumeLayout(false); + this.CapsuleTabPage.PerformLayout(); + this.BoxTabPage.ResumeLayout(false); + this.BoxTabPage.PerformLayout(); + this.CylinderTabPage.ResumeLayout(false); + this.CylinderTabPage.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.TriEdge1UpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.TriEdge2UpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.TriEdge3UpDown)).EndInit(); + this.MaterialTabControl.ResumeLayout(false); + this.MaterialTabPage.ResumeLayout(false); + this.MaterialTabPage.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.MatUnkUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatPedDensityUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatRoomIDUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatProceduralIDUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MatColourUpDown)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl PolyTabControl; + private System.Windows.Forms.TabPage TriangleTabPage; + private System.Windows.Forms.TabPage SphereTabPage; + private System.Windows.Forms.TabPage CapsuleTabPage; + private System.Windows.Forms.TabPage BoxTabPage; + private System.Windows.Forms.TabPage CylinderTabPage; + private System.Windows.Forms.TextBox TriVertex3TextBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox TriVertex2TextBox; + private System.Windows.Forms.TextBox TriVertex1TextBox; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox TriAreaTextBox; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.NumericUpDown TriEdge1UpDown; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.NumericUpDown TriEdge3UpDown; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.NumericUpDown TriEdge2UpDown; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.CheckBox TriFlag3CheckBox; + private System.Windows.Forms.CheckBox TriFlag2CheckBox; + private System.Windows.Forms.CheckBox TriFlag1CheckBox; + private System.Windows.Forms.TabControl MaterialTabControl; + private System.Windows.Forms.TabPage MaterialTabPage; + private System.Windows.Forms.TextBox SphRadiusTextBox; + private System.Windows.Forms.TextBox SphPositionTextBox; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.TextBox CapRadiusTextBox; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.TextBox CapVertex2TextBox; + private System.Windows.Forms.TextBox CapVertex1TextBox; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.TextBox BoxVertex4TextBox; + private System.Windows.Forms.Label label16; + private System.Windows.Forms.TextBox BoxVertex3TextBox; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.TextBox BoxVertex2TextBox; + private System.Windows.Forms.TextBox BoxVertex1TextBox; + private System.Windows.Forms.Label label18; + private System.Windows.Forms.Label label19; + private System.Windows.Forms.TextBox CylRadiusTextBox; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TextBox CylVertex2TextBox; + private System.Windows.Forms.TextBox CylVertex1TextBox; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.ComboBox MatTypeCombo; + private System.Windows.Forms.Label label20; + private System.Windows.Forms.NumericUpDown MatUnkUpDown; + private System.Windows.Forms.Label label21; + private System.Windows.Forms.NumericUpDown MatPedDensityUpDown; + private System.Windows.Forms.Label label22; + private System.Windows.Forms.NumericUpDown MatRoomIDUpDown; + private System.Windows.Forms.Label label23; + private System.Windows.Forms.NumericUpDown MatProceduralIDUpDown; + private System.Windows.Forms.Label label24; + private System.Windows.Forms.NumericUpDown MatColourUpDown; + private System.Windows.Forms.Label label25; + private System.Windows.Forms.CheckedListBox MatFlagsCheckedListBox; + } +} \ No newline at end of file diff --git a/Project/Panels/EditYbnBoundPolyPanel.cs b/Project/Panels/EditYbnBoundPolyPanel.cs new file mode 100644 index 0000000..93acf57 --- /dev/null +++ b/Project/Panels/EditYbnBoundPolyPanel.cs @@ -0,0 +1,609 @@ +using CodeWalker.GameFiles; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CodeWalker.Project.Panels +{ + public partial class EditYbnBoundPolyPanel : ProjectPanel + { + public ProjectForm ProjectForm; + public BoundPolygon CollisionPoly { get; set; } + public BoundPolygonTriangle CollisionTriangle { get; set; } + public BoundPolygonSphere CollisionSphere { get; set; } + public BoundPolygonCapsule CollisionCapsule { get; set; } + public BoundPolygonBox CollisionBox { get; set; } + public BoundPolygonCylinder CollisionCylinder { get; set; } + + private bool populatingui = false; + private bool waschanged = false; + + public EditYbnBoundPolyPanel(ProjectForm projectForm) + { + ProjectForm = projectForm; + InitializeComponent(); + + LoadDropDowns(); + } + + private void LoadDropDowns() + { + MatTypeCombo.Items.Clear(); + if (BoundsMaterialTypes.Materials == null) return; + foreach (var mat in BoundsMaterialTypes.Materials) + { + MatTypeCombo.Items.Add(mat); + } + } + + public void SetCollisionPoly(BoundPolygon b) + { + CollisionPoly = b; + CollisionTriangle = b as BoundPolygonTriangle; + CollisionSphere = b as BoundPolygonSphere; + CollisionCapsule = b as BoundPolygonCapsule; + CollisionBox = b as BoundPolygonBox; + CollisionCylinder = b as BoundPolygonCylinder; + Tag = b; + UpdateFormTitle(); + UpdateUI(); + waschanged = b?.Owner?.HasChanged ?? false; + } + + public void UpdateFormTitleYbnChanged() + { + bool changed = CollisionPoly?.Owner?.HasChanged ?? false; + if (!waschanged && changed) + { + UpdateFormTitle(); + waschanged = true; + } + else if (waschanged && !changed) + { + UpdateFormTitle(); + waschanged = false; + } + } + private void UpdateFormTitle() + { + string fn = CollisionPoly?.Title ?? "untitled"; + Text = fn + ((CollisionPoly?.Owner?.HasChanged ?? false) ? "*" : ""); + } + + + public void UpdateUI() + { + if (CollisionPoly == null) + { + PolyTabControl.TabPages.Clear(); + TriVertex1TextBox.Text = string.Empty; + TriVertex2TextBox.Text = string.Empty; + TriVertex3TextBox.Text = string.Empty; + TriAreaTextBox.Text = string.Empty; + TriEdge1UpDown.Value = 0; + TriEdge2UpDown.Value = 0; + TriEdge3UpDown.Value = 0; + TriFlag1CheckBox.Checked = false; + TriFlag2CheckBox.Checked = false; + TriFlag3CheckBox.Checked = false; + SphPositionTextBox.Text = string.Empty; + SphRadiusTextBox.Text = string.Empty; + CapVertex1TextBox.Text = string.Empty; + CapVertex2TextBox.Text = string.Empty; + CapRadiusTextBox.Text = string.Empty; + BoxVertex1TextBox.Text = string.Empty; + BoxVertex2TextBox.Text = string.Empty; + BoxVertex3TextBox.Text = string.Empty; + BoxVertex4TextBox.Text = string.Empty; + CylVertex1TextBox.Text = string.Empty; + CylVertex2TextBox.Text = string.Empty; + CylRadiusTextBox.Text = string.Empty; + MatTypeCombo.Text = string.Empty; + MatColourUpDown.Value = 0; + MatProceduralIDUpDown.Value = 0; + MatRoomIDUpDown.Value = 0; + MatPedDensityUpDown.Value = 0; + MatUnkUpDown.Value = 0; + SetCheckedListBoxValues(MatFlagsCheckedListBox, 0); + } + else + { + populatingui = true; + + if (CollisionTriangle != null) + { + TriVertex1TextBox.Text = FloatUtil.GetVector3String(CollisionTriangle.Vertex1); + TriVertex2TextBox.Text = FloatUtil.GetVector3String(CollisionTriangle.Vertex2); + TriVertex3TextBox.Text = FloatUtil.GetVector3String(CollisionTriangle.Vertex3); + TriAreaTextBox.Text = FloatUtil.ToString(CollisionTriangle.triArea); + TriEdge1UpDown.Value = CollisionTriangle.edgeIndex1; + TriEdge2UpDown.Value = CollisionTriangle.edgeIndex2; + TriEdge3UpDown.Value = CollisionTriangle.edgeIndex3; + TriFlag1CheckBox.Checked = CollisionTriangle.vertFlag1; + TriFlag2CheckBox.Checked = CollisionTriangle.vertFlag2; + TriFlag3CheckBox.Checked = CollisionTriangle.vertFlag3; + if (!PolyTabControl.TabPages.Contains(TriangleTabPage)) PolyTabControl.TabPages.Add(TriangleTabPage); + } + else + { + PolyTabControl.TabPages.Remove(TriangleTabPage); + } + + if (CollisionSphere != null) + { + SphPositionTextBox.Text = FloatUtil.GetVector3String(CollisionSphere.Position); + SphRadiusTextBox.Text = FloatUtil.ToString(CollisionSphere.sphereRadius); + if (!PolyTabControl.TabPages.Contains(SphereTabPage)) PolyTabControl.TabPages.Add(SphereTabPage); + } + else + { + PolyTabControl.TabPages.Remove(SphereTabPage); + } + + if (CollisionCapsule != null) + { + CapVertex1TextBox.Text = FloatUtil.GetVector3String(CollisionCapsule.Vertex1); + CapVertex2TextBox.Text = FloatUtil.GetVector3String(CollisionCapsule.Vertex2); + CapRadiusTextBox.Text = FloatUtil.ToString(CollisionCapsule.capsuleRadius); + if (!PolyTabControl.TabPages.Contains(CapsuleTabPage)) PolyTabControl.TabPages.Add(CapsuleTabPage); + } + else + { + PolyTabControl.TabPages.Remove(CapsuleTabPage); + } + + if (CollisionBox != null) + { + BoxVertex1TextBox.Text = FloatUtil.GetVector3String(CollisionBox.Vertex1); + BoxVertex2TextBox.Text = FloatUtil.GetVector3String(CollisionBox.Vertex2); + BoxVertex3TextBox.Text = FloatUtil.GetVector3String(CollisionBox.Vertex3); + BoxVertex4TextBox.Text = FloatUtil.GetVector3String(CollisionBox.Vertex4); + if (!PolyTabControl.TabPages.Contains(BoxTabPage)) PolyTabControl.TabPages.Add(BoxTabPage); + } + else + { + PolyTabControl.TabPages.Remove(BoxTabPage); + } + + if (CollisionCylinder != null) + { + CylVertex1TextBox.Text = FloatUtil.GetVector3String(CollisionCylinder.Vertex1); + CylVertex2TextBox.Text = FloatUtil.GetVector3String(CollisionCylinder.Vertex1); + CylRadiusTextBox.Text = FloatUtil.ToString(CollisionCylinder.cylinderRadius); + if (!PolyTabControl.TabPages.Contains(CylinderTabPage)) PolyTabControl.TabPages.Add(CylinderTabPage); + } + else + { + PolyTabControl.TabPages.Remove(CylinderTabPage); + } + + var m = CollisionPoly.Material; + MatTypeCombo.SelectedIndex = m.Type.Index; + MatColourUpDown.Value = m.MaterialColorIndex; + MatProceduralIDUpDown.Value = m.ProceduralId; + MatRoomIDUpDown.Value = m.RoomId; + MatPedDensityUpDown.Value = m.PedDensity; + MatUnkUpDown.Value = m.Unk4; + SetCheckedListBoxValues(MatFlagsCheckedListBox, (ushort)m.Flags); + + populatingui = false; + } + } + + private void SetCheckedListBoxValues(CheckedListBox clb, uint flags) + { + for (int i = 0; i < clb.Items.Count; i++) + { + var c = ((flags & (1 << i)) > 0); + clb.SetItemCheckState(i, c ? CheckState.Checked : CheckState.Unchecked); + } + } + private uint GetCheckedListBoxValues(CheckedListBox clb, ItemCheckEventArgs e) + { + uint r = 0; + for (int i = 0; i < clb.Items.Count; i++) + { + if ((e != null) && (e.Index == i)) + { + if (e.NewValue == CheckState.Checked) + { + r += (uint)(1 << i); + } + } + else + { + bool v = clb.GetItemChecked(i);// == CheckState.Checked; + r = BitUtil.UpdateBit(r, i, v); + } + } + return r; + } + + + + private void TriVertex1TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(TriVertex1TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.Vertex1 != v) + { + CollisionTriangle.Vertex1 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriVertex2TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(TriVertex2TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.Vertex2 != v) + { + CollisionTriangle.Vertex2 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriVertex3TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(TriVertex3TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.Vertex3 != v) + { + CollisionTriangle.Vertex3 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriAreaTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(TriAreaTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.triArea != v) + { + CollisionTriangle.triArea = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriEdge1UpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = (short)TriEdge1UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.edgeIndex1 != v) + { + CollisionTriangle.edgeIndex1 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriEdge2UpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = (short)TriEdge2UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.edgeIndex2 != v) + { + CollisionTriangle.edgeIndex2 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriEdge3UpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = (short)TriEdge3UpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.edgeIndex3 != v) + { + CollisionTriangle.edgeIndex3 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriFlag1CheckBox_CheckedChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = TriFlag1CheckBox.Checked; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.vertFlag1 != v) + { + CollisionTriangle.vertFlag1 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriFlag2CheckBox_CheckedChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = TriFlag2CheckBox.Checked; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.vertFlag2 != v) + { + CollisionTriangle.vertFlag2 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void TriFlag3CheckBox_CheckedChanged(object sender, EventArgs e) + { + if (CollisionTriangle == null) return; + if (populatingui) return; + var v = TriFlag3CheckBox.Checked; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionTriangle.vertFlag3 != v) + { + CollisionTriangle.vertFlag3 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void SphPositionTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionSphere == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(SphPositionTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionSphere.Position != v) + { + CollisionSphere.Position = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void SphRadiusTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionSphere == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(SphRadiusTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionSphere.sphereRadius != v) + { + CollisionSphere.sphereRadius = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void CapVertex1TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionCapsule == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(CapVertex1TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionCapsule.Vertex1 != v) + { + CollisionCapsule.Vertex1 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void CapVertex2TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionCapsule == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(CapVertex2TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionCapsule.Vertex2 != v) + { + CollisionCapsule.Vertex2 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void CapRadiusTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionCapsule == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(CapRadiusTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionCapsule.capsuleRadius != v) + { + CollisionCapsule.capsuleRadius = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BoxVertex1TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBox == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BoxVertex1TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBox.Vertex1 != v) + { + CollisionBox.Vertex1 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BoxVertex2TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBox == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BoxVertex2TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBox.Vertex2 != v) + { + CollisionBox.Vertex2 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BoxVertex3TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBox == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BoxVertex3TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBox.Vertex3 != v) + { + CollisionBox.Vertex3 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BoxVertex4TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBox == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BoxVertex4TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBox.Vertex4 != v) + { + CollisionBox.Vertex4 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void CylVertex1TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionCylinder == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(CylVertex1TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionCylinder.Vertex1 != v) + { + CollisionCylinder.Vertex1 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void CylVertex2TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionCylinder == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(CylVertex2TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionCylinder.Vertex2 != v) + { + CollisionCylinder.Vertex2 = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void CylRadiusTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionCylinder == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(CylRadiusTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionCylinder.cylinderRadius != v) + { + CollisionCylinder.cylinderRadius = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void MatTypeCombo_SelectedIndexChanged(object sender, EventArgs e) + { + if (CollisionPoly == null) return; + if (populatingui) return; + + } + + private void MatColourUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionPoly == null) return; + if (populatingui) return; + + } + + private void MatProceduralIDUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionPoly == null) return; + if (populatingui) return; + + } + + private void MatRoomIDUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionPoly == null) return; + if (populatingui) return; + + } + + private void MatPedDensityUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionPoly == null) return; + if (populatingui) return; + + } + + private void MatUnkUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionPoly == null) return; + if (populatingui) return; + + } + + private void MatFlagsCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e) + { + if (CollisionPoly == null) return; + if (populatingui) return; + + } + } +} diff --git a/Project/Panels/EditYbnBoundPolyPanel.resx b/Project/Panels/EditYbnBoundPolyPanel.resx new file mode 100644 index 0000000..1431f6b --- /dev/null +++ b/Project/Panels/EditYbnBoundPolyPanel.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f// + /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA + AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc + skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU + 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq + +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz + /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR + p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm + +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB + AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/ + /f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/ + +fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd + 4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/ + 1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + /v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA + /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/ + 9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA + AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA + /v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/ + /P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/ + /f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// + ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB/////// + //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA + H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A + A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA + /f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A + AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf + AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4 + AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A// + ///////gD/////////Af//////////////8= + + + \ No newline at end of file diff --git a/Project/Panels/EditYbnBoundsPanel.Designer.cs b/Project/Panels/EditYbnBoundsPanel.Designer.cs new file mode 100644 index 0000000..29937d6 --- /dev/null +++ b/Project/Panels/EditYbnBoundsPanel.Designer.cs @@ -0,0 +1,653 @@ +namespace CodeWalker.Project.Panels +{ + partial class EditYbnBoundsPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EditYbnBoundsPanel)); + this.BoundsTabControl = new System.Windows.Forms.TabControl(); + this.BoundsTabPage = new System.Windows.Forms.TabPage(); + this.MaterialCombo = new System.Windows.Forms.ComboBox(); + this.UnkTypeUpDown = new System.Windows.Forms.NumericUpDown(); + this.label16 = new System.Windows.Forms.Label(); + this.label15 = new System.Windows.Forms.Label(); + this.UnkVectorTextBox = new System.Windows.Forms.TextBox(); + this.label14 = new System.Windows.Forms.Label(); + this.VolumeTextBox = new System.Windows.Forms.TextBox(); + this.UnkFlagsUpDown = new System.Windows.Forms.NumericUpDown(); + this.label9 = new System.Windows.Forms.Label(); + this.PolyFlagsUpDown = new System.Windows.Forms.NumericUpDown(); + this.label8 = new System.Windows.Forms.Label(); + this.MaterialColourUpDown = new System.Windows.Forms.NumericUpDown(); + this.label7 = new System.Windows.Forms.Label(); + this.PedDensityUpDown = new System.Windows.Forms.NumericUpDown(); + this.label6 = new System.Windows.Forms.Label(); + this.RoomIDUpDown = new System.Windows.Forms.NumericUpDown(); + this.label4 = new System.Windows.Forms.Label(); + this.ProceduralIDUpDown = new System.Windows.Forms.NumericUpDown(); + this.label3 = new System.Windows.Forms.Label(); + this.label10 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.MarginTextBox = new System.Windows.Forms.TextBox(); + this.BBCenterTextBox = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label13 = new System.Windows.Forms.Label(); + this.BSRadiusTextBox = new System.Windows.Forms.TextBox(); + this.BSCenterTextBox = new System.Windows.Forms.TextBox(); + this.label12 = new System.Windows.Forms.Label(); + this.BBMaxTextBox = new System.Windows.Forms.TextBox(); + this.BBMinTextBox = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.GeometryTabPage = new System.Windows.Forms.TabPage(); + this.CenterGeomTextBox = new System.Windows.Forms.TextBox(); + this.label17 = new System.Windows.Forms.Label(); + this.QuantumTextBox = new System.Windows.Forms.TextBox(); + this.label18 = new System.Windows.Forms.Label(); + this.UnkFloat1TextBox = new System.Windows.Forms.TextBox(); + this.label19 = new System.Windows.Forms.Label(); + this.UnkFloat2TextBox = new System.Windows.Forms.TextBox(); + this.label20 = new System.Windows.Forms.Label(); + this.VertexCountLabel = new System.Windows.Forms.Label(); + this.PolyCountLabel = new System.Windows.Forms.Label(); + this.BoundsTabControl.SuspendLayout(); + this.BoundsTabPage.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.UnkTypeUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.UnkFlagsUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyFlagsUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.MaterialColourUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.PedDensityUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.RoomIDUpDown)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.ProceduralIDUpDown)).BeginInit(); + this.GeometryTabPage.SuspendLayout(); + this.SuspendLayout(); + // + // BoundsTabControl + // + this.BoundsTabControl.Controls.Add(this.BoundsTabPage); + this.BoundsTabControl.Controls.Add(this.GeometryTabPage); + this.BoundsTabControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.BoundsTabControl.Location = new System.Drawing.Point(0, 0); + this.BoundsTabControl.Name = "BoundsTabControl"; + this.BoundsTabControl.SelectedIndex = 0; + this.BoundsTabControl.Size = new System.Drawing.Size(565, 505); + this.BoundsTabControl.TabIndex = 0; + // + // BoundsTabPage + // + this.BoundsTabPage.Controls.Add(this.MaterialCombo); + this.BoundsTabPage.Controls.Add(this.UnkTypeUpDown); + this.BoundsTabPage.Controls.Add(this.label16); + this.BoundsTabPage.Controls.Add(this.label15); + this.BoundsTabPage.Controls.Add(this.UnkVectorTextBox); + this.BoundsTabPage.Controls.Add(this.label14); + this.BoundsTabPage.Controls.Add(this.VolumeTextBox); + this.BoundsTabPage.Controls.Add(this.UnkFlagsUpDown); + this.BoundsTabPage.Controls.Add(this.label9); + this.BoundsTabPage.Controls.Add(this.PolyFlagsUpDown); + this.BoundsTabPage.Controls.Add(this.label8); + this.BoundsTabPage.Controls.Add(this.MaterialColourUpDown); + this.BoundsTabPage.Controls.Add(this.label7); + this.BoundsTabPage.Controls.Add(this.PedDensityUpDown); + this.BoundsTabPage.Controls.Add(this.label6); + this.BoundsTabPage.Controls.Add(this.RoomIDUpDown); + this.BoundsTabPage.Controls.Add(this.label4); + this.BoundsTabPage.Controls.Add(this.ProceduralIDUpDown); + this.BoundsTabPage.Controls.Add(this.label3); + this.BoundsTabPage.Controls.Add(this.label10); + this.BoundsTabPage.Controls.Add(this.label2); + this.BoundsTabPage.Controls.Add(this.MarginTextBox); + this.BoundsTabPage.Controls.Add(this.BBCenterTextBox); + this.BoundsTabPage.Controls.Add(this.label1); + this.BoundsTabPage.Controls.Add(this.label13); + this.BoundsTabPage.Controls.Add(this.BSRadiusTextBox); + this.BoundsTabPage.Controls.Add(this.BSCenterTextBox); + this.BoundsTabPage.Controls.Add(this.label12); + this.BoundsTabPage.Controls.Add(this.BBMaxTextBox); + this.BoundsTabPage.Controls.Add(this.BBMinTextBox); + this.BoundsTabPage.Controls.Add(this.label11); + this.BoundsTabPage.Controls.Add(this.label5); + this.BoundsTabPage.Location = new System.Drawing.Point(4, 22); + this.BoundsTabPage.Name = "BoundsTabPage"; + this.BoundsTabPage.Padding = new System.Windows.Forms.Padding(3); + this.BoundsTabPage.Size = new System.Drawing.Size(557, 479); + this.BoundsTabPage.TabIndex = 0; + this.BoundsTabPage.Text = "Bounds"; + this.BoundsTabPage.UseVisualStyleBackColor = true; + // + // MaterialCombo + // + this.MaterialCombo.FormattingEnabled = true; + this.MaterialCombo.Location = new System.Drawing.Point(91, 214); + this.MaterialCombo.Name = "MaterialCombo"; + this.MaterialCombo.Size = new System.Drawing.Size(195, 21); + this.MaterialCombo.TabIndex = 18; + this.MaterialCombo.SelectedIndexChanged += new System.EventHandler(this.MaterialCombo_SelectedIndexChanged); + // + // UnkTypeUpDown + // + this.UnkTypeUpDown.Location = new System.Drawing.Point(91, 397); + this.UnkTypeUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.UnkTypeUpDown.Name = "UnkTypeUpDown"; + this.UnkTypeUpDown.Size = new System.Drawing.Size(64, 20); + this.UnkTypeUpDown.TabIndex = 32; + this.UnkTypeUpDown.ValueChanged += new System.EventHandler(this.UnkTypeUpDown_ValueChanged); + // + // label16 + // + this.label16.AutoSize = true; + this.label16.Location = new System.Drawing.Point(28, 399); + this.label16.Name = "label16"; + this.label16.Size = new System.Drawing.Size(57, 13); + this.label16.TabIndex = 31; + this.label16.Text = "Unk Type:"; + // + // label15 + // + this.label15.AutoSize = true; + this.label15.Location = new System.Drawing.Point(21, 191); + this.label15.Name = "label15"; + this.label15.Size = new System.Drawing.Size(64, 13); + this.label15.TabIndex = 15; + this.label15.Text = "Unk Vector:"; + // + // UnkVectorTextBox + // + this.UnkVectorTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.UnkVectorTextBox.Location = new System.Drawing.Point(91, 188); + this.UnkVectorTextBox.Name = "UnkVectorTextBox"; + this.UnkVectorTextBox.Size = new System.Drawing.Size(458, 20); + this.UnkVectorTextBox.TabIndex = 16; + this.UnkVectorTextBox.TextChanged += new System.EventHandler(this.UnkVectorTextBox_TextChanged); + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Location = new System.Drawing.Point(40, 165); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(45, 13); + this.label14.TabIndex = 13; + this.label14.Text = "Volume:"; + // + // VolumeTextBox + // + this.VolumeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.VolumeTextBox.Location = new System.Drawing.Point(91, 162); + this.VolumeTextBox.Name = "VolumeTextBox"; + this.VolumeTextBox.Size = new System.Drawing.Size(458, 20); + this.VolumeTextBox.TabIndex = 14; + this.VolumeTextBox.TextChanged += new System.EventHandler(this.VolumeTextBox_TextChanged); + // + // UnkFlagsUpDown + // + this.UnkFlagsUpDown.Location = new System.Drawing.Point(91, 371); + this.UnkFlagsUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.UnkFlagsUpDown.Name = "UnkFlagsUpDown"; + this.UnkFlagsUpDown.Size = new System.Drawing.Size(64, 20); + this.UnkFlagsUpDown.TabIndex = 30; + this.UnkFlagsUpDown.ValueChanged += new System.EventHandler(this.UnkFlagsUpDown_ValueChanged); + // + // label9 + // + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point(27, 373); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size(58, 13); + this.label9.TabIndex = 29; + this.label9.Text = "Unk Flags:"; + // + // PolyFlagsUpDown + // + this.PolyFlagsUpDown.Location = new System.Drawing.Point(91, 345); + this.PolyFlagsUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.PolyFlagsUpDown.Name = "PolyFlagsUpDown"; + this.PolyFlagsUpDown.Size = new System.Drawing.Size(64, 20); + this.PolyFlagsUpDown.TabIndex = 28; + this.PolyFlagsUpDown.ValueChanged += new System.EventHandler(this.PolyFlagsUpDown_ValueChanged); + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(27, 347); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(58, 13); + this.label8.TabIndex = 27; + this.label8.Text = "Poly Flags:"; + // + // MaterialColourUpDown + // + this.MaterialColourUpDown.Location = new System.Drawing.Point(91, 241); + this.MaterialColourUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.MaterialColourUpDown.Name = "MaterialColourUpDown"; + this.MaterialColourUpDown.Size = new System.Drawing.Size(64, 20); + this.MaterialColourUpDown.TabIndex = 20; + this.MaterialColourUpDown.ValueChanged += new System.EventHandler(this.MaterialColourUpDown_ValueChanged); + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Location = new System.Drawing.Point(5, 243); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(80, 13); + this.label7.TabIndex = 19; + this.label7.Text = "Material Colour:"; + // + // PedDensityUpDown + // + this.PedDensityUpDown.Location = new System.Drawing.Point(91, 319); + this.PedDensityUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.PedDensityUpDown.Name = "PedDensityUpDown"; + this.PedDensityUpDown.Size = new System.Drawing.Size(64, 20); + this.PedDensityUpDown.TabIndex = 26; + this.PedDensityUpDown.ValueChanged += new System.EventHandler(this.PedDensityUpDown_ValueChanged); + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point(18, 321); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(67, 13); + this.label6.TabIndex = 25; + this.label6.Text = "Ped Density:"; + // + // RoomIDUpDown + // + this.RoomIDUpDown.Location = new System.Drawing.Point(91, 293); + this.RoomIDUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.RoomIDUpDown.Name = "RoomIDUpDown"; + this.RoomIDUpDown.Size = new System.Drawing.Size(64, 20); + this.RoomIDUpDown.TabIndex = 24; + this.RoomIDUpDown.ValueChanged += new System.EventHandler(this.RoomIDUpDown_ValueChanged); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(33, 295); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(52, 13); + this.label4.TabIndex = 23; + this.label4.Text = "Room ID:"; + // + // ProceduralIDUpDown + // + this.ProceduralIDUpDown.Location = new System.Drawing.Point(91, 267); + this.ProceduralIDUpDown.Maximum = new decimal(new int[] { + 255, + 0, + 0, + 0}); + this.ProceduralIDUpDown.Name = "ProceduralIDUpDown"; + this.ProceduralIDUpDown.Size = new System.Drawing.Size(64, 20); + this.ProceduralIDUpDown.TabIndex = 22; + this.ProceduralIDUpDown.ValueChanged += new System.EventHandler(this.ProceduralIDUpDown_ValueChanged); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(10, 269); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(75, 13); + this.label3.TabIndex = 21; + this.label3.Text = "Procedural ID:"; + // + // label10 + // + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point(38, 217); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size(47, 13); + this.label10.TabIndex = 17; + this.label10.Text = "Material:"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(43, 139); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(42, 13); + this.label2.TabIndex = 11; + this.label2.Text = "Margin:"; + // + // MarginTextBox + // + this.MarginTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.MarginTextBox.Location = new System.Drawing.Point(91, 136); + this.MarginTextBox.Name = "MarginTextBox"; + this.MarginTextBox.Size = new System.Drawing.Size(458, 20); + this.MarginTextBox.TabIndex = 12; + this.MarginTextBox.TextChanged += new System.EventHandler(this.MarginTextBox_TextChanged); + // + // BBCenterTextBox + // + this.BBCenterTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BBCenterTextBox.Location = new System.Drawing.Point(91, 58); + this.BBCenterTextBox.Name = "BBCenterTextBox"; + this.BBCenterTextBox.Size = new System.Drawing.Size(458, 20); + this.BBCenterTextBox.TabIndex = 6; + this.BBCenterTextBox.TextChanged += new System.EventHandler(this.BBCenterTextBox_TextChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(23, 61); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(62, 13); + this.label1.TabIndex = 5; + this.label1.Text = "Box Center:"; + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Location = new System.Drawing.Point(5, 113); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(80, 13); + this.label13.TabIndex = 9; + this.label13.Text = "Sphere Radius:"; + // + // BSRadiusTextBox + // + this.BSRadiusTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BSRadiusTextBox.Location = new System.Drawing.Point(91, 110); + this.BSRadiusTextBox.Name = "BSRadiusTextBox"; + this.BSRadiusTextBox.Size = new System.Drawing.Size(458, 20); + this.BSRadiusTextBox.TabIndex = 10; + this.BSRadiusTextBox.TextChanged += new System.EventHandler(this.BSRadiusTextBox_TextChanged); + // + // BSCenterTextBox + // + this.BSCenterTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BSCenterTextBox.Location = new System.Drawing.Point(91, 84); + this.BSCenterTextBox.Name = "BSCenterTextBox"; + this.BSCenterTextBox.Size = new System.Drawing.Size(458, 20); + this.BSCenterTextBox.TabIndex = 8; + this.BSCenterTextBox.TextChanged += new System.EventHandler(this.BSCenterTextBox_TextChanged); + // + // label12 + // + this.label12.AutoSize = true; + this.label12.Location = new System.Drawing.Point(7, 87); + this.label12.Name = "label12"; + this.label12.Size = new System.Drawing.Size(78, 13); + this.label12.TabIndex = 7; + this.label12.Text = "Sphere Center:"; + // + // BBMaxTextBox + // + this.BBMaxTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BBMaxTextBox.Location = new System.Drawing.Point(91, 32); + this.BBMaxTextBox.Name = "BBMaxTextBox"; + this.BBMaxTextBox.Size = new System.Drawing.Size(458, 20); + this.BBMaxTextBox.TabIndex = 4; + this.BBMaxTextBox.TextChanged += new System.EventHandler(this.BBMaxTextBox_TextChanged); + // + // BBMinTextBox + // + this.BBMinTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.BBMinTextBox.Location = new System.Drawing.Point(91, 6); + this.BBMinTextBox.Name = "BBMinTextBox"; + this.BBMinTextBox.Size = new System.Drawing.Size(458, 20); + this.BBMinTextBox.TabIndex = 2; + this.BBMinTextBox.TextChanged += new System.EventHandler(this.BBMinTextBox_TextChanged); + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(34, 35); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(51, 13); + this.label11.TabIndex = 3; + this.label11.Text = "Box Max:"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point(37, 9); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(48, 13); + this.label5.TabIndex = 1; + this.label5.Text = "Box Min:"; + // + // GeometryTabPage + // + this.GeometryTabPage.Controls.Add(this.PolyCountLabel); + this.GeometryTabPage.Controls.Add(this.VertexCountLabel); + this.GeometryTabPage.Controls.Add(this.UnkFloat2TextBox); + this.GeometryTabPage.Controls.Add(this.label20); + this.GeometryTabPage.Controls.Add(this.UnkFloat1TextBox); + this.GeometryTabPage.Controls.Add(this.label19); + this.GeometryTabPage.Controls.Add(this.QuantumTextBox); + this.GeometryTabPage.Controls.Add(this.label18); + this.GeometryTabPage.Controls.Add(this.CenterGeomTextBox); + this.GeometryTabPage.Controls.Add(this.label17); + this.GeometryTabPage.Location = new System.Drawing.Point(4, 22); + this.GeometryTabPage.Name = "GeometryTabPage"; + this.GeometryTabPage.Padding = new System.Windows.Forms.Padding(3); + this.GeometryTabPage.Size = new System.Drawing.Size(557, 479); + this.GeometryTabPage.TabIndex = 1; + this.GeometryTabPage.Text = "Geometry"; + this.GeometryTabPage.UseVisualStyleBackColor = true; + // + // CenterGeomTextBox + // + this.CenterGeomTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.CenterGeomTextBox.Location = new System.Drawing.Point(91, 6); + this.CenterGeomTextBox.Name = "CenterGeomTextBox"; + this.CenterGeomTextBox.Size = new System.Drawing.Size(458, 20); + this.CenterGeomTextBox.TabIndex = 4; + this.CenterGeomTextBox.TextChanged += new System.EventHandler(this.CenterGeomTextBox_TextChanged); + // + // label17 + // + this.label17.AutoSize = true; + this.label17.Location = new System.Drawing.Point(13, 9); + this.label17.Name = "label17"; + this.label17.Size = new System.Drawing.Size(72, 13); + this.label17.TabIndex = 3; + this.label17.Text = "Geom Center:"; + // + // QuantumTextBox + // + this.QuantumTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.QuantumTextBox.Location = new System.Drawing.Point(91, 32); + this.QuantumTextBox.Name = "QuantumTextBox"; + this.QuantumTextBox.Size = new System.Drawing.Size(458, 20); + this.QuantumTextBox.TabIndex = 6; + this.QuantumTextBox.TextChanged += new System.EventHandler(this.QuantumTextBox_TextChanged); + // + // label18 + // + this.label18.AutoSize = true; + this.label18.Location = new System.Drawing.Point(32, 35); + this.label18.Name = "label18"; + this.label18.Size = new System.Drawing.Size(53, 13); + this.label18.TabIndex = 5; + this.label18.Text = "Quantum:"; + // + // UnkFloat1TextBox + // + this.UnkFloat1TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.UnkFloat1TextBox.Location = new System.Drawing.Point(91, 58); + this.UnkFloat1TextBox.Name = "UnkFloat1TextBox"; + this.UnkFloat1TextBox.Size = new System.Drawing.Size(458, 20); + this.UnkFloat1TextBox.TabIndex = 8; + this.UnkFloat1TextBox.TextChanged += new System.EventHandler(this.UnkFloat1TextBox_TextChanged); + // + // label19 + // + this.label19.AutoSize = true; + this.label19.Location = new System.Drawing.Point(20, 61); + this.label19.Name = "label19"; + this.label19.Size = new System.Drawing.Size(65, 13); + this.label19.TabIndex = 7; + this.label19.Text = "Unk Float 1:"; + // + // UnkFloat2TextBox + // + this.UnkFloat2TextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.UnkFloat2TextBox.Location = new System.Drawing.Point(91, 84); + this.UnkFloat2TextBox.Name = "UnkFloat2TextBox"; + this.UnkFloat2TextBox.Size = new System.Drawing.Size(458, 20); + this.UnkFloat2TextBox.TabIndex = 10; + this.UnkFloat2TextBox.TextChanged += new System.EventHandler(this.UnkFloat2TextBox_TextChanged); + // + // label20 + // + this.label20.AutoSize = true; + this.label20.Location = new System.Drawing.Point(20, 87); + this.label20.Name = "label20"; + this.label20.Size = new System.Drawing.Size(65, 13); + this.label20.TabIndex = 9; + this.label20.Text = "Unk Float 2:"; + // + // VertexCountLabel + // + this.VertexCountLabel.AutoSize = true; + this.VertexCountLabel.Location = new System.Drawing.Point(88, 124); + this.VertexCountLabel.Name = "VertexCountLabel"; + this.VertexCountLabel.Size = new System.Drawing.Size(53, 13); + this.VertexCountLabel.TabIndex = 11; + this.VertexCountLabel.Text = "0 vertices"; + // + // PolyCountLabel + // + this.PolyCountLabel.AutoSize = true; + this.PolyCountLabel.Location = new System.Drawing.Point(88, 144); + this.PolyCountLabel.Name = "PolyCountLabel"; + this.PolyCountLabel.Size = new System.Drawing.Size(58, 13); + this.PolyCountLabel.TabIndex = 12; + this.PolyCountLabel.Text = "0 polygons"; + // + // EditYbnBoundsPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(565, 505); + this.Controls.Add(this.BoundsTabControl); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EditYbnBoundsPanel"; + this.Text = "EditYbnBoundsPanel"; + this.BoundsTabControl.ResumeLayout(false); + this.BoundsTabPage.ResumeLayout(false); + this.BoundsTabPage.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.UnkTypeUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.UnkFlagsUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PolyFlagsUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.MaterialColourUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.PedDensityUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.RoomIDUpDown)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.ProceduralIDUpDown)).EndInit(); + this.GeometryTabPage.ResumeLayout(false); + this.GeometryTabPage.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl BoundsTabControl; + private System.Windows.Forms.TabPage BoundsTabPage; + private System.Windows.Forms.Label label15; + private System.Windows.Forms.TextBox UnkVectorTextBox; + private System.Windows.Forms.Label label14; + private System.Windows.Forms.TextBox VolumeTextBox; + private System.Windows.Forms.NumericUpDown UnkFlagsUpDown; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.NumericUpDown PolyFlagsUpDown; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.NumericUpDown MaterialColourUpDown; + private System.Windows.Forms.Label label7; + private System.Windows.Forms.NumericUpDown PedDensityUpDown; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.NumericUpDown RoomIDUpDown; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.NumericUpDown ProceduralIDUpDown; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox MarginTextBox; + private System.Windows.Forms.TextBox BBCenterTextBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.TextBox BSRadiusTextBox; + private System.Windows.Forms.TextBox BSCenterTextBox; + private System.Windows.Forms.Label label12; + private System.Windows.Forms.TextBox BBMaxTextBox; + private System.Windows.Forms.TextBox BBMinTextBox; + private System.Windows.Forms.Label label11; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TabPage GeometryTabPage; + private System.Windows.Forms.NumericUpDown UnkTypeUpDown; + private System.Windows.Forms.Label label16; + private System.Windows.Forms.ComboBox MaterialCombo; + private System.Windows.Forms.TextBox QuantumTextBox; + private System.Windows.Forms.Label label18; + private System.Windows.Forms.TextBox CenterGeomTextBox; + private System.Windows.Forms.Label label17; + private System.Windows.Forms.TextBox UnkFloat2TextBox; + private System.Windows.Forms.Label label20; + private System.Windows.Forms.TextBox UnkFloat1TextBox; + private System.Windows.Forms.Label label19; + private System.Windows.Forms.Label PolyCountLabel; + private System.Windows.Forms.Label VertexCountLabel; + } +} \ No newline at end of file diff --git a/Project/Panels/EditYbnBoundsPanel.cs b/Project/Panels/EditYbnBoundsPanel.cs new file mode 100644 index 0000000..6878b27 --- /dev/null +++ b/Project/Panels/EditYbnBoundsPanel.cs @@ -0,0 +1,451 @@ +using CodeWalker.GameFiles; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CodeWalker.Project.Panels +{ + public partial class EditYbnBoundsPanel : ProjectPanel + { + public ProjectForm ProjectForm; + public Bounds CollisionBounds { get; set; } + public BoundGeometry CollisionGeom { get; set; } + + private bool populatingui = false; + private bool waschanged = false; + + public EditYbnBoundsPanel(ProjectForm projectForm) + { + ProjectForm = projectForm; + InitializeComponent(); + + LoadDropDowns(); + } + + private void LoadDropDowns() + { + MaterialCombo.Items.Clear(); + if (BoundsMaterialTypes.Materials == null) return; + foreach (var mat in BoundsMaterialTypes.Materials) + { + MaterialCombo.Items.Add(mat); + } + } + + public void SetCollisionBounds(Bounds b) + { + CollisionBounds = b; + CollisionGeom = b as BoundGeometry; + Tag = b; + UpdateFormTitle(); + UpdateUI(); + waschanged = b?.HasChanged ?? false; + } + + public void UpdateFormTitleYbnChanged() + { + bool changed = CollisionBounds?.HasChanged ?? false; + if (!waschanged && changed) + { + UpdateFormTitle(); + waschanged = true; + } + else if (waschanged && !changed) + { + UpdateFormTitle(); + waschanged = false; + } + } + private void UpdateFormTitle() + { + string fn = CollisionBounds?.GetTitle() ?? "untitled"; + Text = fn + ((CollisionBounds?.HasChanged??false) ? "*" : ""); + } + + + public void UpdateUI() + { + var b = CollisionBounds; + if (b == null) + { + BBMinTextBox.Text = string.Empty; + BBMaxTextBox.Text = string.Empty; + BBCenterTextBox.Text = string.Empty; + BSCenterTextBox.Text = string.Empty; + BSRadiusTextBox.Text = string.Empty; + MarginTextBox.Text = string.Empty; + VolumeTextBox.Text = string.Empty; + UnkVectorTextBox.Text = string.Empty; + MaterialColourUpDown.Value = 0; + MaterialCombo.Text = ""; + ProceduralIDUpDown.Value = 0; + RoomIDUpDown.Value = 0; + PedDensityUpDown.Value = 0; + PolyFlagsUpDown.Value = 0; + UnkFlagsUpDown.Value = 0; + UnkTypeUpDown.Value = 0; + BoundsTabControl.TabPages.Remove(GeometryTabPage); + CenterGeomTextBox.Text = string.Empty; + QuantumTextBox.Text = string.Empty; + UnkFloat1TextBox.Text = string.Empty; + UnkFloat2TextBox.Text = string.Empty; + VertexCountLabel.Text = "0 vertices"; + PolyCountLabel.Text = "0 polygons"; + } + else + { + populatingui = true; + + BBMinTextBox.Text = FloatUtil.GetVector3String(b.BoxMin); + BBMaxTextBox.Text = FloatUtil.GetVector3String(b.BoxMax); + BBCenterTextBox.Text = FloatUtil.GetVector3String(b.BoxCenter); + BSCenterTextBox.Text = FloatUtil.GetVector3String(b.SphereCenter); + BSRadiusTextBox.Text = FloatUtil.ToString(b.SphereRadius); + MarginTextBox.Text = FloatUtil.ToString(b.Margin); + VolumeTextBox.Text = FloatUtil.ToString(b.Volume); + UnkVectorTextBox.Text = FloatUtil.GetVector3String(b.Unknown_60h); + MaterialColourUpDown.Value = b.MaterialColorIndex; + MaterialCombo.SelectedIndex = b.MaterialIndex; + ProceduralIDUpDown.Value = b.ProceduralId; + RoomIDUpDown.Value = b.RoomId; + PedDensityUpDown.Value = b.PedDensity; + PolyFlagsUpDown.Value = b.PolyFlags; + UnkFlagsUpDown.Value = b.UnkFlags; + UnkTypeUpDown.Value = b.Unknown_3Ch; + + if (b is BoundGeometry bg) + { + if (!BoundsTabControl.TabPages.Contains(GeometryTabPage)) + { + BoundsTabControl.TabPages.Add(GeometryTabPage); + } + + CenterGeomTextBox.Text = FloatUtil.GetVector3String(bg.CenterGeom); + QuantumTextBox.Text = FloatUtil.GetVector3String(bg.Quantum); + UnkFloat1TextBox.Text = FloatUtil.ToString(bg.Unknown_9Ch); + UnkFloat2TextBox.Text = FloatUtil.ToString(bg.Unknown_ACh); + VertexCountLabel.Text = bg.VerticesCount.ToString() + ((bg.VerticesCount == 1) ? " vertex" : " vertices"); + PolyCountLabel.Text = bg.PolygonsCount.ToString() + ((bg.PolygonsCount == 1) ? " polygon" : " polygons"); + } + else + { + BoundsTabControl.TabPages.Remove(GeometryTabPage); + CenterGeomTextBox.Text = string.Empty; + QuantumTextBox.Text = string.Empty; + UnkFloat1TextBox.Text = string.Empty; + UnkFloat2TextBox.Text = string.Empty; + VertexCountLabel.Text = "0 vertices"; + PolyCountLabel.Text = "0 polygons"; + } + + populatingui = false; + } + } + + private void BBMinTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BBMinTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.BoxMin != v) + { + CollisionBounds.BoxMin = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BBMaxTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BBMaxTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.BoxMax != v) + { + CollisionBounds.BoxMax = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BBCenterTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BBCenterTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.BoxCenter != v) + { + CollisionBounds.BoxCenter = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BSCenterTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(BSCenterTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.SphereCenter != v) + { + CollisionBounds.SphereCenter = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void BSRadiusTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(BSRadiusTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.SphereRadius != v) + { + CollisionBounds.SphereRadius = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void MarginTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(MarginTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.Margin != v) + { + CollisionBounds.Margin = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void VolumeTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(VolumeTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.Volume != v) + { + CollisionBounds.Volume = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void UnkVectorTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(UnkVectorTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.Unknown_60h != v) + { + CollisionBounds.Unknown_60h = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void MaterialCombo_SelectedIndexChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (byte)MaterialCombo.SelectedIndex; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.MaterialIndex != v) + { + CollisionBounds.MaterialIndex = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void MaterialColourUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (byte)MaterialColourUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.MaterialColorIndex != v) + { + CollisionBounds.MaterialColorIndex = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void ProceduralIDUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (byte)ProceduralIDUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.ProceduralId != v) + { + CollisionBounds.ProceduralId = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void RoomIDUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (byte)RoomIDUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.RoomId != v) + { + CollisionBounds.RoomId = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void PedDensityUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (byte)PedDensityUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.PedDensity != v) + { + CollisionBounds.PedDensity = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void PolyFlagsUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (byte)PolyFlagsUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.PolyFlags != v) + { + CollisionBounds.PolyFlags = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void UnkFlagsUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (byte)UnkFlagsUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.UnkFlags != v) + { + CollisionBounds.UnkFlags = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void UnkTypeUpDown_ValueChanged(object sender, EventArgs e) + { + if (CollisionBounds == null) return; + if (populatingui) return; + var v = (uint)UnkTypeUpDown.Value; + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionBounds.Unknown_3Ch != v) + { + CollisionBounds.Unknown_3Ch = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void CenterGeomTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionGeom == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(CenterGeomTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionGeom.CenterGeom != v) + { + CollisionGeom.CenterGeom = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void QuantumTextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionGeom == null) return; + if (populatingui) return; + var v = FloatUtil.ParseVector3String(QuantumTextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionGeom.Quantum != v) + { + CollisionGeom.Quantum = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void UnkFloat1TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionGeom == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(UnkFloat1TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionGeom.Unknown_9Ch != v) + { + CollisionGeom.Unknown_9Ch = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + + private void UnkFloat2TextBox_TextChanged(object sender, EventArgs e) + { + if (CollisionGeom == null) return; + if (populatingui) return; + var v = FloatUtil.Parse(UnkFloat2TextBox.Text); + lock (ProjectForm.ProjectSyncRoot) + { + if (CollisionGeom.Unknown_ACh != v) + { + CollisionGeom.Unknown_ACh = v; + ProjectForm.SetYbnHasChanged(true); + } + } + } + } +} diff --git a/Project/Panels/EditYbnBoundsPanel.resx b/Project/Panels/EditYbnBoundsPanel.resx new file mode 100644 index 0000000..1431f6b --- /dev/null +++ b/Project/Panels/EditYbnBoundsPanel.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f// + /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA + AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc + skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU + 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq + +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz + /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR + p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm + +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB + AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/ + /f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/ + +fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd + 4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/ + 1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + /v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA + /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/ + 9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA + AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA + /v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/ + /P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/ + /f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// + ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB/////// + //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA + H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A + A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA + /f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A + AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf + AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4 + AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A// + ///////gD/////////Af//////////////8= + + + \ No newline at end of file diff --git a/Project/Panels/EditYbnPanel.Designer.cs b/Project/Panels/EditYbnPanel.Designer.cs new file mode 100644 index 0000000..268441a --- /dev/null +++ b/Project/Panels/EditYbnPanel.Designer.cs @@ -0,0 +1,48 @@ +namespace CodeWalker.Project.Panels +{ + partial class EditYbnPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EditYbnPanel)); + this.SuspendLayout(); + // + // EditYbnPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(565, 505); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EditYbnPanel"; + this.Text = "EditYbnPanel"; + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/Project/Panels/EditYbnPanel.cs b/Project/Panels/EditYbnPanel.cs new file mode 100644 index 0000000..52106cd --- /dev/null +++ b/Project/Panels/EditYbnPanel.cs @@ -0,0 +1,77 @@ +using CodeWalker.GameFiles; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CodeWalker.Project.Panels +{ + public partial class EditYbnPanel : ProjectPanel + { + public ProjectForm ProjectForm; + public YbnFile Ybn { get; set; } + + //private bool populatingui = false; + private bool waschanged = false; + + public EditYbnPanel(ProjectForm projectForm) + { + ProjectForm = projectForm; + InitializeComponent(); + } + + public void SetYbn(YbnFile ybn) + { + Ybn = ybn; + Tag = ybn; + UpdateFormTitle(); + UpdateUI(); + waschanged = ybn?.HasChanged ?? false; + } + + public void UpdateFormTitleYbnChanged() + { + bool changed = Ybn?.HasChanged ?? false; + if (!waschanged && changed) + { + UpdateFormTitle(); + waschanged = true; + } + else if (waschanged && !changed) + { + UpdateFormTitle(); + waschanged = false; + } + } + private void UpdateFormTitle() + { + string fn = Ybn?.RpfFileEntry?.Name ?? Ybn?.Name; + if (string.IsNullOrEmpty(fn)) fn = "untitled.ybn"; + Text = fn + ((Ybn?.HasChanged??false) ? "*" : ""); + } + + + public void UpdateUI() + { + if (Ybn?.Bounds == null) + { + + + } + else + { + var b = Ybn.Bounds; + //populatingui = true; + + + //populatingui = false; + } + } + + } +} diff --git a/Project/Panels/EditYbnPanel.resx b/Project/Panels/EditYbnPanel.resx new file mode 100644 index 0000000..1431f6b --- /dev/null +++ b/Project/Panels/EditYbnPanel.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAMAICAAAAAAGACoDAAANgAAABAQAAAAABgAaAMAAN4MAABAQAAAAAAYACgyAABGEAAAKAAAACAA + AABAAAAAAQAYAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv8/u3v+Pn6//7+/wAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AP7+/vX3/rzA3OHl9fz9/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7//+zv+3Z6qcLI5Pr7/wAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAP7+/+br+15in6+33vf5/wAAAAAAAAAAAAAAAP7+//7+/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3+//v8//v8//3+/wAAAAAAAAAAAAAAAAAAAP7+/+Ho+1dana20 + 4/b4/wAAAAAAAPz9//P2/+Tp/ezw/vz9/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7///X4 + /9Pa+tPa+/H1//z9/wAAAAAAAAAAAAAAAP7+/93k+SsscaSr3PX3/wAAAP7+//L1/7W98AcWgrvC8Pj6 + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+/+bs/xohiAEJdrvF9+7y//z9/wAAAAAAAAAA + AP7+/9rh+CEkapmh0/T3/wAAAPj6/9HZ/AEHcgEEb9LZ+/r7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAP7//+/z/3F+zAAAXwQLcZai3fb4/wAAAAAAAAAAAP3+/97l/E9Tmaau4fT3/wAAAO/0/1dd + sAAAV7a/8/H1//7+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPr8/+jv/46Y3QUUf6Ot + 5PX4/wAAAAAAAAAAAP3+/9zj+3Z6wLe/7fX4/wAAAPD0/212xnaAzerw//z9/wAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv8/+/z/+Dm+/D0//z9/wAAAAAAAP7+//j6/9Pd+UhLjb/H + 9/D0//3+//n7/+nt/+jt//n7/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AP7///7+//7+//7+/wAAAAAAAPr8/+7z/83W+ImU2A0UdFNarr/K9env//X4//z9//3+//7//wAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7///j6/+Pq/255 + xhckjE5XsVVftUlTqwAKeTA9nr3H8+7z//v8/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7+//b4/9Tc+Sc0mRonj8rV/crX/ZSb48rX/brG8wwWgQAEdJei + 4efu//n7//7+//z9//z9//z9//z9//3+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAP3+//f5/+3y/+nv/+ft + /8vV+io2mImU2M7c/7vG9yIvlQAOfCg4mM3Y/s/c/4aR1AQRfGtzwtni/ebt/9vi/tri/tXd+9Tc+O3x + /vz9/wAAAAAAAAAAAAAAAAAAAAAAAPn6/87V+FVftkRPrFlnvSEqjQoUfmJvwWFvvg0TfQQIcxEchwAD + cy89n19rvVVitQwZgwAAaiMrkT9NqTVBoiw3mhQihig1mNLX+fv8/wAAAAAAAAAAAAAAAAAAAAAAAPb5 + /52l4EFLqoCK03yF0VBctGhyw52o5GVrvQAAaneBzsHM+jA3mhYgiTtIpJOf3ouW2AAAbmh0wbbA8bS+ + 7qiz5pCb16+56e/z//3+/wAAAAAAAAAAAAAAAAAAAAAAAPv8//H1/+vw/+zx/+nv/7/J9YqP3MbP/8LM + +hwqkFZftaCp5EhRrcTQ+9jj/8rW/UJMqn6J0ebt//X3//f5//b4//X3//f5//z9/wAAAAAAAAAAAAAA + AAAAAAAAAP7+//z9//3+/wAAAAAAAP3+/+7z/6at64iP3aWs7XN8zRIfhyUykp2o5MHM+oKM0xonjY6X + 2+jv//v8/wAAAP7+//n7//b5//r7//7//wAAAAAAAAAAAAAAAP7+//f5/+rw/9Pa9fL0/v7//wAAAAAA + APv8//H1/+Tr/7i/91liu0NPq0VQrS06m0NNqDdCoYqU1+nv//v8/wAAAAAAAPn7/9zi/qSt59ri/fL1 + //v8//7//wAAAPz9//D0/8rT+h0sjkVQrPD0/wAAAAAAAAAAAAAAAAAAAPz9/+7z/8LL9Jqk4aGq6LW/ + 8c3W9+Xs/vH1//v8/wAAAAAAAAAAAPf5/6at5gAAbxIfh6u16+Po/fr7/wAAAPb5/6ev5gAIeAAPernC + 8fX4/wAAAAAAAP3+//v8//z9/wAAAP3+//j6//P3//P2//b4//r8//7+//7+//v8//r8//3+/wAAAPv8 + /+Xr/nuIzwAAbBseg5Sb2fb5/wAAAPf5/8DF8pWe3d/n/vT3//39/wAAAPv8/+zx/87V9+3x/v3+/wAA + AP3+//j6//X4//v8/wAAAAAAAPn7/+Dm/snR9fD0//39//z8/fv8/+3y/8LK9aGq4dfd9/n7/wAAAPz9 + //b5//X4//v8/wAAAAAAAP7+/+7z/4aP1gEPet7k/f39/wAAAPf5/83U+ZCZ2u3x/v7+/wAAAPP3/215 + wgAJd7fB8/L1//7+/wAAAP3+//j6//f5//r8//7+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAPj6/87W/AAA + X2duue3y//7+/wAAAPD0/05asBQfidzj/P39/wAAAPX4/6Su6AAAXBccgtff/vv8/wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPP3/3F8xhYli9Xe/fn6/wAAAAAAAO3y/1pltQAJd9be + /fv8/wAAAPz9/+rw/36I0Bknjs/W+vv8/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAPf5/8HI7tnf+/X4//7+/wAAAAAAAO/0/3R7xgAAb9ng/Pz9/wAAAAAAAPn7/+Ln/dLY+fP2//3+ + /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3+//r7//v8//7+/wAAAAAAAAAA + APb4/7/F84eP0e/0//7+/wAAAAAAAP7+//z9//v8//3+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz9//b5//X4//v8/wAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////w////4 + P///+D////g8//D4MH/geCB/4Dggf+A4IH/wOCD/+DAB//hgAf//gAP//wAAB/AAAAPwAAAD8AAAA/AA + AAfjAAEHgYADAQPgBwEDEAEBAghgAQwIIEH8CCB//Bggf/wYMH/8ODD///h/////////////KAAAABAA + AAAgAAAAAQAYAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///+vv/fL1/v///wAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///4+Vx7/F5v///wAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAP///4CHtrS62////////////////////wAAAAAAAAAAAP////H0/vf6/v// + /////////4yTwrrB4f///+zw+7rA6P39/////wAAAAAAAAAAAP///56l2BkcguXr/P///////42Uw8jO + 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f// + /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA + AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc + skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU + 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq + +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz + /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR + p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm + +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB + AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/ + /f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/ + +fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd + 4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/ + 1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2OL+NjZ7AAArX2Ok + 4uz/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/ + 2eP/LjJ1DAxKfYTE4Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//v7//f7//f7//v7//v// + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3OX/gILIR0eVeoHC3eb/8fX/+/z/AAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+Pr/ + +Pr/+Pr/+vv//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3/+vv/+vv/+/z//f3//v7/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8PX/2eP9ZWeqHx1obnOz4Or/8fX/+/z/AAAAAAAAAAAAAAAA/v7/ + +/z/9fj/8vb/8PX/7vT/8fb/9fj/+fr//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v///P3/+Pr/9fj/9fj/9Pj/9Pf/9vn/+/z//v7/ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP9ODp9AAA5jZDQ5O7/8PX/+/z/AAAA + AAAAAAAA/v7/+/z/9Pf/7fP/5u//wsz6j5XfuMDx7fL/9vn//P3/AAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f7/+Pr/8/b/5+3/2eH/2uP/ + 5u3/7fP/8/b/+vv//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8PX/3ef/U1ebBgVKio/O + 4uz/8fX/+/z/AAAAAAAA/v///P3/9fj/7fP/4uv/hIzZHSWPAABmU1i14ub/9/r/+/z/AAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/9Pf/ + 7/X/09z/TlSzNzWYj5bh5O7/6/L/8vb/+fv//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fX/ + 2eP/QUWIEhBZbnSz3uj/8fb/+/z/AAAAAAAA/f7/+Pr/7/T/6PH/iI7cAABvAABqAABncXjK6O//9fj/ + +/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+/z/8/f/2uD/Z27EAABnAABiBgl4jJTd5vD/6O//8vX/+fv//f7/AAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8fb/2OP/Mjd6AQE6ZGup4er/8fX/+/z/AAAAAAAA+vz/8fX/6/T/xM/8ExyJAABwAABu + GySRxc387fT/9ff//P3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vz/8/f/1Nr/MzqhAABhAxOBAARyBgp5jpLg5Oz/7PP/9Pf/+vz//v7/ + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP/KCtvBwZOjJHS4Or/8fX/+/z/AAAA/f7/9/n/7fP/3+j/ + UFq3AABtAAZ3BAh6mZ/n5vD/7vP/+Pr//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/6e//sbb1KzWcAABwBhaBAAFyAgp6fITR + 1d777/T/+Pr//f7/AAAAAAAAAAAAAAAAAAAAAAAA+vv/8PX/3+j/WF2hBglTnaTj5O3/8PX/+/z/AAAA + /P3/9Pf/6vL/k5riAAByAAR0AABrY2vE4ur/6vH/9ff//P3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/9/n/7fL/5O3/ytX/RU6w + AABpAA5+AABuAABnhord6e7/+fv//f7/AAAAAAAAAAAAAAAAAAAAAAAA+vv/7/T/3+j/k5jbT1KdgYjJ + 3uf+8fX/+/z/AAAA+/z/9fn/4ef/NDqhAABnAABrJjCU0Nn/5/D/8fX/+vv//v7/AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7/+/z/ + 9vn/7vP/6vP/ztb/O0CmAABpAABrQkuoxMn57PH/+Pr//f7/AAAAAAAAAAAAAAAAAAAAAAAA+vv/8PX/ + 2+X/en/CUFGak5nY3+j/8fX//P3/AAAA/P3/9fj/4en/i5DbNT2hIyuTpqzv4uz/7vP/9/n//f7/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAA/v7//P3/9vn/7/P/6vL/ytH/X2i9XWi7wsf/6e//8/f/+Pr//v7/AAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3OX/WF2hW1ylvMD+3uf/8PX/+/z/AAAA/f7/9vn/7fP/4uj/j5Pgf4LV3+X/6fD/ + 9Pf//P3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v///P3/+Pr/8vX/7fP/5+//5u7/6vD/8PT/9vn//P3//v7/ + AAAAAAAAAAAAAAAAAAAA/f7/9/n/7fP/0tz9LDJzNjh/nqTk2uT/7fL/9/n//f7//f7/+fv/8/b/7PL/ + 3eX/zM//5ev/9fj/+fv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v///f3/+vv/9/n/9vn/9fj/9vn/ + +fr//P3//v7/AAAAAAAAAAAA/v///f7/+vv/9vn/7/T/5vD/2Ob/VFubERNdoajk4u//5O7/7vP/9vj/ + +fr/+vv/+Pr/9fj/9Pj/9fj/9fj/+Pr//P3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v///v7/ + /f7//P3//P3//f3//v7//v//AAAAAAAAAAAA/f7/+vz/9vn/8fX/7vT/5O3/3eb/z9n/cHjICxN5d37L + z9n/2eP/5O3/6/L/8PT/9Pf/9/n/+vv/+vv/+/z//P3//f3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/+Pr/8/b/7vT/6vL/z9r+jZjeQUeq + IiuQCBN3AAFrBRB8Nj2iUViym6XlydH/4+z/6/L/8PT/9/n/+/z//f7//v//AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/9/n/8fX/6/L/3uf/ + mKTkLzibAABoAAB0Fx+HDBh7FSGDAg16AABYAABlCBB/Ji2UhYza1+D/6PL/7fL/9Pf/+vv//f7/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/9/n/ + 8PT/7PT/z9j/XmO+AABtAABcMDSXoajsu8X7VV+5hYzblZ/fTVSxFSKMAABkAABnAAN2Qkmpsbrz5e3/ + 6vH/8fX/+Pr//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAA/P3/9/n/8PX/7PT/vcn3LTOZAABaAgR1ZWzD0Nf/5vL/1OP/l53lzs3/6fP/4+7/sLzwZ23CBxSD + AABnAABlHiaSmqHo3+j/5+//7/T/9vn//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAA/v//AAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7/ + /v7//v7//v7//f7/+/z/9vj/7vP/7PX/tcLzEBeGAABkPEWlqLPt2eX/4e7/3On/uMX1gofVe3vPhYzY + z93+5/X/4e3/lJ3gHiOPAABtAABqChiEbHLIytD/5/D/7PL/8/f/+Pr/+fr/+Pr/+Pr/+Pr/+Pr/+Pr/ + +Pr/+fv/+vv/+/z//f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + /v7//f7/+/z/+fv/9/n/9vj/9fj/9Pf/8fX/7PL/4uv/l6HgDhF7AAN4iZDe0d7/3uz/4vD/w83/VVm3 + ICiSAAFyAABlAABwaHTD1N//2un/3er/w838ZW3BEyOJJzKVAQ16NDmfwsn75fD/5u7/7PL/7vP/7fP/ + 7fP/7fL/7fP/7vP/7/T/8fb/9Pj/9vn/+fr//f3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAA/v7//P3/+Pr/9Pf/8fX/7vT/7PL/6/L/6fH/5u7/6vX/tsD0CQx4AAFwkZvi7ff/4vD/ + 4fD/z9j/OkGlAABiAABwBxWAAAt7BBN+P0uofYLUztb/4O7/6fb/6fP/qa7xQkyoBg56AABqMjugx8/+ + 5fH/4Ov/4On/3uj/3eb/3+j/3uj/1+L/0d3/1d7/3+f/7fL/9vj/+vz//v7/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/f7/+fr/8/f/6/L/2d//v8j6vcf5ucP1wMv8wM3+vMj6PkqoAABo + UF25usP7tsPyvsr6sLrwQ0utAABqAAV1OUameIDRKDWZAAd2GyeOLDecmaHntsL0pbLom6riq7LzUlu0 + AANzBhR/AAZ0NT+ja3bBY2i/XGG6UViyWl65XGG7XGC6TVWvQU6pPkalODygqK7p8vb/+vz//v7/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/9/n/7/T/wcj2R0ysExeFERmGDxuIFB6K + FBqICxSEAABsAAByDBiDCRSBBRCADhaFCRODAAh4AxF/AAl4CxeDHSaPAAp6AAN0AA19AAd3CBOBEBqH + BhGBAAh5AABwAAByAAh5BhSCAxWCAABsAABvAABlAABnAABxAABjAABmAABhAABdAABYAABhCAt/q7Lr + 8/f/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/+fv/3uT/SE2vAABn + CBB/GiCMLzmfLTWcGByJFRyKGCOOMj2gHymRDxiGGyOPLDCXBRF/AAh3BhaCEyKMICqTKC2WNDqfIzCV + Awx6Eh+JHiaPAAR3AAZ5CxSDICWQX2q7Q1CqAA1+AAFxDxuHiZTbVGC4dHnQnabrTVqzY23EUV62Slau + LjaZXWm9sLjz5ez/9vn/+fv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/ + +Pv/4+n+e4LPfoPVpqv2vsf/zNX/zdb/xtH/v8v8pK7spKfysLb3vcr4ws784ej/hI/YAAZ1AAJzVF25 + yM//3Of/5+//i5LcAABpMzyfp6vxoKznlqHhqbbtx9H/8fz/kpvfAABiAABph4zc5PD/2OP/193/3un/ + 1+D/2OH/1+D/0Nr/zNL/3+j/6/L/7/T/9vn//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAA/f7/+Pr/9Pf/6vD/5u3/3+b/4uv/6PD/5+//5O3/5/P/sL3sXmS7mZzoz9f/3+z/4e// + mKLiEiKKCBF/KTWZr7T06/f/3ev/VF2zChSBipPcz9v+4u7/3ur/3ev/5/X/qrPrISmSDRJ2Xmq/3ur/ + 4uv/6vH/7fP/7fL/7/T/7vP/7fP/7fP/8PX/8fX/9Pf/+Pr/+/z//v7/AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+Pr/9vn/9Pf/8vb/8vb/8/b/9Pf/7/T/6/L/tL/ubXLH + en/Ti43gqavy0t3/nafjMj6fJzaaAAV1GyeOYmW7Nz6fAABgNj6i1N//3uz/2uX/3Oj/5PH/wcj7FR2J + AAN0gong0tr/6fH/7/P/9vj/+Pr/+fv/+fv/+Pr/+Pr/+Pr/+fv/+vv//P3//f7//v//AAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3/+/z/+/z/+/z//f3//f7/ + +fv/8fX/5Oz/jpbfc3jObnXLcXfOk5rks7b4iY3dR1KvDhuEAABoAABlEBV9U12ytcD13Or/3en/3ej/ + 1eL/q7fvGR+MKDKZbnnNxc/76PD/8fX/+fr//f7//v//AAAA/v7//f7//f3//P3//f3//f7//v//AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//f7//v7/AAAA + AAAAAAAAAAAAAAAA/f7/9vn/7/T/yNH5lJrleoDVmZ3pmpzpc3nPfoTWf4bYVFy3HSaLZ3PGsrb8v8r8 + y9n9q7jre4LRf4fUgIvXAwZ1AABrhYjb0NX/6PH/8PX/+Pr//f7/AAAAAAAA/v///f3/+vv/+Pr/9/r/ + 9/n/+Pr/+/z//f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v///f7/+/z/+fr/9vj/9/n/ + +vz/+vv/+/z//v7/AAAAAAAAAAAAAAAA/v7/+vz/8/f/7PL/2uT/t8H1srP6vcH+nKTnSlOxV2C7TVaz + WGS8QUqmSlSuSFOtR1GtbXTKVl23ARB5AAh2AABnd33P3eP/4ur/7/T/9/n//P3/AAAAAAAAAAAA/P3/ + 9/n/8vb/7PH/6fD/7PL/7vP/8vb/9vn/+/z//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7/+/z/+Pr/ + 8/b/7/T/8Pb/6vH/3eP97vL++fr//P3/AAAAAAAAAAAAAAAAAAAA/f7/+vv/9fj/7/T/5+//z9f+t7v4 + uLn9Z2zFLzucFCGIMz6gGCCMAAd4AAl2Dx2EER+GXWK8c3XLKzKXd4LP4er/6/L/8PX/9/n//P3//v// + AAAAAAAA/v7/+fv/8/b/7PP/y9H/i4/erLbt4er/5e3/7fP/8/b/+fv//f3//v7/AAAAAAAAAAAAAAAA + /v7/+/z/9vj/8PT/6/L/3+n/x9H9aHTAZGvG3+b9+Pr/+/z/AAAAAAAAAAAAAAAAAAAAAAAA/v7/+/z/ + +Pr/8vb/6/H/3OX+wMn4maDmdHrPWGG6T1a1eoHWcHfOTlayUlq1SlKubHjAxMj/0dn/4+v/7PL/8vb/ + +Pr//P3//v7/AAAAAAAAAAAA/f7/+fr/7vP/xsv5YGXAHymRKjKYYWS9rbLz4u3/6/P/8vb/+fr//f7/ + AAAAAAAAAAAA/v//+/z/9vj/7fL/5e3/xs7/Y23BIiiSAABeLTab3+b/9/r/+/z/AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAA/f7/+vz/9vj/8PX/6vH/3eb/ydL8xM/6uMPyt733w8j/zNb/1Nz/3OT/4uz/5u7/ + 7fP/8vb/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAA/f7/+fv/7vP/jpHiAAJ1CxaBER6GAABoFRmGbXbH + 0Nf/7PL/9fj//P3/AAAAAAAAAAAA/v7/+fv/8/f/4Of/hYvbKDGZAABuAABdAAZyi5La5+7/9vn/+/z/ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/9ff/8vb/7/X/7fP/6/L/5u3/5ez/6fD/ + 7PP/7/T/8fX/9Pf/9/n/+vv//P3//v7//v//AAAAAAAAAAAAAAAAAAAA/v7/+fv/8fb/2eH9fIbQExqH + AABrAAp6AAFyAABwS0+uztX39vn/+vz/AAAAAAAAAAAA/f7/+Pr/8ff/qbLpAABrAABhAABwDBWAfobX + 5e3/8PX/9vn//f3/AAAAAAAA/v///f7/+/z/+vv/+vv/+vz//P3//v7//v///v7//P3/+vz/+Pr/9/n/ + 9vj/9vj/9vj/9vj/9/n/+fr/+/z//P3//f7//v7//f7//P3/+/z/+vz/+/z//P3//v7/AAAA/v7/+/z/ + 9fj/7/T/5/H/uML1U1e1AAh5AABuAABvMjmdv8bz9vr/+vv/AAAAAAAAAAAA/f7/+fv/7/T/iY7aDxSA + GiONa3XHsr7w4Oj/6/H/9Pf/+vz//v7/AAAA/v///P3/+Pr/9Pf/8/f/9fj/9fj/9vn/+/z//v7/AAAA + AAAAAAAA/v7//f7//P3/+/z/+/z//P3//f7//v//AAAAAAAAAAAA/v7/+/z/9/n/9vn/9vn/9Pj/9vn/ + +/z//v7/AAAA/f7/+vz/9fj/7/T/6vL/3ef/i5PbGRqJBQl5jJbZ6vH/9Pj/+/z/AAAAAAAAAAAA/f7/ + +fv/8fT/1Nn9t7/0wcr54er/7fT/8fX/9fj/+vv//f7/AAAAAAAA/f3/+Pr/8PT/6/L/3uX/ztb/5Or/ + 8/f/+Pr//f7/AAAAAAAAAAAA/f7/+vz/+Pr/+fv/+fv/+vv//f3//v//AAAAAAAAAAAA/P3/9/n/7vL/ + 193/ztf/5u3/7vP/9Pf/+/z//v7/AAAA/v7//P3/+Pr/8fX/7PP/5/D/sLfxoKnk4+r/8vf/9/n//f3/ + AAAAAAAAAAAA/v7/+/z/9vn/9Pf/8vb/8fb/8fX/9Pf/+Pr//P3//v7/AAAAAAAA/v7/+vv/8vb/5+7/ + y9H/WWO9KSmSkZXj6vD/+Pv//P3/AAAAAAAA/f7/+Pr/9fj/8vb/6O7/7vP/9fj/+Pr//f7/AAAAAAAA + /v//+vv/8vb/7PP/hYraKiqKlp7i6PD/7fP/9ff/+/z//v7/AAAAAAAA/f7/+vv/9ff/8fX/8PX/8vb/ + 8/f/9vn/+/z//v7/AAAAAAAAAAAAAAAA/f7/+/z/+vv/+fr/+fr/+vv//P3//v7/AAAAAAAAAAAAAAAA + /P3/9fj/7PL/1d7/RUysAABhAABlg4ja6/D/+Pr//P3/AAAAAAAA+/z/9fj/6e7/2eD/h4/bnaXg7PH/ + 9fj/+/z/AAAAAAAA/v7/+Pr/8PX/y9X1JDGVAABaERWDoKnp6PH/7vP/9/n//P3/AAAAAAAAAAAA/v7/ + /P3/+vv/+fv/+fv/+vv//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAA/v7//v7//v7//v7//v//AAAAAAAA + AAAAAAAAAAAA/v7/+fv/8PX/7PX/ipPdAABsAABlQ1Cp3Ob/7vP/9/n//f7/AAAAAAAA+fv/9Pj/yNH5 + Ule2DBJ8Ljie0df+8fb/+fv//v7/AAAA/v7/+Pr/7/X/hY3YAABxAAl7AABuEBaEs7nz6fH/8fX/+vv/ + /v7/AAAAAAAAAAAAAAAA/v///v7//v7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/9vn/7PL/0tn/LzidAQFsAAB0iZHb6vP/8PT/+fv//v//AAAA + /v7/+Pr/8vf/r7rqAAV4AABdPUen1N//7PL/9vn//f7/AAAA/v7/+fr/7/T/yc75S1G0AABrARKAAABp + Qker0df/7fP/9/n//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/9/n/5+7/cXXNAAd2AABuMDebzdT97PL/ + 9vj//P3/AAAAAAAA/v7/9/n/7/X/tL/uFCCLAABqHSqRvcf46fD/9Pf//f3/AAAAAAAA+vv/8vX/6vH/ + yM3+JC2XAABtAAV2Agx9q7Ly7vT/9vn//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/4uj/WWO1AAVx + KTaYu8T07fT/8vb/+vv//v7/AAAAAAAA/v7/9/n/7vX/vsn1Iy2SAABrAQ99mp/o6PD/9Pf//P3/AAAA + AAAA/P3/9/n/7vP/6fL/s7z2DBB/AABeQ0uttrr56e7/+Pr//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/P3/ + +fv/4ef6g4zNbXfFw8v27fT/8vb/+Pr//f3/AAAAAAAAAAAA/v7/9/n/7vT/yNL7MjucAABtBxF/nKLo + 6fH/9Pf//P3/AAAAAAAA/v7/+/z/9fj/7fL/6/T/jZXbLzScrrP14en/7fL/+fv//v7/AAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAA/f7/+vz/8PP91dr34+f/8vb/8/f/9/r//P3//v//AAAAAAAAAAAA/v7/+Pr/8PX/1N3/ + QUqmAQRxBQ98m6Dm7PL/9fj//P3/AAAAAAAAAAAA/v7/+/z/9ff/8PX/5ez/ytH94ej/8vb/9vj/+/z/ + /v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA + /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/ + 9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA + AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA + /v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/ + /P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/ + /f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// + ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB/////// + //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA + H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A + A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA + /f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A + AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf + AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4 + AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A// + ///////gD/////////Af//////////////8= + + + \ No newline at end of file diff --git a/Project/Panels/EditYtypArchetypePanel.Designer.cs b/Project/Panels/EditYtypArchetypePanel.Designer.cs index e86a349..72af0a8 100644 --- a/Project/Panels/EditYtypArchetypePanel.Designer.cs +++ b/Project/Panels/EditYtypArchetypePanel.Designer.cs @@ -120,8 +120,8 @@ // // ArchetypeDeleteButton // - this.ArchetypeDeleteButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.ArchetypeDeleteButton.Location = new System.Drawing.Point(270, 440); + this.ArchetypeDeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.ArchetypeDeleteButton.Location = new System.Drawing.Point(110, 439); this.ArchetypeDeleteButton.Name = "ArchetypeDeleteButton"; this.ArchetypeDeleteButton.Size = new System.Drawing.Size(126, 23); this.ArchetypeDeleteButton.TabIndex = 79; @@ -131,8 +131,7 @@ // // label13 // - this.label13.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.label13.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label13.AutoSize = true; this.label13.Location = new System.Drawing.Point(8, 405); this.label13.Name = "label13"; @@ -182,8 +181,7 @@ // // ArchetypeNameTextBox // - this.ArchetypeNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.ArchetypeNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.ArchetypeNameTextBox.Location = new System.Drawing.Point(110, 9); this.ArchetypeNameTextBox.Name = "ArchetypeNameTextBox"; @@ -202,8 +200,7 @@ // // PhysicsDictionaryTextBox // - this.PhysicsDictionaryTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.PhysicsDictionaryTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.PhysicsDictionaryTextBox.Location = new System.Drawing.Point(110, 191); this.PhysicsDictionaryTextBox.Name = "PhysicsDictionaryTextBox"; @@ -213,8 +210,7 @@ // // ClipDictionaryTextBox // - this.ClipDictionaryTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.ClipDictionaryTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.ClipDictionaryTextBox.Location = new System.Drawing.Point(110, 165); this.ClipDictionaryTextBox.Name = "ClipDictionaryTextBox"; @@ -224,8 +220,7 @@ // // AssetNameTextBox // - this.AssetNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.AssetNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.AssetNameTextBox.Location = new System.Drawing.Point(110, 35); this.AssetNameTextBox.Name = "AssetNameTextBox"; @@ -235,8 +230,7 @@ // // TextureDictTextBox // - this.TextureDictTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.TextureDictTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.TextureDictTextBox.Location = new System.Drawing.Point(110, 139); this.TextureDictTextBox.Name = "TextureDictTextBox"; @@ -246,8 +240,7 @@ // // label12 // - this.label12.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.label12.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label12.AutoSize = true; this.label12.Location = new System.Drawing.Point(8, 379); this.label12.Name = "label12"; @@ -257,8 +250,7 @@ // // label11 // - this.label11.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.label11.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label11.AutoSize = true; this.label11.Location = new System.Drawing.Point(19, 353); this.label11.Name = "label11"; @@ -268,8 +260,7 @@ // // label5 // - this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label5.AutoSize = true; this.label5.Location = new System.Drawing.Point(24, 327); this.label5.Name = "label5"; @@ -279,8 +270,7 @@ // // PhysicsDictHashLabel // - this.PhysicsDictHashLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Right))); + this.PhysicsDictHashLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.PhysicsDictHashLabel.AutoSize = true; this.PhysicsDictHashLabel.Location = new System.Drawing.Point(322, 194); this.PhysicsDictHashLabel.Name = "PhysicsDictHashLabel"; @@ -290,8 +280,7 @@ // // TextureDictHashLabel // - this.TextureDictHashLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Right))); + this.TextureDictHashLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.TextureDictHashLabel.AutoSize = true; this.TextureDictHashLabel.Location = new System.Drawing.Point(322, 142); this.TextureDictHashLabel.Name = "TextureDictHashLabel"; @@ -356,8 +345,7 @@ // // SpecialAttributeNumericUpDown // - this.SpecialAttributeNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.SpecialAttributeNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.SpecialAttributeNumericUpDown.Location = new System.Drawing.Point(110, 113); this.SpecialAttributeNumericUpDown.Maximum = new decimal(new int[] { @@ -372,9 +360,6 @@ // // label10 // - this.label10.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label10.AutoSize = true; this.label10.Location = new System.Drawing.Point(17, 115); this.label10.Name = "label10"; @@ -384,9 +369,6 @@ // // label9 // - this.label9.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label9.AutoSize = true; this.label9.Location = new System.Drawing.Point(41, 220); this.label9.Name = "label9"; @@ -396,8 +378,7 @@ // // AssetTypeComboBox // - this.AssetTypeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.AssetTypeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.AssetTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.AssetTypeComboBox.FormattingEnabled = true; @@ -408,9 +389,6 @@ // // label8 // - this.label8.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label8.AutoSize = true; this.label8.Location = new System.Drawing.Point(8, 194); this.label8.Name = "label8"; @@ -420,9 +398,6 @@ // // label7 // - this.label7.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label7.AutoSize = true; this.label7.Location = new System.Drawing.Point(27, 168); this.label7.Name = "label7"; @@ -432,9 +407,6 @@ // // label6 // - this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(37, 38); this.label6.Name = "label6"; @@ -444,9 +416,6 @@ // // label4 // - this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(8, 142); this.label4.Name = "label4"; @@ -456,8 +425,7 @@ // // HDTextureDistNumericUpDown // - this.HDTextureDistNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.HDTextureDistNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.HDTextureDistNumericUpDown.DecimalPlaces = 8; this.HDTextureDistNumericUpDown.Location = new System.Drawing.Point(110, 87); @@ -473,9 +441,6 @@ // // label3 // - this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(18, 89); this.label3.Name = "label3"; @@ -485,8 +450,7 @@ // // LodDistNumericUpDown // - this.LodDistNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.LodDistNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.LodDistNumericUpDown.DecimalPlaces = 8; this.LodDistNumericUpDown.Location = new System.Drawing.Point(110, 61); @@ -502,9 +466,6 @@ // // label2 // - this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(55, 63); this.label2.Name = "label2"; @@ -514,9 +475,6 @@ // // label1 // - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(66, 12); this.label1.Name = "label1"; diff --git a/Project/Panels/GenerateNavMeshPanel.cs b/Project/Panels/GenerateNavMeshPanel.cs index 084cd48..dc3f258 100644 --- a/Project/Panels/GenerateNavMeshPanel.cs +++ b/Project/Panels/GenerateNavMeshPanel.cs @@ -150,8 +150,8 @@ namespace CodeWalker.Project.Panels } if (ybn.Loaded && (ybn.Bounds != null)) { - bmin.Z = Math.Min(bmin.Z, ybn.Bounds.BoundingBoxMin.Z); - bmax.Z = Math.Max(bmax.Z, ybn.Bounds.BoundingBoxMax.Z); + bmin.Z = Math.Min(bmin.Z, ybn.Bounds.BoxMin.Z); + bmax.Z = Math.Max(bmax.Z, ybn.Bounds.BoxMax.Z); } } diff --git a/Project/Panels/ProjectExplorerPanel.cs b/Project/Panels/ProjectExplorerPanel.cs index 614874f..0623f11 100644 --- a/Project/Panels/ProjectExplorerPanel.cs +++ b/Project/Panels/ProjectExplorerPanel.cs @@ -89,6 +89,27 @@ namespace CodeWalker.Project.Panels ytypsnode.Expand(); } + if (CurrentProjectFile.YbnFiles.Count > 0) + { + var ybnsnode = projnode.Nodes.Add("Ybn Files"); + ybnsnode.Name = "Ybn"; + + foreach (var ybnfile in CurrentProjectFile.YbnFiles) + { + var ycstr = ybnfile.HasChanged ? "*" : ""; + string name = ybnfile.Name; + if (ybnfile.RpfFileEntry != null) + { + name = ybnfile.RpfFileEntry.Name; + } + var yndnode = ybnsnode.Nodes.Add(ycstr + name); + yndnode.Tag = ybnfile; + + LoadYbnTreeNodes(ybnfile, yndnode); + } + ybnsnode.Expand(); + } + if (CurrentProjectFile.YndFiles.Count > 0) { var yndsnode = projnode.Nodes.Add("Ynd Files"); @@ -353,6 +374,50 @@ namespace CodeWalker.Project.Panels } } } + private void LoadYbnTreeNodes(YbnFile ybn, TreeNode node) + { + if (ybn == null) return; + + if (!string.IsNullOrEmpty(node.Name)) return; //named nodes are eg Nodes + + node.Nodes.Clear(); + + if (ybn.Bounds != null) + { + LoadYbnBoundsTreeNode(ybn.Bounds, node); + } + + } + private void LoadYbnBoundsTreeNode(Bounds b, TreeNode node) + { + + var boundsnode = node.Nodes.Add(b.Type.ToString()); + boundsnode.Tag = b; + + if (b is BoundComposite bc) + { + var children = bc.Children?.data_items; + if (children != null) + { + for (int i = 0; i < children.Length; i++) + { + var child = children[i]; + if (child != null) + { + LoadYbnBoundsTreeNode(child, boundsnode); + } + } + } + } + else if (b is BoundGeometry bg) + { + TreeNode n; + n = boundsnode.Nodes.Add("Edit Polygon"); + n.Name = "EditPoly"; + n.Tag = b; //this tag should get updated with the selected poly! + } + + } private void LoadYndTreeNodes(YndFile ynd, TreeNode node) { if (ynd == null) return; @@ -700,6 +765,34 @@ namespace CodeWalker.Project.Panels } } } + public void SetYbnHasChanged(YbnFile ybn, bool changed) + { + if (ybn != null) + { + ybn.HasChanged = true; + } + if (ProjectTreeView.Nodes.Count > 0) + { + var pnode = ProjectTreeView.Nodes[0]; + var ynnode = GetChildTreeNode(pnode, "Ybn"); + if (ynnode == null) return; + string changestr = changed ? "*" : ""; + for (int i = 0; i < ynnode.Nodes.Count; i++) + { + var ynode = ynnode.Nodes[i]; + if (ynode.Tag == ybn) + { + string name = ybn.Name; + if (ybn.RpfFileEntry != null) + { + name = ybn.RpfFileEntry.Name; + } + ynode.Text = changestr + name; + break; + } + } + } + } public void SetYndHasChanged(YndFile ynd, bool changed) { if (ynd != null) @@ -1059,6 +1152,40 @@ namespace CodeWalker.Project.Panels return null; } + public TreeNode FindYbnTreeNode(YbnFile ybn) + { + if (ProjectTreeView.Nodes.Count <= 0) return null; + var projnode = ProjectTreeView.Nodes[0]; + var ybnsnode = GetChildTreeNode(projnode, "Ybn"); + if (ybnsnode == null) return null; + for (int i = 0; i < ybnsnode.Nodes.Count; i++) + { + var ybnnode = ybnsnode.Nodes[i]; + if (ybnnode.Tag == ybn) return ybnnode; + } + return null; + } + public TreeNode FindCollisionBoundsTreeNode(Bounds b) + { + if (b == null) return null; + var bnode = (b.Parent != null) ? FindCollisionBoundsTreeNode(b.Parent) : FindYbnTreeNode(b.GetRootYbn()); + if (bnode == null) return null; + for (int i = 0; i < bnode.Nodes.Count; i++) + { + var nnode = bnode.Nodes[i]; + if (nnode.Tag == b) return nnode; + } + return null; + } + public TreeNode FindCollisionPolyTreeNode(BoundPolygon p) + { + if (p == null) return null; + var ybnnode = FindCollisionBoundsTreeNode(p.Owner); + var polynode = GetChildTreeNode(ybnnode, "EditPoly"); + if (polynode == null) return null; + polynode.Tag = p; + return polynode; + } public TreeNode FindYndTreeNode(YndFile ynd) { if (ProjectTreeView.Nodes.Count <= 0) return null; @@ -1106,12 +1233,6 @@ namespace CodeWalker.Project.Panels if (polynode == null) return null; polynode.Tag = p; return polynode; - //for (int i = 0; i < polysnode.Nodes.Count; i++) - //{ - // TreeNode pnode = polysnode.Nodes[i]; - // if (pnode.Tag == p) return pnode; - //} - //return null; } public TreeNode FindNavPointTreeNode(YnvPoint p) { @@ -1417,6 +1538,48 @@ namespace CodeWalker.Project.Panels } } } + public void TrySelectCollisionBoundsTreeNode(Bounds bounds) + { + TreeNode tnode = FindCollisionBoundsTreeNode(bounds); + if (tnode == null) + { + tnode = FindYbnTreeNode(bounds?.GetRootYbn()); + } + if (tnode != null) + { + if (ProjectTreeView.SelectedNode == tnode) + { + OnItemSelected?.Invoke(bounds); + } + else + { + ProjectTreeView.SelectedNode = tnode; + } + } + } + public void TrySelectCollisionPolyTreeNode(BoundPolygon poly) + { + TreeNode tnode = FindCollisionPolyTreeNode(poly); + if (tnode == null) + { + tnode = FindCollisionBoundsTreeNode(poly?.Owner); + } + if (tnode == null) + { + tnode = FindYbnTreeNode(poly?.Owner?.GetRootYbn()); + } + if (tnode != null) + { + if (ProjectTreeView.SelectedNode == tnode) + { + OnItemSelected?.Invoke(poly); + } + else + { + ProjectTreeView.SelectedNode = tnode; + } + } + } public void TrySelectPathNodeTreeNode(YndNode node) { TreeNode tnode = FindPathNodeTreeNode(node); @@ -1786,7 +1949,6 @@ namespace CodeWalker.Project.Panels tn.Parent.Nodes.Remove(tn); } } - public void RemoveCarGenTreeNode(YmapCarGen cargen) { var tn = FindCarGenTreeNode(cargen); @@ -1796,7 +1958,6 @@ namespace CodeWalker.Project.Panels tn.Parent.Nodes.Remove(tn); } } - public void RemoveGrassBatchTreeNode(YmapGrassInstanceBatch batch) { var tn = FindGrassTreeNode(batch); @@ -1850,6 +2011,14 @@ namespace CodeWalker.Project.Panels tn.Parent.Nodes.Remove(tn); } } + public void RemoveCollisionBoundsTreeNode(Bounds bounds) + { + var tn = FindCollisionBoundsTreeNode(bounds); + if ((tn != null) && (tn.Parent != null)) + { + tn.Parent.Nodes.Remove(tn); + } + } public void RemovePathNodeTreeNode(YndNode node) { var tn = FindPathNodeTreeNode(node); diff --git a/Project/ProjectFile.cs b/Project/ProjectFile.cs index c6a6f2e..fb2630b 100644 --- a/Project/ProjectFile.cs +++ b/Project/ProjectFile.cs @@ -17,6 +17,7 @@ namespace CodeWalker.Project public int Version { get; set; } public List YmapFilenames { get; set; } = new List(); public List YtypFilenames { get; set; } = new List(); + public List YbnFilenames { get; set; } = new List(); public List YndFilenames { get; set; } = new List(); public List YnvFilenames { get; set; } = new List(); public List TrainsFilenames { get; set; } = new List(); @@ -30,6 +31,7 @@ namespace CodeWalker.Project public List YmapFiles { get; set; } = new List(); public List YtypFiles { get; set; } = new List(); + public List YbnFiles { get; set; } = new List(); public List YndFiles { get; set; } = new List(); public List YnvFiles { get; set; } = new List(); public List TrainsFiles { get; set; } = new List(); @@ -59,6 +61,11 @@ namespace CodeWalker.Project Xml.AddChildWithInnerText(doc, ytypselem, "Item", ytypfilename); } + var ybnselem = Xml.AddChild(doc, projelem, "YbnFilenames"); + foreach (string ybnfilename in YbnFilenames) + { + Xml.AddChildWithInnerText(doc, ybnselem, "Item", ybnfilename); + } var yndselem = Xml.AddChild(doc, projelem, "YndFilenames"); foreach (string yndfilename in YndFilenames) @@ -139,6 +146,22 @@ namespace CodeWalker.Project } + YbnFilenames.Clear(); + YbnFiles.Clear(); + var ybnselem = Xml.GetChild(projelem, "YbnFilenames"); + if (ybnselem != null) + { + foreach (var node in ybnselem.SelectNodes("Item")) + { + XmlElement ybnel = node as XmlElement; + if (ybnel != null) + { + AddYbnFile(ybnel.InnerText); + } + } + } + + YndFilenames.Clear(); YndFiles.Clear(); var yndselem = Xml.GetChild(projelem, "YndFilenames"); @@ -234,6 +257,10 @@ namespace CodeWalker.Project { YtypFilenames[i] = GetUpdatedFilePath(YtypFilenames[i], oldprojpath); } + for (int i = 0; i < YbnFilenames.Count; i++) + { + YbnFilenames[i] = GetUpdatedFilePath(YbnFilenames[i], oldprojpath); + } for (int i = 0; i < YndFilenames.Count; i++) { YndFilenames[i] = GetUpdatedFilePath(YndFilenames[i], oldprojpath); @@ -456,6 +483,73 @@ namespace CodeWalker.Project } + public YbnFile AddYbnFile(string filename) + { + YbnFile ybn = new YbnFile(); + ybn.RpfFileEntry = new RpfResourceFileEntry(); + ybn.RpfFileEntry.Name = Path.GetFileName(filename); + ybn.FilePath = GetFullFilePath(filename); + ybn.Name = ybn.RpfFileEntry.Name; + if (!AddYbnFile(ybn)) return null; + return ybn; + } + public bool AddYbnFile(YbnFile ybn) + { + string relpath = GetRelativePath(ybn.FilePath); + if (string.IsNullOrEmpty(relpath)) relpath = ybn.Name; + if (YndFilenames.Contains(relpath)) return false; + YbnFilenames.Add(relpath); + YbnFiles.Add(ybn); + return true; + } + public void RemoveYbnFile(YbnFile ybn) + { + if (ybn == null) return; + var relpath = GetRelativePath(ybn.FilePath); + if (string.IsNullOrEmpty(relpath)) relpath = ybn.Name; + YbnFiles.Remove(ybn); + YbnFilenames.Remove(relpath); + HasChanged = true; + } + public bool ContainsYbn(string filename) + { + bool found = false; + filename = filename.ToLowerInvariant(); + foreach (var yndfn in YbnFilenames) + { + if (yndfn == filename) + { + found = true; + break; + } + } + return found; + } + public bool ContainsYbn(YbnFile ybn) + { + foreach (var f in YbnFiles) + { + if (f == ybn) return true; + } + return false; + } + public bool RenameYbn(string oldfilename, string newfilename) + { + oldfilename = oldfilename.ToLowerInvariant(); + newfilename = newfilename.ToLowerInvariant(); + for (int i = 0; i < YbnFilenames.Count; i++) + { + if (YbnFilenames[i] == oldfilename) + { + YbnFilenames[i] = newfilename; + HasChanged = true; + return true; + } + } + return false; + } + + public YndFile AddYndFile(string filename) { YndFile ynd = new YndFile(); diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index b9f02cf..a076723 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -72,12 +72,17 @@ namespace CodeWalker.Project private Dat151Interior CurrentAudioInterior; private Dat151InteriorRoom CurrentAudioInteriorRoom; + private YbnFile CurrentYbnFile; + private Bounds CurrentCollisionBounds; + private BoundPolygon CurrentCollisionPoly; + private bool renderitems = true; private bool hidegtavmap = false; private object projectsyncroot = new object(); public object ProjectSyncRoot { get { return projectsyncroot; } } + private Dictionary visibleybns = new Dictionary(); private Dictionary visibleynds = new Dictionary(); private Dictionary visibleynvs = new Dictionary(); private Dictionary visibletrains = new Dictionary(); @@ -387,6 +392,27 @@ namespace CodeWalker.Project (panel) => { panel.SetArchetype(CurrentArchetype); }, //updateFunc (panel) => { return panel.CurrentArchetype == CurrentArchetype; }); //findFunc } + public void ShowEditYbnPanel(bool promote) + { + ShowPanel(promote, + () => { return new EditYbnPanel(this); }, //createFunc + (panel) => { panel.SetYbn(CurrentYbnFile); }, //updateFunc + (panel) => { return panel.Ybn == CurrentYbnFile; }); //findFunc + } + public void ShowEditYbnBoundsPanel(bool promote) + { + ShowPanel(promote, + () => { return new EditYbnBoundsPanel(this); }, //createFunc + (panel) => { panel.SetCollisionBounds(CurrentCollisionBounds); }, //updateFunc + (panel) => { return panel.CollisionBounds == CurrentCollisionBounds; }); //findFunc + } + public void ShowEditYbnBoundPolyPanel(bool promote) + { + ShowPanel(promote, + () => { return new EditYbnBoundPolyPanel(this); }, //createFunc + (panel) => { panel.SetCollisionPoly(CurrentCollisionPoly); }, //updateFunc + (panel) => { return panel.CollisionPoly == CurrentCollisionPoly; }); //findFunc + } public void ShowEditYndPanel(bool promote) { ShowPanel(promote, @@ -570,6 +596,18 @@ namespace CodeWalker.Project { ShowEditYtypPanel(promote); } + else if (CurrentCollisionPoly != null) + { + ShowEditYbnBoundPolyPanel(promote); + } + else if (CurrentCollisionBounds != null) + { + ShowEditYbnBoundsPanel(promote); + } + else if (CurrentYbnFile != null) + { + ShowEditYbnPanel(promote); + } if (CurrentPathNode != null) { ShowEditYndNodePanel(promote); @@ -666,6 +704,9 @@ namespace CodeWalker.Project CurrentGrassBatch = item as YmapGrassInstanceBatch; CurrentYtypFile = item as YtypFile; CurrentArchetype = item as Archetype; + CurrentYbnFile = item as YbnFile; + CurrentCollisionBounds = item as Bounds; + CurrentCollisionPoly = item as BoundPolygon; CurrentYndFile = item as YndFile; CurrentPathNode = item as YndNode; CurrentYnvFile = item as YnvFile; @@ -747,6 +788,14 @@ namespace CodeWalker.Project { CurrentYtypFile = CurrentEntity?.MloParent?.Archetype?.Ytyp ?? CurrentArchetype?.Ytyp; } + if (CurrentCollisionPoly != null) + { + CurrentCollisionBounds = CurrentCollisionPoly.Owner; + } + if (CurrentCollisionBounds != null) + { + CurrentYbnFile = CurrentCollisionBounds.GetRootYbn(); + } if (CurrentPathNode != null) { CurrentYndFile = CurrentPathNode.Ynd; @@ -1092,6 +1141,19 @@ namespace CodeWalker.Project } } + foreach (var ybn in CurrentProjectFile.YbnFiles) + { + if ((ybn != null) && (ybn.HasChanged)) + { + //save the current ybn first? + if (MessageBox.Show("Would you like to save " + ybn.Name + " before closing?", "Save .ybn before closing?", MessageBoxButtons.YesNo) == DialogResult.Yes) + { + CurrentYbnFile = ybn; + SaveYbn(); + } + } + } + foreach (var ynd in CurrentProjectFile.YndFiles) { if ((ynd != null) && (ynd.HasChanged)) @@ -1172,6 +1234,7 @@ namespace CodeWalker.Project CurrentProjectFile = null; CurrentYmapFile = null; CurrentYtypFile = null; + CurrentYbnFile = null; CurrentYndFile = null; CurrentYnvFile = null; CurrentTrainTrack = null; @@ -1215,6 +1278,10 @@ namespace CodeWalker.Project { SaveYtyp(); } + else if (CurrentYbnFile != null) + { + SaveYbn(); + } else if (CurrentYndFile != null) { SaveYnd(); @@ -1268,6 +1335,18 @@ namespace CodeWalker.Project //ShowEditYtypPanel(false); } + if (CurrentProjectFile.YbnFiles != null) + { + var cybn = CurrentYbnFile; + foreach (var ybn in CurrentProjectFile.YbnFiles) + { + CurrentYbnFile = ybn; + SaveYbn(); + } + CurrentYbnFile = cybn; + //ShowEditYbnPanel(false); + } + if (CurrentProjectFile.YndFiles != null) { var cynd = CurrentYndFile; @@ -1342,6 +1421,10 @@ namespace CodeWalker.Project { SaveYtyp(saveas); } + else if (CurrentYbnFile != null) + { + SaveYbn(saveas); + } else if (CurrentYndFile != null) { SaveYnd(saveas); @@ -1488,7 +1571,7 @@ namespace CodeWalker.Project if (!CurrentProjectFile.RenameYmap(origpath, newpath)) { //couldn't rename it in the project? - MessageBox.Show("Couldn't rename ymap in project! This shouldn't happen - check the project file XML."); + //MessageBox.Show("Couldn't rename ymap in project! This shouldn't happen - check the project file XML."); } } SetProjectHasChanged(true); @@ -2130,6 +2213,11 @@ namespace CodeWalker.Project + + + + + public void NewYtyp() { if (CurrentProjectFile == null) @@ -2250,7 +2338,7 @@ namespace CodeWalker.Project if (!CurrentProjectFile.RenameYtyp(origpath, newpath)) { //couldn't rename it in the project? - MessageBox.Show("Couldn't rename ytyp in project! This shouldn't happen - check the project file XML."); + //MessageBox.Show("Couldn't rename ytyp in project! This shouldn't happen - check the project file XML."); } } SetProjectHasChanged(true); @@ -2780,6 +2868,192 @@ namespace CodeWalker.Project } + + + + + + public void NewYbn() + { + if (CurrentProjectFile == null) + { + NewProject(); + } + if (CurrentProjectFile == null) return; + + int testi = 1; + string fname = string.Empty; + bool filenameok = false; + while (!filenameok) + { + fname = "bounds" + testi.ToString() + ".ynd"; + filenameok = !CurrentProjectFile.ContainsYbn(fname); + testi++; + } + + lock (projectsyncroot) + { + YbnFile ybn = CurrentProjectFile.AddYbnFile(fname); + if (ybn != null) + { + ybn.Loaded = true; + ybn.HasChanged = true; //new ynd, flag as not saved + + //TODO: set new ybn default values... + ybn.Bounds = new Bounds(); + } + } + + CurrentProjectFile.HasChanged = true; + + LoadProjectTree(); + } + public void OpenYbn() + { + string[] files = ShowOpenDialogMulti("Ybn files|*.ybn", string.Empty); + if (files == null) + { + return; + } + + if (CurrentProjectFile == null) + { + NewProject(); + } + + foreach (string file in files) + { + if (!File.Exists(file)) continue; + + var ybn = CurrentProjectFile.AddYbnFile(file); + + if (ybn != null) + { + SetProjectHasChanged(true); + + LoadYbnFromFile(ybn, file); + + LoadProjectTree(); + } + else + { + MessageBox.Show("Couldn't add\n" + file + "\n - the file already exists in the project."); + } + + } + } + public void SaveYbn(bool saveas = false) + { + if ((CurrentYbnFile == null) && (CurrentCollisionBounds != null)) CurrentYbnFile = CurrentCollisionBounds.GetRootYbn(); + if (CurrentYbnFile == null) return; + + + string ybnname = CurrentYbnFile.Name; + string filepath = CurrentYbnFile.FilePath; + if (string.IsNullOrEmpty(filepath)) + { + filepath = ybnname; + } + string origfile = filepath; + if (!File.Exists(filepath)) + { + saveas = true; + } + + + byte[] data; + lock (projectsyncroot) //need to sync writes to ybn objects... + { + saveas = saveas || string.IsNullOrEmpty(filepath); + if (saveas) + { + filepath = ShowSaveDialog("Ybn files|*.ybn", filepath); + if (string.IsNullOrEmpty(filepath)) + { return; } + + string newname = Path.GetFileNameWithoutExtension(filepath); + JenkIndex.Ensure(newname); + CurrentYbnFile.FilePath = filepath; + CurrentYbnFile.RpfFileEntry.Name = new FileInfo(filepath).Name; + CurrentYbnFile.Name = CurrentYbnFile.RpfFileEntry.Name; + } + + + data = CurrentYbnFile.Save(); + } + + + if (data != null) + { + File.WriteAllBytes(filepath, data); + } + + SetYbnHasChanged(false); + + if (saveas) + { + //ShowEditYbnPanel(false); + if (CurrentProjectFile != null) + { + string origpath = CurrentProjectFile.GetRelativePath(origfile); + string newpath = CurrentProjectFile.GetRelativePath(CurrentYbnFile.FilePath); + if (!CurrentProjectFile.RenameYbn(origpath, newpath)) + { //couldn't rename it in the project? happens when project not saved yet... + //MessageBox.Show("Couldn't rename ybn in project! This shouldn't happen - check the project file XML."); + } + } + SetProjectHasChanged(true); + SetCurrentSaveItem(); + } + + } + public void AddYbnToProject(YbnFile ybn) + { + if (ybn == null) return; + if (CurrentProjectFile == null) + { + NewProject(); + } + if (YbnExistsInProject(ybn)) return; + if (CurrentProjectFile.AddYbnFile(ybn)) + { + ybn.HasChanged = true; + CurrentProjectFile.HasChanged = true; + LoadProjectTree(); + } + CurrentYbnFile = ybn; + RefreshUI(); + if (CurrentCollisionPoly != null) + { + ProjectExplorer?.TrySelectCollisionPolyTreeNode(CurrentCollisionPoly); + } + else if (CurrentCollisionBounds != null) + { + ProjectExplorer?.TrySelectCollisionBoundsTreeNode(CurrentCollisionBounds); + } + } + public void RemoveYbnFromProject() + { + if (CurrentYbnFile == null) return; + if (CurrentProjectFile == null) return; + CurrentProjectFile.RemoveYbnFile(CurrentYbnFile); + CurrentYbnFile = null; + LoadProjectTree(); + RefreshUI(); + } + public bool YbnExistsInProject(YbnFile ybn) + { + if (ybn == null) return false; + if (CurrentProjectFile == null) return false; + return CurrentProjectFile.ContainsYbn(ybn); + } + + + + + + + public void NewYnd() { if (CurrentProjectFile == null) @@ -3079,6 +3353,11 @@ namespace CodeWalker.Project + + + + + public void NewYnv() { if (CurrentProjectFile == null) @@ -3285,6 +3564,11 @@ namespace CodeWalker.Project + + + + + public void NewTrainTrack() { if (CurrentProjectFile == null) @@ -3545,6 +3829,11 @@ namespace CodeWalker.Project + + + + + public void NewScenario() { if (CurrentProjectFile == null) @@ -5389,6 +5678,12 @@ namespace CodeWalker.Project + + + + + + public void GetVisibleYmaps(Camera camera, Dictionary ymaps) { if (hidegtavmap) @@ -5450,19 +5745,40 @@ namespace CodeWalker.Project } } } - public void GetVisibleCollisionMeshes(Camera camera, List items) + public void GetVisibleYbns(Camera camera, List ybns) { if (hidegtavmap) { - items.Clear(); + ybns.Clear(); } - } - public void GetVisibleWaterQuads(Camera camera, List quads) - { - if (hidegtavmap) + + if (CurrentProjectFile == null) return; + + lock (projectsyncroot) { - quads.Clear(); + visibleybns.Clear(); + for (int i = 0; i < ybns.Count; i++) + { + var ybn = ybns[i]; + visibleybns[ybn.Name] = ybn; + } + + for (int i = 0; i < CurrentProjectFile.YbnFiles.Count; i++) + { + var ybn = CurrentProjectFile.YbnFiles[i]; + if (ybn.Loaded) + { + visibleybns[ybn.Name] = ybn; + } + } + + ybns.Clear(); + foreach (var ybn in visibleybns.Values) + { + ybns.Add(ybn); + } } + } public void GetVisibleYnds(Camera camera, List ynds) { @@ -5642,6 +5958,13 @@ namespace CodeWalker.Project } + public void GetVisibleWaterQuads(Camera camera, List quads) + { + if (hidegtavmap) + { + quads.Clear(); + } + } public MloInstanceData TryGetMloInstance(MloArchetype arch) { @@ -5671,6 +5994,8 @@ namespace CodeWalker.Project var ent = sel.EntityDef; var cargen = sel.CarGenerator; var grassbatch = sel.GrassBatch; + var collpoly = sel.CollisionPoly; + var collbound = sel.CollisionBounds ?? collpoly?.Owner; var pathnode = sel.PathNode; var pathlink = sel.PathLink; var navpoly = sel.NavPoly; @@ -5683,6 +6008,7 @@ namespace CodeWalker.Project Archetype arch = mlo?.Archetype ?? ent?.MloParent?.Archetype ?? ent?.Archetype; YtypFile ytyp = mlo?.Archetype?.Ytyp ?? ent?.MloParent?.Archetype?.Ytyp ?? ent?.Archetype?.Ytyp ?? room?.OwnerMlo?.Ytyp; YmapFile ymap = ent?.Ymap ?? cargen?.Ymap ?? grassbatch?.Ymap ?? mlo?.Ymap; + YbnFile ybn = collbound?.GetRootYbn(); YndFile ynd = pathnode?.Ynd; YnvFile ynv = navpoly?.Ynv ?? navpoint?.Ynv ?? navportal?.Ynv; TrainTrack traintrack = trainnode?.Track; @@ -5726,6 +6052,17 @@ namespace CodeWalker.Project ProjectExplorer?.TrySelectMloRoomTreeNode(room); } } + else if (YbnExistsInProject(ybn)) + { + if (collpoly != CurrentCollisionPoly) + { + ProjectExplorer?.TrySelectCollisionPolyTreeNode(collpoly); + } + if (collbound != CurrentCollisionBounds) + { + ProjectExplorer?.TrySelectCollisionBoundsTreeNode(collbound); + } + } else if (YndExistsInProject(ynd)) { if (pathnode != CurrentPathNode) @@ -5789,6 +6126,9 @@ namespace CodeWalker.Project CurrentEntity = ent ?? mlo; CurrentCarGen = cargen; CurrentGrassBatch = grassbatch; + CurrentYbnFile = ybn; + CurrentCollisionPoly = collpoly; + CurrentCollisionBounds = collbound; CurrentYndFile = ynd; CurrentPathNode = pathnode; CurrentPathLink = pathlink; @@ -5839,6 +6179,14 @@ namespace CodeWalker.Project { OnWorldCarGenModified(sel.CarGenerator); } + else if (sel.CollisionPoly != null) + { + OnWorldCollisionPolyModified(sel.CollisionPoly); + } + else if (sel.CollisionBounds != null) + { + OnWorldCollisionBoundsModified(sel.CollisionBounds); + } else if (sel.PathNode != null) { OnWorldPathNodeModified(sel.PathNode, sel.PathLink); @@ -5976,6 +6324,84 @@ namespace CodeWalker.Project } } + } + private void OnWorldCollisionPolyModified(BoundPolygon poly) + { + var ybn = poly?.Owner?.GetRootYbn(); + if (ybn == null) return; + + CurrentYbnFile = ybn; + + if (CurrentProjectFile == null) + { + NewProject(); + } + + if (!YbnExistsInProject(ybn)) + { + ybn.HasChanged = true; + poly.Owner.HasChanged = true; + AddYbnToProject(ybn); + ProjectExplorer?.TrySelectCollisionPolyTreeNode(poly); + } + + if (poly != CurrentCollisionPoly) + { + CurrentCollisionPoly = poly; + ProjectExplorer?.TrySelectCollisionPolyTreeNode(poly); + } + + if (poly == CurrentCollisionPoly) + { + ShowEditYbnBoundPolyPanel(false); + + //////UpdateCollisionPolyTreeNode(poly); + + if (ybn != null) + { + SetYbnHasChanged(true); + } + } + + } + private void OnWorldCollisionBoundsModified(Bounds bounds) + { + var ybn = bounds?.GetRootYbn(); + if (ybn == null) return; + + CurrentYbnFile = ybn; + + if (CurrentProjectFile == null) + { + NewProject(); + } + + if (!YbnExistsInProject(ybn)) + { + ybn.HasChanged = true; + bounds.HasChanged = true; + AddYbnToProject(ybn); + ProjectExplorer?.TrySelectCollisionBoundsTreeNode(bounds); + } + + if (bounds != CurrentCollisionBounds) + { + CurrentCollisionBounds = bounds; + ProjectExplorer?.TrySelectCollisionBoundsTreeNode(bounds); + } + + if (bounds == CurrentCollisionBounds) + { + ShowEditYbnBoundsPanel(false); + + //////UpdateCollisionBoundsTreeNode(bounds); + + if (ybn != null) + { + SetYbnHasChanged(true); + } + } + } private void OnWorldPathNodeModified(YndNode node, YndLink link) { @@ -6282,6 +6708,19 @@ namespace CodeWalker.Project PromoteIfPreviewPanelActive(); } + public void SetYbnHasChanged(bool changed) + { + if (CurrentYbnFile == null) return; + + bool changechange = changed != CurrentYbnFile.HasChanged; + if (!changechange) return; + + CurrentYbnFile.HasChanged = changed; + + ProjectExplorer?.SetYbnHasChanged(CurrentYbnFile, changed); + + PromoteIfPreviewPanelActive(); + } public void SetYndHasChanged(bool changed) { if (CurrentYndFile == null) return; @@ -6441,6 +6880,20 @@ namespace CodeWalker.Project AddProjectArchetypes(ytyp); } + private void LoadYbnFromFile(YbnFile ybn, string filename) + { + byte[] data = File.ReadAllBytes(filename); + + ybn.Load(data); + + if (WorldForm != null) + { + if (ybn?.Bounds != null) + { + WorldForm.UpdateCollisionBoundsGraphics(ybn?.Bounds); + } + } + } private void LoadYndFromFile(YndFile ynd, string filename) { byte[] data = File.ReadAllBytes(filename); @@ -6534,6 +6987,7 @@ namespace CodeWalker.Project RefreshEntityUI(); RefreshCarGenUI(); RefreshYtypUI(); + RefreshYbnUI(); RefreshYndUI(); RefreshYnvUI(); RefreshTrainTrackUI(); @@ -6632,6 +7086,13 @@ namespace CodeWalker.Project { //WorldForm.EnableYtypUI(enable, CurrentYtypFile?.Name ?? ""); } + } + private void RefreshYbnUI() + { + bool enable = (CurrentYbnFile != null); + bool inproj = YbnExistsInProject(CurrentYbnFile); + + } private void RefreshYndUI() { @@ -6781,6 +7242,10 @@ namespace CodeWalker.Project { filename = CurrentYtypFile.RpfFileEntry?.Name; } + else if (CurrentYbnFile != null) + { + filename = CurrentYbnFile.RpfFileEntry?.Name; + } else if (CurrentYndFile != null) { filename = CurrentYndFile.RpfFileEntry?.Name; diff --git a/Rendering/Renderable.cs b/Rendering/Renderable.cs index 643bb5a..5b8ca58 100644 --- a/Rendering/Renderable.cs +++ b/Rendering/Renderable.cs @@ -2024,15 +2024,15 @@ namespace CodeWalker.Rendering Bound = bgeom; BoundGeom = bgeom; CenterGeom = bgeom.CenterGeom; - BBMin = bgeom.BoundingBoxMin; - BBMax = bgeom.BoundingBoxMax; + BBMin = bgeom.BoxMin; + BBMax = bgeom.BoxMax; if ((bgeom.Polygons == null) || (bgeom.Vertices == null)) { return; } - Vector3 vbox = (bgeom.BoundingBoxMax - bgeom.BoundingBoxMin); + //Vector3 vbox = (bgeom.BoxMax - bgeom.BoxMin); //var verts = bgeom.Vertices; //int vertcount = bgeom.Vertices.Length; @@ -2069,8 +2069,7 @@ namespace CodeWalker.Rendering { var poly = bgeom.Polygons[i]; if (poly == null) continue; - byte matind = ((bgeom.PolygonMaterialIndices != null) && (i < bgeom.PolygonMaterialIndices.Length)) ? bgeom.PolygonMaterialIndices[i] : (byte)0; - BoundMaterial_s mat = ((bgeom.Materials != null) && (matind < bgeom.Materials.Length)) ? bgeom.Materials[matind] : new BoundMaterial_s(); + BoundMaterial_s mat = poly.Material; Color color = BoundsMaterialTypes.GetMaterialColour(mat.Type); Vector3 p1, p2, p3, p4, a1, n1;//, n2, n3, p5, p7, p8; Vector3 norm = Vector3.Zero; @@ -2169,8 +2168,8 @@ namespace CodeWalker.Rendering rmat.TranslationVector = Vector3.Zero; Bound = bcap; - BBMin = bcap.BoundingBoxMin; - BBMax = bcap.BoundingBoxMax; + BBMin = bcap.BoxMin; + BBMax = bcap.BoxMax; BBOffset = xform.TranslationVector; BBOrientation = Quaternion.RotationMatrix(rmat); @@ -2178,11 +2177,11 @@ namespace CodeWalker.Rendering var colourf = BoundsMaterialTypes.GetMaterialColour(mat); var colour = (uint)colourf.ToRgba(); - float extent = bcap.BoundingSphereRadius - bcap.Margin; + float extent = bcap.SphereRadius - bcap.Margin; var rcap = new RenderableCapsule(); rcap.Colour = colour; - rcap.Point1 = Vector3.TransformCoordinate(bcap.Center - new Vector3(0, extent, 0), xform); + rcap.Point1 = Vector3.TransformCoordinate(bcap.SphereCenter - new Vector3(0, extent, 0), xform); rcap.Orientation = BBOrientation; rcap.Length = extent * 2.0f; rcap.Radius = bcap.Margin; @@ -2194,8 +2193,8 @@ namespace CodeWalker.Rendering public void Init(BoundSphere bsph, ref Matrix xform) { Bound = bsph; - BBMin = bsph.BoundingBoxMin; - BBMax = bsph.BoundingBoxMax; + BBMin = bsph.BoxMin; + BBMax = bsph.BoxMax; BBOffset = xform.TranslationVector; var mat = (BoundsMaterialType)bsph.MaterialIndex; @@ -2204,8 +2203,8 @@ namespace CodeWalker.Rendering var rsph = new RenderableSphere(); rsph.Colour = colour; - rsph.Center = Vector3.TransformCoordinate(bsph.Center, xform); - rsph.Radius = bsph.BoundingSphereRadius; + rsph.Center = Vector3.TransformCoordinate(bsph.SphereCenter, xform); + rsph.Radius = bsph.SphereRadius; Spheres = new[] { rsph }; @@ -2217,8 +2216,8 @@ namespace CodeWalker.Rendering rmat.TranslationVector = Vector3.Zero; Bound = bbox; - BBMin = bbox.BoundingBoxMin; - BBMax = bbox.BoundingBoxMax; + BBMin = bbox.BoxMin; + BBMax = bbox.BoxMax; BBOffset = xform.TranslationVector; BBOrientation = Quaternion.RotationMatrix(rmat); @@ -2226,11 +2225,11 @@ namespace CodeWalker.Rendering var colourf = BoundsMaterialTypes.GetMaterialColour(mat); var colour = (uint)colourf.ToRgba(); - var extent = (bbox.BoundingBoxMax - bbox.BoundingBoxMin).Abs(); + var extent = (bbox.BoxMax - bbox.BoxMin).Abs(); var rbox = new RenderableBox(); rbox.Colour = colour; - rbox.Corner = Vector3.TransformCoordinate(bbox.BoundingBoxMin, xform); + rbox.Corner = Vector3.TransformCoordinate(bbox.BoxMin, xform); rbox.Edge1 = Vector3.TransformNormal(new Vector3(extent.X, 0, 0), xform); rbox.Edge2 = Vector3.TransformNormal(new Vector3(0, extent.Y, 0), xform); rbox.Edge3 = Vector3.TransformNormal(new Vector3(0, 0, extent.Z), xform); @@ -2245,8 +2244,8 @@ namespace CodeWalker.Rendering rmat.TranslationVector = Vector3.Zero; Bound = bcyl; - BBMin = bcyl.BoundingBoxMin; - BBMax = bcyl.BoundingBoxMax; + BBMin = bcyl.BoxMin; + BBMax = bcyl.BoxMax; BBOffset = xform.TranslationVector; BBOrientation = Quaternion.RotationMatrix(rmat); @@ -2254,13 +2253,13 @@ namespace CodeWalker.Rendering var colourf = BoundsMaterialTypes.GetMaterialColour(mat); var colour = (uint)colourf.ToRgba(); - var extent = (bcyl.BoundingBoxMax - bcyl.BoundingBoxMin).Abs(); + var extent = (bcyl.BoxMax - bcyl.BoxMin).Abs(); var length = extent.Y; var radius = extent.X * 0.5f; var rcyl = new RenderableCylinder(); rcyl.Colour = colour; - rcyl.Point1 = Vector3.TransformCoordinate(bcyl.Center - new Vector3(0, length * 0.5f, 0), xform); + rcyl.Point1 = Vector3.TransformCoordinate(bcyl.SphereCenter - new Vector3(0, length * 0.5f, 0), xform); rcyl.Orientation = BBOrientation; rcyl.Length = length; rcyl.Radius = radius; @@ -2275,8 +2274,8 @@ namespace CodeWalker.Rendering rmat.TranslationVector = Vector3.Zero; Bound = bdisc; - BBMin = bdisc.BoundingBoxMin; - BBMax = bdisc.BoundingBoxMax; + BBMin = bdisc.BoxMin; + BBMax = bdisc.BoxMax; BBOffset = xform.TranslationVector; BBOrientation = Quaternion.LookAtLH(Vector3.Zero, Vector3.UnitX, Vector3.UnitZ) * Quaternion.RotationMatrix(rmat); @@ -2286,10 +2285,10 @@ namespace CodeWalker.Rendering var rcyl = new RenderableCylinder(); rcyl.Colour = colour; - rcyl.Point1 = Vector3.TransformCoordinate(bdisc.Center - new Vector3(bdisc.Margin, 0, 0), xform); + rcyl.Point1 = Vector3.TransformCoordinate(bdisc.SphereCenter - new Vector3(bdisc.Margin, 0, 0), xform); rcyl.Orientation = BBOrientation; rcyl.Length = bdisc.Margin * 2.0f; - rcyl.Radius = bdisc.BoundingSphereRadius; + rcyl.Radius = bdisc.SphereRadius; Cylinders = new[] { rcyl }; diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index 9f4c76e..87bde0c 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -3085,7 +3085,7 @@ namespace CodeWalker.Rendering { if (valign) { - float minz = caryft.Fragment.PhysicsLODGroup?.PhysicsLOD1?.Bound?.BoundingBoxMin.Z ?? 0.0f; + float minz = caryft.Fragment.PhysicsLODGroup?.PhysicsLOD1?.Bound?.BoxMin.Z ?? 0.0f; pos.Z -= minz; } diff --git a/Utils/MapUtils.cs b/Utils/MapUtils.cs index c89687c..a5a7335 100644 --- a/Utils/MapUtils.cs +++ b/Utils/MapUtils.cs @@ -597,7 +597,7 @@ namespace CodeWalker } else if (CollisionBounds != null) { - return CollisionBounds.Center; + return CollisionBounds.Position; } else if (NavPoly != null) { @@ -830,7 +830,7 @@ namespace CodeWalker } else if (CollisionBounds != null) { - CollisionBounds.Center = newpos; + CollisionBounds.Position = newpos; } else if (NavPoly != null) { diff --git a/WorldForm.cs b/WorldForm.cs index cf1ba5f..d065971 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -109,6 +109,7 @@ namespace CodeWalker bool rendercollisionmeshes = Settings.Default.ShowCollisionMeshes; List collisionitems = new List(); + List collisionybns = new List(); int collisionmeshrange = Settings.Default.CollisionMeshRange; bool[] collisionmeshlayers = { true, true, true }; @@ -738,14 +739,23 @@ namespace CodeWalker collisionitems.Clear(); space.GetVisibleBounds(camera, collisionmeshrange, collisionmeshlayers, collisionitems); - if (ProjectForm != null) - { - ProjectForm.GetVisibleCollisionMeshes(camera, collisionitems); - } - + collisionybns.Clear(); foreach (var item in collisionitems) { YbnFile ybn = gameFileCache.GetYbn(item.Name); + if ((ybn != null) && (ybn.Loaded)) + { + collisionybns.Add(ybn); + } + } + + if (ProjectForm != null) + { + ProjectForm.GetVisibleYbns(camera, collisionybns); + } + + foreach (var ybn in collisionybns) + { if ((ybn != null) && (ybn.Loaded)) { Renderer.RenderCollisionMesh(ybn.Bounds, null); @@ -2293,7 +2303,7 @@ namespace CodeWalker CurMouseHit.CamRel = camrel + orientation.Multiply(trans); CurMouseHit.BBOffset = trans; CurMouseHit.BBOrientation = MouseRayCollision.HitBounds?.Transform.ToQuaternion() ?? Quaternion.Identity; - CurMouseHit.AABB = new BoundingBox(MouseRayCollision.HitBounds?.BoundingBoxMin ?? Vector3.Zero, MouseRayCollision.HitBounds?.BoundingBoxMax ?? Vector3.Zero); + CurMouseHit.AABB = new BoundingBox(MouseRayCollision.HitBounds?.BoxMin ?? Vector3.Zero, MouseRayCollision.HitBounds?.BoxMax ?? Vector3.Zero); } } } @@ -3543,7 +3553,7 @@ namespace CodeWalker MapSelection ms = new MapSelection(); ms.CollisionBounds = b; - ms.AABB = new BoundingBox(b.BoundingBoxMin, b.BoundingBoxMax); + ms.AABB = new BoundingBox(b.BoxMin, b.BoxMax); SelectItem(ms); }