From 3cecd0c6dcb98586177186ef1ce7179fe6f97ca5 Mon Sep 17 00:00:00 2001 From: SaracenOne Date: Tue, 12 Sep 2017 14:06:13 +0100 Subject: [PATCH] Box selection for MeshInstances and subscene nodes. --- editor/plugins/spatial_editor_plugin.cpp | 15 +++++++---- editor/spatial_editor_gizmos.cpp | 34 +++++++++++++++++++++--- editor/spatial_editor_gizmos.h | 3 ++- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 6b485aab7c7..07797be47df 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -465,7 +465,6 @@ void SpatialEditorViewport::_select_region() { Vector frustum; Vector3 cam_pos = _get_camera_position(); - Set > found_gizmos; for (int i = 0; i < 4; i++) { @@ -485,6 +484,9 @@ void SpatialEditorViewport::_select_region() { frustum.push_back(far); Vector instances = VisualServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world()->get_scenario()); + Vector selected; + + Node *edited_scene = get_tree()->get_edited_scene_root(); for (int i = 0; i < instances.size(); i++) { @@ -497,11 +499,14 @@ void SpatialEditorViewport::_select_region() { if (!seg.is_valid()) continue; - if (found_gizmos.has(seg)) - continue; + Spatial *root_sp = sp; + while (root_sp && root_sp != edited_scene && root_sp->get_owner() != edited_scene && !edited_scene->is_editable_instance(root_sp->get_owner())) { + root_sp = Object::cast_to(root_sp->get_owner()); + } - if (seg->intersect_frustum(camera, frustum)) - _select(sp, true, false); + if (selected.find(root_sp) == -1) + if (seg->intersect_frustum(camera, frustum)) + _select(root_sp, true, false); } } diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 9c7ea506aad..450c9f4b3ce 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -211,9 +211,10 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref &p_material, instances.push_back(ins); } -void EditorSpatialGizmo::add_collision_triangles(const Ref &p_tmesh) { +void EditorSpatialGizmo::add_collision_triangles(const Ref &p_tmesh, const Rect3 &p_bounds) { collision_mesh = p_tmesh; + collision_mesh_bounds = p_bounds; } void EditorSpatialGizmo::add_collision_segments(const Vector &p_lines) { @@ -359,6 +360,29 @@ bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera, const Vector< return false; } + if (collision_mesh_bounds.size != Vector3(0.0, 0.0, 0.0)) { + Transform t = spatial_node->get_global_transform(); + const Plane *p = p_frustum.ptr(); + int fc = p_frustum.size(); + + Vector3 mins = t.xform(collision_mesh_bounds.get_position()); + Vector3 max = t.xform(collision_mesh_bounds.get_position() + collision_mesh_bounds.get_size()); + + bool any_out = false; + + for (int j = 0; j < fc; j++) { + + if (p[j].distance_to(mins) > 0 || p[j].distance_to(max) > 0) { + + any_out = true; + break; + } + } + + if (!any_out) + return true; + } + return false; } @@ -637,7 +661,7 @@ void EditorSpatialGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard"), &EditorSpatialGizmo::add_lines, DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton"), &EditorSpatialGizmo::add_mesh, DEFVAL(false), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorSpatialGizmo::add_collision_segments); - ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles"), &EditorSpatialGizmo::add_collision_triangles); + ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles", "bounds"), &EditorSpatialGizmo::add_collision_triangles); ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1)); ClassDB::bind_method(D_METHOD("add_handles", "handles", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node); @@ -1249,8 +1273,10 @@ void MeshInstanceSpatialGizmo::redraw() { return; //none Ref tm = m->generate_triangle_mesh(); - if (tm.is_valid()) - add_collision_triangles(tm); + if (tm.is_valid()) { + Rect3 aabb; + add_collision_triangles(tm, aabb); + } } MeshInstanceSpatialGizmo::MeshInstanceSpatialGizmo(MeshInstance *p_mesh) { diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h index d63a804055c..afe64c723c6 100644 --- a/editor/spatial_editor_gizmos.h +++ b/editor/spatial_editor_gizmos.h @@ -78,6 +78,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo { Vector collision_segments; Ref collision_mesh; + Rect3 collision_mesh_bounds; struct Handle { Vector3 pos; @@ -99,7 +100,7 @@ protected: void add_lines(const Vector &p_lines, const Ref &p_material, bool p_billboard = false); void add_mesh(const Ref &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID()); void add_collision_segments(const Vector &p_lines); - void add_collision_triangles(const Ref &p_tmesh); + void add_collision_triangles(const Ref &p_tmesh, const Rect3 &p_bounds = Rect3()); void add_unscaled_billboard(const Ref &p_material, float p_scale = 1); void add_handles(const Vector &p_handles, bool p_billboard = false, bool p_secondary = false); void add_solid_box(Ref &p_material, Vector3 size);