From 741cf0ecfce99e1f0755dae8d1e0bb6cb8d9f83d Mon Sep 17 00:00:00 2001 From: dexy Date: Mon, 13 Jan 2020 16:25:52 +1100 Subject: [PATCH] Collisions editing progress --- .../GameFiles/FileTypes/YbnFile.cs | 9 + CodeWalker.Core/GameFiles/Resources/Bounds.cs | 65 +++++- Project/Panels/EditYbnBoundsPanel.cs | 2 + Project/ProjectForm.cs | 196 +++++++++++++----- Rendering/Renderer.cs | 15 +- 5 files changed, 230 insertions(+), 57 deletions(-) diff --git a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs index ccf40a6..c9b22a8 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs @@ -76,6 +76,15 @@ namespace CodeWalker.GameFiles } return false; } + public bool AddBounds(Bounds b) + { + if (b == null) return false; + if (Bounds != null) return false; + Bounds = b; + Bounds.OwnerYbn = this; + Bounds.OwnerName = Name ?? RpfFileEntry?.Name; + return true; + } } } diff --git a/CodeWalker.Core/GameFiles/Resources/Bounds.cs b/CodeWalker.Core/GameFiles/Resources/Bounds.cs index e54254e..7aa0342 100644 --- a/CodeWalker.Core/GameFiles/Resources/Bounds.cs +++ b/CodeWalker.Core/GameFiles/Resources/Bounds.cs @@ -421,6 +421,24 @@ namespace CodeWalker.GameFiles } } + public virtual void CopyFrom(Bounds other) + { + if (other == null) return; + SphereRadius = other.SphereRadius; + SphereCenter = other.SphereCenter; + BoxMin = other.BoxMin; + BoxMax = other.BoxMax; + Margin = other.Margin; + Unknown_3Ch = other.Unknown_3Ch; + MaterialIndex = other.MaterialIndex; + MaterialColorIndex = other.MaterialColorIndex; + ProceduralId = other.ProceduralId; + RoomId_and_PedDensity = other.RoomId_and_PedDensity; + UnkFlags = other.UnkFlags; + PolyFlags = other.PolyFlags; + Unknown_60h = other.Unknown_60h; + Volume = other.Volume; + } public virtual SpaceSphereIntersectResult SphereIntersect(ref BoundingSphere sph) { @@ -2003,10 +2021,18 @@ namespace CodeWalker.GameFiles Polygons = newpolys; PolygonMaterialIndices = newpolymats; - + BoxMin = bvh.BoundingBoxMin.XYZ(); + BoxMax = bvh.BoundingBoxMax.XYZ(); + BoxCenter = bvh.BoundingBoxCenter.XYZ(); + SphereCenter = BoxCenter; + SphereRadius = (BoxMax - BoxCenter).Length(); BVH = bvh; + if (Parent != null) + { + Parent.BuildBVH(); + } } @@ -2384,6 +2410,12 @@ namespace CodeWalker.GameFiles var bvh = BVHBuilder.Build(items, 1); //composites have BVH item threshold of 1 + BoxMin = bvh.BoundingBoxMin.XYZ(); + BoxMax = bvh.BoundingBoxMax.XYZ(); + BoxCenter = bvh.BoundingBoxCenter.XYZ(); + SphereCenter = BoxCenter; + SphereRadius = (BoxMax - BoxCenter).Length(); + BVH = bvh; } @@ -2560,6 +2592,37 @@ namespace CodeWalker.GameFiles return false; } + public void AddChild(Bounds child) + { + if (Children == null) Children = new ResourcePointerArray64(); + + var children = Children.data_items?.ToList() ?? new List(); + var transforms1 = ChildrenTransformation1?.ToList() ?? new List(); + var transforms2 = ChildrenTransformation2?.ToList() ?? new List(); + var bboxes = ChildrenBoundingBoxes?.ToList() ?? new List(); + var flags1 = ChildrenFlags1?.ToList(); + var flags2 = ChildrenFlags2?.ToList(); + var idx = children.Count; + + child.Parent = this; + + children.Add(child); + transforms1.Add(Matrix.Identity); + transforms2.Add(Matrix.Identity); + bboxes.Add(new AABB_s());//will get updated later + flags1?.Add(new BoundCompositeChildrenFlags()); + flags2?.Add(new BoundCompositeChildrenFlags()); + Children.data_items = children.ToArray(); + ChildrenTransformation1 = transforms1.ToArray(); + ChildrenTransformation2 = transforms2.ToArray(); + ChildrenBoundingBoxes = bboxes.ToArray(); + ChildrenFlags1 = flags1?.ToArray(); + ChildrenFlags2 = flags2?.ToArray(); + BuildBVH(); + UpdateChildrenBounds(); + + } + } diff --git a/Project/Panels/EditYbnBoundsPanel.cs b/Project/Panels/EditYbnBoundsPanel.cs index 098b583..e5dc790 100644 --- a/Project/Panels/EditYbnBoundsPanel.cs +++ b/Project/Panels/EditYbnBoundsPanel.cs @@ -151,6 +151,8 @@ namespace CodeWalker.Project.Panels DeleteButton.Enabled = !AddToProjectButton.Enabled; populatingui = false; + + ProjectForm.WorldForm?.SelectCollisionBounds(b); } } diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index fabc75c..47352c9 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -2177,10 +2177,10 @@ namespace CodeWalker.Project if (CurrentCarGen.Ymap != CurrentYmapFile) return false; if (CurrentYmapFile.CarGenerators == null) return false; //nothing to delete.. - if (MessageBox.Show("Are you sure you want to delete this car generator?\n" + CurrentCarGen.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this car generator?\n" + CurrentCarGen.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -2882,10 +2882,11 @@ namespace CodeWalker.Project return true; } - if (MessageBox.Show("Are you sure you want to delete this entity?\n" + CurrentEntity._CEntityDef.archetypeName.ToString() + "\n" + CurrentEntity.Position.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this entity?\n" + CurrentEntity._CEntityDef.archetypeName.ToString() + "\n" + CurrentEntity.Position.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} + MloInstanceData mloInstance = CurrentEntity.MloParent.MloInstance; if (mloInstance == null) return false; @@ -3078,7 +3079,7 @@ namespace CodeWalker.Project bool filenameok = false; while (!filenameok) { - fname = "bounds" + testi.ToString() + ".ynd"; + fname = "bounds" + testi.ToString() + ".ybn"; filenameok = !CurrentProjectFile.ContainsYbn(fname); testi++; } @@ -3090,9 +3091,6 @@ namespace CodeWalker.Project { ybn.Loaded = true; ybn.HasChanged = true; //new ynd, flag as not saved - - //TODO: set new ybn default values... - ybn.Bounds = new Bounds(); } } @@ -3248,9 +3246,107 @@ namespace CodeWalker.Project { if (CurrentYbnFile == null) return null; - //////// TODO!! + Bounds b = null; + switch (type) + { + case BoundsType.Sphere: + b = new BoundSphere(); + break; + case BoundsType.Capsule: + b = new BoundCapsule(); + break; + case BoundsType.Box: + b = new BoundBox(); + break; + case BoundsType.Geometry: + b = new BoundGeometry(); + break; + case BoundsType.GeometryBVH: + b = new BoundBVH(); + break; + case BoundsType.Composite: + b = new BoundComposite(); + break; + case BoundsType.Disc: + b = new BoundDisc(); + break; + case BoundsType.Cylinder: + b = new BoundCylinder(); + break; + case BoundsType.Cloth: + b = new BoundCloth(); + break; + } - return null; + if (b == null) return null; + + if ((copy != null) && (copy.Type == type)) + { + b.CopyFrom(copy); + } + else + { + var pos = GetSpawnPos(10.0f); + + b.Type = type; + b.Margin = 0.005f; + b.Volume = 1.0f; + b.Unknown_60h = Vector3.One; + b.Unknown_3Ch = 1; + b.SphereCenter = Vector3.Zero; + b.SphereRadius = 1.0f; + b.BoxCenter = Vector3.Zero; + b.BoxMin = -Vector3.One; + b.BoxMax = Vector3.One; + b.Position = pos; + + if (b is BoundBVH bbvh) + { } + if (b is BoundGeometry bgeo) + { + bgeo.CenterGeom = Vector3.Zero; + bgeo.Quantum = Vector3.Zero; + bgeo.Unknown_9Ch = 7.629627e-8f; + bgeo.Unknown_ACh = 0.0025f; + bgeo.Position = Vector3.Zero;//start geometry transform at 0 + } + if (b is BoundComposite bcmp) + { + bcmp.Position = Vector3.Zero;//start composite transform at 0 + } + } + + + var bcomp = (CurrentCollisionBounds as BoundComposite) ?? CurrentCollisionBounds?.Parent; + if (bcomp != null) + { + bcomp.AddChild(b); + } + else + { + CurrentYbnFile.AddBounds(b); + } + + + if (selectNew) + { + LoadProjectTree(); + ProjectExplorer?.TrySelectCollisionBoundsTreeNode(b); + CurrentCollisionBounds = b; + //ShowEditYbnPanel(false);; + ShowEditYbnBoundsPanel(false); + } + + if (bcomp != null) + { + if (WorldForm != null) + { + WorldForm.UpdateCollisionBoundsGraphics(bcomp); + } + } + + + return b; } public void AddCollisionBoundsToProject() { @@ -3500,10 +3596,10 @@ namespace CodeWalker.Project if (CurrentYbnFile == null) return false; if (CurrentCollisionPoly.Owner != CurrentCollisionBounds) return false; - if (MessageBox.Show("Are you sure you want to delete this collision poly?\n" + CurrentCollisionPoly.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this collision poly?\n" + CurrentCollisionPoly.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -3580,10 +3676,10 @@ namespace CodeWalker.Project if (CurrentYbnFile == null) return false; if (CurrentCollisionVertex.Owner != CurrentCollisionBounds) return false; - if (MessageBox.Show("Are you sure you want to delete this collision vertex, and all attached polygons?\n" + CurrentCollisionVertex.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this collision vertex, and all attached polygons?\n" + CurrentCollisionVertex.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -3885,10 +3981,10 @@ namespace CodeWalker.Project if (CurrentPathNode.Ynd != CurrentYndFile) return false; if (CurrentYndFile.Nodes == null) return false; //nothing to delete.. - if (MessageBox.Show("Are you sure you want to delete this path node?\n" + CurrentPathNode.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this path node?\n" + CurrentPathNode.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -4369,10 +4465,10 @@ namespace CodeWalker.Project if (CurrentTrainNode.Track != CurrentTrainTrack) return false; if (CurrentTrainTrack.Nodes == null) return false; //nothing to delete.. - if (MessageBox.Show("Are you sure you want to delete this train track node?\n" + CurrentTrainNode.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this train track node?\n" + CurrentTrainNode.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -4651,10 +4747,10 @@ namespace CodeWalker.Project if (CurrentScenarioNode == null) return false; - if (MessageBox.Show("Are you sure you want to delete this scenario node?\n" + CurrentScenarioNode.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this scenario node?\n" + CurrentScenarioNode.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -5830,10 +5926,10 @@ namespace CodeWalker.Project if (CurrentAudioZone?.AudioZone == null) return false; - if (MessageBox.Show("Are you sure you want to delete this audio zone?\n" + CurrentAudioZone.GetNameString() + "\n" + CurrentAudioZone.Position.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this audio zone?\n" + CurrentAudioZone.GetNameString() + "\n" + CurrentAudioZone.Position.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -5948,10 +6044,10 @@ namespace CodeWalker.Project if (CurrentAudioEmitter?.AudioEmitter == null) return false; - if (MessageBox.Show("Are you sure you want to delete this audio emitter?\n" + CurrentAudioEmitter.GetNameString() + "\n" + CurrentAudioEmitter.Position.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this audio emitter?\n" + CurrentAudioEmitter.GetNameString() + "\n" + CurrentAudioEmitter.Position.ToString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -6021,10 +6117,10 @@ namespace CodeWalker.Project if (CurrentAudioFile?.RelDatasSorted == null) return false; //nothing to delete.. - if (MessageBox.Show("Are you sure you want to delete this audio zone list?\n" + CurrentAudioZoneList.GetNameString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this audio zone list?\n" + CurrentAudioZoneList.GetNameString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) @@ -6088,10 +6184,10 @@ namespace CodeWalker.Project if (CurrentAudioFile?.RelDatasSorted == null) return false; //nothing to delete.. - if (MessageBox.Show("Are you sure you want to delete this audio emitter list?\n" + CurrentAudioEmitterList.GetNameString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) - { - return true; - } + //if (MessageBox.Show("Are you sure you want to delete this audio emitter list?\n" + CurrentAudioEmitterList.GetNameString() + "\n\nThis operation cannot be undone. Continue?", "Confirm delete", MessageBoxButtons.YesNo) != DialogResult.Yes) + //{ + // return true; + //} bool res = false; if (WorldForm != null) diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index 59adb7b..4a60d10 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -3267,13 +3267,16 @@ namespace CodeWalker.Rendering rbginst.Inst.Renderable = rndbc; rbginst.Inst.Orientation = orientation; rbginst.Inst.Scale = scale; - foreach (var geom in rndbc.Geometries) + if (rndbc.Geometries != null) { - if (geom == null) continue; - rbginst.Geom = geom; - rbginst.Inst.Position = position + orientation.Multiply(geom.CenterGeom * scale); - rbginst.Inst.CamRel = rbginst.Inst.Position - camera.Position; - shaders.Enqueue(ref rbginst); + foreach (var geom in rndbc.Geometries) + { + if (geom == null) continue; + rbginst.Geom = geom; + rbginst.Inst.Position = position + orientation.Multiply(geom.CenterGeom * scale); + rbginst.Inst.CamRel = rbginst.Inst.Position - camera.Position; + shaders.Enqueue(ref rbginst); + } } if (RenderedBoundCompsListEnable) //for later hit tests