Skip to content

Commit 131ba00

Browse files
committed
Merge pull request #112524 from TokageItLab/deterministic-ik
Add Deterministic option to IterateIK3D
2 parents f41c846 + 3812c74 commit 131ba00

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

doc/classes/IterateIK3D.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@
145145
The maximum amount each bone can rotate in a single iteration.
146146
[b]Note:[/b] This limitation is applied during each iteration. For example, if [member max_iterations] is [code]4[/code] and [member angular_delta_limit] is [code]5[/code] degrees, the maximum rotation possible in a single frame is [code]20[/code] degrees.
147147
</member>
148+
<member name="deterministic" type="bool" setter="set_deterministic" getter="is_deterministic" default="false">
149+
If [code]false[/code], the result is calculated from the previous frame's [IterateIK3D] result as the initial state.
150+
If [code]true[/code], the previous frame's [IterateIK3D] result is discarded. At this point, the new result is calculated from the bone pose excluding the [IterateIK3D] as the initial state. This means the result will be always equal as long as the target position and the previous bone pose are the same. However, if [member angular_delta_limit] and [member max_iterations] are set too small, the end bone of the chain will never reach the target.
151+
</member>
148152
<member name="max_iterations" type="int" setter="set_max_iterations" getter="get_max_iterations" default="4">
149153
The number of iteration loops used by the IK solver to produce more accurate results.
150154
</member>

scene/3d/iterate_ik_3d.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,14 @@ double IterateIK3D::get_angular_delta_limit() const {
190190
return angular_delta_limit;
191191
}
192192

193+
void IterateIK3D::set_deterministic(bool p_deterministic) {
194+
deterministic = p_deterministic;
195+
}
196+
197+
bool IterateIK3D::is_deterministic() const {
198+
return deterministic;
199+
}
200+
193201
// Setting.
194202

195203
void IterateIK3D::set_target_node(int p_index, const NodePath &p_node_path) {
@@ -362,6 +370,8 @@ void IterateIK3D::_bind_methods() {
362370
ClassDB::bind_method(D_METHOD("get_min_distance"), &IterateIK3D::get_min_distance);
363371
ClassDB::bind_method(D_METHOD("set_angular_delta_limit", "angular_delta_limit"), &IterateIK3D::set_angular_delta_limit);
364372
ClassDB::bind_method(D_METHOD("get_angular_delta_limit"), &IterateIK3D::get_angular_delta_limit);
373+
ClassDB::bind_method(D_METHOD("set_deterministic", "deterministic"), &IterateIK3D::set_deterministic);
374+
ClassDB::bind_method(D_METHOD("is_deterministic"), &IterateIK3D::is_deterministic);
365375

366376
// Setting.
367377
ClassDB::bind_method(D_METHOD("set_target_node", "index", "target_node"), &IterateIK3D::set_target_node);
@@ -384,6 +394,7 @@ void IterateIK3D::_bind_methods() {
384394
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_iterations", PROPERTY_HINT_RANGE, "0,100,or_greater"), "set_max_iterations", "get_max_iterations");
385395
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min_distance", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater"), "set_min_distance", "get_min_distance");
386396
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_delta_limit", PROPERTY_HINT_RANGE, "0,180,0.001,radians_as_degrees"), "set_angular_delta_limit", "get_angular_delta_limit");
397+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deterministic"), "set_deterministic", "is_deterministic");
387398
ADD_ARRAY_COUNT("Settings", "setting_count", "set_setting_count", "get_setting_count", "settings/");
388399
}
389400

@@ -414,6 +425,8 @@ void IterateIK3D::_init_joints(Skeleton3D *p_skeleton, int p_index) {
414425
_clear_joints(p_index);
415426
setting->init_joints(p_skeleton, mutable_bone_axes);
416427
setting->simulation_dirty = false;
428+
} else if (deterministic) {
429+
setting->init_joints(p_skeleton, mutable_bone_axes);
417430
}
418431

419432
if (mutable_bone_axes) {

scene/3d/iterate_ik_3d.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ class IterateIK3D : public ChainIK3D {
279279
double min_distance_squared = min_distance * min_distance; // For cache.
280280
double angular_delta_limit = Math::deg_to_rad(2.0); // If the delta is too large, the results before and after iterating can change significantly, and divergence of calculations can easily occur.
281281

282+
bool deterministic = false;
283+
282284
bool _get(const StringName &p_path, Variant &r_ret) const;
283285
bool _set(const StringName &p_path, const Variant &p_value);
284286
void _get_property_list(List<PropertyInfo> *p_list) const;
@@ -325,6 +327,9 @@ class IterateIK3D : public ChainIK3D {
325327
void set_angular_delta_limit(double p_angular_delta_limit);
326328
double get_angular_delta_limit() const;
327329

330+
void set_deterministic(bool p_deterministic);
331+
bool is_deterministic() const;
332+
328333
// Setting.
329334
void set_target_node(int p_index, const NodePath &p_target_node);
330335
NodePath get_target_node(int p_index) const;

0 commit comments

Comments
 (0)