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 Mar 10, 2022
1 parent 7866c98 commit 13fe177
Show file tree
Hide file tree
Showing 47 changed files with 5,983 additions and 504 deletions.
8 changes: 8 additions & 0 deletions core/extension/gdnative_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,13 @@ static GDNativeBool gdnative_variant_booleanize(const GDNativeVariantPtr p_self)
return self->booleanize();
}

static void gdnative_variant_sub(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, GDNativeVariantPtr r_dst) {
const Variant *a = (const Variant *)p_a;
const Variant *b = (const Variant *)p_b;
memnew_placement(r_dst, Variant);
Variant::sub(*a, *b, *(Variant *)r_dst);
}

static void gdnative_variant_blend(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst) {
const Variant *a = (const Variant *)p_a;
const Variant *b = (const Variant *)p_b;
Expand Down Expand Up @@ -925,6 +932,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.variant_iter_get = gdnative_variant_iter_get;
gdni.variant_hash_compare = gdnative_variant_hash_compare;
gdni.variant_booleanize = gdnative_variant_booleanize;
gdni.variant_sub = gdnative_variant_sub;
gdni.variant_blend = gdnative_variant_blend;
gdni.variant_interpolate = gdnative_variant_interpolate;
gdni.variant_duplicate = gdnative_variant_duplicate;
Expand Down
1 change: 1 addition & 0 deletions core/extension/gdnative_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ typedef struct {
void (*variant_iter_get)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_iter, GDNativeVariantPtr r_ret, GDNativeBool *r_valid);
GDNativeBool (*variant_hash_compare)(const GDNativeVariantPtr p_self, const GDNativeVariantPtr p_other);
GDNativeBool (*variant_booleanize)(const GDNativeVariantPtr p_self);
void (*variant_sub)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, GDNativeVariantPtr r_dst);
void (*variant_blend)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst);
void (*variant_interpolate)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst);
void (*variant_duplicate)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep);
Expand Down
19 changes: 19 additions & 0 deletions core/math/quaternion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ Quaternion Quaternion::inverse() const {
return Quaternion(-x, -y, -z, w);
}

Quaternion Quaternion::log() const {
Quaternion src = *this;
Vector3 src_v = src.get_axis() * src.get_angle();
return Quaternion(src_v.x, src_v.y, src_v.z, 0);
}

Quaternion Quaternion::exp() const {
Quaternion src = *this;
Vector3 src_v = Vector3(src.x, src.y, src.z);
float theta = src_v.length();
if (theta < CMP_EPSILON) {
return Quaternion(0, 0, 0, 1);
}
return Quaternion(src_v.normalized(), theta);
}

Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) const {
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
Expand Down Expand Up @@ -190,6 +206,9 @@ Quaternion::operator String() const {
}

Vector3 Quaternion::get_axis() const {
if (Math::abs(w) > 1 - CMP_EPSILON) {
return Vector3(x, y, z);
}
real_t r = ((real_t)1) / Math::sqrt(1 - w * w);
return Vector3(x * r, y * r, z * r);
}
Expand Down
2 changes: 2 additions & 0 deletions core/math/quaternion.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ struct _NO_DISCARD_ Quaternion {
Quaternion normalized() const;
bool is_normalized() const;
Quaternion inverse() const;
Quaternion log() const;
Quaternion exp() const;
_FORCE_INLINE_ real_t dot(const Quaternion &p_q) const;
real_t angle_to(const Quaternion &p_to) const;

Expand Down
1 change: 1 addition & 0 deletions core/variant/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,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
2 changes: 2 additions & 0 deletions core/variant/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,8 @@ static void _register_variant_builtin_methods() {
bind_method(Quaternion, is_normalized, sarray(), varray());
bind_method(Quaternion, is_equal_approx, sarray("to"), varray());
bind_method(Quaternion, inverse, sarray(), varray());
bind_method(Quaternion, log, sarray(), varray());
bind_method(Quaternion, exp, sarray(), varray());
bind_method(Quaternion, angle_to, sarray("to"), varray());
bind_method(Quaternion, dot, sarray("with"), varray());
bind_method(Quaternion, slerp, sarray("to", "weight"), varray());
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
10 changes: 10 additions & 0 deletions doc/classes/Quaternion.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@
Returns the dot product of two quaternions.
</description>
</method>
<method name="exp" qualifiers="const">
<return type="Quaternion" />
<description>
</description>
</method>
<method name="get_angle" qualifiers="const">
<return type="float" />
<description>
Expand Down Expand Up @@ -138,6 +143,11 @@
Returns the length of the quaternion, squared.
</description>
</method>
<method name="log" qualifiers="const">
<return type="Quaternion" />
<description>
</description>
</method>
<method name="normalized" qualifiers="const">
<return type="Quaternion" />
<description>
Expand Down
Loading

0 comments on commit 13fe177

Please sign in to comment.