Skip to content

Commit

Permalink
Physics Interpolation - Fix 2D skinning
Browse files Browse the repository at this point in the history
2D skinning required the interpolated skeleton base transform to be updated when using interpolation.
  • Loading branch information
lawnjelly committed Jun 18, 2024
1 parent 72aac81 commit 44f6042
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 11 deletions.
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

0 comments on commit 44f6042

Please sign in to comment.