feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
|
|
@ -31,6 +31,7 @@
|
|||
#include "camera_3d.h"
|
||||
|
||||
#include "core/math/projection.h"
|
||||
#include "core/math/transform_interpolator.h"
|
||||
#include "scene/main/viewport.h"
|
||||
|
||||
void Camera3D::_update_audio_listener_state() {
|
||||
|
|
@ -88,7 +89,16 @@ void Camera3D::_update_camera() {
|
|||
return;
|
||||
}
|
||||
|
||||
RenderingServer::get_singleton()->camera_set_transform(camera, get_camera_transform());
|
||||
if (!is_physics_interpolated_and_enabled()) {
|
||||
RenderingServer::get_singleton()->camera_set_transform(camera, get_camera_transform());
|
||||
} else {
|
||||
// Ideally we shouldn't be moving a physics interpolated camera within a frame,
|
||||
// because it will break smooth interpolation, but it may occur on e.g. level load.
|
||||
if (!Engine::get_singleton()->is_in_physics_frame() && camera.is_valid()) {
|
||||
_physics_interpolation_ensure_transform_calculated(true);
|
||||
RenderingServer::get_singleton()->camera_set_transform(camera, _interpolation_data.camera_xform_interpolated);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_part_of_edited_scene() || !is_current()) {
|
||||
return;
|
||||
|
|
@ -97,6 +107,64 @@ void Camera3D::_update_camera() {
|
|||
get_viewport()->_camera_3d_transform_changed_notify();
|
||||
}
|
||||
|
||||
void Camera3D::_physics_interpolated_changed() {
|
||||
_update_process_mode();
|
||||
}
|
||||
|
||||
void Camera3D::_physics_interpolation_ensure_data_flipped() {
|
||||
// The curr -> previous update can either occur
|
||||
// on the INTERNAL_PHYSICS_PROCESS OR
|
||||
// on NOTIFICATION_TRANSFORM_CHANGED,
|
||||
// if NOTIFICATION_TRANSFORM_CHANGED takes place
|
||||
// earlier than INTERNAL_PHYSICS_PROCESS on a tick.
|
||||
// This is to ensure that the data keeps flowing, but the new data
|
||||
// doesn't overwrite before prev has been set.
|
||||
|
||||
// Keep the data flowing.
|
||||
uint64_t tick = Engine::get_singleton()->get_physics_frames();
|
||||
if (_interpolation_data.last_update_physics_tick != tick) {
|
||||
_interpolation_data.xform_prev = _interpolation_data.xform_curr;
|
||||
_interpolation_data.last_update_physics_tick = tick;
|
||||
physics_interpolation_flip_data();
|
||||
}
|
||||
}
|
||||
|
||||
void Camera3D::_physics_interpolation_ensure_transform_calculated(bool p_force) const {
|
||||
DEV_CHECK_ONCE(!Engine::get_singleton()->is_in_physics_frame());
|
||||
|
||||
InterpolationData &id = _interpolation_data;
|
||||
uint64_t frame = Engine::get_singleton()->get_frames_drawn();
|
||||
|
||||
if (id.last_update_frame != frame || p_force) {
|
||||
id.last_update_frame = frame;
|
||||
|
||||
TransformInterpolator::interpolate_transform_3d(id.xform_prev, id.xform_curr, id.xform_interpolated, Engine::get_singleton()->get_physics_interpolation_fraction());
|
||||
|
||||
Transform3D &tr = id.camera_xform_interpolated;
|
||||
tr = _get_adjusted_camera_transform(id.xform_interpolated);
|
||||
}
|
||||
}
|
||||
|
||||
void Camera3D::set_desired_process_modes(bool p_process_internal, bool p_physics_process_internal) {
|
||||
_desired_process_internal = p_process_internal;
|
||||
_desired_physics_process_internal = p_physics_process_internal;
|
||||
_update_process_mode();
|
||||
}
|
||||
|
||||
void Camera3D::_update_process_mode() {
|
||||
bool process = _desired_process_internal;
|
||||
bool physics_process = _desired_physics_process_internal;
|
||||
|
||||
if (is_physics_interpolated_and_enabled()) {
|
||||
if (is_current()) {
|
||||
process = true;
|
||||
physics_process = true;
|
||||
}
|
||||
}
|
||||
set_process_internal(process);
|
||||
set_physics_process_internal(physics_process);
|
||||
}
|
||||
|
||||
void Camera3D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_WORLD: {
|
||||
|
|
@ -118,11 +186,60 @@ void Camera3D::_notification(int p_what) {
|
|||
#endif
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_INTERNAL_PROCESS: {
|
||||
if (is_physics_interpolated_and_enabled() && camera.is_valid()) {
|
||||
_physics_interpolation_ensure_transform_calculated();
|
||||
|
||||
#ifdef RENDERING_SERVER_DEBUG_PHYSICS_INTERPOLATION
|
||||
print_line("\t\tinterpolated Camera3D: " + rtos(_interpolation_data.xform_interpolated.origin.x) + "\t( prev " + rtos(_interpolation_data.xform_prev.origin.x) + ", curr " + rtos(_interpolation_data.xform_curr.origin.x) + " ) on tick " + itos(Engine::get_singleton()->get_physics_frames()));
|
||||
#endif
|
||||
|
||||
RenderingServer::get_singleton()->camera_set_transform(camera, _interpolation_data.camera_xform_interpolated);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
|
||||
if (is_physics_interpolated_and_enabled()) {
|
||||
_physics_interpolation_ensure_data_flipped();
|
||||
_interpolation_data.xform_curr = get_global_transform();
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||
if (is_physics_interpolated_and_enabled()) {
|
||||
_physics_interpolation_ensure_data_flipped();
|
||||
_interpolation_data.xform_curr = get_global_transform();
|
||||
#if defined(DEBUG_ENABLED) && defined(TOOLS_ENABLED)
|
||||
if (!Engine::get_singleton()->is_in_physics_frame()) {
|
||||
PHYSICS_INTERPOLATION_NODE_WARNING(get_instance_id(), "Interpolated Camera3D triggered from outside physics process");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
_request_camera_update();
|
||||
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
|
||||
velocity_tracker->update_position(get_global_transform().origin);
|
||||
}
|
||||
// Allow auto-reset when first adding to the tree, as a convenience.
|
||||
if (_is_physics_interpolation_reset_requested() && is_inside_tree()) {
|
||||
_notification(NOTIFICATION_RESET_PHYSICS_INTERPOLATION);
|
||||
_set_physics_interpolation_reset_requested(false);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: {
|
||||
if (is_inside_tree()) {
|
||||
_interpolation_data.xform_curr = get_global_transform();
|
||||
_interpolation_data.xform_prev = _interpolation_data.xform_curr;
|
||||
_update_process_mode();
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_SUSPENDED:
|
||||
case NOTIFICATION_PAUSED: {
|
||||
if (is_physics_interpolated_and_enabled() && is_inside_tree() && is_visible_in_tree()) {
|
||||
_physics_interpolation_ensure_transform_calculated(true);
|
||||
RenderingServer::get_singleton()->camera_set_transform(camera, _interpolation_data.camera_xform_interpolated);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_WORLD: {
|
||||
|
|
@ -151,23 +268,34 @@ void Camera3D::_notification(int p_what) {
|
|||
if (viewport) {
|
||||
viewport->find_world_3d()->_register_camera(this);
|
||||
}
|
||||
_update_process_mode();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_LOST_CURRENT: {
|
||||
if (viewport) {
|
||||
viewport->find_world_3d()->_remove_camera(this);
|
||||
}
|
||||
_update_process_mode();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
Transform3D Camera3D::get_camera_transform() const {
|
||||
Transform3D tr = get_global_transform().orthonormalized();
|
||||
Transform3D Camera3D::_get_adjusted_camera_transform(const Transform3D &p_xform) const {
|
||||
Transform3D tr = p_xform.orthonormalized();
|
||||
tr.origin += tr.basis.get_column(1) * v_offset;
|
||||
tr.origin += tr.basis.get_column(0) * h_offset;
|
||||
return tr;
|
||||
}
|
||||
|
||||
Transform3D Camera3D::get_camera_transform() const {
|
||||
if (is_physics_interpolated_and_enabled() && !Engine::get_singleton()->is_in_physics_frame()) {
|
||||
_physics_interpolation_ensure_transform_calculated();
|
||||
return _interpolation_data.camera_xform_interpolated;
|
||||
}
|
||||
|
||||
return _get_adjusted_camera_transform(get_global_transform());
|
||||
}
|
||||
|
||||
Projection Camera3D::_get_camera_projection(real_t p_near) const {
|
||||
Size2 viewport_size = get_viewport()->get_visible_rect().size;
|
||||
Projection cm;
|
||||
|
|
@ -250,7 +378,7 @@ void Camera3D::set_projection(ProjectionType p_mode) {
|
|||
|
||||
RID Camera3D::get_camera() const {
|
||||
return camera;
|
||||
};
|
||||
}
|
||||
|
||||
void Camera3D::make_current() {
|
||||
current = true;
|
||||
|
|
@ -296,7 +424,7 @@ bool Camera3D::is_current() const {
|
|||
Vector3 Camera3D::project_ray_normal(const Point2 &p_pos) const {
|
||||
Vector3 ray = project_local_ray_normal(p_pos);
|
||||
return get_camera_transform().basis.xform(ray).normalized();
|
||||
};
|
||||
}
|
||||
|
||||
Vector3 Camera3D::project_local_ray_normal(const Point2 &p_pos) const {
|
||||
ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
|
||||
|
|
@ -314,7 +442,7 @@ Vector3 Camera3D::project_local_ray_normal(const Point2 &p_pos) const {
|
|||
}
|
||||
|
||||
return ray;
|
||||
};
|
||||
}
|
||||
|
||||
Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const {
|
||||
ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
|
||||
|
|
@ -343,7 +471,7 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const {
|
|||
} else {
|
||||
return get_camera_transform().origin;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
bool Camera3D::is_position_behind(const Vector3 &p_pos) const {
|
||||
Transform3D t = get_global_transform();
|
||||
|
|
@ -379,6 +507,11 @@ Point2 Camera3D::unproject_position(const Vector3 &p_pos) const {
|
|||
Plane p(get_camera_transform().xform_inv(p_pos), 1.0);
|
||||
|
||||
p = cm.xform4(p);
|
||||
|
||||
// Prevent divide by zero.
|
||||
// TODO: Investigate, this was causing NaNs.
|
||||
ERR_FAIL_COND_V(p.d == 0, Point2());
|
||||
|
||||
p.normal /= p.d;
|
||||
|
||||
Point2 res;
|
||||
|
|
@ -396,9 +529,12 @@ Vector3 Camera3D::project_position(const Point2 &p_point, real_t p_z_depth) cons
|
|||
}
|
||||
Size2 viewport_size = get_viewport()->get_visible_rect().size;
|
||||
|
||||
Projection cm = _get_camera_projection(p_z_depth);
|
||||
Projection cm = _get_camera_projection(_near);
|
||||
|
||||
Vector2 vp_he = cm.get_viewport_half_extents();
|
||||
Plane z_slice(Vector3(0, 0, 1), -p_z_depth);
|
||||
Vector3 res;
|
||||
z_slice.intersect_3(cm.get_projection_plane(Projection::Planes::PLANE_RIGHT), cm.get_projection_plane(Projection::Planes::PLANE_TOP), &res);
|
||||
Vector2 vp_he(res.x, res.y);
|
||||
|
||||
Vector2 point;
|
||||
point.x = (p_point.x / viewport_size.x) * 2.0 - 1.0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue