From 4fb2d3f7f3e89486e8aaba7d7ae441c8d7d26548 Mon Sep 17 00:00:00 2001 From: NoriteSC <53096989+NoriteSC@users.noreply.github.com> Date: Thu, 7 Dec 2023 23:55:10 +0100 Subject: [PATCH] sync --- Source/Editor/Gizmo/TransformGizmo.cs | 4 +- .../Editor/Gizmo/TransformGizmoBase.Draw.cs | 255 ++++++++++-------- .../Gizmo/TransformGizmoBase.Selection.cs | 7 +- Source/Editor/Gizmo/TransformGizmoBase.cs | 112 +++++++- .../Editor/SceneGraph/Actors/FoliageNode.cs | 13 +- Source/Editor/SceneGraph/SceneGraphNode.cs | 68 ++++- .../Editor/Tools/Foliage/EditFoliageGizmo.cs | 6 +- 7 files changed, 330 insertions(+), 135 deletions(-) diff --git a/Source/Editor/Gizmo/TransformGizmo.cs b/Source/Editor/Gizmo/TransformGizmo.cs index 4a3fa39ba..f9d18bafd 100644 --- a/Source/Editor/Gizmo/TransformGizmo.cs +++ b/Source/Editor/Gizmo/TransformGizmo.cs @@ -255,9 +255,9 @@ namespace FlaxEditor.Gizmo protected override int SelectionCount => _selectionParents.Count; /// - protected override Transform GetSelectedObject(int index) + protected override SceneGraphNode GetSelectedObject(int index) { - return _selectionParents[index].Transform; + return _selectionParents[index]; } /// diff --git a/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs b/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs index 0d421a17e..8cc049716 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.Draw.cs @@ -72,139 +72,160 @@ namespace FlaxEditor.Gizmo const float gizmoModelsScale2RealGizmoSize = 0.075f; Mesh sphereMesh, cubeMesh; + cubeMesh = _modelCube.LODs[0].Meshes[0]; + + Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); + Matrix.Multiply(ref m3, ref world, out m1); + mx1 = m1; + mx1.M41 += 0.05f; + switch (_activeMode) { - case Mode.Translate: - { - if (!_modelTranslationAxis || !_modelTranslationAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded) - break; - var transAxisMesh = _modelTranslationAxis.LODs[0].Meshes[0]; - cubeMesh = _modelCube.LODs[0].Meshes[0]; - sphereMesh = _modelSphere.LODs[0].Meshes[0]; - Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); - Matrix.Multiply(ref m3, ref world, out m1); - mx1 = m1; - mx1.M41 += 0.05f; + case Mode.Translate: + { + if (!_modelTranslationAxis || !_modelTranslationAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded) + break; + var transAxisMesh = _modelTranslationAxis.LODs[0].Meshes[0]; - // X axis - Matrix.RotationY(-Mathf.PiOverTwo, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - transAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); + sphereMesh = _modelSphere.LODs[0].Meshes[0]; - // Y axis - Matrix.RotationX(Mathf.PiOverTwo, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - transAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3); + // X axis + Matrix.RotationY(-Mathf.PiOverTwo, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + transAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); - // Z axis - Matrix.RotationX(Mathf.Pi, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - transAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); + // Y axis + Matrix.RotationX(Mathf.PiOverTwo, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + transAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3); - // XY plane - m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); - Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3); + // Z axis + Matrix.RotationX(Mathf.Pi, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + transAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); - // ZX plane - m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); - Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3); + // XY plane + m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); + Matrix.Multiply(ref m2, ref m1, out m3); + cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3); - // YZ plane - m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); - Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3); + // ZX plane + m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); + Matrix.Multiply(ref m2, ref m1, out m3); + cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3); - // Center sphere - Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3); + // YZ plane + m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); + Matrix.Multiply(ref m2, ref m1, out m3); + cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3); - break; + // Center sphere + Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3); + + break; + } + + case Mode.Rotate: + { + if (!_modelRotationAxis || !_modelRotationAxis.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded) + break; + var rotationAxisMesh = _modelRotationAxis.LODs[0].Meshes[0]; + sphereMesh = _modelSphere.LODs[0].Meshes[0]; + + // X axis + Matrix.RotationZ(Mathf.PiOverTwo, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + rotationAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); + + // Y axis + rotationAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m1); + + // Z axis + Matrix.RotationX(-Mathf.PiOverTwo, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + rotationAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); + + // Center box + Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3); + + break; + } + + case Mode.Scale: + { + if (!_modelScaleAxis || !_modelScaleAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded) + break; + var scaleAxisMesh = _modelScaleAxis.LODs[0].Meshes[0]; + cubeMesh = _modelCube.LODs[0].Meshes[0]; + sphereMesh = _modelSphere.LODs[0].Meshes[0]; + + // X axis + Matrix.RotationY(-Mathf.PiOverTwo, out m2); + Matrix.Multiply(ref m2, ref mx1, out m3); + scaleAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); + + // Y axis + Matrix.RotationX(Mathf.PiOverTwo, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + scaleAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3); + + // Z axis + Matrix.RotationX(Mathf.Pi, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + scaleAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); + + // XY plane + m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); + Matrix.Multiply(ref m2, ref m1, out m3); + cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3); + + // ZX plane + m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); + Matrix.Multiply(ref m2, ref m1, out m3); + cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3); + + // YZ plane + m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); + Matrix.Multiply(ref m2, ref m1, out m3); + cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3); + + // Center box + Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); + Matrix.Multiply(ref m2, ref m1, out m3); + sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3); + + break; + } } - - case Mode.Rotate: + if (verts != null && selectedvert != -1) { - if (!_modelRotationAxis || !_modelRotationAxis.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded) - break; - var rotationAxisMesh = _modelRotationAxis.LODs[0].Meshes[0]; - sphereMesh = _modelSphere.LODs[0].Meshes[0]; - Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); - Matrix.Multiply(ref m3, ref world, out m1); - mx1 = m1; - mx1.M41 += 0.05f; + Transform t = GetSelectedObject(0).Transform; + Vector3 selected = ((verts[selectedvert].Position * t.Orientation) * t.Scale) + t.Translation; + Matrix matrix = new Transform(selected, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld(); + cubeMesh.Draw(ref renderContext, _materialSphere, ref matrix); - // X axis - Matrix.RotationZ(Mathf.PiOverTwo, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - rotationAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); + if (otherVerts != null && otherSelectedvert != -1) + { + t = otherTransform; + Vector3 other = ((otherVerts[otherSelectedvert].Position * t.Orientation) * t.Scale) + t.Translation; + matrix = new Transform(selected, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld(); + cubeMesh.Draw(ref renderContext, _materialSphere, ref matrix); + DebugDraw.DrawLine(other, selected, Color.Aqua); + } - // Y axis - rotationAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m1); + //t = otherTransform; + //for (int i = 0; i < otherVerts.Length; i++) + //{ + // Matrix matrix = new Transform(((otherVerts[i].Position * t.Orientation) * t.Scale) + t.Translation, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld(); + // cubeMesh.Draw(ref renderContext, i == otherSelectedvert ? _materialAxisFocus : _materialSphere, ref matrix); + //} - // Z axis - Matrix.RotationX(-Mathf.PiOverTwo, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - rotationAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); + //t = GetSelectedObject(0).Transform; - // Center box - Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3); - - break; - } - - case Mode.Scale: - { - if (!_modelScaleAxis || !_modelScaleAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded) - break; - var scaleAxisMesh = _modelScaleAxis.LODs[0].Meshes[0]; - cubeMesh = _modelCube.LODs[0].Meshes[0]; - sphereMesh = _modelSphere.LODs[0].Meshes[0]; - Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); - Matrix.Multiply(ref m3, ref world, out m1); - mx1 = m1; - mx1.M41 -= 0.05f; - - // X axis - Matrix.RotationY(-Mathf.PiOverTwo, out m2); - Matrix.Multiply(ref m2, ref mx1, out m3); - scaleAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); - - // Y axis - Matrix.RotationX(Mathf.PiOverTwo, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - scaleAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3); - - // Z axis - Matrix.RotationX(Mathf.Pi, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - scaleAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); - - // XY plane - m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); - Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3); - - // ZX plane - m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); - Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3); - - // YZ plane - m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); - Matrix.Multiply(ref m2, ref m1, out m3); - cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3); - - // Center box - Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); - Matrix.Multiply(ref m2, ref m1, out m3); - sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3); - - break; - } } } } diff --git a/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs b/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs index 86c0a6afe..1ebe0f254 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.Selection.cs @@ -27,7 +27,7 @@ namespace FlaxEditor.Gizmo // Get center point Vector3 center = Vector3.Zero; for (int i = 0; i < count; i++) - center += GetSelectedObject(i).Translation; + center += GetSelectedObject(i).Transform.Translation; // Return arithmetic average or whatever it means return center / count; @@ -47,6 +47,11 @@ namespace FlaxEditor.Gizmo private void SelectAxis() { + if (Owner.IsControlDown) + { + + } + // Get mouse ray Ray ray = Owner.MouseRay; diff --git a/Source/Editor/Gizmo/TransformGizmoBase.cs b/Source/Editor/Gizmo/TransformGizmoBase.cs index 6123d348a..dfae81dc1 100644 --- a/Source/Editor/Gizmo/TransformGizmoBase.cs +++ b/Source/Editor/Gizmo/TransformGizmoBase.cs @@ -108,7 +108,7 @@ namespace FlaxEditor.Gizmo _startTransforms.Capacity = Mathf.NextPowerOfTwo(count); for (var i = 0; i < count; i++) { - _startTransforms.Add(GetSelectedObject(i)); + _startTransforms.Add(GetSelectedObject(i).Transform); } GetSelectedObjectsBounds(out _startBounds, out _navigationDirty); @@ -139,7 +139,7 @@ namespace FlaxEditor.Gizmo { case PivotType.ObjectCenter: if (SelectionCount > 0) - Position = GetSelectedObject(0).Translation; + Position = GetSelectedObject(0).Transform.Translation; break; case PivotType.SelectionCenter: Position = GetSelectionCenter(); @@ -180,7 +180,7 @@ namespace FlaxEditor.Gizmo _screenScale = (float)(vLength.Length / GizmoScaleFactor * gizmoSize); } // Setup world - Quaternion orientation = GetSelectedObject(0).Orientation; + Quaternion orientation = GetSelectedObject(0).Transform.Orientation; _gizmoWorld = new Transform(position, orientation, new Float3(_screenScale)); if (_activeTransformSpace == TransformSpace.World && _activeMode != Mode.Scale) { @@ -394,6 +394,13 @@ namespace FlaxEditor.Gizmo /// public override bool IsControllingMouse => _isTransforming; + //vertex snaping stff + Mesh.Vertex[] verts; + Mesh.Vertex[] otherVerts; + Transform otherTransform; + bool hasSelectedVertex; + int selectedvert; + int otherSelectedvert; /// public override void Update(float dt) { @@ -429,12 +436,22 @@ namespace FlaxEditor.Gizmo UpdateRotate(dt); break; } + VertexSnap(); } else { // If nothing selected, try to select any axis if (!isLeftBtnDown && !Owner.IsRightMouseButtonDown) + { + if (Owner.IsAltKeyDown) + SelectVertexSnaping(); SelectAxis(); + } + else + { + verts = null; + otherVerts = null; + } } // Set positions of the gizmo @@ -516,6 +533,93 @@ namespace FlaxEditor.Gizmo // Update UpdateMatrices(); } + void SelectVertexSnaping() + { + //this + if (GetSelectedObject(0).EditableObject is Actor e) + { + if (e is StaticModel model) + { + verts = model.Model.LODs[0].Meshes[0].DownloadVertexBuffer(); + var ray = Owner.MouseRay; + var bb = model.EditorBox; + //select vertex + if (CollisionsHelper.RayIntersectsBox(ref ray, ref bb, out Vector3 point)) + { + point = GetSelectedObject(0).Transform.WorldToLocal(point); + Real lastdistance = Vector3.Distance(point, verts[0].Position); + for (int i = 0; i < verts.Length; i++) + { + var d = Vector3.Distance(point, verts[i].Position); + if (d <= lastdistance) + { + lastdistance = d; + selectedvert = i; + } + } + } + } + } + } + void VertexSnap() + { + Profiler.BeginEvent("VertexSnap"); + //ray cast others + if (verts != null) + { + var ray = Owner.MouseRay; + + SceneGraphNode.RayCastData rayCast = new SceneGraphNode.RayCastData() + { + Ray = ray, + Exclude = new List() { (Actor)GetSelectedObject(0).EditableObject }, + Scan = new List() { typeof(StaticModel) } + }; + var actor = GetSelectedObject(0).ParentScene.RayCast(ref rayCast, out var distance, out var _); + if (actor != null) + { + if (actor.EditableObject is StaticModel model) + { + otherTransform = model.Transform; + Vector3 p = rayCast.Ray.Position + (rayCast.Ray.Direction * distance); + + otherVerts = model.Model.LODs[0].Meshes[0].DownloadVertexBuffer(); + + p = actor.Transform.WorldToLocal(p); + Real lastdistance = Vector3.Distance(p, otherVerts[0].Position); + + for (int i = 0; i < otherVerts.Length; i++) + { + var d = Vector3.Distance(p, otherVerts[i].Position); + if (d <= lastdistance) + { + lastdistance = d; + otherSelectedvert = i; + } + } + if(lastdistance > 25) + { + otherSelectedvert = -1; + otherVerts = null; + } + } + } + } + + if (verts != null && otherVerts != null) + { + Transform t = GetSelectedObject(0).Transform; + Vector3 selected = ((verts[selectedvert].Position * t.Orientation) * t.Scale) + t.Translation; + + t = otherTransform; + Vector3 other = ((otherVerts[otherSelectedvert].Position * t.Orientation) * t.Scale) + t.Translation; + + // Translation + _translationDelta = -(selected - other); + } + + Profiler.EndEvent(); + } /// /// Gets a value indicating whether this tool can transform objects. @@ -536,7 +640,7 @@ namespace FlaxEditor.Gizmo /// Gets the selected object transformation. /// /// The selected object index. - protected abstract Transform GetSelectedObject(int index); + protected abstract SceneGraphNode GetSelectedObject(int index); /// /// Gets the selected objects bounding box (contains the whole selection). diff --git a/Source/Editor/SceneGraph/Actors/FoliageNode.cs b/Source/Editor/SceneGraph/Actors/FoliageNode.cs index 9cb405092..50756170a 100644 --- a/Source/Editor/SceneGraph/Actors/FoliageNode.cs +++ b/Source/Editor/SceneGraph/Actors/FoliageNode.cs @@ -10,10 +10,21 @@ namespace FlaxEditor.SceneGraph.Actors [HideInEditor] public sealed class FoliageNode : ActorNode { + private FoliageInstance instance; + /// + /// The selected instance index + /// + public int SelectedInstanceIndex; + /// - public FoliageNode(Actor actor) + public FoliageNode(Foliage actor, int selectedInstanceIndex = -1) : base(actor) { + SelectedInstanceIndex = selectedInstanceIndex; + if (selectedInstanceIndex != -1) + { + instance = actor.GetInstance(selectedInstanceIndex); + } } } } diff --git a/Source/Editor/SceneGraph/SceneGraphNode.cs b/Source/Editor/SceneGraph/SceneGraphNode.cs index 672a239dc..4ca8034e1 100644 --- a/Source/Editor/SceneGraph/SceneGraphNode.cs +++ b/Source/Editor/SceneGraph/SceneGraphNode.cs @@ -13,6 +13,7 @@ using FlaxEditor.Modules; using FlaxEditor.SceneGraph.Actors; using FlaxEditor.Windows; using FlaxEngine; +using System.Runtime.CompilerServices; namespace FlaxEditor.SceneGraph { @@ -216,6 +217,29 @@ namespace FlaxEditor.SceneGraph /// The flags. /// public FlagTypes Flags; + + /// + /// The exclude list actors specyfaied in + /// + public List Exclude = new List(); + + /// + /// The scan for types + /// + public List Scan = new List(); + + /// + /// if this is true it will include the types specyfaied in + /// otherwise it will include all types excluding types specyfaied in + /// + public bool ExcludeScan; + + /// + /// Initializes a new instance of the struct. + /// + public RayCastData() + { + } } /// @@ -271,16 +295,18 @@ namespace FlaxEditor.SceneGraph normal = Vector3.Up; return null; } - - // Check itself SceneGraphNode minTarget = null; Real minDistance = Real.MaxValue; Vector3 minDistanceNormal = Vector3.Up; - if (RayCastSelf(ref ray, out distance, out normal)) + if (Mask(ref ray)) { - minTarget = this; - minDistance = distance; - minDistanceNormal = normal; + // Check itself + if (RayCastSelf(ref ray, out distance, out normal)) + { + minTarget = this; + minDistance = distance; + minDistanceNormal = normal; + } } // Check all children @@ -294,12 +320,40 @@ namespace FlaxEditor.SceneGraph minDistanceNormal = normal; } } - // Return result distance = minDistance; normal = minDistanceNormal; return minTarget; } + /// + /// Masks the objects base of and . + /// + /// The ray. + /// true if can pass through mask + private bool Mask(ref RayCastData ray) + { + //filter actors + for (int j = 0; j < ray.Exclude.Count; j++) + { + if ((EditableObject is Actor a) && a == ray.Exclude[j]) + { + //remove form exclude + //because it is pased by ref and funcion is recursive it will slowly shrink the list untile nothing is left + //micro optimization + ray.Exclude.RemoveAt(j); + return false; + } + } + //filter types + for (int i = 0; i < ray.Scan.Count; i++) + { + if (EditableObject.GetType() != ray.Scan[i]) + { + return false; + } + } + return true; + } /// /// Checks if given ray intersects with the node. diff --git a/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs b/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs index 0c0172b36..1ba8ef445 100644 --- a/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs +++ b/Source/Editor/Tools/Foliage/EditFoliageGizmo.cs @@ -3,6 +3,7 @@ using System; using FlaxEditor.Gizmo; using FlaxEditor.SceneGraph; +using FlaxEditor.SceneGraph.Actors; using FlaxEditor.Tools.Foliage.Undo; using FlaxEngine; @@ -69,7 +70,7 @@ namespace FlaxEditor.Tools.Foliage } /// - protected override Transform GetSelectedObject(int index) + protected override SceneGraphNode GetSelectedObject(int index) { var foliage = GizmoMode.SelectedFoliage; if (!foliage) @@ -77,8 +78,7 @@ namespace FlaxEditor.Tools.Foliage var instanceIndex = GizmoMode.SelectedInstanceIndex; if (instanceIndex < 0 || instanceIndex >= foliage.InstancesCount) throw new InvalidOperationException("No foliage instance selected."); - var instance = foliage.GetInstance(instanceIndex); - return foliage.Transform.LocalToWorld(instance.Transform); + return new FoliageNode(foliage, instanceIndex); } ///