From e4cc7550eb889f413514cd99120b2c3b3906ace7 Mon Sep 17 00:00:00 2001 From: dexy Date: Fri, 10 Jan 2020 02:12:16 +1100 Subject: [PATCH] Collisions editing progress --- CodeWalker.Core/GameFiles/Resources/Bounds.cs | 43 +++++++ World/MapSelection.cs | 114 +++++++++++++++--- WorldForm.cs | 26 +--- 3 files changed, 148 insertions(+), 35 deletions(-) diff --git a/CodeWalker.Core/GameFiles/Resources/Bounds.cs b/CodeWalker.Core/GameFiles/Resources/Bounds.cs index 4e433a9..173b81d 100644 --- a/CodeWalker.Core/GameFiles/Resources/Bounds.cs +++ b/CodeWalker.Core/GameFiles/Resources/Bounds.cs @@ -2267,6 +2267,7 @@ namespace CodeWalker.GameFiles public abstract Vector3 Position { get; set; } public abstract Quaternion Orientation { get; set; } public abstract BoundVertexRef NearestVertex(Vector3 p); + public abstract void GatherVertices(Dictionary verts); public abstract void Read(byte[] bytes, int offset); public abstract void Write(BinaryWriter bw); public virtual string Title @@ -2405,6 +2406,15 @@ namespace CodeWalker.GameFiles if (d2 <= d3) return new BoundVertexRef(vertIndex2, d2); return new BoundVertexRef(vertIndex3, d3); } + public override void GatherVertices(Dictionary verts) + { + if (Owner != null) + { + verts[Owner.GetVertexObject(vertIndex1)] = vertIndex1; + verts[Owner.GetVertexObject(vertIndex2)] = vertIndex2; + verts[Owner.GetVertexObject(vertIndex3)] = vertIndex3; + } + } public BoundPolygonTriangle() { @@ -2488,6 +2498,13 @@ namespace CodeWalker.GameFiles { return new BoundVertexRef(sphereIndex, sphereRadius); } + public override void GatherVertices(Dictionary verts) + { + if (Owner != null) + { + verts[Owner.GetVertexObject(sphereIndex)] = sphereIndex; + } + } public BoundPolygonSphere() { @@ -2617,6 +2634,14 @@ namespace CodeWalker.GameFiles if (d1 <= d2) return new BoundVertexRef(capsuleIndex1, d1); return new BoundVertexRef(capsuleIndex2, d2); } + public override void GatherVertices(Dictionary verts) + { + if (Owner != null) + { + verts[Owner.GetVertexObject(capsuleIndex1)] = capsuleIndex1; + verts[Owner.GetVertexObject(capsuleIndex2)] = capsuleIndex2; + } + } public BoundPolygonCapsule() { @@ -2773,6 +2798,16 @@ namespace CodeWalker.GameFiles if (d3 <= d4) return new BoundVertexRef(boxIndex3, d3); return new BoundVertexRef(boxIndex4, d4); } + public override void GatherVertices(Dictionary verts) + { + if (Owner != null) + { + verts[Owner.GetVertexObject(boxIndex1)] = boxIndex1; + verts[Owner.GetVertexObject(boxIndex2)] = boxIndex2; + verts[Owner.GetVertexObject(boxIndex3)] = boxIndex3; + verts[Owner.GetVertexObject(boxIndex4)] = boxIndex4; + } + } public BoundPolygonBox() { @@ -2904,6 +2939,14 @@ namespace CodeWalker.GameFiles if (d1 <= d2) return new BoundVertexRef(cylinderIndex1, d1); return new BoundVertexRef(cylinderIndex2, d2); } + public override void GatherVertices(Dictionary verts) + { + if (Owner != null) + { + verts[Owner.GetVertexObject(cylinderIndex1)] = cylinderIndex1; + verts[Owner.GetVertexObject(cylinderIndex2)] = cylinderIndex2; + } + } public BoundPolygonCylinder() { diff --git a/World/MapSelection.cs b/World/MapSelection.cs index b392476..5ab4b09 100644 --- a/World/MapSelection.cs +++ b/World/MapSelection.cs @@ -69,10 +69,11 @@ namespace CodeWalker public MCScenarioChainingEdge ScenarioEdge { get; set; } public AudioPlacement Audio { get; set; } - public MapSelection[] MultipleSelectionItems { get; set; } + public MapSelection[] MultipleSelectionItems { get; private set; } public Vector3 MultipleSelectionCenter { get; set; } public Quaternion MultipleSelectionRotation { get; set; } public Vector3 MultipleSelectionScale { get; set; } + public BoundVertex[] GatheredCollisionVerts { get; private set; } //for collision polys, need to move all the individual vertices instead public Vector3 BBOffset { get; set; } public Quaternion BBOrientation { get; set; } @@ -210,6 +211,7 @@ namespace CodeWalker MultipleSelectionCenter = Vector3.Zero; MultipleSelectionRotation = Quaternion.Identity; MultipleSelectionScale = Vector3.One; + GatheredCollisionVerts = null; AABB = new BoundingBox(); GeometryIndex = 0; CamRel = Vector3.Zero; @@ -760,6 +762,14 @@ namespace CodeWalker { get { + if (MultipleSelectionItems != null) + { + for (int i = 0; i < MultipleSelectionItems.Length; i++) + { + if (MultipleSelectionItems[i].EntityDef != null) return true; + } + return false; + } if (CollisionBounds != null) { return false; @@ -774,6 +784,39 @@ namespace CodeWalker + public void SetMultipleSelectionItems(MapSelection[] items) + { + if ((items != null) && (items.Length == 0)) items = null; + MultipleSelectionItems = items; + GatheredCollisionVerts = null; + var center = Vector3.Zero; + if (items != null) + { + Dictionary collVerts = null; + for (int i = 0; i < items.Length; i++) + { + center += items[i].WidgetPosition; + var collPoly = items[i].CollisionPoly; + if (collPoly != null) + { + + if (collVerts == null) collVerts = new Dictionary(); + collPoly.GatherVertices(collVerts); + } + } + if (collVerts != null) + { + GatheredCollisionVerts = collVerts.Keys.ToArray(); + } + if (items.Length > 0) + { + center *= (1.0f / items.Length); + } + } + MultipleSelectionCenter = center; + } + + public void SetPosition(Vector3 newpos, bool editPivot) { if (MultipleSelectionItems != null) @@ -787,8 +830,19 @@ namespace CodeWalker if (dpos == Vector3.Zero) return; //nothing moved.. (probably due to snap) for (int i = 0; i < MultipleSelectionItems.Length; i++) { - var refpos = MultipleSelectionItems[i].WidgetPosition; - MultipleSelectionItems[i].SetPosition(refpos + dpos, false); + if (MultipleSelectionItems[i].CollisionPoly == null)//skip polys, they use gathered verts + { + var refpos = MultipleSelectionItems[i].WidgetPosition; + MultipleSelectionItems[i].SetPosition(refpos + dpos, false); + } + } + if (GatheredCollisionVerts != null) + { + for (int i = 0; i < GatheredCollisionVerts.Length; i++) + { + var refpos = GatheredCollisionVerts[i].Position; + GatheredCollisionVerts[i].Position = refpos + dpos; + } } MultipleSelectionCenter = newpos; } @@ -864,13 +918,26 @@ namespace CodeWalker var trans = newrot * orinv; for (int i = 0; i < MultipleSelectionItems.Length; i++) { - var refpos = MultipleSelectionItems[i].WidgetPosition; - var relpos = refpos - cen; - var newpos = trans.Multiply(relpos) + cen; - var refori = MultipleSelectionItems[i].WidgetRotation; - var newori = trans * refori; - MultipleSelectionItems[i].SetPosition(newpos, false); - MultipleSelectionItems[i].SetRotation(newori, false); + if (MultipleSelectionItems[i].CollisionPoly == null)//skip polys, they use gathered verts + { + var refpos = MultipleSelectionItems[i].WidgetPosition; + var relpos = refpos - cen; + var newpos = trans.Multiply(relpos) + cen; + var refori = MultipleSelectionItems[i].WidgetRotation; + var newori = trans * refori; + MultipleSelectionItems[i].SetPosition(newpos, false); + MultipleSelectionItems[i].SetRotation(newori, false); + } + } + if (GatheredCollisionVerts != null) + { + for (int i = 0; i < GatheredCollisionVerts.Length; i++) + { + var refpos = GatheredCollisionVerts[i].Position; + var relpos = refpos - cen; + var newpos = trans.Multiply(relpos) + cen; + GatheredCollisionVerts[i].Position = newpos; + } } MultipleSelectionRotation = newrot; } @@ -934,11 +1001,24 @@ namespace CodeWalker var rsca = newscale / MultipleSelectionScale; for (int i = 0; i < MultipleSelectionItems.Length; i++) { - var refpos = MultipleSelectionItems[i].WidgetPosition; - var relpos = refpos - cen; - var newpos = ori.Multiply(orinv.Multiply(relpos) * rsca) + cen; - MultipleSelectionItems[i].SetPosition(newpos, false); - MultipleSelectionItems[i].SetScale(newscale, false); + if (MultipleSelectionItems[i].CollisionPoly == null)//skip polys, they use gathered verts + { + var refpos = MultipleSelectionItems[i].WidgetPosition; + var relpos = refpos - cen; + var newpos = ori.Multiply(orinv.Multiply(relpos) * rsca) + cen; + MultipleSelectionItems[i].SetPosition(newpos, false); + MultipleSelectionItems[i].SetScale(newscale, false); + } + } + if (GatheredCollisionVerts != null) + { + for (int i = 0; i < GatheredCollisionVerts.Length; i++) + { + var refpos = GatheredCollisionVerts[i].Position; + var relpos = refpos - cen; + var newpos = ori.Multiply(orinv.Multiply(relpos) * rsca) + cen; + GatheredCollisionVerts[i].Position = newpos; + } } MultipleSelectionScale = newscale; } @@ -952,6 +1032,10 @@ namespace CodeWalker CarGenerator.SetScale(newscale); AABB = new BoundingBox(CarGenerator.BBMin, CarGenerator.BBMax); } + else if (CollisionVertex != null) + { + //do nothing, but stop any poly from being scaled also + } else if (CollisionPoly != null) { CollisionPoly.Scale = newscale; diff --git a/WorldForm.cs b/WorldForm.cs index 71a2bf5..dede18b 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -3277,11 +3277,11 @@ namespace CodeWalker mhitv.Clear(); items.Clear();//this shouldn't really happen.. } - mhitv.MultipleSelectionItems = items.ToArray(); + mhitv.SetMultipleSelectionItems(items.ToArray()); } else { - mhitv.MultipleSelectionItems = null; + mhitv.SetMultipleSelectionItems(null); items.Add(mhitv); } change = true; @@ -3299,11 +3299,11 @@ namespace CodeWalker { if (SelectedItem.HasValue) //add the existing item to the selection list, if it's not empty { - mhitv.MultipleSelectionItems = null; - SelectedItem.MultipleSelectionItems = null; + mhitv.SetMultipleSelectionItems(null); + SelectedItem.SetMultipleSelectionItems(null); items.Add(SelectedItem); items.Add(mhitv); - SelectedItem.MultipleSelectionItems = items.ToArray(); + SelectedItem.SetMultipleSelectionItems(items.ToArray()); } } else //empty incoming value... do nothing? @@ -3322,21 +3322,8 @@ namespace CodeWalker if (items.Count > 1) { //iterate the selected items, and calculate the selection position - var center = Vector3.Zero; - foreach (var item in items) - { - center += item.WidgetPosition; - } - if (items.Count > 0) - { - center *= (1.0f / items.Count); - } - mhitv.Clear(); - mhitv.MultipleSelectionItems = items.ToArray(); - mhitv.MultipleSelectionCenter = center; - mhitv.MultipleSelectionRotation = Quaternion.Identity; - mhitv.MultipleSelectionScale = Vector3.One; + mhitv.SetMultipleSelectionItems(items.ToArray()); } } else @@ -3344,7 +3331,6 @@ namespace CodeWalker if (SelectedItem.MultipleSelectionItems != null) { change = true; - SelectedItem.MultipleSelectionItems = null; SelectedItem.Clear(); } }