summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp37
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h5
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp60
-rw-r--r--editor/plugins/node_3d_editor_plugin.h9
4 files changed, 101 insertions, 10 deletions
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index de56767929..67d5e44ce5 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -81,6 +81,8 @@ void EditorNode3DGizmo::redraw() {
gizmo_plugin->redraw(this);
}
+ _update_bvh();
+
if (Node3DEditor::get_singleton()->is_current_selected_gizmo(this)) {
Node3DEditor::get_singleton()->update_transform_gizmo();
}
@@ -244,6 +246,32 @@ void EditorNode3DGizmo::add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p
instances.push_back(ins);
}
+void EditorNode3DGizmo::_update_bvh() {
+ ERR_FAIL_NULL(spatial_node);
+
+ Transform3D transform = spatial_node->get_global_transform();
+
+ float effective_icon_size = selectable_icon_size > 0.0f ? selectable_icon_size : 0.0f;
+ Vector3 icon_size_vector3 = Vector3(effective_icon_size, effective_icon_size, effective_icon_size);
+ AABB aabb(spatial_node->get_position() - icon_size_vector3 * 100.0f, icon_size_vector3 * 200.0f);
+
+ for (const Vector3 &segment_end : collision_segments) {
+ aabb.expand_to(transform.xform(segment_end));
+ }
+
+ if (collision_mesh.is_valid()) {
+ for (const Face3 &face : collision_mesh->get_faces()) {
+ aabb.expand_to(transform.xform(face.vertex[0]));
+ aabb.expand_to(transform.xform(face.vertex[1]));
+ aabb.expand_to(transform.xform(face.vertex[2]));
+ }
+ }
+
+ Node3DEditor::get_singleton()->update_gizmo_bvh_node(
+ bvh_node_id,
+ aabb);
+}
+
void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard, const Color &p_modulate) {
add_vertices(p_lines, p_material, Mesh::PRIMITIVE_LINES, p_billboard, p_modulate);
}
@@ -765,6 +793,10 @@ void EditorNode3DGizmo::create() {
instances.write[i].create_instance(spatial_node, hidden);
}
+ bvh_node_id = Node3DEditor::get_singleton()->insert_gizmo_bvh_node(
+ spatial_node,
+ AABB(spatial_node->get_position(), Vector3(0, 0, 0)));
+
transform();
}
@@ -774,6 +806,8 @@ void EditorNode3DGizmo::transform() {
for (int i = 0; i < instances.size(); i++) {
RS::get_singleton()->instance_set_transform(instances[i].instance, spatial_node->get_global_transform() * instances[i].xform);
}
+
+ _update_bvh();
}
void EditorNode3DGizmo::free() {
@@ -790,6 +824,9 @@ void EditorNode3DGizmo::free() {
clear();
+ Node3DEditor::get_singleton()->remove_gizmo_bvh_node(bvh_node_id);
+ bvh_node_id = DynamicBVH::ID();
+
valid = false;
}
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index d7c368d5d0..c4b275032a 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -31,6 +31,7 @@
#ifndef NODE_3D_EDITOR_GIZMOS_H
#define NODE_3D_EDITOR_GIZMOS_H
+#include "core/math/dynamic_bvh.h"
#include "core/templates/hash_map.h"
#include "core/templates/local_vector.h"
#include "scene/3d/camera_3d.h"
@@ -72,8 +73,12 @@ class EditorNode3DGizmo : public Node3DGizmo {
Vector<Instance> instances;
Node3D *spatial_node = nullptr;
+ DynamicBVH::ID bvh_node_id;
+
void _set_node_3d(Node *p_node) { set_node_3d(Object::cast_to<Node3D>(p_node)); }
+ void _update_bvh();
+
protected:
static void _bind_methods();
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 19e81e075e..f5b0a3b51e 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -800,7 +800,6 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
RS::get_singleton()->sdfgi_set_debug_probe_select(pos, ray);
}
- Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario());
HashSet<Ref<EditorNode3DGizmo>> found_gizmos;
Node *edited_scene = get_tree()->get_edited_scene_root();
@@ -808,9 +807,9 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const {
Node *item = nullptr;
float closest_dist = 1e20;
- for (int i = 0; i < instances.size(); i++) {
- Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
+ Vector<Node3D *> nodes_with_gizmos = Node3DEditor::get_singleton()->gizmo_bvh_ray_query(pos, pos + ray * camera->get_far());
+ for (Node3D *spat : nodes_with_gizmos) {
if (!spat) {
continue;
}
@@ -863,12 +862,11 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayRe
Vector3 ray = get_ray(p_pos);
Vector3 pos = get_ray_pos(p_pos);
- Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario());
- HashSet<Node3D *> found_nodes;
+ Vector<Node3D *> nodes_with_gizmos = Node3DEditor::get_singleton()->gizmo_bvh_ray_query(pos, pos + ray * camera->get_far());
- for (int i = 0; i < instances.size(); i++) {
- Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
+ HashSet<Node3D *> found_nodes;
+ for (Node3D *spat : nodes_with_gizmos) {
if (!spat) {
continue;
}
@@ -1046,7 +1044,7 @@ void Node3DEditorViewport::_select_region() {
_clear_selected();
}
- Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world_3d()->get_scenario());
+ Vector<Node3D *> nodes_with_gizmos = Node3DEditor::get_singleton()->gizmo_bvh_frustum_query(frustum);
HashSet<Node3D *> found_nodes;
Vector<Node *> selected;
@@ -1055,8 +1053,7 @@ void Node3DEditorViewport::_select_region() {
return;
}
- for (int i = 0; i < instances.size(); i++) {
- Node3D *sp = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
+ for (Node3D *sp : nodes_with_gizmos) {
if (!sp || _is_node_locked(sp)) {
continue;
}
@@ -9236,6 +9233,49 @@ void Node3DEditor::remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin) {
_update_gizmos_menu();
}
+DynamicBVH::ID Node3DEditor::insert_gizmo_bvh_node(Node3D *p_node, const AABB &p_aabb) {
+ return gizmo_bvh.insert(p_aabb, p_node);
+}
+
+void Node3DEditor::update_gizmo_bvh_node(DynamicBVH::ID p_id, const AABB &p_aabb) {
+ gizmo_bvh.update(p_id, p_aabb);
+ gizmo_bvh.optimize_incremental(1);
+}
+
+void Node3DEditor::remove_gizmo_bvh_node(DynamicBVH::ID p_id) {
+ gizmo_bvh.remove(p_id);
+}
+
+Vector<Node3D *> Node3DEditor::gizmo_bvh_ray_query(const Vector3 &p_ray_start, const Vector3 &p_ray_end) {
+ struct Result {
+ Vector<Node3D *> nodes;
+ bool operator()(void *p_data) {
+ nodes.append((Node3D *)p_data);
+ return false;
+ }
+ } result;
+
+ gizmo_bvh.ray_query(p_ray_start, p_ray_end, result);
+
+ return result.nodes;
+}
+
+Vector<Node3D *> Node3DEditor::gizmo_bvh_frustum_query(const Vector<Plane> &p_frustum) {
+ Vector<Vector3> points = Geometry3D::compute_convex_mesh_points(&p_frustum[0], p_frustum.size());
+
+ struct Result {
+ Vector<Node3D *> nodes;
+ bool operator()(void *p_data) {
+ nodes.append((Node3D *)p_data);
+ return false;
+ }
+ } result;
+
+ gizmo_bvh.convex_query(p_frustum.ptr(), p_frustum.size(), points.ptr(), points.size(), result);
+
+ return result.nodes;
+}
+
Node3DEditorPlugin::Node3DEditorPlugin() {
spatial_editor = memnew(Node3DEditor);
spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 5bd14748c0..9e7d46c5e8 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -31,6 +31,7 @@
#ifndef NODE_3D_EDITOR_PLUGIN_H
#define NODE_3D_EDITOR_PLUGIN_H
+#include "core/math/dynamic_bvh.h"
#include "editor/plugins/editor_plugin.h"
#include "editor/plugins/node_3d_editor_gizmos.h"
#include "editor/themes/editor_scale.h"
@@ -629,6 +630,8 @@ private:
int current_hover_gizmo_handle;
bool current_hover_gizmo_handle_secondary;
+ DynamicBVH gizmo_bvh;
+
real_t snap_translate_value;
real_t snap_rotate_value;
real_t snap_scale_value;
@@ -933,6 +936,12 @@ public:
void add_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
void remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin);
+ DynamicBVH::ID insert_gizmo_bvh_node(Node3D *p_node, const AABB &p_aabb);
+ void update_gizmo_bvh_node(DynamicBVH::ID p_id, const AABB &p_aabb);
+ void remove_gizmo_bvh_node(DynamicBVH::ID p_id);
+ Vector<Node3D *> gizmo_bvh_ray_query(const Vector3 &p_ray_start, const Vector3 &p_ray_end);
+ Vector<Node3D *> gizmo_bvh_frustum_query(const Vector<Plane> &p_frustum);
+
void edit(Node3D *p_spatial);
void clear();