You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
Polished 3D selection
This commit is contained in:
@@ -217,7 +217,7 @@ bool SpatialEditorGizmo::intersect_frustum(const Camera *p_camera, const Vector<
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpatialEditorGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) {
|
||||
bool SpatialEditorGizmo::intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) {
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -320,24 +320,20 @@ void SpatialEditorViewport::_select_clicked(bool p_append, bool p_single) {
|
||||
void SpatialEditorViewport::_select(Spatial *p_node, bool p_append, bool p_single) {
|
||||
|
||||
if (!p_append) {
|
||||
|
||||
// should not modify the selection..
|
||||
|
||||
editor_selection->clear();
|
||||
editor_selection->add_node(p_node);
|
||||
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
editor->call("edit_node", p_node);
|
||||
}
|
||||
|
||||
if (editor_selection->is_selected(p_node)) {
|
||||
//erase
|
||||
editor_selection->remove_node(p_node);
|
||||
} else {
|
||||
|
||||
if (editor_selection->is_selected(p_node) && p_single) {
|
||||
//erase
|
||||
editor_selection->remove_node(p_node);
|
||||
} else {
|
||||
editor_selection->add_node(p_node);
|
||||
}
|
||||
|
||||
editor_selection->add_node(p_node);
|
||||
}
|
||||
if (p_single) {
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
editor->call("edit_node", p_node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,7 +372,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2 &p_pos, bool p_append,
|
||||
Vector3 normal;
|
||||
|
||||
int handle = -1;
|
||||
bool inters = seg->intersect_ray(camera, p_pos, point, normal, NULL, p_alt_select);
|
||||
bool inters = seg->intersect_ray(camera, p_pos, point, normal, &handle, p_alt_select);
|
||||
|
||||
if (!inters)
|
||||
continue;
|
||||
@@ -475,7 +471,7 @@ void SpatialEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_incl
|
||||
Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) {
|
||||
|
||||
CameraMatrix cm;
|
||||
cm.set_perspective(get_fov(), get_size().aspect(), get_znear(), get_zfar());
|
||||
cm.set_perspective(get_fov(), get_size().aspect(), get_znear() + p_vector3.z, get_zfar());
|
||||
float screen_w, screen_h;
|
||||
cm.get_viewport_size(screen_w, screen_h);
|
||||
|
||||
@@ -485,7 +481,7 @@ Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) {
|
||||
camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
|
||||
camera_transform.translate(0, 0, cursor.distance);
|
||||
|
||||
return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_w, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_h, -get_znear()));
|
||||
return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_w, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_h, -(get_znear() + p_vector3.z)));
|
||||
}
|
||||
|
||||
void SpatialEditorViewport::_select_region() {
|
||||
@@ -493,23 +489,25 @@ void SpatialEditorViewport::_select_region() {
|
||||
if (cursor.region_begin == cursor.region_end)
|
||||
return; //nothing really
|
||||
|
||||
float z_offset = MAX(0.0, 5.0 - get_znear());
|
||||
|
||||
Vector3 box[4] = {
|
||||
Vector3(
|
||||
MIN(cursor.region_begin.x, cursor.region_end.x),
|
||||
MIN(cursor.region_begin.y, cursor.region_end.y),
|
||||
0),
|
||||
z_offset),
|
||||
Vector3(
|
||||
MAX(cursor.region_begin.x, cursor.region_end.x),
|
||||
MIN(cursor.region_begin.y, cursor.region_end.y),
|
||||
0),
|
||||
z_offset),
|
||||
Vector3(
|
||||
MAX(cursor.region_begin.x, cursor.region_end.x),
|
||||
MAX(cursor.region_begin.y, cursor.region_end.y),
|
||||
0),
|
||||
z_offset),
|
||||
Vector3(
|
||||
MIN(cursor.region_begin.x, cursor.region_end.x),
|
||||
MAX(cursor.region_begin.y, cursor.region_end.y),
|
||||
0)
|
||||
z_offset)
|
||||
};
|
||||
|
||||
Vector<Plane> frustum;
|
||||
@@ -529,7 +527,7 @@ void SpatialEditorViewport::_select_region() {
|
||||
frustum.push_back(near);
|
||||
|
||||
Plane far = -near;
|
||||
far.d += 500.0;
|
||||
far.d += get_zfar();
|
||||
|
||||
frustum.push_back(far);
|
||||
|
||||
@@ -544,19 +542,26 @@ void SpatialEditorViewport::_select_region() {
|
||||
if (!sp)
|
||||
continue;
|
||||
|
||||
Ref<SpatialEditorGizmo> seg = sp->get_gizmo();
|
||||
|
||||
if (!seg.is_valid())
|
||||
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<Spatial>(root_sp->get_owner());
|
||||
}
|
||||
|
||||
if (selected.find(root_sp) == -1)
|
||||
if (seg->intersect_frustum(camera, frustum))
|
||||
_select(root_sp, true, false);
|
||||
if (selected.find(root_sp) != -1) continue;
|
||||
|
||||
Ref<SpatialEditorGizmo> seg = sp->get_gizmo();
|
||||
|
||||
if (!seg.is_valid())
|
||||
continue;
|
||||
|
||||
if (seg->intersect_frustum(camera, frustum)) {
|
||||
selected.push_back(root_sp);
|
||||
}
|
||||
}
|
||||
|
||||
bool single = selected.size() == 1;
|
||||
for (int i = 0; i < selected.size(); i++) {
|
||||
_select(selected[i], true, single);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1170,6 +1175,9 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
||||
}
|
||||
|
||||
if (cursor.region_select) {
|
||||
|
||||
if (!clicked_wants_append) _clear_selected();
|
||||
|
||||
_select_region();
|
||||
cursor.region_select = false;
|
||||
surface->update();
|
||||
@@ -1279,7 +1287,6 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
||||
}
|
||||
|
||||
if (cursor.region_select && nav_mode == NAVIGATION_NONE) {
|
||||
|
||||
cursor.region_end = m->get_position();
|
||||
surface->update();
|
||||
return;
|
||||
@@ -2153,10 +2160,7 @@ void SpatialEditorViewport::_notification(int p_what) {
|
||||
|
||||
VisualInstance *vi = Object::cast_to<VisualInstance>(sp);
|
||||
|
||||
if (se->aabb.has_no_surface()) {
|
||||
|
||||
se->aabb = vi ? vi->get_aabb() : AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4));
|
||||
}
|
||||
se->aabb = vi ? vi->get_aabb() : AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4));
|
||||
|
||||
Transform t = sp->get_global_gizmo_transform();
|
||||
t.translate(se->aabb.position);
|
||||
|
||||
Reference in New Issue
Block a user