Skip to content

Commit cba1afd

Browse files
committed
Merge pull request godotengine#103639 from TokageItLab/delta-modifiers
Add `delta` argument to `_process_modification()` as `_process_modification_with_delta(delta)` and expose `advance()` at `Skeleton3D`
2 parents 6bd249a + 96200ab commit cba1afd

20 files changed

+87
-40
lines changed

doc/classes/Skeleton3D.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
[b]Note:[/b] Bone names should be unique, non empty, and cannot include the [code]:[/code] and [code]/[/code] characters.
2121
</description>
2222
</method>
23+
<method name="advance">
24+
<return type="void" />
25+
<param index="0" name="delta" type="float" />
26+
<description>
27+
Manually advance the child [SkeletonModifier3D]s by the specified time (in seconds).
28+
[b]Note:[/b] The [param delta] is temporarily accumulated in the [Skeleton3D], and the deferred process uses the accumulated value to process the modification.
29+
</description>
30+
</method>
2331
<method name="clear_bones">
2432
<return type="void" />
2533
<description>
@@ -420,5 +428,8 @@
420428
<constant name="MODIFIER_CALLBACK_MODE_PROCESS_IDLE" value="1" enum="ModifierCallbackModeProcess">
421429
Set a flag to process modification during process frames (see [constant Node.NOTIFICATION_INTERNAL_PROCESS]).
422430
</constant>
431+
<constant name="MODIFIER_CALLBACK_MODE_PROCESS_MANUAL" value="2" enum="ModifierCallbackModeProcess">
432+
Do not process modification. Use [method advance] to process the modification manually.
433+
</constant>
423434
</constants>
424435
</class>

doc/classes/SkeletonModifier3D.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,22 @@
1212
<link title="Design of the Skeleton Modifier 3D">https://godotengine.org/article/design-of-the-skeleton-modifier-3d/</link>
1313
</tutorials>
1414
<methods>
15-
<method name="_process_modification" qualifiers="virtual">
15+
<method name="_process_modification" qualifiers="virtual" deprecated="Use [method _process_modification_with_delta] instead.">
1616
<return type="void" />
1717
<description>
1818
Override this virtual method to implement a custom skeleton modifier. You should do things like get the [Skeleton3D]'s current pose and apply the pose here.
1919
[method _process_modification] must not apply [member influence] to bone poses because the [Skeleton3D] automatically applies influence to all bone poses set by the modifier.
2020
</description>
2121
</method>
22+
<method name="_process_modification_with_delta" qualifiers="virtual">
23+
<return type="void" />
24+
<param index="0" name="delta" type="float" />
25+
<description>
26+
Override this virtual method to implement a custom skeleton modifier. You should do things like get the [Skeleton3D]'s current pose and apply the pose here.
27+
[method _process_modification_with_delta] must not apply [member influence] to bone poses because the [Skeleton3D] automatically applies influence to all bone poses set by the modifier.
28+
[param delta] is passed from parent [Skeleton3D]. See also [method Skeleton3D.advance].
29+
</description>
30+
</method>
2231
<method name="get_skeleton" qualifiers="const">
2332
<return type="Skeleton3D" />
2433
<description>

scene/3d/look_at_modifier_3d.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ void LookAtModifier3D::_bind_methods() {
487487
BIND_ENUM_CONSTANT(ORIGIN_FROM_EXTERNAL_NODE);
488488
}
489489

490-
void LookAtModifier3D::_process_modification() {
490+
void LookAtModifier3D::_process_modification(double p_delta) {
491491
if (!is_inside_tree()) {
492492
return;
493493
}
@@ -570,13 +570,7 @@ void LookAtModifier3D::_process_modification() {
570570

571571
// Do time-based interpolation.
572572
if (remaining > 0) {
573-
double delta = 0.0;
574-
if (skeleton->get_modifier_callback_mode_process() == Skeleton3D::MODIFIER_CALLBACK_MODE_PROCESS_IDLE) {
575-
delta = get_process_delta_time();
576-
} else {
577-
delta = get_physics_process_delta_time();
578-
}
579-
remaining = MAX(0, remaining - time_step * delta);
573+
remaining = MAX(0, remaining - time_step * p_delta);
580574
if (is_flippable) {
581575
// Interpolate through the rest same as AnimationTree blending for preventing to penetrate the bone into the body.
582576
Quaternion rest = skeleton->get_bone_rest(bone).basis.get_rotation_quaternion();

scene/3d/look_at_modifier_3d.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class LookAtModifier3D : public SkeletonModifier3D {
107107

108108
static void _bind_methods();
109109

110-
virtual void _process_modification() override;
110+
virtual void _process_modification(double p_delta) override;
111111

112112
public:
113113
void set_bone_name(const String &p_bone_name);

scene/3d/physics/physical_bone_simulator_3d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ void PhysicalBoneSimulator3D::set_bone_global_pose(int p_bone, const Transform3D
364364
bones.write[p_bone].global_pose = p_pose;
365365
}
366366

367-
void PhysicalBoneSimulator3D::_process_modification() {
367+
void PhysicalBoneSimulator3D::_process_modification(double p_delta) {
368368
Skeleton3D *skeleton = get_skeleton();
369369
if (!skeleton) {
370370
return;

scene/3d/physics/physical_bone_simulator_3d.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class PhysicalBoneSimulator3D : public SkeletonModifier3D {
7272
void _pose_updated();
7373
void _bone_pose_updated(Skeleton3D *skeleton, int p_bone_id);
7474

75-
virtual void _process_modification() override;
75+
virtual void _process_modification(double p_delta) override;
7676

7777
virtual void _skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) override;
7878

scene/3d/retarget_modifier_3d.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ void RetargetModifier3D::_retarget_pose() {
370370
}
371371
}
372372

373-
void RetargetModifier3D::_process_modification() {
373+
void RetargetModifier3D::_process_modification(double p_delta) {
374374
if (use_global_pose) {
375375
_retarget_global_pose();
376376
} else {

scene/3d/retarget_modifier_3d.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class RetargetModifier3D : public SkeletonModifier3D {
9696
virtual void remove_child_notify(Node *p_child) override;
9797

9898
virtual void _set_active(bool p_active) override;
99-
virtual void _process_modification() override;
99+
virtual void _process_modification(double p_delta) override;
100100

101101
public:
102102
virtual PackedStringArray get_configuration_warnings() const override;

scene/3d/skeleton_3d.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,9 @@ void Skeleton3D::_notification(int p_what) {
357357
// Store dirty flags for global bone poses.
358358
bone_global_pose_dirty_backup = bone_global_pose_dirty;
359359

360-
_process_modifiers();
360+
if (update_flags & UPDATE_FLAG_MODIFIER) {
361+
_process_modifiers();
362+
}
361363
}
362364

363365
// Abort if pose is not changed.
@@ -438,16 +440,23 @@ void Skeleton3D::_notification(int p_what) {
438440
updating = false;
439441
update_flags = UPDATE_FLAG_NONE;
440442
} break;
441-
case NOTIFICATION_INTERNAL_PROCESS:
443+
case NOTIFICATION_INTERNAL_PROCESS: {
444+
advance(get_process_delta_time());
445+
} break;
442446
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
443-
_find_modifiers();
444-
if (!modifiers.is_empty()) {
445-
_update_deferred(UPDATE_FLAG_MODIFIER);
446-
}
447+
advance(get_physics_process_delta_time());
447448
} break;
448449
}
449450
}
450451

452+
void Skeleton3D::advance(double p_delta) {
453+
_find_modifiers();
454+
if (!modifiers.is_empty()) {
455+
update_delta += p_delta; // Accumulate delta for manual advance as it needs to process in deferred update.
456+
_update_deferred(UPDATE_FLAG_MODIFIER);
457+
}
458+
}
459+
451460
void Skeleton3D::set_modifier_callback_mode_process(Skeleton3D::ModifierCallbackModeProcess p_mode) {
452461
if (modifier_callback_mode_process == p_mode) {
453462
return;
@@ -467,6 +476,9 @@ void Skeleton3D::_process_changed() {
467476
} else if (modifier_callback_mode_process == MODIFIER_CALLBACK_MODE_PROCESS_PHYSICS) {
468477
set_process_internal(false);
469478
set_physics_process_internal(true);
479+
} else {
480+
set_process_internal(false);
481+
set_physics_process_internal(false);
470482
}
471483
}
472484

@@ -1194,7 +1206,7 @@ void Skeleton3D::_process_modifiers() {
11941206
for (int i = 0; i < get_bone_count(); i++) {
11951207
old_poses.push_back(get_bone_pose(i));
11961208
}
1197-
mod->process_modification();
1209+
mod->process_modification(update_delta);
11981210
LocalVector<Transform3D> new_poses;
11991211
for (int i = 0; i < get_bone_count(); i++) {
12001212
new_poses.push_back(get_bone_pose(i));
@@ -1206,10 +1218,11 @@ void Skeleton3D::_process_modifiers() {
12061218
set_bone_pose(i, old_poses[i].interpolate_with(new_poses[i], influence));
12071219
}
12081220
} else {
1209-
mod->process_modification();
1221+
mod->process_modification(update_delta);
12101222
}
12111223
force_update_all_dirty_bones();
12121224
}
1225+
update_delta = 0; // Reset accumulated delta.
12131226
}
12141227

12151228
void Skeleton3D::add_child_notify(Node *p_child) {
@@ -1297,11 +1310,13 @@ void Skeleton3D::_bind_methods() {
12971310
ClassDB::bind_method(D_METHOD("set_modifier_callback_mode_process", "mode"), &Skeleton3D::set_modifier_callback_mode_process);
12981311
ClassDB::bind_method(D_METHOD("get_modifier_callback_mode_process"), &Skeleton3D::get_modifier_callback_mode_process);
12991312

1313+
ClassDB::bind_method(D_METHOD("advance", "delta"), &Skeleton3D::advance);
1314+
13001315
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "motion_scale", PROPERTY_HINT_RANGE, "0.001,10,0.001,or_greater"), "set_motion_scale", "get_motion_scale");
13011316
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_rest_only"), "set_show_rest_only", "is_show_rest_only");
13021317

13031318
ADD_GROUP("Modifier", "modifier_");
1304-
ADD_PROPERTY(PropertyInfo(Variant::INT, "modifier_callback_mode_process", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_modifier_callback_mode_process", "get_modifier_callback_mode_process");
1319+
ADD_PROPERTY(PropertyInfo(Variant::INT, "modifier_callback_mode_process", PROPERTY_HINT_ENUM, "Physics,Idle,Manual"), "set_modifier_callback_mode_process", "get_modifier_callback_mode_process");
13051320

13061321
ADD_SIGNAL(MethodInfo("rest_updated"));
13071322
ADD_SIGNAL(MethodInfo("pose_updated"));
@@ -1313,6 +1328,7 @@ void Skeleton3D::_bind_methods() {
13131328
BIND_CONSTANT(NOTIFICATION_UPDATE_SKELETON);
13141329
BIND_ENUM_CONSTANT(MODIFIER_CALLBACK_MODE_PROCESS_PHYSICS);
13151330
BIND_ENUM_CONSTANT(MODIFIER_CALLBACK_MODE_PROCESS_IDLE);
1331+
BIND_ENUM_CONSTANT(MODIFIER_CALLBACK_MODE_PROCESS_MANUAL);
13161332

13171333
#ifndef DISABLE_DEPRECATED
13181334
ClassDB::bind_method(D_METHOD("clear_bones_global_pose_override"), &Skeleton3D::clear_bones_global_pose_override);

scene/3d/skeleton_3d.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class Skeleton3D : public Node3D {
7979
enum ModifierCallbackModeProcess {
8080
MODIFIER_CALLBACK_MODE_PROCESS_PHYSICS,
8181
MODIFIER_CALLBACK_MODE_PROCESS_IDLE,
82+
MODIFIER_CALLBACK_MODE_PROCESS_MANUAL,
8283
};
8384

8485
private:
@@ -93,6 +94,7 @@ class Skeleton3D : public Node3D {
9394
void _update_deferred(UpdateFlag p_update_flag = UPDATE_FLAG_POSE);
9495
uint8_t update_flags = UPDATE_FLAG_NONE;
9596
bool updating = false; // Is updating now?
97+
double update_delta = 0.0;
9698

9799
struct Bone {
98100
String name;
@@ -294,6 +296,8 @@ class Skeleton3D : public Node3D {
294296
void set_modifier_callback_mode_process(ModifierCallbackModeProcess p_mode);
295297
ModifierCallbackModeProcess get_modifier_callback_mode_process() const;
296298

299+
void advance(double p_delta);
300+
297301
#ifndef DISABLE_DEPRECATED
298302
Transform3D get_bone_global_pose_no_override(int p_bone) const;
299303
void clear_bones_global_pose_override();

0 commit comments

Comments
 (0)