Skip to content

Commit

Permalink
Merge pull request #2 from naiiveprojects/3.x
Browse files Browse the repository at this point in the history
Merge PR from 3.x branch
  • Loading branch information
illlustr authored Jun 20, 2024
2 parents a0f0a35 + b2be47e commit 18179bd
Show file tree
Hide file tree
Showing 25 changed files with 468 additions and 300 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
1 change: 1 addition & 0 deletions doc/classes/Spatial.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<description>
When using physics interpolation, there will be circumstances in which you want to know the interpolated (displayed) transform of a node rather than the standard transform (which may only be accurate to the most recent physics tick).
This is particularly important for frame-based operations that take place in [method Node._process], rather than [method Node._physics_process]. Examples include [Camera]s focusing on a node, or finding where to fire lasers from on a frame rather than physics tick.
[b]Note:[/b] This function creates an interpolation pump on the [Spatial] the first time it is called, which can respond to physics interpolation resets. If you get problems with "streaking" when initially following a [Spatial], be sure to call [method get_global_transform_interpolated] at least once [i]before[/i] resetting the [Spatial] physics interpolation.
</description>
</method>
<method name="get_parent_spatial" qualifiers="const">
Expand Down
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
18 changes: 12 additions & 6 deletions editor/plugins/spatial_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6274,9 +6274,15 @@ void SpatialEditor::_init_grid() {

bool orthogonal = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL;

PoolVector<Color> grid_colors[3];
PoolVector<Vector3> grid_points[3];
PoolVector<Vector3> grid_normals[3];
static LocalVector<Color> grid_colors[3];
static LocalVector<Vector3> grid_points[3];
static LocalVector<Vector3> grid_normals[3];

for (uint32_t n = 0; n < 3; n++) {
grid_colors[n].clear();
grid_points[n].clear();
grid_normals[n].clear();
}

Color primary_grid_color = EditorSettings::get_singleton()->get("editors/3d/primary_grid_color");
Color secondary_grid_color = EditorSettings::get_singleton()->get("editors/3d/secondary_grid_color");
Expand Down Expand Up @@ -6402,9 +6408,9 @@ void SpatialEditor::_init_grid() {
grid[c] = RID_PRIME(VisualServer::get_singleton()->mesh_create());
Array d;
d.resize(VS::ARRAY_MAX);
d[VisualServer::ARRAY_VERTEX] = grid_points[c];
d[VisualServer::ARRAY_COLOR] = grid_colors[c];
d[VisualServer::ARRAY_NORMAL] = grid_normals[c];
d[VisualServer::ARRAY_VERTEX] = (PoolVector<Vector3>)grid_points[c];
d[VisualServer::ARRAY_COLOR] = (PoolVector<Color>)grid_colors[c];
d[VisualServer::ARRAY_NORMAL] = (PoolVector<Vector3>)grid_normals[c];
VisualServer::get_singleton()->mesh_add_surface_from_arrays(grid[c], VisualServer::PRIMITIVE_LINES, d);
VisualServer::get_singleton()->mesh_surface_set_material(grid[c], 0, grid_mat[c]->get_rid());
grid_instance[c] = VisualServer::get_singleton()->instance_create2(grid[c], get_tree()->get_root()->get_world()->get_scenario());
Expand Down
6 changes: 3 additions & 3 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2367,14 +2367,14 @@ bool Main::iteration() {

uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();

PhysicsServer::get_singleton()->flush_queries();

// Prepare the fixed timestep interpolated nodes
// BEFORE they are updated by the physics 2D,
// BEFORE they are updated by the physics,
// otherwise the current and previous transforms
// may be the same, and no interpolation takes place.
OS::get_singleton()->get_main_loop()->iteration_prepare();

PhysicsServer::get_singleton()->flush_queries();

Physics2DServer::get_singleton()->sync();
Physics2DServer::get_singleton()->flush_queries();

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
80 changes: 69 additions & 11 deletions scene/2d/skeleton_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
/**************************************************************************/

#include "skeleton_2d.h"
#include "core/engine.h"
#include "core/math/transform_interpolator.h"

void Bone2D::_order_changed_in_parent() {
if (skeleton) {
Expand Down Expand Up @@ -270,20 +272,76 @@ Bone2D *Skeleton2D::get_bone(int p_idx) {
return bones[p_idx].bone;
}

void Skeleton2D::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
if (bone_setup_dirty) {
_update_bone_setup();
}
if (transform_dirty) {
_update_transform();
}
void Skeleton2D::_update_process_mode() {
bool process = is_physics_interpolated_and_enabled() && is_visible_in_tree();

set_process_internal(process);
set_physics_process_internal(process);
}

request_ready();
void Skeleton2D::_ensure_update_interpolation_data() {
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;
}
}

if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
VS::get_singleton()->skeleton_set_base_transform_2d(skeleton, get_global_transform());
void Skeleton2D::_physics_interpolated_changed() {
_update_process_mode();
}

void Skeleton2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
if (bone_setup_dirty) {
_update_bone_setup();
}
if (transform_dirty) {
_update_transform();
}

request_ready();
} break;
case NOTIFICATION_ENTER_TREE: {
_update_process_mode();

if (is_physics_interpolated_and_enabled()) {
_interpolation_data.xform_curr = get_global_transform();
_interpolation_data.xform_prev = _interpolation_data.xform_curr;
}
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
if (is_physics_interpolated_and_enabled()) {
_ensure_update_interpolation_data();
if (Engine::get_singleton()->is_in_physics_frame()) {
_interpolation_data.xform_curr = get_global_transform();
}
} else {
VS::get_singleton()->skeleton_set_base_transform_2d(skeleton, get_global_transform());
}
} break;
case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: {
_interpolation_data.xform_curr = get_global_transform();
_interpolation_data.xform_prev = _interpolation_data.xform_curr;
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (is_physics_interpolated_and_enabled()) {
_ensure_update_interpolation_data();
_interpolation_data.xform_curr = get_global_transform();
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
if (is_physics_interpolated_and_enabled()) {
Transform2D res;
TransformInterpolator::interpolate_transform_2d(_interpolation_data.xform_prev, _interpolation_data.xform_curr, res, Engine::get_singleton()->get_physics_interpolation_fraction());
VS::get_singleton()->skeleton_set_base_transform_2d(skeleton, res);
}
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
_update_process_mode();
} break;
}
}

Expand Down
11 changes: 11 additions & 0 deletions scene/2d/skeleton_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,21 @@ class Skeleton2D : public Node2D {

RID skeleton;

void _update_process_mode();
void _ensure_update_interpolation_data();

struct InterpolationData {
Transform2D xform_curr;
Transform2D xform_prev;
uint32_t last_update_physics_tick = UINT32_MAX;
} _interpolation_data;

protected:
void _notification(int p_what);
static void _bind_methods();

virtual void _physics_interpolated_changed();

public:
int get_bone_count() const;
Bone2D *get_bone(int p_idx);
Expand Down
Loading

0 comments on commit 18179bd

Please sign in to comment.