Merge pull request #94553 from juanjp600/gizmo-bvh
Fix gizmos without visible geometry not being selectable
This commit is contained in:
commit
93fe5c6598
4 changed files with 101 additions and 10 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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());
|
||||
Vector<Node3D *> nodes_with_gizmos = Node3DEditor::get_singleton()->gizmo_bvh_ray_query(pos, pos + ray * camera->get_far());
|
||||
|
||||
HashSet<Node3D *> found_nodes;
|
||||
|
||||
for (int i = 0; i < instances.size(); i++) {
|
||||
Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
|
||||
|
||||
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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue