You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-09 12:50:35 +00:00
Cleanup and simplify camera override API
- Harmonise the camera override 2D and 3D APIs - Switch to using Camera2D/3D nodes to provide override functionality. This makes for simpler code, gets rid of much of copy-pasted camera code and makes code that relies on current viewport camera such as VisibleOnScreenNotifiers and object picking work out of the box. - Make camera override code only accesible within DEBUG_ENABLED builds
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#include "core/object/script_language.h"
|
||||
#include "core/os/time.h"
|
||||
#include "core/templates/local_vector.h"
|
||||
#include "scene/2d/camera_2d.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/main/canvas_layer.h"
|
||||
#include "scene/main/scene_tree.h"
|
||||
@@ -196,7 +197,7 @@ Error SceneDebugger::_msg_override_cameras(const Array &p_args) {
|
||||
ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA);
|
||||
bool enable = p_args[0];
|
||||
bool from_editor = p_args[1];
|
||||
SceneTree::get_singleton()->get_root()->enable_canvas_transform_override(enable);
|
||||
SceneTree::get_singleton()->get_root()->enable_camera_2d_override(enable);
|
||||
#ifndef _3D_DISABLED
|
||||
SceneTree::get_singleton()->get_root()->enable_camera_3d_override(enable);
|
||||
#endif // _3D_DISABLED
|
||||
@@ -206,8 +207,9 @@ Error SceneDebugger::_msg_override_cameras(const Array &p_args) {
|
||||
|
||||
Error SceneDebugger::_msg_transform_camera_2d(const Array &p_args) {
|
||||
ERR_FAIL_COND_V(p_args.is_empty(), ERR_INVALID_DATA);
|
||||
ERR_FAIL_COND_V(!SceneTree::get_singleton()->get_root()->is_camera_2d_override_enabled(), ERR_BUG);
|
||||
Transform2D transform = p_args[0];
|
||||
SceneTree::get_singleton()->get_root()->set_canvas_transform_override(transform);
|
||||
SceneTree::get_singleton()->get_root()->get_override_camera_2d()->set_transform(transform);
|
||||
RuntimeNodeSelect::get_singleton()->_queue_selection_update();
|
||||
return OK;
|
||||
}
|
||||
@@ -215,17 +217,20 @@ Error SceneDebugger::_msg_transform_camera_2d(const Array &p_args) {
|
||||
#ifndef _3D_DISABLED
|
||||
Error SceneDebugger::_msg_transform_camera_3d(const Array &p_args) {
|
||||
ERR_FAIL_COND_V(p_args.size() < 5, ERR_INVALID_DATA);
|
||||
ERR_FAIL_COND_V(!SceneTree::get_singleton()->get_root()->is_camera_3d_override_enabled(), ERR_BUG);
|
||||
Transform3D transform = p_args[0];
|
||||
bool is_perspective = p_args[1];
|
||||
float size_or_fov = p_args[2];
|
||||
float depth_near = p_args[3];
|
||||
float depth_far = p_args[4];
|
||||
|
||||
Camera3D *override_camera = SceneTree::get_singleton()->get_root()->get_override_camera_3d();
|
||||
if (is_perspective) {
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_perspective(size_or_fov, depth_near, depth_far);
|
||||
override_camera->set_perspective(size_or_fov, depth_near, depth_far);
|
||||
} else {
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_orthogonal(size_or_fov, depth_near, depth_far);
|
||||
override_camera->set_orthogonal(size_or_fov, depth_near, depth_far);
|
||||
}
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(transform);
|
||||
override_camera->set_transform(transform);
|
||||
RuntimeNodeSelect::get_singleton()->_queue_selection_update();
|
||||
return OK;
|
||||
}
|
||||
@@ -1598,23 +1603,24 @@ void RuntimeNodeSelect::_select_set_mode(SelectMode p_mode) {
|
||||
void RuntimeNodeSelect::_set_camera_override_enabled(bool p_enabled) {
|
||||
camera_override = p_enabled;
|
||||
|
||||
if (p_enabled) {
|
||||
_update_view_2d();
|
||||
}
|
||||
|
||||
#ifndef _3D_DISABLED
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
if (camera_first_override) {
|
||||
_reset_camera_2d();
|
||||
#ifndef _3D_DISABLED
|
||||
_reset_camera_3d();
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
camera_first_override = false;
|
||||
} else if (p_enabled) {
|
||||
_update_view_2d();
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(_get_cursor_transform());
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
}
|
||||
#ifndef _3D_DISABLED
|
||||
ERR_FAIL_COND(!root->is_camera_3d_override_enabled());
|
||||
Camera3D *override_camera = root->get_override_camera_3d();
|
||||
override_camera->set_transform(_get_cursor_transform());
|
||||
override_camera->set_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
#endif // _3D_DISABLED
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_root_window_input(const Ref<InputEvent> &p_event) {
|
||||
@@ -1756,13 +1762,16 @@ void RuntimeNodeSelect::_process_frame() {
|
||||
}
|
||||
|
||||
if (direction != Vector3()) {
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
ERR_FAIL_COND(!root->is_camera_3d_override_enabled());
|
||||
|
||||
// Calculate the process time manually, as the time scale is frozen.
|
||||
const double process_time = (1.0 / Engine::get_singleton()->get_frames_per_second()) * Engine::get_singleton()->get_unfrozen_time_scale();
|
||||
const Vector3 motion = direction * speed * process_time;
|
||||
cursor.pos += motion;
|
||||
cursor.eye_pos += motion;
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(_get_cursor_transform());
|
||||
root->get_override_camera_3d()->set_transform(_get_cursor_transform());
|
||||
}
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
@@ -2091,8 +2100,6 @@ void RuntimeNodeSelect::_queue_selection_update() {
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_update_selection() {
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
|
||||
RS::get_singleton()->canvas_item_clear(sbox_2d_ci);
|
||||
RS::get_singleton()->canvas_item_set_visible(sbox_2d_ci, selection_visible);
|
||||
|
||||
@@ -2109,13 +2116,7 @@ void RuntimeNodeSelect::_update_selection() {
|
||||
continue;
|
||||
}
|
||||
|
||||
Transform2D xform;
|
||||
// Cameras (overridden or not) don't affect `CanvasLayer`s.
|
||||
if (root->is_canvas_transform_override_enabled() && !(ci->get_canvas_layer_node() && !ci->get_canvas_layer_node()->is_following_viewport())) {
|
||||
xform = root->get_canvas_transform_override() * ci->get_global_transform();
|
||||
} else {
|
||||
xform = ci->get_global_transform_with_canvas();
|
||||
}
|
||||
Transform2D xform = ci->get_global_transform_with_canvas();
|
||||
|
||||
// Fallback.
|
||||
Rect2 rect = Rect2(Vector2(), Vector2(10, 10));
|
||||
@@ -2247,27 +2248,8 @@ void RuntimeNodeSelect::_update_selection_drag(const Point2 &p_end_pos) {
|
||||
return;
|
||||
}
|
||||
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
Rect2 selection_drawing;
|
||||
int thickness;
|
||||
if (root->is_canvas_transform_override_enabled()) {
|
||||
Transform2D xform = root->get_canvas_transform_override();
|
||||
RS::get_singleton()->canvas_item_set_transform(sel_drag_ci, xform);
|
||||
RS::get_singleton()->canvas_item_reset_physics_interpolation(sel_drag_ci);
|
||||
|
||||
selection_drawing.position = xform.affine_inverse().xform(selection_drag_area.position);
|
||||
selection_drawing.size = xform.affine_inverse().xform(p_end_pos);
|
||||
thickness = MAX(1, Math::ceil(1 / view_2d_zoom));
|
||||
} else {
|
||||
RS::get_singleton()->canvas_item_set_transform(sel_drag_ci, Transform2D());
|
||||
RS::get_singleton()->canvas_item_reset_physics_interpolation(sel_drag_ci);
|
||||
|
||||
selection_drawing.position = selection_drag_area.position;
|
||||
selection_drawing.size = p_end_pos;
|
||||
thickness = 1;
|
||||
}
|
||||
selection_drawing.size -= selection_drawing.position;
|
||||
selection_drawing = selection_drawing.abs();
|
||||
Rect2 selection_drawing = selection_drag_area.abs();
|
||||
int thickness = 1;
|
||||
|
||||
const Vector2 endpoints[4] = {
|
||||
selection_drawing.position,
|
||||
@@ -2352,9 +2334,10 @@ void RuntimeNodeSelect::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_n
|
||||
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
Point2 pos;
|
||||
// Cameras (overridden or not) don't affect `CanvasLayer`s.
|
||||
|
||||
// Cameras don't affect `CanvasLayer`s.
|
||||
if (!ci->get_canvas_layer_node() || ci->get_canvas_layer_node()->is_following_viewport()) {
|
||||
pos = (root->is_canvas_transform_override_enabled() ? root->get_canvas_transform_override() : root->get_canvas_transform()).affine_inverse().xform(p_pos);
|
||||
pos = root->get_canvas_transform().affine_inverse().xform(p_pos);
|
||||
} else {
|
||||
pos = p_pos;
|
||||
}
|
||||
@@ -2414,9 +2397,9 @@ void RuntimeNodeSelect::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_
|
||||
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
Rect2 rect;
|
||||
// Cameras (overridden or not) don't affect `CanvasLayer`s.
|
||||
// Cameras don't affect `CanvasLayer`s.
|
||||
if (!ci->get_canvas_layer_node() || ci->get_canvas_layer_node()->is_following_viewport()) {
|
||||
rect = (root->is_canvas_transform_override_enabled() ? root->get_canvas_transform_override() : root->get_canvas_transform()).affine_inverse().xform(p_rect);
|
||||
rect = root->get_canvas_transform().affine_inverse().xform(p_rect);
|
||||
} else {
|
||||
rect = p_rect;
|
||||
}
|
||||
@@ -2475,18 +2458,30 @@ void RuntimeNodeSelect::_zoom_callback(float p_zoom_factor, Vector2 p_origin, Re
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_reset_camera_2d() {
|
||||
view_2d_offset = -SceneTree::get_singleton()->get_root()->get_canvas_transform().get_origin();
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
Camera2D *game_camera = root->is_camera_2d_override_enabled() ? root->get_overridden_camera_2d() : root->get_camera_2d();
|
||||
if (game_camera) {
|
||||
// Ideally we should be using Camera2D::get_camera_transform() but it's not so this hack will have to do for now.
|
||||
view_2d_offset = game_camera->get_camera_screen_center() - (0.5 * root->get_visible_rect().size);
|
||||
} else {
|
||||
view_2d_offset = Vector2();
|
||||
}
|
||||
|
||||
view_2d_zoom = 1;
|
||||
|
||||
_update_view_2d();
|
||||
if (root->is_camera_2d_override_enabled()) {
|
||||
_update_view_2d();
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_update_view_2d() {
|
||||
Transform2D transform = Transform2D();
|
||||
transform.scale_basis(Size2(view_2d_zoom, view_2d_zoom));
|
||||
transform.columns[2] = -view_2d_offset * view_2d_zoom;
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
ERR_FAIL_COND(!root->is_camera_2d_override_enabled());
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_canvas_transform_override(transform);
|
||||
Camera2D *override_camera = root->get_override_camera_2d();
|
||||
override_camera->set_anchor_mode(Camera2D::ANCHOR_MODE_FIXED_TOP_LEFT);
|
||||
override_camera->set_zoom(Vector2(view_2d_zoom, view_2d_zoom));
|
||||
override_camera->set_position(view_2d_offset);
|
||||
|
||||
_queue_selection_update();
|
||||
}
|
||||
@@ -2496,21 +2491,15 @@ void RuntimeNodeSelect::_find_3d_items_at_pos(const Point2 &p_pos, Vector<Select
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
|
||||
Vector3 ray, pos, to;
|
||||
if (root->is_camera_3d_override_enabled()) {
|
||||
ray = root->camera_3d_override_project_ray_normal(p_pos);
|
||||
pos = root->camera_3d_override_project_ray_origin(p_pos);
|
||||
to = pos + ray * root->get_camera_3d_override_properties()["z_far"];
|
||||
} else {
|
||||
Camera3D *camera = root->get_camera_3d();
|
||||
if (!camera) {
|
||||
return;
|
||||
}
|
||||
|
||||
ray = camera->project_ray_normal(p_pos);
|
||||
pos = camera->project_ray_origin(p_pos);
|
||||
to = pos + ray * camera->get_far();
|
||||
Camera3D *camera = root->get_camera_3d();
|
||||
if (!camera) {
|
||||
return;
|
||||
}
|
||||
|
||||
ray = camera->project_ray_normal(p_pos);
|
||||
pos = camera->project_ray_origin(p_pos);
|
||||
to = pos + ray * camera->get_far();
|
||||
|
||||
#ifndef PHYSICS_3D_DISABLED
|
||||
// Start with physical objects.
|
||||
PhysicsDirectSpaceState3D *ss = root->get_world_3d()->get_direct_space_state();
|
||||
@@ -2585,30 +2574,12 @@ void RuntimeNodeSelect::_find_3d_items_at_rect(const Rect2 &p_rect, Vector<Selec
|
||||
return;
|
||||
}
|
||||
|
||||
bool cam_override = root->is_camera_3d_override_enabled();
|
||||
Vector3 cam_pos;
|
||||
Vector3 dist_pos;
|
||||
if (cam_override) {
|
||||
cam_pos = root->get_camera_3d_override_transform().origin;
|
||||
dist_pos = root->camera_3d_override_project_ray_origin(p_rect.position + p_rect.size / 2);
|
||||
} else {
|
||||
cam_pos = camera->get_global_position();
|
||||
dist_pos = camera->project_ray_origin(p_rect.position + p_rect.size / 2);
|
||||
}
|
||||
Vector3 cam_pos = camera->get_global_position();
|
||||
Vector3 dist_pos = camera->project_ray_origin(p_rect.position + p_rect.size / 2);
|
||||
|
||||
real_t znear, zfar = 0;
|
||||
real_t zofs = 5.0;
|
||||
if (cam_override) {
|
||||
HashMap<StringName, real_t> override_props = root->get_camera_3d_override_properties();
|
||||
znear = override_props["z_near"];
|
||||
zfar = override_props["z_far"];
|
||||
zofs -= znear;
|
||||
} else {
|
||||
znear = camera->get_near();
|
||||
zfar = camera->get_far();
|
||||
zofs -= znear;
|
||||
}
|
||||
zofs = MAX(0.0, zofs);
|
||||
real_t znear = camera->get_near();
|
||||
real_t zfar = camera->get_far();
|
||||
real_t zofs = MAX(0.0, 5.0 - znear);
|
||||
|
||||
const Point2 pos_end = p_rect.position + p_rect.size;
|
||||
Vector3 box[4] = {
|
||||
@@ -2637,13 +2608,9 @@ void RuntimeNodeSelect::_find_3d_items_at_rect(const Rect2 &p_rect, Vector<Selec
|
||||
frustum.push_back(Plane(a, b, cam_pos));
|
||||
}
|
||||
|
||||
Plane near_plane;
|
||||
// Get the camera normal.
|
||||
if (cam_override) {
|
||||
near_plane = Plane(root->get_camera_3d_override_transform().basis.get_column(2), cam_pos);
|
||||
} else {
|
||||
near_plane = Plane(camera->get_global_transform().basis.get_column(2), cam_pos);
|
||||
}
|
||||
Plane near_plane = Plane(camera->get_global_transform().basis.get_column(2), cam_pos);
|
||||
|
||||
near_plane.d -= znear;
|
||||
frustum.push_back(near_plane);
|
||||
|
||||
@@ -2728,27 +2695,10 @@ Vector3 RuntimeNodeSelect::_get_screen_to_space(const Vector3 &p_vector3) {
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
Camera3D *camera = root->get_camera_3d();
|
||||
|
||||
Transform3D camera_transform = camera->get_camera_transform();
|
||||
Size2 size = root->get_size();
|
||||
real_t znear = 0;
|
||||
|
||||
Projection cm;
|
||||
Transform3D camera_transform;
|
||||
if (root->is_camera_3d_override_enabled()) {
|
||||
HashMap<StringName, real_t> override_props = root->get_camera_3d_override_properties();
|
||||
znear = override_props["z_near"];
|
||||
cm.set_perspective(override_props["fov"], size.aspect(), znear + p_vector3.z, override_props["z_far"]);
|
||||
|
||||
camera_transform.translate_local(cursor.pos);
|
||||
camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot);
|
||||
camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
|
||||
camera_transform.translate_local(0, 0, cursor.distance);
|
||||
} else {
|
||||
znear = camera->get_near();
|
||||
cm.set_perspective(camera->get_fov(), size.aspect(), znear + p_vector3.z, camera->get_far());
|
||||
|
||||
camera_transform = camera->get_camera_transform();
|
||||
}
|
||||
|
||||
real_t znear = camera->get_near();
|
||||
Projection cm = Projection::create_perspective(camera->get_fov(), size.aspect(), znear + p_vector3.z, camera->get_far());
|
||||
Vector2 screen_he = cm.get_viewport_half_extents();
|
||||
return camera_transform.xform(Vector3(((p_vector3.x / size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (p_vector3.y / size.height)) * 2.0 - 1.0) * screen_he.y, -(znear + p_vector3.z)));
|
||||
}
|
||||
@@ -2808,20 +2758,23 @@ bool RuntimeNodeSelect::_handle_3d_input(const Ref<InputEvent> &p_event) {
|
||||
} else if (k->is_ctrl_pressed()) {
|
||||
switch (k->get_physical_keycode()) {
|
||||
case Key::EQUAL: {
|
||||
ERR_FAIL_COND_V(!SceneTree::get_singleton()->get_root()->is_camera_3d_override_enabled(), false);
|
||||
cursor.fov_scale = CLAMP(cursor.fov_scale - 0.05, CAMERA_MIN_FOV_SCALE, CAMERA_MAX_FOV_SCALE);
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
SceneTree::get_singleton()->get_root()->get_override_camera_3d()->set_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
|
||||
return true;
|
||||
} break;
|
||||
case Key::MINUS: {
|
||||
ERR_FAIL_COND_V(!SceneTree::get_singleton()->get_root()->is_camera_3d_override_enabled(), false);
|
||||
cursor.fov_scale = CLAMP(cursor.fov_scale + 0.05, CAMERA_MIN_FOV_SCALE, CAMERA_MAX_FOV_SCALE);
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
SceneTree::get_singleton()->get_root()->get_override_camera_3d()->set_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
|
||||
return true;
|
||||
} break;
|
||||
case Key::KEY_0: {
|
||||
ERR_FAIL_COND_V(!SceneTree::get_singleton()->get_root()->is_camera_3d_override_enabled(), false);
|
||||
cursor.fov_scale = 1;
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_perspective(camera_fov, camera_znear, camera_zfar);
|
||||
SceneTree::get_singleton()->get_root()->get_override_camera_3d()->set_perspective(camera_fov, camera_znear, camera_zfar);
|
||||
|
||||
return true;
|
||||
} break;
|
||||
@@ -2861,11 +2814,12 @@ void RuntimeNodeSelect::_set_camera_freelook_enabled(bool p_enabled) {
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_cursor_scale_distance(real_t p_scale) {
|
||||
ERR_FAIL_COND(!SceneTree::get_singleton()->get_root()->is_camera_3d_override_enabled());
|
||||
real_t min_distance = MAX(camera_znear * 4, VIEW_3D_MIN_ZOOM);
|
||||
real_t max_distance = MIN(camera_zfar / 4, VIEW_3D_MAX_ZOOM);
|
||||
cursor.distance = CLAMP(cursor.distance * p_scale, min_distance, max_distance);
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(_get_cursor_transform());
|
||||
SceneTree::get_singleton()->get_root()->get_override_camera_3d()->set_transform(_get_cursor_transform());
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_scale_freelook_speed(real_t p_scale) {
|
||||
@@ -2880,6 +2834,8 @@ void RuntimeNodeSelect::_scale_freelook_speed(real_t p_scale) {
|
||||
|
||||
void RuntimeNodeSelect::_cursor_look(Ref<InputEventWithModifiers> p_event) {
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
ERR_FAIL_COND(!root->is_camera_3d_override_enabled());
|
||||
|
||||
const Vector2 relative = _get_warped_mouse_motion(p_event, Rect2(Vector2(), root->get_size()));
|
||||
const Transform3D prev_camera_transform = _get_cursor_transform();
|
||||
|
||||
@@ -2900,11 +2856,13 @@ void RuntimeNodeSelect::_cursor_look(Ref<InputEventWithModifiers> p_event) {
|
||||
Vector3 diff = prev_pos - pos;
|
||||
cursor.pos += diff;
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(_get_cursor_transform());
|
||||
root->get_override_camera_3d()->set_transform(_get_cursor_transform());
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_cursor_pan(Ref<InputEventWithModifiers> p_event) {
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
ERR_FAIL_COND(!root->is_camera_3d_override_enabled());
|
||||
|
||||
// Reduce all sides of the area by 1, so warping works when windows are maximized/fullscreen.
|
||||
const Vector2 relative = _get_warped_mouse_motion(p_event, Rect2(Vector2(1, 1), root->get_size() - Vector2(2, 2)));
|
||||
const real_t pan_speed = translation_sensitivity / 150.0;
|
||||
@@ -2919,11 +2877,13 @@ void RuntimeNodeSelect::_cursor_pan(Ref<InputEventWithModifiers> p_event) {
|
||||
camera_transform.translate_local(translation);
|
||||
cursor.pos = camera_transform.origin;
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(_get_cursor_transform());
|
||||
root->get_override_camera_3d()->set_transform(_get_cursor_transform());
|
||||
}
|
||||
|
||||
void RuntimeNodeSelect::_cursor_orbit(Ref<InputEventWithModifiers> p_event) {
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
ERR_FAIL_COND(!root->is_camera_3d_override_enabled());
|
||||
|
||||
// Reduce all sides of the area by 1, so warping works when windows are maximized/fullscreen.
|
||||
const Vector2 relative = _get_warped_mouse_motion(p_event, Rect2(Vector2(1, 1), root->get_size() - Vector2(2, 2)));
|
||||
|
||||
@@ -2941,7 +2901,7 @@ void RuntimeNodeSelect::_cursor_orbit(Ref<InputEventWithModifiers> p_event) {
|
||||
cursor.y_rot += relative.x * orbit_sensitivity;
|
||||
}
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(_get_cursor_transform());
|
||||
root->get_override_camera_3d()->set_transform(_get_cursor_transform());
|
||||
}
|
||||
|
||||
Point2 RuntimeNodeSelect::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_event, Rect2 p_area) const {
|
||||
@@ -2969,22 +2929,25 @@ void RuntimeNodeSelect::_reset_camera_3d() {
|
||||
|
||||
cursor = Cursor();
|
||||
Window *root = SceneTree::get_singleton()->get_root();
|
||||
Camera3D *camera = root->get_camera_3d();
|
||||
if (camera) {
|
||||
Transform3D transform = camera->get_global_transform();
|
||||
Camera3D *game_camera = root->is_camera_3d_override_enabled() ? root->get_overridden_camera_3d() : root->get_camera_3d();
|
||||
if (game_camera) {
|
||||
Transform3D transform = game_camera->get_camera_transform();
|
||||
transform.translate_local(0, 0, -cursor.distance);
|
||||
cursor.pos = transform.origin;
|
||||
|
||||
cursor.x_rot = -camera->get_global_rotation().x;
|
||||
cursor.y_rot = -camera->get_global_rotation().y;
|
||||
cursor.x_rot = -game_camera->get_global_rotation().x;
|
||||
cursor.y_rot = -game_camera->get_global_rotation().y;
|
||||
|
||||
cursor.fov_scale = CLAMP(camera->get_fov() / camera_fov, CAMERA_MIN_FOV_SCALE, CAMERA_MAX_FOV_SCALE);
|
||||
cursor.fov_scale = CLAMP(game_camera->get_fov() / camera_fov, CAMERA_MIN_FOV_SCALE, CAMERA_MAX_FOV_SCALE);
|
||||
} else {
|
||||
cursor.fov_scale = 1.0;
|
||||
}
|
||||
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_transform(_get_cursor_transform());
|
||||
SceneTree::get_singleton()->get_root()->set_camera_3d_override_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
if (root->is_camera_3d_override_enabled()) {
|
||||
Camera3D *override_camera = root->get_override_camera_3d();
|
||||
override_camera->set_transform(_get_cursor_transform());
|
||||
override_camera->set_perspective(camera_fov * cursor.fov_scale, camera_znear, camera_zfar);
|
||||
}
|
||||
}
|
||||
#endif // _3D_DISABLED
|
||||
|
||||
|
||||
Reference in New Issue
Block a user