From 786b9e51990fb62ad4e76c67e42492a1921ec5fa Mon Sep 17 00:00:00 2001 From: dexy Date: Mon, 30 Dec 2019 18:05:02 +1100 Subject: [PATCH] Improved mouse selection in collisions mode --- CodeWalker.Core/GameFiles/Resources/Bounds.cs | 6 ++ CodeWalker.Core/World/Space.cs | 16 ++++++ WorldForm.cs | 56 +++++++++++++++++-- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/CodeWalker.Core/GameFiles/Resources/Bounds.cs b/CodeWalker.Core/GameFiles/Resources/Bounds.cs index 32e023b..2ad2aca 100644 --- a/CodeWalker.Core/GameFiles/Resources/Bounds.cs +++ b/CodeWalker.Core/GameFiles/Resources/Bounds.cs @@ -272,6 +272,7 @@ namespace CodeWalker.GameFiles { res.Hit = true; res.HitDist = testdist; + res.HitBounds = this; res.Position = ray.Position + ray.Direction * testdist; res.Normal = Vector3.Normalize(res.Position - Center); res.Material.Type = MaterialIndex; @@ -340,6 +341,7 @@ namespace CodeWalker.GameFiles { res.Hit = true; res.HitDist = testdist; + res.HitBounds = this; res.Position = ray.Position + ray.Direction * testdist; res.Normal = bcap.Normal(ref res.Position); res.Material.Type = MaterialIndex; @@ -392,6 +394,7 @@ namespace CodeWalker.GameFiles { n = Vector3.UnitZ; } //ray starts inside the box... res.Hit = true; res.HitDist = testdist; + res.HitBounds = this; res.Position = hpt; res.Normal = n; res.Material.Type = MaterialIndex; @@ -461,6 +464,7 @@ namespace CodeWalker.GameFiles { res.Hit = true; res.HitDist = testdist; + res.HitBounds = this; res.Position = ray.Position + ray.Direction * testdist; res.Normal = n; res.Material.Type = MaterialIndex; @@ -533,6 +537,7 @@ namespace CodeWalker.GameFiles { res.Hit = true; res.HitDist = testdist; + res.HitBounds = this; res.Position = ray.Position + ray.Direction * testdist; res.Normal = n; res.Material.Type = MaterialIndex; @@ -1125,6 +1130,7 @@ namespace CodeWalker.GameFiles res.Hit = true; 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(); diff --git a/CodeWalker.Core/World/Space.cs b/CodeWalker.Core/World/Space.cs index 8dcafb2..1d357d0 100644 --- a/CodeWalker.Core/World/Space.cs +++ b/CodeWalker.Core/World/Space.cs @@ -1106,6 +1106,10 @@ namespace CodeWalker.World var b = ybn.Bounds; var bhit = b.RayIntersect(ref ray, res.HitDist); + if (bhit.Hit) + { + bhit.HitYbn = ybn; + } res.TryUpdate(ref bhit); } } @@ -1225,6 +1229,10 @@ namespace CodeWalker.World } } } + if (res.Hit) + { + res.HitEntity = ent; + } return res; } @@ -1249,6 +1257,8 @@ namespace CodeWalker.World var ihit = ybn.Bounds.RayIntersect(ref iray, res.HitDist); if (ihit.Hit) { + ihit.HitYbn = ybn; + ihit.HitEntity = mlo; ihit.Position = iori.Multiply(ihit.Position) + mlo.Position; ihit.Normal = iori.Multiply(ihit.Normal); } @@ -2141,6 +2151,9 @@ namespace CodeWalker.World public bool Hit; public float HitDist; public BoundPolygon HitPolygon; + public Bounds HitBounds; + public YbnFile HitYbn; + public YmapEntityDef HitEntity; public Vector3 Position; public Vector3 Normal; public int TestedNodeCount; @@ -2155,6 +2168,9 @@ namespace CodeWalker.World Hit = true; HitDist = r.HitDist; HitPolygon = r.HitPolygon; + HitBounds = r.HitBounds; + HitYbn = r.HitYbn; + HitEntity = r.HitEntity; Material = r.Material; Position = r.Position; Normal = r.Normal; diff --git a/WorldForm.cs b/WorldForm.cs index 3571735..134df1f 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -442,7 +442,7 @@ namespace CodeWalker RenderSingleItem(); } - UpdateMouseHitsFromRenderer(); + UpdateMouseHits(); RenderSelection(); @@ -2203,8 +2203,8 @@ namespace CodeWalker //reset variables for beginning the mouse hit test CurMouseHit.Clear(); - // Get whether or not we can brush from the project form. - if (Input.CtrlPressed && ProjectForm != null && ProjectForm.CanPaintInstances()) + + if (Input.CtrlPressed && ProjectForm != null && ProjectForm.CanPaintInstances()) // Get whether or not we can brush from the project form. { ControlBrushEnabled = true; MouseRayCollisionVisible = false; @@ -2253,16 +2253,62 @@ namespace CodeWalker return space.RayIntersect(ray, float.MaxValue, collisionmeshlayers); } + private void UpdateMouseHits() + { + UpdateMouseHitsFromRenderer(); + UpdateMouseHitsFromSpace(); + } private void UpdateMouseHitsFromRenderer() { foreach (var rd in Renderer.RenderedDrawables) { UpdateMouseHits(rd.Drawable, rd.Archetype, rd.Entity); } - foreach (var rb in Renderer.RenderedBoundComps) + //foreach (var rb in Renderer.RenderedBoundComps) + //{ + // UpdateMouseHits(rb.BoundComp, rb.Entity); + //} + } + private void UpdateMouseHitsFromSpace() + { + if (SelectionMode == MapSelectionMode.Collision) { - UpdateMouseHits(rb.BoundComp, rb.Entity); + MouseRayCollision = GetSpaceMouseRay(); + + if (MouseRayCollision.Hit) + { + Matrix rmat = MouseRayCollision.HitBounds?.Transform ?? Matrix.Identity; + rmat.TranslationVector = Vector3.Zero; + + var position = MouseRayCollision.HitEntity?.Position ?? Vector3.Zero; + var orientation = MouseRayCollision.HitEntity?.Orientation ?? Quaternion.Identity; + var scale = MouseRayCollision.HitEntity?.Scale ?? Vector3.One; + var camrel = position - camera.Position; + var trans = MouseRayCollision.HitBounds?.Transform.TranslationVector ?? Vector3.Zero; + + CurMouseHit.CollisionBounds = MouseRayCollision.HitBounds; + CurMouseHit.EntityDef = MouseRayCollision.HitEntity; + CurMouseHit.Archetype = MouseRayCollision.HitEntity?.Archetype; + CurMouseHit.HitDist = MouseRayCollision.HitDist; + CurMouseHit.CamRel = camrel + orientation.Multiply(trans); + CurMouseHit.BBOffset = trans; + CurMouseHit.BBOrientation = Quaternion.RotationMatrix(rmat); + CurMouseHit.AABB = new BoundingBox(MouseRayCollision.HitBounds?.BoundingBoxMin ?? Vector3.Zero, MouseRayCollision.HitBounds?.BoundingBoxMax ?? Vector3.Zero); + + + MapBox mb = new MapBox(); + mb.CamRelPos = MouseRayCollision.Position - camera.Position; + mb.Orientation = Quaternion.Identity; + mb.Scale = Vector3.One; + mb.BBMin = new Vector3(-0.01f); + mb.BBMax = new Vector3(+0.01f); + Renderer.BoundingBoxes.Add(mb); + + + } + } + } private void UpdateMouseHits(DrawableBase drawable, Archetype arche, YmapEntityDef entity) {