Skip to content

Commit

Permalink
Implement skeleton retarget and overhaul some animation features
Browse files Browse the repository at this point in the history
  • Loading branch information
TokageItLab committed Feb 28, 2022
1 parent 353be62 commit a72ecb3
Show file tree
Hide file tree
Showing 52 changed files with 6,113 additions and 723 deletions.
1 change: 1 addition & 0 deletions core/variant/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ class Variant {
Variant recursive_duplicate(bool p_deep, int recursion_count) const;
static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
static void sub(const Variant &a, const Variant &b, Variant &r_dst);

/* Built-In Methods */

Expand Down
104 changes: 104 additions & 0 deletions core/variant/variant_setget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,110 @@ Variant Variant::recursive_duplicate(bool p_deep, int recursion_count) const {
}
}

void Variant::sub(const Variant &a, const Variant &b, Variant &r_dst) {
if (a.type != b.type) {
return;
}

switch (a.type) {
case NIL: {
r_dst = Variant();
}
return;
case INT: {
int64_t va = a._data._int;
int64_t vb = b._data._int;
r_dst = int(va - vb);
}
return;
case FLOAT: {
double ra = a._data._float;
double rb = b._data._float;
r_dst = ra - rb;
}
return;
case VECTOR2: {
r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) - *reinterpret_cast<const Vector2 *>(b._data._mem);
}
return;
case VECTOR2I: {
int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x;
int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x;
int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y;
int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y;
r_dst = Vector2i(int32_t(vax - vbx), int32_t(vay - vby));
}
return;
case RECT2: {
const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem);
const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem);
r_dst = Rect2(ra->position - rb->position, ra->size - rb->size);
}
return;
case RECT2I: {
const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem);
const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem);

int32_t vax = ra->position.x;
int32_t vay = ra->position.y;
int32_t vbx = ra->size.x;
int32_t vby = ra->size.y;
int32_t vcx = rb->position.x;
int32_t vcy = rb->position.y;
int32_t vdx = rb->size.x;
int32_t vdy = rb->size.y;

r_dst = Rect2i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vcx - vdx), int32_t(vcy - vdy));
}
return;
case VECTOR3: {
r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) - *reinterpret_cast<const Vector3 *>(b._data._mem);
}
return;
case VECTOR3I: {
int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x;
int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x;
int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y;
int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y;
int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z;
int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z;
r_dst = Vector3i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vaz - vbz));
}
return;
case AABB: {
const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem);
const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem);
r_dst = ::AABB(ra->position - rb->position, ra->size - rb->size);
}
return;
case QUATERNION: {
Quaternion empty_rot;
const Quaternion *qa = reinterpret_cast<const Quaternion *>(a._data._mem);
const Quaternion *qb = reinterpret_cast<const Quaternion *>(b._data._mem);
r_dst = (*qb).inverse() * *qa;
}
return;
case COLOR: {
const Color *ca = reinterpret_cast<const Color *>(a._data._mem);
const Color *cb = reinterpret_cast<const Color *>(b._data._mem);
float new_r = ca->r - cb->r;
float new_g = ca->g - cb->g;
float new_b = ca->b - cb->b;
float new_a = ca->a - cb->a;
new_r = new_r > 1.0 ? 1.0 : new_r;
new_g = new_g > 1.0 ? 1.0 : new_g;
new_b = new_b > 1.0 ? 1.0 : new_b;
new_a = new_a > 1.0 ? 1.0 : new_a;
r_dst = Color(new_r, new_g, new_b, new_a);
}
return;
default: {
r_dst = a;
}
return;
}
}

void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) {
if (a.type != b.type) {
if (a.is_num() && b.is_num()) {
Expand Down
69 changes: 69 additions & 0 deletions doc/classes/Animation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@
Sets the key identified by [code]key_idx[/code] to value [code]animation[/code]. The [code]track_idx[/code] must be the index of an Animation Track.
</description>
</method>
<method name="audio_track_get_auto_volume" qualifiers="const">
<return type="bool" />
<argument index="0" name="track_idx" type="int" />
<description>
Returns [code]true[/code] if the track at [code]idx[/code] override the volume in [AudioStreamPlayer].
</description>
</method>
<method name="audio_track_get_key_end_offset" qualifiers="const">
<return type="float" />
<argument index="0" name="track_idx" type="int" />
Expand Down Expand Up @@ -103,6 +110,14 @@
[code]stream[/code] is the [AudioStream] resource to play. [code]start_offset[/code] is the number of seconds cut off at the beginning of the audio stream, while [code]end_offset[/code] is at the ending.
</description>
</method>
<method name="audio_track_set_auto_volume">
<return type="void" />
<argument index="0" name="track_idx" type="int" />
<argument index="1" name="enable" type="bool" />
<description>
If [code]true[/code], the track at [code]idx[/code] override the volume in [AudioStreamPlayer].
</description>
</method>
<method name="audio_track_set_key_end_offset">
<return type="void" />
<argument index="0" name="track_idx" type="int" />
Expand Down Expand Up @@ -291,6 +306,13 @@
Returns the arguments values to be called on a method track for a given key in a given track.
</description>
</method>
<method name="position_track_get_retarget_mode" qualifiers="const">
<return type="int" enum="Animation.RetargetMode" />
<argument index="0" name="track_idx" type="int" />
<description>
Returns the retarget mode of a given track.
</description>
</method>
<method name="position_track_insert_key">
<return type="int" />
<argument index="0" name="track_idx" type="int" />
Expand All @@ -299,13 +321,28 @@
<description>
</description>
</method>
<method name="position_track_set_retarget_mode">
<return type="void" />
<argument index="0" name="track_idx" type="int" />
<argument index="1" name="retarget_mode" type="int" enum="Animation.RetargetMode" />
<description>
Sets the retarget mode of a given track.
</description>
</method>
<method name="remove_track">
<return type="void" />
<argument index="0" name="track_idx" type="int" />
<description>
Removes a track by specifying the track index.
</description>
</method>
<method name="rotation_track_get_retarget_mode" qualifiers="const">
<return type="int" enum="Animation.RetargetMode" />
<argument index="0" name="track_idx" type="int" />
<description>
Returns the retarget mode of a given track.
</description>
</method>
<method name="rotation_track_insert_key">
<return type="int" />
<argument index="0" name="track_idx" type="int" />
Expand All @@ -314,6 +351,21 @@
<description>
</description>
</method>
<method name="rotation_track_set_retarget_mode">
<return type="void" />
<argument index="0" name="track_idx" type="int" />
<argument index="1" name="retarget_mode" type="int" enum="Animation.RetargetMode" />
<description>
Sets the retarget mode of a given track.
</description>
</method>
<method name="scale_track_get_retarget_mode" qualifiers="const">
<return type="int" enum="Animation.RetargetMode" />
<argument index="0" name="track_idx" type="int" />
<description>
Returns the retarget mode of a given track.
</description>
</method>
<method name="scale_track_insert_key">
<return type="int" />
<argument index="0" name="track_idx" type="int" />
Expand All @@ -322,6 +374,14 @@
<description>
</description>
</method>
<method name="scale_track_set_retarget_mode">
<return type="void" />
<argument index="0" name="track_idx" type="int" />
<argument index="1" name="retarget_mode" type="int" enum="Animation.RetargetMode" />
<description>
Sets the retarget mode of a given track.
</description>
</method>
<method name="track_find_key" qualifiers="const">
<return type="int" />
<argument index="0" name="track_idx" type="int" />
Expand Down Expand Up @@ -646,5 +706,14 @@
<constant name="HANDLE_MODE_BALANCED" value="1" enum="HandleMode">
Assigning the balanced handle mode to a Bezier Track's keyframe makes it so the two handles of the keyframe always stay aligned when changing either the keyframe's left or right handle.
</constant>
<constant name="RETARGET_MODE_GLOBAL" value="0" enum="RetargetMode">
Retarget the global transform in the model space relative to the bone rest.
</constant>
<constant name="RETARGET_MODE_LOCAL" value="1" enum="RetargetMode">
Retarget the local transform relative to the bone rest.
</constant>
<constant name="RETARGET_MODE_ABSOLUTE" value="2" enum="RetargetMode">
Retarget the local transform relative to the initial value of transform which is [code]Transform()[/code].
</constant>
</constants>
</class>
13 changes: 13 additions & 0 deletions doc/classes/AnimationPlayer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
</method>
<method name="clear_caches">
<return type="void" />
<argument index="0" name="p_emit_signal" type="bool" default="false" />
<description>
[AnimationPlayer] caches animated nodes. It may not notice if a node disappears; [method clear_caches] forces it to update the cache again.
</description>
Expand Down Expand Up @@ -215,6 +216,18 @@
This is used by the editor. If set to [code]true[/code], the scene will be saved with the effects of the reset animation applied (as if it had been seeked to time 0), then reverted after saving.
In other words, the saved scene file will contain the "default pose", as defined by the reset animation, if any, with the editor keeping the values that the nodes had before saving.
</member>
<member name="retarget_map" type="RetargetBoneMap" setter="set_retarget_map" getter="get_retarget_map">
The map used when extracting and applying retarget tracks.
</member>
<member name="retarget_option" type="RetargetBoneOption" setter="set_retarget_option" getter="get_retarget_option">
The option used when extracting retarget tracks.
</member>
<member name="retarget_profile" type="RetargetProfile" setter="set_retarget_profile" getter="get_retarget_profile">
The profile used when editing [RetargetBoneMap] and [RetargetBoneOption].
</member>
<member name="retarget_skeleton" type="NodePath" setter="set_retarget_skeleton" getter="get_retarget_skeleton" default="NodePath(&quot;&quot;)">
The [Skeleton3D] to extract or apply retarget tracks.
</member>
<member name="root_node" type="NodePath" setter="set_root" getter="get_root" default="NodePath(&quot;..&quot;)">
The node from which node path references will travel.
</member>
Expand Down
13 changes: 0 additions & 13 deletions doc/classes/BoneAttachment3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@
Returns the [NodePath] to the external [Skeleton3D] node, if one has been set.
</description>
</method>
<method name="get_override_mode" qualifiers="const">
<return type="int" />
<description>
Returns the override mode for the BoneAttachment3D node.
</description>
</method>
<method name="get_override_pose" qualifiers="const">
<return type="bool" />
<description>
Expand All @@ -48,13 +42,6 @@
Sets the [NodePath] to the external skeleton that the BoneAttachment3D node should use. The external [Skeleton3D] node is only used when [code]use_external_skeleton[/code] is set to [code]true[/code].
</description>
</method>
<method name="set_override_mode">
<return type="void" />
<argument index="0" name="override_mode" type="int" />
<description>
Sets the override mode for the BoneAttachment3D node. The override mode defines which of the bone poses the BoneAttachment3D node will override.
</description>
</method>
<method name="set_override_pose">
<return type="void" />
<argument index="0" name="override_pose" type="bool" />
Expand Down
67 changes: 67 additions & 0 deletions doc/classes/RetargetBoneMap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="RetargetBoneMap" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A map of skeleton bone names with intermediate bone names as key.
</brief_description>
<description>
To register a key in the editor, a [RetargetProfile] is required.
In the inspector, maps are organized by [RetargetProfile], but if there is no [RetargetProfile], they are listed in the unprofiled bones section.
</description>
<tutorials>
</tutorials>
<methods>
<method name="add_key">
<return type="void" />
<argument index="0" name="intermediate_bone_name" type="StringName" />
<description>
</description>
</method>
<method name="find_key" qualifiers="const">
<return type="StringName" />
<argument index="0" name="bone_name" type="StringName" />
<description>
</description>
</method>
<method name="get_bone_name" qualifiers="const">
<return type="StringName" />
<argument index="0" name="intermediate_bone_name" type="StringName" />
<description>
</description>
</method>
<method name="get_keys" qualifiers="const">
<return type="PackedStringArray" />
<description>
</description>
</method>
<method name="has_key">
<return type="bool" />
<argument index="0" name="intermediate_bone_name" type="StringName" />
<description>
</description>
</method>
<method name="remove_key">
<return type="void" />
<argument index="0" name="intermediate_bone_name" type="StringName" />
<description>
</description>
</method>
<method name="set_bone_name">
<return type="void" />
<argument index="0" name="intermediate_bone_name" type="StringName" />
<argument index="1" name="bone_name" type="StringName" />
<description>
</description>
</method>
</methods>
<signals>
<signal name="redraw_needed">
<description>
Emitted when the drawing on the inspector needs to be updated, it is enable only when [code]tools[/code] is enabled.
</description>
</signal>
<signal name="retarget_map_updated">
<description>
</description>
</signal>
</signals>
</class>
Loading

0 comments on commit a72ecb3

Please sign in to comment.