From 308e2eda2980b126d3063dd06a7899eb6f92a206 Mon Sep 17 00:00:00 2001 From: dexy Date: Fri, 10 Jan 2020 23:41:58 +1100 Subject: [PATCH] Collisions editing progress --- .../GameFiles/FileTypes/YbnFile.cs | 2 + Project/ProjectForm.cs | 115 ++++++++++++++---- World/MapSelection.cs | 32 +++++ WorldForm.cs | 41 +++---- 4 files changed, 140 insertions(+), 50 deletions(-) diff --git a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs index 8c8f543..5918832 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YbnFile.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; using System.Text; @@ -7,6 +8,7 @@ using System.Threading.Tasks; namespace CodeWalker.GameFiles { + [TypeConverter(typeof(ExpandableObjectConverter))] public class YbnFile : GameFile, PackedFile { public Bounds Bounds { get; set; } diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index 7892457..0a0471a 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -1040,6 +1040,23 @@ namespace CodeWalker.Project } } + foreach (var ybn in CurrentProjectFile.YbnFiles) + { + string filename = ybn.FilePath; + if (!File.Exists(filename)) + { + filename = cpath + "\\" + filename; + } + if (File.Exists(filename)) + { + LoadYbnFromFile(ybn, filename); + } + else + { + MessageBox.Show("Couldn't find file: " + filename); + } + } + foreach (var ynd in CurrentProjectFile.YndFiles) { string filename = ynd.FilePath; @@ -1246,18 +1263,23 @@ namespace CodeWalker.Project } } - CloseAllProjectItems(); + lock (projectsyncroot) + { - CurrentProjectFile = null; - CurrentYmapFile = null; - CurrentYtypFile = null; - CurrentYbnFile = null; - CurrentYndFile = null; - CurrentYnvFile = null; - CurrentTrainTrack = null; - CurrentScenario = null; + CloseAllProjectItems(); - LoadProjectUI(); + CurrentProjectFile = null; + CurrentYmapFile = null; + CurrentYtypFile = null; + CurrentYbnFile = null; + CurrentYndFile = null; + CurrentYnvFile = null; + CurrentTrainTrack = null; + CurrentScenario = null; + + LoadProjectUI(); + + } if (WorldForm != null) @@ -5932,9 +5954,9 @@ namespace CodeWalker.Project ymaps.Clear(); //remove all the gtav ymaps. } - if (renderitems && (CurrentProjectFile != null)) + lock (projectsyncroot) { - lock (projectsyncroot) + if (renderitems && (CurrentProjectFile != null)) { for (int i = 0; i < CurrentProjectFile.YmapFiles.Count; i++) { @@ -5993,10 +6015,10 @@ namespace CodeWalker.Project ybns.Clear(); } - if (CurrentProjectFile == null) return; - lock (projectsyncroot) { + if (CurrentProjectFile == null) return; + visibleybns.Clear(); for (int i = 0; i < ybns.Count; i++) { @@ -6028,10 +6050,10 @@ namespace CodeWalker.Project ynds.Clear(); } - if (CurrentProjectFile == null) return; - lock (projectsyncroot) { + if (CurrentProjectFile == null) return; + visibleynds.Clear(); for (int i = 0; i < ynds.Count; i++) { @@ -6063,10 +6085,10 @@ namespace CodeWalker.Project ynvs.Clear(); } - if (CurrentProjectFile == null) return; - lock (projectsyncroot) { + if (CurrentProjectFile == null) return; + visibleynvs.Clear(); for (int i = 0; i < ynvs.Count; i++) { @@ -6099,10 +6121,10 @@ namespace CodeWalker.Project } - if (CurrentProjectFile == null) return; - lock (projectsyncroot) { + if (CurrentProjectFile == null) return; + visibletrains.Clear(); for (int i = 0; i < tracks.Count; i++) { @@ -6135,10 +6157,10 @@ namespace CodeWalker.Project } - if (CurrentProjectFile == null) return; - lock (projectsyncroot) { + if (CurrentProjectFile == null) return; + visiblescenarios.Clear(); for (int i = 0; i < ymts.Count; i++) { @@ -6170,10 +6192,10 @@ namespace CodeWalker.Project rels.Clear(); } - if (CurrentProjectFile == null) return; - lock (projectsyncroot) { + if (CurrentProjectFile == null) return; + visibleaudiofiles.Clear(); for (int i = 0; i < rels.Count; i++) { @@ -6207,6 +6229,51 @@ namespace CodeWalker.Project } } + public void GetMouseCollision(Camera camera, ref MapSelection curHit) + { + Ray mray = new Ray(); + mray.Position = camera.MouseRay.Position + camera.Position; + mray.Direction = camera.MouseRay.Direction; + + var bounds = curHit.CollisionBounds ?? curHit.CollisionPoly?.Owner ?? curHit.CollisionVertex?.Owner; + var curybn = bounds?.GetRootYbn(); + + if (hidegtavmap && (curybn != null)) + { + curHit.Clear(); + } + + + lock (projectsyncroot) + { + if (renderitems && (CurrentProjectFile != null)) + { + for (int i = 0; i < CurrentProjectFile.YbnFiles.Count; i++) + { + var ybn = CurrentProjectFile.YbnFiles[i]; + if (ybn.Loaded) + { + if (ybn.Name == curybn?.Name) + { + curHit.Clear(); + } + + if (ybn.Bounds != null) + { + var hit = ybn.Bounds.RayIntersect(ref mray); //TODO: interior ybns! + if (hit.Hit) + { + curHit.UpdateCollisionFromRayHit(ref hit, camera); + } + } + } + } + } + } + + + } + public MloInstanceData TryGetMloInstance(MloArchetype arch) { lock (projectsyncroot) diff --git a/World/MapSelection.cs b/World/MapSelection.cs index 5ab4b09..efefe96 100644 --- a/World/MapSelection.cs +++ b/World/MapSelection.cs @@ -1047,6 +1047,38 @@ namespace CodeWalker } + + public void UpdateCollisionFromRayHit(ref SpaceRayIntersectResult hit, Camera camera) + { + var position = hit.HitEntity?.Position ?? Vector3.Zero; + var orientation = hit.HitEntity?.Orientation ?? Quaternion.Identity; + var scale = hit.HitEntity?.Scale ?? Vector3.One; + var camrel = position - camera.Position; + var trans = hit.HitBounds?.Transform.TranslationVector ?? Vector3.Zero; + + CollisionPoly = hit.HitPolygon; + CollisionBounds = hit.HitBounds; + EntityDef = hit.HitEntity; + Archetype = hit.HitEntity?.Archetype; + HitDist = hit.HitDist; + CamRel = camrel + orientation.Multiply(trans); + BBOffset = trans; + BBOrientation = hit.HitBounds?.Transform.ToQuaternion() ?? Quaternion.Identity; + AABB = new BoundingBox(hit.HitBounds?.BoxMin ?? Vector3.Zero, hit.HitBounds?.BoxMax ?? Vector3.Zero); + + float vertexDist = 0.1f; + if ((hit.HitVertex.Distance < vertexDist) && (hit.HitBounds is BoundGeometry bgeom)) + { + CollisionVertex = bgeom.GetVertexObject(hit.HitVertex.Index); + } + else + { + CollisionVertex = null; + } + } + + + public override string ToString() { return GetFullNameString("[Empty]"); diff --git a/WorldForm.cs b/WorldForm.cs index dede18b..7afa796 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -2184,6 +2184,7 @@ namespace CodeWalker { UpdateMouseHitsFromRenderer(); UpdateMouseHitsFromSpace(); + UpdateMouseHitsFromProject(); } private void UpdateMouseHitsFromRenderer() { @@ -2200,35 +2201,23 @@ namespace CodeWalker if (MouseRayCollision.Hit) { - 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.CollisionPoly = MouseRayCollision.HitPolygon; - 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 = MouseRayCollision.HitBounds?.Transform.ToQuaternion() ?? Quaternion.Identity; - CurMouseHit.AABB = new BoundingBox(MouseRayCollision.HitBounds?.BoxMin ?? Vector3.Zero, MouseRayCollision.HitBounds?.BoxMax ?? Vector3.Zero); - - float vertexDist = 0.1f; - if ((MouseRayCollision.HitVertex.Distance < vertexDist) && (MouseRayCollision.HitBounds is BoundGeometry bgeom)) - { - CurMouseHit.CollisionVertex = bgeom.GetVertexObject(MouseRayCollision.HitVertex.Index); - } - else - { - CurMouseHit.CollisionVertex = null; - } - + CurMouseHit.UpdateCollisionFromRayHit(ref MouseRayCollision, camera); } } } + private void UpdateMouseHitsFromProject() + { + if (ProjectForm == null) return; + + if (SelectionMode == MapSelectionMode.Collision) + { + + ProjectForm.GetMouseCollision(camera, ref CurMouseHit); + + + + } + } private void UpdateMouseHits(DrawableBase drawable, Archetype arche, YmapEntityDef entity) { //if ((SelectionMode == MapSelectionMode.Entity) && !MouseSelectEnabled) return; //performance improvement when not selecting entities...