Add inspector plugin for key time edit & Change find key argument
This commit is contained in:
parent
291add339f
commit
060fb2d093
@ -305,9 +305,9 @@
|
||||
<return type="int" />
|
||||
<param index="0" name="track_idx" type="int" />
|
||||
<param index="1" name="time" type="float" />
|
||||
<param index="2" name="exact" type="bool" default="false" />
|
||||
<param index="2" name="find_mode" type="int" enum="Animation.FindMode" default="0" />
|
||||
<description>
|
||||
Finds the key index by time in a given track. Optionally, only find it if the exact time is given.
|
||||
Finds the key index by time in a given track. Optionally, only find it if the approx/exact time is given.
|
||||
</description>
|
||||
</method>
|
||||
<method name="track_get_interpolation_loop_wrap" qualifiers="const">
|
||||
@ -622,5 +622,14 @@
|
||||
<constant name="LOOPED_FLAG_START" value="2" enum="LoopedFlag">
|
||||
This flag indicates that the animation has reached the start of the animation and just after loop processed.
|
||||
</constant>
|
||||
<constant name="FIND_MODE_NEAREST" value="0" enum="FindMode">
|
||||
Finds the nearest time key.
|
||||
</constant>
|
||||
<constant name="FIND_MODE_APPROX" value="1" enum="FindMode">
|
||||
Finds only the key with approximating the time.
|
||||
</constant>
|
||||
<constant name="FIND_MODE_EXACT" value="2" enum="FindMode">
|
||||
Finds only the key with matching the time.
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
||||
|
@ -28,4 +28,26 @@
|
||||
The suffix to display after the value (in a faded color). This should generally be a plural word. You may have to use an abbreviation if the suffix is too long to be displayed.
|
||||
</member>
|
||||
</members>
|
||||
<signals>
|
||||
<signal name="grabbed">
|
||||
<description>
|
||||
Emitted when the spinner/slider is grabbed.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="ungrabbed">
|
||||
<description>
|
||||
Emitted when the spinner/slider is ungrabbed.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="value_focus_entered">
|
||||
<description>
|
||||
Emitted when the value form gains focus.
|
||||
</description>
|
||||
</signal>
|
||||
<signal name="value_focus_exited">
|
||||
<description>
|
||||
Emitted when the value form loses focus.
|
||||
</description>
|
||||
</signal>
|
||||
</signals>
|
||||
</class>
|
||||
|
@ -575,7 +575,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
|
||||
ep.point_rect.size = bezier_icon->get_size();
|
||||
if (selection.has(IntPair(i, j))) {
|
||||
draw_texture(selected_icon, ep.point_rect.position);
|
||||
draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 8), TTR("Time:") + " " + TS->format_number(rtos(Math::snapped(offset, 0.001))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
|
||||
draw_string(font, ep.point_rect.position + Vector2(8, -font->get_height(font_size) - 8), TTR("Time:") + " " + TS->format_number(rtos(Math::snapped(offset, 0.0001))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
|
||||
draw_string(font, ep.point_rect.position + Vector2(8, -8), TTR("Value:") + " " + TS->format_number(rtos(Math::snapped(value, 0.001))), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, accent);
|
||||
} else {
|
||||
Color track_color = Color(1, 1, 1, 1);
|
||||
@ -812,7 +812,7 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = animation->track_find_key(p_track, p_pos, true);
|
||||
int idx = animation->track_find_key(p_track, p_pos, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND(idx < 0);
|
||||
|
||||
selection.insert(IntPair(p_track, idx));
|
||||
@ -1168,8 +1168,8 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||
new_point[4] = 0;
|
||||
|
||||
real_t time = ((mb->get_position().x - limit) / timeline->get_zoom_scale()) + timeline->get_value();
|
||||
while (animation->track_find_key(selected_track, time, true) != -1) {
|
||||
time += 0.001;
|
||||
while (animation->track_find_key(selected_track, time, Animation::FIND_MODE_APPROX) != -1) {
|
||||
time += 0.0001;
|
||||
}
|
||||
|
||||
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
||||
@ -1179,7 +1179,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||
undo_redo->commit_action();
|
||||
|
||||
//then attempt to move
|
||||
int index = animation->track_find_key(selected_track, time, true);
|
||||
int index = animation->track_find_key(selected_track, time, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND(index == -1);
|
||||
_clear_selection();
|
||||
selection.insert(IntPair(selected_track, index));
|
||||
@ -1283,7 +1283,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
|
||||
for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) {
|
||||
real_t newtime = editor->snap_time(animation->track_get_key_time(E->get().first, E->get().second) + moving_selection_offset.x);
|
||||
|
||||
int idx = animation->track_find_key(E->get().first, newtime, true);
|
||||
int idx = animation->track_find_key(E->get().first, newtime, Animation::FIND_MODE_APPROX);
|
||||
if (idx == -1) {
|
||||
continue;
|
||||
}
|
||||
@ -1539,7 +1539,7 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) {
|
||||
|
||||
real_t time = ((menu_insert_key.x - limit) / timeline->get_zoom_scale()) + timeline->get_value();
|
||||
|
||||
while (animation->track_find_key(selected_track, time, true) != -1) {
|
||||
while (animation->track_find_key(selected_track, time, Animation::FIND_MODE_APPROX) != -1) {
|
||||
time += 0.001;
|
||||
}
|
||||
|
||||
@ -1599,7 +1599,7 @@ void AnimationBezierTrackEdit::duplicate_selection() {
|
||||
for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) {
|
||||
real_t t = animation->track_get_key_time(E->get().first, E->get().second);
|
||||
real_t dst_time = t + (timeline->get_play_position() - top_time);
|
||||
int existing_idx = animation->track_find_key(E->get().first, dst_time, true);
|
||||
int existing_idx = animation->track_find_key(E->get().first, dst_time, Animation::FIND_MODE_APPROX);
|
||||
|
||||
undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->get().first, dst_time, animation->track_get_key_value(E->get().first, E->get().second), animation->track_get_key_transition(E->get().first, E->get().second));
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", E->get().first, dst_time);
|
||||
@ -1623,7 +1623,7 @@ void AnimationBezierTrackEdit::duplicate_selection() {
|
||||
int track = E.first;
|
||||
real_t time = E.second;
|
||||
|
||||
int existing_idx = animation->track_find_key(track, time, true);
|
||||
int existing_idx = animation->track_find_key(track, time, Animation::FIND_MODE_APPROX);
|
||||
|
||||
if (existing_idx == -1) {
|
||||
continue;
|
||||
|
@ -48,22 +48,7 @@
|
||||
#include "scene/scene_string_names.h"
|
||||
#include "servers/audio/audio_stream.h"
|
||||
|
||||
class AnimationTrackKeyEdit : public Object {
|
||||
GDCLASS(AnimationTrackKeyEdit, Object);
|
||||
|
||||
public:
|
||||
bool setting = false;
|
||||
bool animation_read_only = false;
|
||||
|
||||
bool _hide_script_from_inspector() { return true; }
|
||||
bool _hide_metadata_from_inspector() { return true; }
|
||||
bool _dont_undo_redo() { return true; }
|
||||
|
||||
bool _is_read_only() {
|
||||
return animation_read_only;
|
||||
}
|
||||
|
||||
static void _bind_methods() {
|
||||
void AnimationTrackKeyEdit::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_update_obj"), &AnimationTrackKeyEdit::_update_obj);
|
||||
ClassDB::bind_method(D_METHOD("_key_ofs_changed"), &AnimationTrackKeyEdit::_key_ofs_changed);
|
||||
ClassDB::bind_method(D_METHOD("_hide_script_from_inspector"), &AnimationTrackKeyEdit::_hide_script_from_inspector);
|
||||
@ -71,9 +56,9 @@ public:
|
||||
ClassDB::bind_method(D_METHOD("get_root_path"), &AnimationTrackKeyEdit::get_root_path);
|
||||
ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &AnimationTrackKeyEdit::_dont_undo_redo);
|
||||
ClassDB::bind_method(D_METHOD("_is_read_only"), &AnimationTrackKeyEdit::_is_read_only);
|
||||
}
|
||||
}
|
||||
|
||||
void _fix_node_path(Variant &value) {
|
||||
void AnimationTrackKeyEdit::_fix_node_path(Variant &value) {
|
||||
NodePath np = value;
|
||||
|
||||
if (np == NodePath()) {
|
||||
@ -89,17 +74,17 @@ public:
|
||||
ERR_FAIL_COND(!edited_node);
|
||||
|
||||
value = edited_node->get_path_to(np_node);
|
||||
}
|
||||
}
|
||||
|
||||
void _update_obj(const Ref<Animation> &p_anim) {
|
||||
void AnimationTrackKeyEdit::_update_obj(const Ref<Animation> &p_anim) {
|
||||
if (setting || animation != p_anim) {
|
||||
return;
|
||||
}
|
||||
|
||||
notify_change();
|
||||
}
|
||||
}
|
||||
|
||||
void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
|
||||
void AnimationTrackKeyEdit::_key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
|
||||
if (animation != p_anim || from != key_ofs) {
|
||||
return;
|
||||
}
|
||||
@ -111,55 +96,13 @@ public:
|
||||
}
|
||||
|
||||
notify_change();
|
||||
}
|
||||
}
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value) {
|
||||
int key = animation->track_find_key(track, key_ofs, true);
|
||||
bool AnimationTrackKeyEdit::_set(const StringName &p_name, const Variant &p_value) {
|
||||
int key = animation->track_find_key(track, key_ofs, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND_V(key == -1, false);
|
||||
|
||||
String name = p_name;
|
||||
if (name == "time" || name == "frame") {
|
||||
float new_time = p_value;
|
||||
|
||||
if (name == "frame") {
|
||||
float fps = animation->get_step();
|
||||
if (fps > 0) {
|
||||
fps = 1.0 / fps;
|
||||
}
|
||||
new_time /= fps;
|
||||
}
|
||||
|
||||
if (new_time == key_ofs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int existing = animation->track_find_key(track, new_time, true);
|
||||
|
||||
setting = true;
|
||||
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
||||
undo_redo->create_action(TTR("Animation Change Keyframe Time"), UndoRedo::MERGE_ENDS);
|
||||
|
||||
Variant val = animation->track_get_key_value(track, key);
|
||||
float trans = animation->track_get_key_transition(track, key);
|
||||
|
||||
undo_redo->add_do_method(animation.ptr(), "track_remove_key", track, key);
|
||||
undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, new_time, val, trans);
|
||||
undo_redo->add_do_method(this, "_key_ofs_changed", animation, key_ofs, new_time);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", track, new_time);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, key_ofs, val, trans);
|
||||
undo_redo->add_undo_method(this, "_key_ofs_changed", animation, new_time, key_ofs);
|
||||
|
||||
if (existing != -1) {
|
||||
Variant v = animation->track_get_key_value(track, existing);
|
||||
trans = animation->track_get_key_transition(track, existing);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, new_time, v, trans);
|
||||
}
|
||||
undo_redo->commit_action();
|
||||
|
||||
setting = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "easing") {
|
||||
float val = p_value;
|
||||
float prev_val = animation->track_get_key_transition(track, key);
|
||||
@ -199,7 +142,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
undo_redo->create_action(vformat(TTR("Anim Change %s"), chan));
|
||||
undo_redo->create_action(vformat(TTR("Animation Change %s"), chan));
|
||||
undo_redo->add_do_method(animation.ptr(), "track_set_key_value", track, key, p_value);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_set_key_value", track, key, old);
|
||||
undo_redo->add_do_method(this, "_update_obj", animation);
|
||||
@ -433,27 +376,13 @@ public:
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const {
|
||||
int key = animation->track_find_key(track, key_ofs, true);
|
||||
bool AnimationTrackKeyEdit::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
int key = animation->track_find_key(track, key_ofs, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND_V(key == -1, false);
|
||||
|
||||
String name = p_name;
|
||||
if (name == "time") {
|
||||
r_ret = key_ofs;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "frame") {
|
||||
float fps = animation->get_step();
|
||||
if (fps > 0) {
|
||||
fps = 1.0 / fps;
|
||||
}
|
||||
r_ret = key_ofs * fps;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "easing") {
|
||||
r_ret = animation->track_get_key_transition(track, key);
|
||||
return true;
|
||||
@ -560,23 +489,17 @@ public:
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const {
|
||||
}
|
||||
|
||||
void AnimationTrackKeyEdit::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
if (animation.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ERR_FAIL_INDEX(track, animation->get_track_count());
|
||||
int key = animation->track_find_key(track, key_ofs, true);
|
||||
int key = animation->track_find_key(track, key_ofs, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND(key == -1);
|
||||
|
||||
if (use_fps && animation->get_step() > 0) {
|
||||
float max_frame = animation->get_length() / animation->get_step();
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("frame"), PROPERTY_HINT_RANGE, "0," + rtos(max_frame) + ",1"));
|
||||
} else {
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("time"), PROPERTY_HINT_RANGE, "0," + rtos(animation->get_length()) + ",0.01"));
|
||||
}
|
||||
|
||||
switch (animation->track_get_type(track)) {
|
||||
case Animation::TYPE_POSITION_3D: {
|
||||
p_list->push_back(PropertyInfo(Variant::VECTOR3, PNAME("position")));
|
||||
@ -654,8 +577,8 @@ public:
|
||||
} break;
|
||||
case Animation::TYPE_AUDIO: {
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("stream"), PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("start_offset"), PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("end_offset"), PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("start_offset"), PROPERTY_HINT_RANGE, "0,3600,0.0001,or_greater"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("end_offset"), PROPERTY_HINT_RANGE, "0,3600,0.0001,or_greater"));
|
||||
|
||||
} break;
|
||||
case Animation::TYPE_ANIMATION: {
|
||||
@ -689,47 +612,22 @@ public:
|
||||
if (animation->track_get_type(track) == Animation::TYPE_VALUE) {
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, PNAME("easing"), PROPERTY_HINT_EXP_EASING));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Animation> animation;
|
||||
int track = -1;
|
||||
float key_ofs = 0;
|
||||
Node *root_path = nullptr;
|
||||
|
||||
PropertyInfo hint;
|
||||
NodePath base;
|
||||
bool use_fps = false;
|
||||
|
||||
void notify_change() {
|
||||
void AnimationTrackKeyEdit::notify_change() {
|
||||
notify_property_list_changed();
|
||||
}
|
||||
}
|
||||
|
||||
Node *get_root_path() {
|
||||
Node *AnimationTrackKeyEdit::get_root_path() {
|
||||
return root_path;
|
||||
}
|
||||
}
|
||||
|
||||
void set_use_fps(bool p_enable) {
|
||||
void AnimationTrackKeyEdit::set_use_fps(bool p_enable) {
|
||||
use_fps = p_enable;
|
||||
notify_property_list_changed();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class AnimationMultiTrackKeyEdit : public Object {
|
||||
GDCLASS(AnimationMultiTrackKeyEdit, Object);
|
||||
|
||||
public:
|
||||
bool setting = false;
|
||||
bool animation_read_only = false;
|
||||
|
||||
bool _hide_script_from_inspector() { return true; }
|
||||
bool _hide_metadata_from_inspector() { return true; }
|
||||
bool _dont_undo_redo() { return true; }
|
||||
|
||||
bool _is_read_only() {
|
||||
return animation_read_only;
|
||||
}
|
||||
|
||||
static void _bind_methods() {
|
||||
void AnimationMultiTrackKeyEdit::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_update_obj"), &AnimationMultiTrackKeyEdit::_update_obj);
|
||||
ClassDB::bind_method(D_METHOD("_key_ofs_changed"), &AnimationMultiTrackKeyEdit::_key_ofs_changed);
|
||||
ClassDB::bind_method(D_METHOD("_hide_script_from_inspector"), &AnimationMultiTrackKeyEdit::_hide_script_from_inspector);
|
||||
@ -737,9 +635,9 @@ public:
|
||||
ClassDB::bind_method(D_METHOD("get_root_path"), &AnimationMultiTrackKeyEdit::get_root_path);
|
||||
ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &AnimationMultiTrackKeyEdit::_dont_undo_redo);
|
||||
ClassDB::bind_method(D_METHOD("_is_read_only"), &AnimationMultiTrackKeyEdit::_is_read_only);
|
||||
}
|
||||
}
|
||||
|
||||
void _fix_node_path(Variant &value, NodePath &base) {
|
||||
void AnimationMultiTrackKeyEdit::_fix_node_path(Variant &value, NodePath &base) {
|
||||
NodePath np = value;
|
||||
|
||||
if (np == NodePath()) {
|
||||
@ -755,17 +653,17 @@ public:
|
||||
ERR_FAIL_COND(!edited_node);
|
||||
|
||||
value = edited_node->get_path_to(np_node);
|
||||
}
|
||||
}
|
||||
|
||||
void _update_obj(const Ref<Animation> &p_anim) {
|
||||
void AnimationMultiTrackKeyEdit::_update_obj(const Ref<Animation> &p_anim) {
|
||||
if (setting || animation != p_anim) {
|
||||
return;
|
||||
}
|
||||
|
||||
notify_change();
|
||||
}
|
||||
}
|
||||
|
||||
void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
|
||||
void AnimationMultiTrackKeyEdit::_key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
|
||||
if (animation != p_anim) {
|
||||
return;
|
||||
}
|
||||
@ -790,53 +688,19 @@ public:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value) {
|
||||
bool AnimationMultiTrackKeyEdit::_set(const StringName &p_name, const Variant &p_value) {
|
||||
bool update_obj = false;
|
||||
bool change_notify_deserved = false;
|
||||
for (const KeyValue<int, List<float>> &E : key_ofs_map) {
|
||||
int track = E.key;
|
||||
for (const float &key_ofs : E.value) {
|
||||
int key = animation->track_find_key(track, key_ofs, true);
|
||||
int key = animation->track_find_key(track, key_ofs, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND_V(key == -1, false);
|
||||
|
||||
String name = p_name;
|
||||
if (name == "time" || name == "frame") {
|
||||
float new_time = p_value;
|
||||
|
||||
if (name == "frame") {
|
||||
float fps = animation->get_step();
|
||||
if (fps > 0) {
|
||||
fps = 1.0 / fps;
|
||||
}
|
||||
new_time /= fps;
|
||||
}
|
||||
|
||||
int existing = animation->track_find_key(track, new_time, true);
|
||||
|
||||
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
||||
if (!setting) {
|
||||
setting = true;
|
||||
undo_redo->create_action(TTR("Animation Multi Change Keyframe Time"), UndoRedo::MERGE_ENDS);
|
||||
}
|
||||
|
||||
Variant val = animation->track_get_key_value(track, key);
|
||||
float trans = animation->track_get_key_transition(track, key);
|
||||
|
||||
undo_redo->add_do_method(animation.ptr(), "track_remove_key", track, key);
|
||||
undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, new_time, val, trans);
|
||||
undo_redo->add_do_method(this, "_key_ofs_changed", animation, key_ofs, new_time);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", track, new_time);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, key_ofs, val, trans);
|
||||
undo_redo->add_undo_method(this, "_key_ofs_changed", animation, new_time, key_ofs);
|
||||
|
||||
if (existing != -1) {
|
||||
Variant v = animation->track_get_key_value(track, existing);
|
||||
trans = animation->track_get_key_transition(track, existing);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, new_time, v, trans);
|
||||
}
|
||||
} else if (name == "easing") {
|
||||
if (name == "easing") {
|
||||
float val = p_value;
|
||||
float prev_val = animation->track_get_key_transition(track, key);
|
||||
|
||||
@ -1079,30 +943,16 @@ public:
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const {
|
||||
bool AnimationMultiTrackKeyEdit::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
for (const KeyValue<int, List<float>> &E : key_ofs_map) {
|
||||
int track = E.key;
|
||||
for (const float &key_ofs : E.value) {
|
||||
int key = animation->track_find_key(track, key_ofs, true);
|
||||
int key = animation->track_find_key(track, key_ofs, Animation::FIND_MODE_APPROX);
|
||||
ERR_CONTINUE(key == -1);
|
||||
|
||||
String name = p_name;
|
||||
if (name == "time") {
|
||||
r_ret = key_ofs;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "frame") {
|
||||
float fps = animation->get_step();
|
||||
if (fps > 0) {
|
||||
fps = 1.0 / fps;
|
||||
}
|
||||
r_ret = key_ofs * fps;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == "easing") {
|
||||
r_ret = animation->track_get_key_transition(track, key);
|
||||
return true;
|
||||
@ -1212,8 +1062,9 @@ public:
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const {
|
||||
}
|
||||
|
||||
void AnimationMultiTrackKeyEdit::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
if (animation.is_null()) {
|
||||
return;
|
||||
}
|
||||
@ -1221,7 +1072,6 @@ public:
|
||||
int first_track = -1;
|
||||
float first_key = -1.0;
|
||||
|
||||
bool show_time = true;
|
||||
bool same_track_type = true;
|
||||
bool same_key_type = true;
|
||||
for (const KeyValue<int, List<float>> &E : key_ofs_map) {
|
||||
@ -1232,10 +1082,6 @@ public:
|
||||
first_track = track;
|
||||
}
|
||||
|
||||
if (show_time && E.value.size() > 1) {
|
||||
show_time = false;
|
||||
}
|
||||
|
||||
if (same_track_type) {
|
||||
if (animation->track_get_type(first_track) != animation->track_get_type(track)) {
|
||||
same_track_type = false;
|
||||
@ -1243,7 +1089,7 @@ public:
|
||||
}
|
||||
|
||||
for (const float &F : E.value) {
|
||||
int key = animation->track_find_key(track, F, true);
|
||||
int key = animation->track_find_key(track, F, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND(key == -1);
|
||||
if (first_key < 0) {
|
||||
first_key = key;
|
||||
@ -1256,15 +1102,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (show_time) {
|
||||
if (use_fps && animation->get_step() > 0) {
|
||||
float max_frame = animation->get_length() / animation->get_step();
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, "frame", PROPERTY_HINT_RANGE, "0," + rtos(max_frame) + ",1"));
|
||||
} else {
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, "time", PROPERTY_HINT_RANGE, "0," + rtos(animation->get_length()) + ",0.01"));
|
||||
}
|
||||
}
|
||||
|
||||
if (same_track_type) {
|
||||
switch (animation->track_get_type(first_track)) {
|
||||
case Animation::TYPE_POSITION_3D: {
|
||||
@ -1339,8 +1176,8 @@ public:
|
||||
} break;
|
||||
case Animation::TYPE_AUDIO: {
|
||||
p_list->push_back(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, "start_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, "end_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, "start_offset", PROPERTY_HINT_RANGE, "0,3600,0.0001,or_greater"));
|
||||
p_list->push_back(PropertyInfo(Variant::FLOAT, "end_offset", PROPERTY_HINT_RANGE, "0,3600,0.0001,or_greater"));
|
||||
} break;
|
||||
case Animation::TYPE_ANIMATION: {
|
||||
if (key_ofs_map.size() > 1) {
|
||||
@ -1373,31 +1210,20 @@ public:
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Animation> animation;
|
||||
|
||||
RBMap<int, List<float>> key_ofs_map;
|
||||
RBMap<int, NodePath> base_map;
|
||||
PropertyInfo hint;
|
||||
|
||||
Node *root_path = nullptr;
|
||||
|
||||
bool use_fps = false;
|
||||
|
||||
void notify_change() {
|
||||
void AnimationMultiTrackKeyEdit::notify_change() {
|
||||
notify_property_list_changed();
|
||||
}
|
||||
}
|
||||
|
||||
Node *get_root_path() {
|
||||
Node *AnimationMultiTrackKeyEdit::get_root_path() {
|
||||
return root_path;
|
||||
}
|
||||
}
|
||||
|
||||
void set_use_fps(bool p_enable) {
|
||||
void AnimationMultiTrackKeyEdit::set_use_fps(bool p_enable) {
|
||||
use_fps = p_enable;
|
||||
notify_property_list_changed();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void AnimationTimelineEdit::_zoom_changed(double) {
|
||||
queue_redraw();
|
||||
@ -1420,7 +1246,7 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) {
|
||||
return;
|
||||
}
|
||||
|
||||
p_new_len = MAX(0.001, p_new_len);
|
||||
p_new_len = MAX(0.0001, p_new_len);
|
||||
if (use_fps && animation->get_step() > 0) {
|
||||
p_new_len *= animation->get_step();
|
||||
}
|
||||
@ -1539,7 +1365,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
|
||||
|
||||
float l = animation->get_length();
|
||||
if (l <= 0) {
|
||||
l = 0.001; // Avoid crashor.
|
||||
l = 0.0001; // Avoid crashor.
|
||||
}
|
||||
|
||||
Ref<Texture2D> hsize_icon = get_theme_icon(SNAME("Hsize"), SNAME("EditorIcons"));
|
||||
@ -1600,7 +1426,7 @@ void AnimationTimelineEdit::_notification(int p_what) {
|
||||
end_px = zoomw;
|
||||
}
|
||||
|
||||
draw_rect(Rect2(Point2(get_name_limit() + begin_px, 0), Point2(end_px - begin_px - 1, h)), timecolor);
|
||||
draw_rect(Rect2(Point2(get_name_limit() + begin_px, 0), Point2(end_px - begin_px, h)), timecolor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1759,7 +1585,7 @@ void AnimationTimelineEdit::update_values() {
|
||||
}
|
||||
} else {
|
||||
length->set_value(animation->get_length());
|
||||
length->set_step(0.001);
|
||||
length->set_step(0.0001);
|
||||
length->set_tooltip_text(TTR("Animation length (seconds)"));
|
||||
time_icon->set_tooltip_text(TTR("Animation length (seconds)"));
|
||||
}
|
||||
@ -1950,9 +1776,9 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
|
||||
time_icon->set_tooltip_text(TTR("Animation length (seconds)"));
|
||||
len_hb->add_child(time_icon);
|
||||
length = memnew(EditorSpinSlider);
|
||||
length->set_min(0.001);
|
||||
length->set_min(0.0001);
|
||||
length->set_max(36000);
|
||||
length->set_step(0.001);
|
||||
length->set_step(0.0001);
|
||||
length->set_allow_greater(true);
|
||||
length->set_custom_minimum_size(Vector2(70 * EDSCALE, 0));
|
||||
length->set_hide_slider(true);
|
||||
@ -2058,7 +1884,7 @@ void AnimationTrackEdit::_notification(int p_what) {
|
||||
} else if (animation->track_get_type(track) == Animation::TYPE_AUDIO) {
|
||||
text = TTR("Audio Clips:");
|
||||
} else if (animation->track_get_type(track) == Animation::TYPE_ANIMATION) {
|
||||
text = TTR("Anim Clips:");
|
||||
text = TTR("Animation Clips:");
|
||||
} else {
|
||||
text += anim_path.get_concatenated_subnames();
|
||||
}
|
||||
@ -2670,7 +2496,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
|
||||
}
|
||||
|
||||
if (key_idx != -1) {
|
||||
String text = TTR("Time (s):") + " " + rtos(animation->track_get_key_time(track, key_idx)) + "\n";
|
||||
String text = TTR("Time (s):") + " " + TS->format_number(rtos(Math::snapped(animation->track_get_key_time(track, key_idx), 0.0001))) + "\n";
|
||||
switch (animation->track_get_type(track)) {
|
||||
case Animation::TYPE_POSITION_3D: {
|
||||
Vector3 t = animation->track_get_key_value(track, key_idx);
|
||||
@ -4390,7 +4216,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
|
||||
p_next_tracks.normal++;
|
||||
} else {
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", p_id.track_idx, time);
|
||||
int existing = animation->track_find_key(p_id.track_idx, time, true);
|
||||
int existing = animation->track_find_key(p_id.track_idx, time, Animation::FIND_MODE_APPROX);
|
||||
if (existing != -1) {
|
||||
Variant v = animation->track_get_key_value(p_id.track_idx, existing);
|
||||
float trans = animation->track_get_key_transition(p_id.track_idx, existing);
|
||||
@ -5005,8 +4831,8 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
|
||||
if (snap->is_pressed() && step->get_value() != 0) {
|
||||
p_ofs = snap_time(p_ofs);
|
||||
}
|
||||
while (animation->track_find_key(p_track, p_ofs, true) != -1) { // Make sure insertion point is valid.
|
||||
p_ofs += 0.001;
|
||||
while (animation->track_find_key(p_track, p_ofs, Animation::FIND_MODE_APPROX) != -1) { // Make sure insertion point is valid.
|
||||
p_ofs += 0.0001;
|
||||
}
|
||||
|
||||
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
||||
@ -5338,7 +5164,7 @@ void AnimationTrackEditor::_select_at_anim(const Ref<Animation> &p_anim, int p_t
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = animation->track_find_key(p_track, p_pos, true);
|
||||
int idx = animation->track_find_key(p_track, p_pos, Animation::FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND(idx < 0);
|
||||
|
||||
SelectedKey sk;
|
||||
@ -5365,7 +5191,7 @@ void AnimationTrackEditor::_move_selection_commit() {
|
||||
// 2 - Remove overlapped keys.
|
||||
for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
|
||||
float newtime = snap_time(E->get().pos + motion);
|
||||
int idx = animation->track_find_key(E->key().track, newtime, true);
|
||||
int idx = animation->track_find_key(E->key().track, newtime, Animation::FIND_MODE_APPROX);
|
||||
if (idx == -1) {
|
||||
continue;
|
||||
}
|
||||
@ -5625,7 +5451,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int existing_idx = animation->track_find_key(dst_track, dst_time, true);
|
||||
int existing_idx = animation->track_find_key(dst_track, dst_time, Animation::FIND_MODE_APPROX);
|
||||
|
||||
undo_redo->add_do_method(animation.ptr(), "track_insert_key", dst_track, dst_time, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", dst_track, dst_time);
|
||||
@ -5916,7 +5742,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
|
||||
// 2 - Remove overlapped keys.
|
||||
for (RBMap<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
|
||||
float newtime = (E->get().pos - from_t) * s + from_t;
|
||||
int idx = animation->track_find_key(E->key().track, newtime, true);
|
||||
int idx = animation->track_find_key(E->key().track, newtime, Animation::FIND_MODE_APPROX);
|
||||
if (idx == -1) {
|
||||
continue;
|
||||
}
|
||||
@ -6127,7 +5953,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
|
||||
undo_redo->add_do_method(reset.ptr(), "track_set_path", dst_track, path);
|
||||
undo_redo->add_undo_method(reset.ptr(), "remove_track", dst_track);
|
||||
} else {
|
||||
existing_idx = reset->track_find_key(dst_track, 0, true);
|
||||
existing_idx = reset->track_find_key(dst_track, 0, Animation::FIND_MODE_APPROX);
|
||||
}
|
||||
|
||||
undo_redo->add_do_method(reset.ptr(), "track_insert_key", dst_track, 0, animation->track_get_key_value(sk.track, sk.key), animation->track_get_key_transition(sk.track, sk.key));
|
||||
@ -6656,7 +6482,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
|
||||
step = memnew(EditorSpinSlider);
|
||||
step->set_min(0);
|
||||
step->set_max(1000000);
|
||||
step->set_step(0.001);
|
||||
step->set_step(0.0001);
|
||||
step->set_hide_slider(true);
|
||||
step->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
|
||||
step->set_tooltip_text(TTR("Animation step value."));
|
||||
@ -6946,3 +6772,103 @@ AnimationTrackEditor::~AnimationTrackEditor() {
|
||||
memdelete(multi_key_edit);
|
||||
}
|
||||
}
|
||||
|
||||
// AnimationTrackKeyEditEditorPlugin
|
||||
|
||||
void AnimationTrackKeyEditEditor::_time_edit_entered() {
|
||||
int key = animation->track_find_key(track, key_ofs, Animation::FIND_MODE_APPROX);
|
||||
if (key == -1) {
|
||||
return;
|
||||
}
|
||||
key_data_cache.time = animation->track_get_key_time(track, key);
|
||||
key_data_cache.transition = animation->track_get_key_transition(track, key);
|
||||
key_data_cache.value = animation->track_get_key_value(track, key);
|
||||
}
|
||||
|
||||
void AnimationTrackKeyEditEditor::_time_edit_exited() {
|
||||
real_t new_time = spinner->get_value();
|
||||
|
||||
if (use_fps) {
|
||||
real_t fps = animation->get_step();
|
||||
if (fps > 0) {
|
||||
fps = 1.0 / fps;
|
||||
}
|
||||
new_time /= fps;
|
||||
}
|
||||
|
||||
if (Math::is_equal_approx(new_time, key_data_cache.time)) {
|
||||
return; // No change.
|
||||
}
|
||||
|
||||
int existing = animation->track_find_key(track, new_time, Animation::FIND_MODE_APPROX);
|
||||
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
||||
undo_redo->create_action(TTR("Animation Change Keyframe Time"), UndoRedo::MERGE_ENDS);
|
||||
|
||||
if (existing != -1) {
|
||||
undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_time", track, animation->track_get_key_time(track, existing));
|
||||
}
|
||||
undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_time", track, key_data_cache.time);
|
||||
undo_redo->add_do_method(animation.ptr(), "track_insert_key", track, new_time, key_data_cache.value, key_data_cache.transition);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", track, new_time);
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, key_data_cache.time, key_data_cache.value, key_data_cache.transition);
|
||||
if (existing != -1) {
|
||||
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, animation->track_get_key_time(track, existing), animation->track_get_key_value(track, existing), animation->track_get_key_transition(track, existing));
|
||||
}
|
||||
|
||||
// Reselect key.
|
||||
AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
|
||||
if (ape) {
|
||||
AnimationTrackEditor *ate = ape->get_track_editor();
|
||||
if (ate) {
|
||||
undo_redo->add_do_method(ate, "_clear_selection_for_anim", animation);
|
||||
undo_redo->add_undo_method(ate, "_clear_selection_for_anim", animation);
|
||||
undo_redo->add_do_method(ate, "_select_at_anim", animation, track, new_time);
|
||||
undo_redo->add_undo_method(ate, "_select_at_anim", animation, track, key_data_cache.time);
|
||||
}
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
AnimationTrackKeyEditEditor::AnimationTrackKeyEditEditor(Ref<Animation> p_animation, int p_track, real_t p_key_ofs, bool p_use_fps) {
|
||||
if (!p_animation.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
animation = p_animation;
|
||||
track = p_track;
|
||||
key_ofs = p_key_ofs;
|
||||
use_fps = p_use_fps;
|
||||
|
||||
set_label("Time");
|
||||
|
||||
spinner = memnew(EditorSpinSlider);
|
||||
spinner->set_focus_mode(Control::FOCUS_CLICK);
|
||||
spinner->set_min(0);
|
||||
spinner->set_allow_greater(true);
|
||||
spinner->set_allow_lesser(true);
|
||||
|
||||
if (use_fps) {
|
||||
spinner->set_step(1);
|
||||
spinner->set_hide_slider(true);
|
||||
real_t fps = animation->get_step();
|
||||
if (fps > 0) {
|
||||
fps = 1.0 / fps;
|
||||
}
|
||||
spinner->set_value(key_ofs * fps);
|
||||
} else {
|
||||
spinner->set_step(0.0001);
|
||||
spinner->set_value(key_ofs);
|
||||
spinner->set_max(animation->get_length());
|
||||
}
|
||||
|
||||
add_child(spinner);
|
||||
|
||||
spinner->connect("grabbed", callable_mp(this, &AnimationTrackKeyEditEditor::_time_edit_entered), CONNECT_DEFERRED);
|
||||
spinner->connect("ungrabbed", callable_mp(this, &AnimationTrackKeyEditEditor::_time_edit_exited), CONNECT_DEFERRED);
|
||||
spinner->connect("value_focus_entered", callable_mp(this, &AnimationTrackKeyEditEditor::_time_edit_entered), CONNECT_DEFERRED);
|
||||
spinner->connect("value_focus_exited", callable_mp(this, &AnimationTrackKeyEditEditor::_time_edit_exited), CONNECT_DEFERRED);
|
||||
}
|
||||
|
||||
AnimationTrackKeyEditEditor::~AnimationTrackKeyEditEditor() {
|
||||
}
|
||||
|
@ -50,9 +50,83 @@
|
||||
#include "scene/resources/animation.h"
|
||||
#include "scene_tree_editor.h"
|
||||
|
||||
class AnimationTrackEditor;
|
||||
class AnimationTrackEdit;
|
||||
class ViewPanner;
|
||||
|
||||
class AnimationTrackKeyEdit : public Object {
|
||||
GDCLASS(AnimationTrackKeyEdit, Object);
|
||||
|
||||
public:
|
||||
bool setting = false;
|
||||
bool animation_read_only = false;
|
||||
|
||||
Ref<Animation> animation;
|
||||
int track = -1;
|
||||
float key_ofs = 0;
|
||||
Node *root_path = nullptr;
|
||||
|
||||
PropertyInfo hint;
|
||||
NodePath base;
|
||||
bool use_fps = false;
|
||||
|
||||
bool _hide_script_from_inspector() { return true; }
|
||||
bool _hide_metadata_from_inspector() { return true; }
|
||||
bool _dont_undo_redo() { return true; }
|
||||
|
||||
bool _is_read_only() { return animation_read_only; }
|
||||
|
||||
void notify_change();
|
||||
Node *get_root_path();
|
||||
void set_use_fps(bool p_enable);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _fix_node_path(Variant &value);
|
||||
void _update_obj(const Ref<Animation> &p_anim);
|
||||
void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to);
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
};
|
||||
|
||||
class AnimationMultiTrackKeyEdit : public Object {
|
||||
GDCLASS(AnimationMultiTrackKeyEdit, Object);
|
||||
|
||||
public:
|
||||
bool setting = false;
|
||||
bool animation_read_only = false;
|
||||
|
||||
Ref<Animation> animation;
|
||||
|
||||
RBMap<int, List<float>> key_ofs_map;
|
||||
RBMap<int, NodePath> base_map;
|
||||
PropertyInfo hint;
|
||||
|
||||
Node *root_path = nullptr;
|
||||
|
||||
bool use_fps = false;
|
||||
|
||||
bool _hide_script_from_inspector() { return true; }
|
||||
bool _hide_metadata_from_inspector() { return true; }
|
||||
bool _dont_undo_redo() { return true; }
|
||||
|
||||
bool _is_read_only() { return animation_read_only; }
|
||||
|
||||
void notify_change();
|
||||
Node *get_root_path();
|
||||
void set_use_fps(bool p_enable);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _fix_node_path(Variant &value, NodePath &base);
|
||||
void _update_obj(const Ref<Animation> &p_anim);
|
||||
void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to);
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
};
|
||||
|
||||
class AnimationTimelineEdit : public Range {
|
||||
GDCLASS(AnimationTimelineEdit, Range);
|
||||
|
||||
@ -129,8 +203,6 @@ public:
|
||||
AnimationTimelineEdit();
|
||||
};
|
||||
|
||||
class AnimationTrackEditor;
|
||||
|
||||
class AnimationTrackEdit : public Control {
|
||||
GDCLASS(AnimationTrackEdit, Control);
|
||||
friend class AnimationTimelineEdit;
|
||||
@ -592,4 +664,30 @@ public:
|
||||
~AnimationTrackEditor();
|
||||
};
|
||||
|
||||
// AnimationTrackKeyEditEditorPlugin
|
||||
|
||||
class AnimationTrackKeyEditEditor : public EditorProperty {
|
||||
GDCLASS(AnimationTrackKeyEditEditor, EditorProperty);
|
||||
|
||||
Ref<Animation> animation;
|
||||
int track = -1;
|
||||
real_t key_ofs = 0.0;
|
||||
bool use_fps = false;
|
||||
|
||||
EditorSpinSlider *spinner = nullptr;
|
||||
|
||||
struct KeyDataCache {
|
||||
real_t time = 0.0;
|
||||
float transition = 0.0;
|
||||
Variant value;
|
||||
} key_data_cache;
|
||||
|
||||
void _time_edit_entered();
|
||||
void _time_edit_exited();
|
||||
|
||||
public:
|
||||
AnimationTrackKeyEditEditor(Ref<Animation> p_animation, int p_track, real_t p_key_ofs, bool p_use_fps);
|
||||
~AnimationTrackKeyEditEditor();
|
||||
};
|
||||
|
||||
#endif // ANIMATION_TRACK_EDITOR_H
|
||||
|
@ -831,8 +831,8 @@ Rect2 AnimationTrackEditTypeAudio::get_key_rect(int p_index, float p_pixels_sec)
|
||||
|
||||
len -= end_ofs;
|
||||
len -= start_ofs;
|
||||
if (len <= 0.001) {
|
||||
len = 0.001;
|
||||
if (len <= 0.0001) {
|
||||
len = 0.0001;
|
||||
}
|
||||
|
||||
if (get_animation()->track_get_key_count(get_track()) > p_index + 1) {
|
||||
@ -887,8 +887,8 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
|
||||
len -= end_ofs;
|
||||
len -= start_ofs;
|
||||
|
||||
if (len <= 0.001) {
|
||||
len = 0.001;
|
||||
if (len <= 0.0001) {
|
||||
len = 0.0001;
|
||||
}
|
||||
|
||||
int pixel_len = len * p_pixels_sec;
|
||||
@ -1014,8 +1014,8 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant
|
||||
|
||||
ofs = get_editor()->snap_time(ofs);
|
||||
|
||||
while (get_animation()->track_find_key(get_track(), ofs, true) != -1) { //make sure insertion point is valid
|
||||
ofs += 0.001;
|
||||
while (get_animation()->track_find_key(get_track(), ofs, Animation::FIND_MODE_APPROX) != -1) { //make sure insertion point is valid
|
||||
ofs += 0.0001;
|
||||
}
|
||||
|
||||
Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo();
|
||||
|
@ -7262,6 +7262,7 @@ EditorNode::EditorNode() {
|
||||
gui_base->add_child(disk_changed);
|
||||
|
||||
add_editor_plugin(memnew(AnimationPlayerEditorPlugin));
|
||||
add_editor_plugin(memnew(AnimationTrackKeyEditEditorPlugin));
|
||||
add_editor_plugin(memnew(CanvasItemEditorPlugin));
|
||||
add_editor_plugin(memnew(Node3DEditorPlugin));
|
||||
add_editor_plugin(memnew(ScriptEditorPlugin));
|
||||
|
@ -1384,10 +1384,11 @@ void EditorPropertyInteger::update_property() {
|
||||
void EditorPropertyInteger::_bind_methods() {
|
||||
}
|
||||
|
||||
void EditorPropertyInteger::setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_allow_greater, bool p_allow_lesser, const String &p_suffix) {
|
||||
void EditorPropertyInteger::setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_hide_slider, bool p_allow_greater, bool p_allow_lesser, const String &p_suffix) {
|
||||
spin->set_min(p_min);
|
||||
spin->set_max(p_max);
|
||||
spin->set_step(p_step);
|
||||
spin->set_hide_slider(p_hide_slider);
|
||||
spin->set_allow_greater(p_allow_greater);
|
||||
spin->set_allow_lesser(p_allow_lesser);
|
||||
spin->set_suffix(p_suffix);
|
||||
@ -2242,12 +2243,11 @@ void EditorPropertyVector2i::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_hide_slider, bool p_link, const String &p_suffix) {
|
||||
void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_link, const String &p_suffix) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
spin[i]->set_min(p_min);
|
||||
spin[i]->set_max(p_max);
|
||||
spin[i]->set_step(1);
|
||||
spin[i]->set_hide_slider(p_hide_slider);
|
||||
spin[i]->set_allow_greater(true);
|
||||
spin[i]->set_allow_lesser(true);
|
||||
spin[i]->set_suffix(p_suffix);
|
||||
@ -2352,12 +2352,11 @@ void EditorPropertyRect2i::_notification(int p_what) {
|
||||
void EditorPropertyRect2i::_bind_methods() {
|
||||
}
|
||||
|
||||
void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_hide_slider, const String &p_suffix) {
|
||||
void EditorPropertyRect2i::setup(int p_min, int p_max, const String &p_suffix) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
spin[i]->set_min(p_min);
|
||||
spin[i]->set_max(p_max);
|
||||
spin[i]->set_step(1);
|
||||
spin[i]->set_hide_slider(p_hide_slider);
|
||||
spin[i]->set_allow_greater(true);
|
||||
spin[i]->set_allow_lesser(true);
|
||||
spin[i]->set_suffix(p_suffix);
|
||||
@ -2496,12 +2495,12 @@ void EditorPropertyVector3i::_notification(int p_what) {
|
||||
void EditorPropertyVector3i::_bind_methods() {
|
||||
}
|
||||
|
||||
void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_hide_slider, bool p_link, const String &p_suffix) {
|
||||
void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_link, const String &p_suffix) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
spin[i]->set_min(p_min);
|
||||
spin[i]->set_max(p_max);
|
||||
spin[i]->set_step(1);
|
||||
spin[i]->set_hide_slider(p_hide_slider);
|
||||
spin[i]->set_hide_slider(false);
|
||||
spin[i]->set_allow_greater(true);
|
||||
spin[i]->set_allow_lesser(true);
|
||||
spin[i]->set_suffix(p_suffix);
|
||||
@ -3004,11 +3003,11 @@ void EditorPropertyVector4i::_notification(int p_what) {
|
||||
void EditorPropertyVector4i::_bind_methods() {
|
||||
}
|
||||
|
||||
void EditorPropertyVector4i::setup(double p_min, double p_max, bool p_hide_slider, const String &p_suffix) {
|
||||
void EditorPropertyVector4i::setup(double p_min, double p_max, const String &p_suffix) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
spin[i]->set_min(p_min);
|
||||
spin[i]->set_max(p_max);
|
||||
spin[i]->set_hide_slider(p_hide_slider);
|
||||
spin[i]->set_step(1);
|
||||
spin[i]->set_allow_greater(true);
|
||||
spin[i]->set_allow_lesser(true);
|
||||
spin[i]->set_suffix(p_suffix);
|
||||
@ -4347,7 +4346,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
||||
EditorPropertyInteger *editor = memnew(EditorPropertyInteger);
|
||||
|
||||
EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1);
|
||||
editor->setup(hint.min, hint.max, hint.step, hint.or_greater, hint.or_less, hint.suffix);
|
||||
editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.or_greater, hint.or_less, hint.suffix);
|
||||
|
||||
return editor;
|
||||
}
|
||||
@ -4475,7 +4474,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
||||
case Variant::VECTOR2I: {
|
||||
EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i(p_wide));
|
||||
EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1);
|
||||
editor->setup(hint.min, hint.max, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix);
|
||||
editor->setup(hint.min, hint.max, p_hint == PROPERTY_HINT_LINK, hint.suffix);
|
||||
return editor;
|
||||
|
||||
} break;
|
||||
@ -4488,7 +4487,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
||||
case Variant::RECT2I: {
|
||||
EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i(p_wide));
|
||||
EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1);
|
||||
editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix);
|
||||
editor->setup(hint.min, hint.max, hint.suffix);
|
||||
|
||||
return editor;
|
||||
} break;
|
||||
@ -4502,7 +4501,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
||||
case Variant::VECTOR3I: {
|
||||
EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i(p_wide));
|
||||
EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1);
|
||||
editor->setup(hint.min, hint.max, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix);
|
||||
editor->setup(hint.min, hint.max, p_hint == PROPERTY_HINT_LINK, hint.suffix);
|
||||
return editor;
|
||||
|
||||
} break;
|
||||
@ -4516,7 +4515,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
||||
case Variant::VECTOR4I: {
|
||||
EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i);
|
||||
EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1);
|
||||
editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix);
|
||||
editor->setup(hint.min, hint.max, hint.suffix);
|
||||
return editor;
|
||||
|
||||
} break;
|
||||
|
@ -378,7 +378,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void update_property() override;
|
||||
void setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_allow_greater, bool p_allow_lesser, const String &p_suffix = String());
|
||||
void setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_hide_slider, bool p_allow_greater, bool p_allow_lesser, const String &p_suffix = String());
|
||||
EditorPropertyInteger();
|
||||
};
|
||||
|
||||
@ -566,7 +566,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void update_property() override;
|
||||
void setup(int p_min, int p_max, bool p_hide_slider, bool p_link = false, const String &p_suffix = String());
|
||||
void setup(int p_min, int p_max, bool p_link = false, const String &p_suffix = String());
|
||||
EditorPropertyVector2i(bool p_force_wide = false);
|
||||
};
|
||||
|
||||
@ -583,7 +583,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void update_property() override;
|
||||
void setup(int p_min, int p_max, bool p_hide_slider, const String &p_suffix = String());
|
||||
void setup(int p_min, int p_max, const String &p_suffix = String());
|
||||
EditorPropertyRect2i(bool p_force_wide = false);
|
||||
};
|
||||
|
||||
@ -608,7 +608,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void update_property() override;
|
||||
void setup(int p_min, int p_max, bool p_hide_slider, bool p_link = false, const String &p_suffix = String());
|
||||
void setup(int p_min, int p_max, bool p_link = false, const String &p_suffix = String());
|
||||
EditorPropertyVector3i(bool p_force_wide = false);
|
||||
};
|
||||
|
||||
@ -693,7 +693,7 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void update_property() override;
|
||||
void setup(double p_min, double p_max, bool p_hide_slider, const String &p_suffix = String());
|
||||
void setup(double p_min, double p_max, const String &p_suffix = String());
|
||||
EditorPropertyVector4i();
|
||||
};
|
||||
|
||||
|
@ -919,7 +919,7 @@ void EditorPropertyDictionary::update_property() {
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
EditorPropertyInteger *editor = memnew(EditorPropertyInteger);
|
||||
editor->setup(-100000, 100000, 1, true, true);
|
||||
editor->setup(-100000, 100000, 1, false, true, true);
|
||||
prop = editor;
|
||||
|
||||
} break;
|
||||
@ -942,7 +942,7 @@ void EditorPropertyDictionary::update_property() {
|
||||
} break;
|
||||
case Variant::VECTOR2I: {
|
||||
EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i);
|
||||
editor->setup(-100000, 100000, true);
|
||||
editor->setup(-100000, 100000);
|
||||
prop = editor;
|
||||
|
||||
} break;
|
||||
@ -954,7 +954,7 @@ void EditorPropertyDictionary::update_property() {
|
||||
} break;
|
||||
case Variant::RECT2I: {
|
||||
EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i);
|
||||
editor->setup(-100000, 100000, true);
|
||||
editor->setup(-100000, 100000);
|
||||
prop = editor;
|
||||
|
||||
} break;
|
||||
@ -966,7 +966,7 @@ void EditorPropertyDictionary::update_property() {
|
||||
} break;
|
||||
case Variant::VECTOR3I: {
|
||||
EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i);
|
||||
editor->setup(-100000, 100000, true);
|
||||
editor->setup(-100000, 100000);
|
||||
prop = editor;
|
||||
|
||||
} break;
|
||||
@ -978,7 +978,7 @@ void EditorPropertyDictionary::update_property() {
|
||||
} break;
|
||||
case Variant::VECTOR4I: {
|
||||
EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i);
|
||||
editor->setup(-100000, 100000, true);
|
||||
editor->setup(-100000, 100000);
|
||||
prop = editor;
|
||||
|
||||
} break;
|
||||
|
@ -76,6 +76,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
|
||||
pre_grab_value = get_value();
|
||||
grabbing_spinner = false;
|
||||
grabbing_spinner_mouse_pos = get_global_mouse_position();
|
||||
emit_signal("grabbed");
|
||||
}
|
||||
} else {
|
||||
if (grabbing_spinner_attempt) {
|
||||
@ -83,6 +84,7 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
|
||||
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
|
||||
Input::get_singleton()->warp_mouse(grabbing_spinner_mouse_pos);
|
||||
queue_redraw();
|
||||
emit_signal("ungrabbed");
|
||||
} else {
|
||||
_focus_entered();
|
||||
}
|
||||
@ -178,9 +180,11 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
|
||||
grabbing_ratio = get_as_ratio();
|
||||
grabbing_from = grabber->get_transform().xform(mb->get_position()).x;
|
||||
}
|
||||
emit_signal("grabbed");
|
||||
} else {
|
||||
grabbing_grabber = false;
|
||||
mousewheel_over_grabber = false;
|
||||
emit_signal("ungrabbed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,10 +303,6 @@ void EditorSpinSlider::_draw_spin_slider() {
|
||||
|
||||
Ref<Texture2D> updown = get_theme_icon(is_read_only() ? SNAME("updown_disabled") : SNAME("updown"), SNAME("SpinBox"));
|
||||
|
||||
if (get_step() == 1) {
|
||||
number_width -= updown->get_width();
|
||||
}
|
||||
|
||||
String numstr = get_text_value();
|
||||
|
||||
int vofs = (size.height - font->get_height(font_size)) / 2 + font->get_ascent(font_size);
|
||||
@ -359,7 +359,9 @@ void EditorSpinSlider::_draw_spin_slider() {
|
||||
}
|
||||
TS->free_rid(num_rid);
|
||||
|
||||
if (!hide_slider) {
|
||||
if (get_step() == 1) {
|
||||
number_width -= updown->get_width();
|
||||
Ref<Texture2D> updown2 = get_theme_icon(is_read_only() ? SNAME("updown_disabled") : SNAME("updown"), SNAME("SpinBox"));
|
||||
int updown_vofs = (size.height - updown2->get_height()) / 2;
|
||||
if (rtl) {
|
||||
@ -375,7 +377,7 @@ void EditorSpinSlider::_draw_spin_slider() {
|
||||
if (grabber->is_visible()) {
|
||||
grabber->hide();
|
||||
}
|
||||
} else if (!hide_slider) {
|
||||
} else {
|
||||
const int grabber_w = 4 * EDSCALE;
|
||||
const int width = size.width - sb->get_minimum_size().width - grabber_w;
|
||||
const int ofs = sb->get_offset().x;
|
||||
@ -431,6 +433,7 @@ void EditorSpinSlider::_draw_spin_slider() {
|
||||
grabber_range = width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorSpinSlider::_notification(int p_what) {
|
||||
@ -584,6 +587,8 @@ void EditorSpinSlider::_value_focus_exited() {
|
||||
//enter, click, esc
|
||||
grab_focus();
|
||||
}
|
||||
|
||||
emit_signal("value_focus_exited");
|
||||
}
|
||||
|
||||
void EditorSpinSlider::_grabber_mouse_entered() {
|
||||
@ -627,6 +632,7 @@ void EditorSpinSlider::_focus_entered() {
|
||||
value_input->call_deferred(SNAME("select_all"));
|
||||
value_input->set_focus_next(find_next_valid_focus()->get_path());
|
||||
value_input->set_focus_previous(find_prev_valid_focus()->get_path());
|
||||
emit_signal("value_focus_entered");
|
||||
}
|
||||
|
||||
void EditorSpinSlider::_bind_methods() {
|
||||
@ -650,6 +656,11 @@ void EditorSpinSlider::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_slider"), "set_hide_slider", "is_hiding_slider");
|
||||
|
||||
ADD_SIGNAL(MethodInfo("grabbed"));
|
||||
ADD_SIGNAL(MethodInfo("ungrabbed"));
|
||||
ADD_SIGNAL(MethodInfo("value_focus_entered"));
|
||||
ADD_SIGNAL(MethodInfo("value_focus_exited"));
|
||||
}
|
||||
|
||||
void EditorSpinSlider::_ensure_input_popup() {
|
||||
|
@ -87,13 +87,13 @@ void AnimationPlayerEditor::_notification(int p_what) {
|
||||
}
|
||||
frame->set_value(player->get_current_animation_position());
|
||||
track_editor->set_anim_pos(player->get_current_animation_position());
|
||||
|
||||
} else if (!player->is_valid()) {
|
||||
// Reset timeline when the player has been stopped externally
|
||||
frame->set_value(0);
|
||||
} else if (last_active) {
|
||||
// Need the last frame after it stopped.
|
||||
frame->set_value(player->get_current_animation_position());
|
||||
track_editor->set_anim_pos(player->get_current_animation_position());
|
||||
}
|
||||
|
||||
last_active = player->is_playing();
|
||||
@ -423,7 +423,7 @@ void AnimationPlayerEditor::_select_anim_by_name(const String &p_anim) {
|
||||
_animation_selected(idx);
|
||||
}
|
||||
|
||||
double AnimationPlayerEditor::_get_editor_step() const {
|
||||
float AnimationPlayerEditor::_get_editor_step() const {
|
||||
// Returns the effective snapping value depending on snapping modifiers, or 0 if snapping is disabled.
|
||||
if (track_editor->is_snap_enabled()) {
|
||||
const String current = player->get_assigned_animation();
|
||||
@ -434,7 +434,7 @@ double AnimationPlayerEditor::_get_editor_step() const {
|
||||
return Input::get_singleton()->is_key_pressed(Key::SHIFT) ? anim->get_step() * 0.25 : anim->get_step();
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void AnimationPlayerEditor::_animation_name_edited() {
|
||||
@ -1973,3 +1973,26 @@ AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin() {
|
||||
|
||||
AnimationPlayerEditorPlugin::~AnimationPlayerEditorPlugin() {
|
||||
}
|
||||
|
||||
// AnimationTrackKeyEditEditorPlugin
|
||||
|
||||
bool EditorInspectorPluginAnimationTrackKeyEdit::can_handle(Object *p_object) {
|
||||
return Object::cast_to<AnimationTrackKeyEdit>(p_object) != nullptr;
|
||||
}
|
||||
|
||||
void EditorInspectorPluginAnimationTrackKeyEdit::parse_begin(Object *p_object) {
|
||||
AnimationTrackKeyEdit *atk = Object::cast_to<AnimationTrackKeyEdit>(p_object);
|
||||
ERR_FAIL_COND(!atk);
|
||||
|
||||
atk_editor = memnew(AnimationTrackKeyEditEditor(atk->animation, atk->track, atk->key_ofs, atk->use_fps));
|
||||
add_custom_control(atk_editor);
|
||||
}
|
||||
|
||||
AnimationTrackKeyEditEditorPlugin::AnimationTrackKeyEditEditorPlugin() {
|
||||
atk_plugin = memnew(EditorInspectorPluginAnimationTrackKeyEdit);
|
||||
EditorInspector::add_inspector_plugin(atk_plugin);
|
||||
}
|
||||
|
||||
bool AnimationTrackKeyEditEditorPlugin::handles(Object *p_object) const {
|
||||
return p_object->is_class("AnimationTrackKeyEdit");
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ class AnimationPlayerEditor : public VBoxContainer {
|
||||
} onion;
|
||||
|
||||
void _select_anim_by_name(const String &p_anim);
|
||||
double _get_editor_step() const;
|
||||
float _get_editor_step() const;
|
||||
void _play_pressed();
|
||||
void _play_from_pressed();
|
||||
void _play_bw_pressed();
|
||||
@ -272,4 +272,30 @@ public:
|
||||
~AnimationPlayerEditorPlugin();
|
||||
};
|
||||
|
||||
// AnimationTrackKeyEditEditorPlugin
|
||||
|
||||
class EditorInspectorPluginAnimationTrackKeyEdit : public EditorInspectorPlugin {
|
||||
GDCLASS(EditorInspectorPluginAnimationTrackKeyEdit, EditorInspectorPlugin);
|
||||
|
||||
AnimationTrackKeyEditEditor *atk_editor = nullptr;
|
||||
|
||||
public:
|
||||
virtual bool can_handle(Object *p_object) override;
|
||||
virtual void parse_begin(Object *p_object) override;
|
||||
};
|
||||
|
||||
class AnimationTrackKeyEditEditorPlugin : public EditorPlugin {
|
||||
GDCLASS(AnimationTrackKeyEditEditorPlugin, EditorPlugin);
|
||||
|
||||
EditorInspectorPluginAnimationTrackKeyEdit *atk_plugin = nullptr;
|
||||
|
||||
public:
|
||||
bool has_main_screen() const override { return false; }
|
||||
virtual bool handles(Object *p_object) const override;
|
||||
|
||||
virtual String get_name() const override { return "AnimationTrackKeyEdit"; }
|
||||
|
||||
AnimationTrackKeyEditEditorPlugin();
|
||||
};
|
||||
|
||||
#endif // ANIMATION_PLAYER_EDITOR_PLUGIN_H
|
||||
|
@ -483,7 +483,7 @@ void EditorPropertyOTVariation::update_property() {
|
||||
Vector3i range = supported.get_value_at_index(i);
|
||||
|
||||
EditorPropertyInteger *prop = memnew(EditorPropertyInteger);
|
||||
prop->setup(range.x, range.y, 1, false, false);
|
||||
prop->setup(range.x, range.y, false, 1, false, false);
|
||||
prop->set_object_and_property(object.ptr(), "keys/" + itos(name_tag));
|
||||
|
||||
String name = TS->tag_to_name(name_tag);
|
||||
@ -762,7 +762,7 @@ void EditorPropertyOTFeatures::update_property() {
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
EditorPropertyInteger *editor = memnew(EditorPropertyInteger);
|
||||
editor->setup(0, 255, 1, false, false);
|
||||
editor->setup(0, 255, 1, false, false, false);
|
||||
prop = editor;
|
||||
} break;
|
||||
default: {
|
||||
|
@ -398,7 +398,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() {
|
||||
source_from_property_editor->connect("property_changed", callable_mp(this, &TileProxiesManagerDialog::_property_changed));
|
||||
source_from_property_editor->set_selectable(false);
|
||||
source_from_property_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
source_from_property_editor->setup(-1, 99999, 1, true, false);
|
||||
source_from_property_editor->setup(-1, 99999, 1, false, true, false);
|
||||
vboxcontainer_from->add_child(source_from_property_editor);
|
||||
|
||||
coords_from_property_editor = memnew(EditorPropertyVector2i);
|
||||
@ -417,7 +417,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() {
|
||||
alternative_from_property_editor->connect("property_changed", callable_mp(this, &TileProxiesManagerDialog::_property_changed));
|
||||
alternative_from_property_editor->set_selectable(false);
|
||||
alternative_from_property_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
alternative_from_property_editor->setup(-1, 99999, 1, true, false);
|
||||
alternative_from_property_editor->setup(-1, 99999, 1, false, true, false);
|
||||
alternative_from_property_editor->hide();
|
||||
vboxcontainer_from->add_child(alternative_from_property_editor);
|
||||
|
||||
@ -432,7 +432,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() {
|
||||
source_to_property_editor->connect("property_changed", callable_mp(this, &TileProxiesManagerDialog::_property_changed));
|
||||
source_to_property_editor->set_selectable(false);
|
||||
source_to_property_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
source_to_property_editor->setup(-1, 99999, 1, true, false);
|
||||
source_to_property_editor->setup(-1, 99999, 1, false, true, false);
|
||||
vboxcontainer_to->add_child(source_to_property_editor);
|
||||
|
||||
coords_to_property_editor = memnew(EditorPropertyVector2i);
|
||||
@ -451,7 +451,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() {
|
||||
alternative_to_property_editor->connect("property_changed", callable_mp(this, &TileProxiesManagerDialog::_property_changed));
|
||||
alternative_to_property_editor->set_selectable(false);
|
||||
alternative_to_property_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
alternative_to_property_editor->setup(-1, 99999, 1, true, false);
|
||||
alternative_to_property_editor->setup(-1, 99999, 1, false, true, false);
|
||||
alternative_to_property_editor->hide();
|
||||
vboxcontainer_to->add_child(alternative_to_property_editor);
|
||||
|
||||
|
@ -691,7 +691,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
||||
}
|
||||
} else {
|
||||
if (p_started) {
|
||||
int first_key = a->track_find_key(i, p_prev_time, true);
|
||||
int first_key = a->track_find_key(i, p_prev_time, Animation::FIND_MODE_EXACT);
|
||||
if (first_key >= 0) {
|
||||
indices.push_back(first_key);
|
||||
}
|
||||
@ -761,7 +761,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
||||
}
|
||||
} else {
|
||||
if (p_started) {
|
||||
int first_key = a->track_find_key(i, p_prev_time, true);
|
||||
int first_key = a->track_find_key(i, p_prev_time, Animation::FIND_MODE_EXACT);
|
||||
if (first_key >= 0) {
|
||||
indices.push_back(first_key);
|
||||
}
|
||||
@ -855,7 +855,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
||||
//find stuff to play
|
||||
List<int> to_play;
|
||||
if (p_started) {
|
||||
int first_key = a->track_find_key(i, p_prev_time, true);
|
||||
int first_key = a->track_find_key(i, p_prev_time, Animation::FIND_MODE_EXACT);
|
||||
if (first_key >= 0) {
|
||||
to_play.push_back(first_key);
|
||||
}
|
||||
@ -968,7 +968,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
||||
//find stuff to play
|
||||
List<int> to_play;
|
||||
if (p_started) {
|
||||
int first_key = a->track_find_key(i, p_prev_time, true);
|
||||
int first_key = a->track_find_key(i, p_prev_time, Animation::FIND_MODE_EXACT);
|
||||
if (first_key >= 0) {
|
||||
to_play.push_back(first_key);
|
||||
}
|
||||
|
@ -1383,7 +1383,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||
}
|
||||
} else {
|
||||
if (seeked) {
|
||||
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
|
||||
if (idx < 0) {
|
||||
continue;
|
||||
}
|
||||
@ -1406,7 +1406,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||
TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
|
||||
|
||||
if (seeked) {
|
||||
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
|
||||
if (idx < 0) {
|
||||
continue;
|
||||
}
|
||||
@ -1440,7 +1440,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||
|
||||
if (seeked) {
|
||||
//find whatever should be playing
|
||||
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
|
||||
if (idx < 0) {
|
||||
continue;
|
||||
}
|
||||
@ -1553,7 +1553,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||
|
||||
if (seeked) {
|
||||
//seek
|
||||
int idx = a->track_find_key(i, time, !is_external_seeking);
|
||||
int idx = a->track_find_key(i, time, is_external_seeking ? Animation::FIND_MODE_NEAREST : Animation::FIND_MODE_EXACT);
|
||||
if (idx < 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1319,7 +1319,7 @@ Error Animation::blend_shape_track_interpolate(int p_track, double p_time, float
|
||||
}
|
||||
|
||||
void Animation::track_remove_key_at_time(int p_track, double p_time) {
|
||||
int idx = track_find_key(p_track, p_time, true);
|
||||
int idx = track_find_key(p_track, p_time, FIND_MODE_APPROX);
|
||||
ERR_FAIL_COND(idx < 0);
|
||||
track_remove_key(p_track, idx);
|
||||
}
|
||||
@ -1400,7 +1400,7 @@ void Animation::track_remove_key(int p_track, int p_idx) {
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
int Animation::track_find_key(int p_track, double p_time, FindMode p_find_mode) const {
|
||||
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
|
||||
Track *t = tracks[p_track];
|
||||
|
||||
@ -1416,7 +1416,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
uint32_t key_index;
|
||||
bool fetch_compressed_success = _fetch_compressed<3>(tt->compressed_track, p_time, key, time, key_next, time_next, &key_index);
|
||||
ERR_FAIL_COND_V(!fetch_compressed_success, -1);
|
||||
if (p_exact && time != p_time) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return key_index;
|
||||
@ -1426,7 +1426,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= tt->positions.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (tt->positions[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(tt->positions[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && tt->positions[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1443,7 +1443,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
uint32_t key_index;
|
||||
bool fetch_compressed_success = _fetch_compressed<3>(rt->compressed_track, p_time, key, time, key_next, time_next, &key_index);
|
||||
ERR_FAIL_COND_V(!fetch_compressed_success, -1);
|
||||
if (p_exact && time != p_time) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return key_index;
|
||||
@ -1453,7 +1453,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= rt->rotations.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (rt->rotations[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(rt->rotations[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && rt->rotations[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1470,7 +1470,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
uint32_t key_index;
|
||||
bool fetch_compressed_success = _fetch_compressed<3>(st->compressed_track, p_time, key, time, key_next, time_next, &key_index);
|
||||
ERR_FAIL_COND_V(!fetch_compressed_success, -1);
|
||||
if (p_exact && time != p_time) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return key_index;
|
||||
@ -1480,7 +1480,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= st->scales.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (st->scales[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(st->scales[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && st->scales[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1497,7 +1497,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
uint32_t key_index;
|
||||
bool fetch_compressed_success = _fetch_compressed<1>(bst->compressed_track, p_time, key, time, key_next, time_next, &key_index);
|
||||
ERR_FAIL_COND_V(!fetch_compressed_success, -1);
|
||||
if (p_exact && time != p_time) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(time, p_time)) || (p_find_mode == FIND_MODE_EXACT && time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return key_index;
|
||||
@ -1507,7 +1507,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= bst->blend_shapes.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (bst->blend_shapes[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(bst->blend_shapes[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && bst->blend_shapes[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1519,7 +1519,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= vt->values.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (vt->values[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(vt->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && vt->values[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1531,7 +1531,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= mt->methods.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (mt->methods[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(mt->methods[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && mt->methods[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1543,7 +1543,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= bt->values.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (bt->values[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(bt->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && bt->values[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1555,7 +1555,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= at->values.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (at->values[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(at->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && at->values[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -1567,7 +1567,7 @@ int Animation::track_find_key(int p_track, double p_time, bool p_exact) const {
|
||||
if (k < 0 || k >= at->values.size()) {
|
||||
return -1;
|
||||
}
|
||||
if (at->values[k].time != p_time && p_exact) {
|
||||
if ((p_find_mode == FIND_MODE_APPROX && !Math::is_equal_approx(at->values[k].time, p_time)) || (p_find_mode == FIND_MODE_EXACT && at->values[k].time != p_time)) {
|
||||
return -1;
|
||||
}
|
||||
return k;
|
||||
@ -2944,12 +2944,12 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
||||
// Not from_time > to_time but most recent of looping...
|
||||
if (p_looped_flag != Animation::LOOPED_FLAG_NONE) {
|
||||
if (!is_backward && Math::is_equal_approx(from_time, 0)) {
|
||||
int edge = track_find_key(p_track, 0, true);
|
||||
int edge = track_find_key(p_track, 0, FIND_MODE_EXACT);
|
||||
if (edge >= 0) {
|
||||
p_indices->push_back(edge);
|
||||
}
|
||||
} else if (is_backward && Math::is_equal_approx(to_time, length)) {
|
||||
int edge = track_find_key(p_track, length, true);
|
||||
int edge = track_find_key(p_track, length, FIND_MODE_EXACT);
|
||||
if (edge >= 0) {
|
||||
p_indices->push_back(edge);
|
||||
}
|
||||
@ -2971,7 +2971,7 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
||||
const PositionTrack *tt = static_cast<const PositionTrack *>(t);
|
||||
if (tt->compressed_track >= 0) {
|
||||
_get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, from_time, p_indices);
|
||||
_get_compressed_key_indices_in_range<3>(tt->compressed_track, CMP_EPSILON, to_time, p_indices);
|
||||
_get_compressed_key_indices_in_range<3>(tt->compressed_track, 0, to_time, p_indices);
|
||||
} else {
|
||||
_track_get_key_indices_in_range(tt->positions, 0, from_time, p_indices, true);
|
||||
_track_get_key_indices_in_range(tt->positions, 0, to_time, p_indices, false);
|
||||
@ -2981,7 +2981,7 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
||||
const RotationTrack *rt = static_cast<const RotationTrack *>(t);
|
||||
if (rt->compressed_track >= 0) {
|
||||
_get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, from_time, p_indices);
|
||||
_get_compressed_key_indices_in_range<3>(rt->compressed_track, CMP_EPSILON, to_time, p_indices);
|
||||
_get_compressed_key_indices_in_range<3>(rt->compressed_track, 0, to_time, p_indices);
|
||||
} else {
|
||||
_track_get_key_indices_in_range(rt->rotations, 0, from_time, p_indices, true);
|
||||
_track_get_key_indices_in_range(rt->rotations, 0, to_time, p_indices, false);
|
||||
@ -3072,7 +3072,7 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
||||
const BlendShapeTrack *bst = static_cast<const BlendShapeTrack *>(t);
|
||||
if (bst->compressed_track >= 0) {
|
||||
_get_compressed_key_indices_in_range<1>(bst->compressed_track, from_time, length, p_indices);
|
||||
_get_compressed_key_indices_in_range<1>(bst->compressed_track, to_time, length - CMP_EPSILON, p_indices);
|
||||
_get_compressed_key_indices_in_range<1>(bst->compressed_track, to_time, length, p_indices);
|
||||
} else {
|
||||
_track_get_key_indices_in_range(bst->blend_shapes, from_time, length, p_indices, false);
|
||||
_track_get_key_indices_in_range(bst->blend_shapes, to_time, length, p_indices, true);
|
||||
@ -3109,9 +3109,9 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
|
||||
|
||||
// The edge will be pingponged in the next frame and processed there, so let's ignore it now...
|
||||
if (!is_backward && Math::is_equal_approx(to_time, length)) {
|
||||
to_time = length - CMP_EPSILON;
|
||||
to_time -= CMP_EPSILON;
|
||||
} else if (is_backward && Math::is_equal_approx(from_time, 0)) {
|
||||
from_time = CMP_EPSILON;
|
||||
from_time += CMP_EPSILON;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
@ -3818,7 +3818,7 @@ void Animation::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("track_get_key_count", "track_idx"), &Animation::track_get_key_count);
|
||||
ClassDB::bind_method(D_METHOD("track_get_key_value", "track_idx", "key_idx"), &Animation::track_get_key_value);
|
||||
ClassDB::bind_method(D_METHOD("track_get_key_time", "track_idx", "key_idx"), &Animation::track_get_key_time);
|
||||
ClassDB::bind_method(D_METHOD("track_find_key", "track_idx", "time", "exact"), &Animation::track_find_key, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("track_find_key", "track_idx", "time", "find_mode"), &Animation::track_find_key, DEFVAL(FIND_MODE_NEAREST));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("track_set_interpolation_type", "track_idx", "interpolation"), &Animation::track_set_interpolation_type);
|
||||
ClassDB::bind_method(D_METHOD("track_get_interpolation_type", "track_idx"), &Animation::track_get_interpolation_type);
|
||||
@ -3905,6 +3905,10 @@ void Animation::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(LOOPED_FLAG_NONE);
|
||||
BIND_ENUM_CONSTANT(LOOPED_FLAG_END);
|
||||
BIND_ENUM_CONSTANT(LOOPED_FLAG_START);
|
||||
|
||||
BIND_ENUM_CONSTANT(FIND_MODE_NEAREST);
|
||||
BIND_ENUM_CONSTANT(FIND_MODE_APPROX);
|
||||
BIND_ENUM_CONSTANT(FIND_MODE_EXACT);
|
||||
}
|
||||
|
||||
void Animation::clear() {
|
||||
|
@ -79,6 +79,12 @@ public:
|
||||
LOOPED_FLAG_START,
|
||||
};
|
||||
|
||||
enum FindMode {
|
||||
FIND_MODE_NEAREST,
|
||||
FIND_MODE_APPROX,
|
||||
FIND_MODE_EXACT,
|
||||
};
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
enum HandleMode {
|
||||
HANDLE_MODE_FREE,
|
||||
@ -392,7 +398,7 @@ public:
|
||||
void track_set_key_transition(int p_track, int p_key_idx, real_t p_transition);
|
||||
void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value);
|
||||
void track_set_key_time(int p_track, int p_key_idx, double p_time);
|
||||
int track_find_key(int p_track, double p_time, bool p_exact = false) const;
|
||||
int track_find_key(int p_track, double p_time, FindMode p_find_mode = FIND_MODE_NEAREST) const;
|
||||
void track_remove_key(int p_track, int p_idx);
|
||||
void track_remove_key_at_time(int p_track, double p_time);
|
||||
int track_get_key_count(int p_track) const;
|
||||
@ -489,6 +495,7 @@ VARIANT_ENUM_CAST(Animation::InterpolationType);
|
||||
VARIANT_ENUM_CAST(Animation::UpdateMode);
|
||||
VARIANT_ENUM_CAST(Animation::LoopMode);
|
||||
VARIANT_ENUM_CAST(Animation::LoopedFlag);
|
||||
VARIANT_ENUM_CAST(Animation::FindMode);
|
||||
#ifdef TOOLS_ENABLED
|
||||
VARIANT_ENUM_CAST(Animation::HandleMode);
|
||||
VARIANT_ENUM_CAST(Animation::HandleSetMode);
|
||||
|
Loading…
Reference in New Issue
Block a user