Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Physics Interpolation - Fix 2D skinning #93309

Merged
merged 1 commit into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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