Skip to content

Commit

Permalink
Physics Interpolation - refactor Camera and fix `get_camera_transfo…
Browse files Browse the repository at this point in the history
…rm()`

* Moves 3D Camera interpolation scene side.
* Automatically switches `get_camera_transform()` to report interpolated transform during `_process()`.
* Fixes `ClippedCamera` to work with physics interpolation.
  • Loading branch information
lawnjelly committed Jun 9, 2024
1 parent b203829 commit 0b30d77
Show file tree
Hide file tree
Showing 20 changed files with 359 additions and 274 deletions.
51 changes: 51 additions & 0 deletions core/error_macros.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
#include "core/ustring.h"
#include "os/os.h"

#if defined(DEBUG_ENABLED) && defined(TOOLS_ENABLED)
#include "scene/main/node.h"
#endif

static ErrorHandlerList *error_handler_list = nullptr;

void add_error_handler(ErrorHandlerList *p_handler) {
Expand Down Expand Up @@ -117,3 +121,50 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
void _err_flush_stdout() {
fflush(stdout);
}

// Prevent error spam by limiting the warnings to a certain frequency.
void _physics_interpolation_warning(const char *p_function, const char *p_file, int p_line, ObjectID p_id, const char *p_warn_string) {
#if defined(DEBUG_ENABLED) && defined(TOOLS_ENABLED)
const uint32_t warn_max = 2048;
const uint32_t warn_timeout_seconds = 15;

static uint32_t warn_count = warn_max;
static uint32_t warn_timeout = warn_timeout_seconds;

uint32_t time_now = UINT32_MAX;

if (warn_count) {
warn_count--;
}

if (!warn_count) {
time_now = OS::get_singleton()->get_ticks_msec() / 1000;
}

if ((warn_count == 0) && (time_now >= warn_timeout)) {
warn_count = warn_max;
warn_timeout = time_now + warn_timeout_seconds;

if (GLOBAL_GET("debug/settings/physics_interpolation/enable_warnings")) {
// UINT64_MAX means unused.
if (p_id == UINT64_MAX) {
_err_print_error(p_function, p_file, p_line, "[Physics interpolation] " + String(p_warn_string) + " (possibly benign).", ERR_HANDLER_WARNING);
} else {
String node_name;
if (p_id != 0) {
if (ObjectDB::get_instance(p_id)) {
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(p_id));
if (node && node->is_inside_tree()) {
node_name = "\"" + String(node->get_path()) + "\"";
} else {
node_name = "\"unknown\"";
}
}
}

_err_print_error(p_function, p_file, p_line, "[Physics interpolation] " + String(p_warn_string) + ": " + node_name + " (possibly benign).", ERR_HANDLER_WARNING);
}
}
}
#endif
}
13 changes: 13 additions & 0 deletions core/error_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#ifndef ERROR_MACROS_H
#define ERROR_MACROS_H

#include "core/object_id.h"
#include "core/safe_refcount.h"
#include "core/typedefs.h"

Expand Down Expand Up @@ -86,6 +87,8 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal = false);
void _err_flush_stdout();

void _physics_interpolation_warning(const char *p_function, const char *p_file, int p_line, ObjectID p_id, const char *p_warn_string);

#ifndef _STR
#define _STR(m_x) #m_x
#define _MKSTR(m_x) _STR(m_x)
Expand Down Expand Up @@ -558,4 +561,14 @@ void _err_flush_stdout();
#define DEV_CHECK_ONCE(m_cond)
#endif

/**
* Physics Interpolation warnings.
* These are spam protection warnings.
*/
#define PHYSICS_INTERPOLATION_NODE_WARNING(m_object_id, m_string) \
_physics_interpolation_warning(FUNCTION_STR, __FILE__, __LINE__, m_object_id, m_string)

#define PHYSICS_INTERPOLATION_WARNING(m_string) \
_physics_interpolation_warning(FUNCTION_STR, __FILE__, __LINE__, UINT64_MAX, m_string)

#endif // ERROR_MACROS_H
16 changes: 0 additions & 16 deletions doc/classes/VisualServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@
Once finished with your RID, you will want to free the RID using the VisualServer's [method free_rid] static method.
</description>
</method>
<method name="camera_reset_physics_interpolation">
<return type="void" />
<argument index="0" name="camera" type="RID" />
<description>
Prevents physics interpolation for the current physics tick.
This is useful when moving a [Camera] to a new location, to give an instantaneous change rather than interpolation from the previous location.
</description>
</method>
<method name="camera_set_cull_mask">
<return type="void" />
<argument index="0" name="camera" type="RID" />
Expand Down Expand Up @@ -80,14 +72,6 @@
Sets camera to use frustum projection. This mode allows adjusting the [code]offset[/code] argument to create "tilted frustum" effects.
</description>
</method>
<method name="camera_set_interpolated">
<return type="void" />
<argument index="0" name="camera" type="RID" />
<argument index="1" name="interpolated" type="bool" />
<description>
Turns on and off physics interpolation for the [Camera].
</description>
</method>
<method name="camera_set_orthogonal">
<return type="void" />
<argument index="0" name="camera" type="RID" />
Expand Down
2 changes: 1 addition & 1 deletion scene/2d/cpu_particles_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1267,7 +1267,7 @@ void CPUParticles2D::_notification(int p_what) {
}
}
}
if (p_what == NOTIFICATION_RESET_PHYSICS_INTERPOLATION) {
if (p_what == NOTIFICATION_RESET_PHYSICS_INTERPOLATION && is_inside_tree()) {
// Make sure current is up to date with any pending global transform changes.
_interpolation_data.global_xform_curr = get_global_transform_const();
_interpolation_data.global_xform_prev = _interpolation_data.global_xform_curr;
Expand Down
Loading

0 comments on commit 0b30d77

Please sign in to comment.