summaryrefslogtreecommitdiff
path: root/scene/resources/animation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/animation.cpp')
-rw-r--r--scene/resources/animation.cpp85
1 files changed, 62 insertions, 23 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index b371266c83..bfbc92a8d4 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -127,6 +127,10 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
}
}
return true;
+ } else if (what == "use_blend") {
+ if (track_get_type(track) == TYPE_AUDIO) {
+ audio_track_set_use_blend(track, p_value);
+ }
} else if (what == "interp") {
track_set_interpolation_type(track, InterpolationType(p_value.operator int()));
} else if (what == "loop_wrap") {
@@ -528,7 +532,10 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
}
return true;
-
+ } else if (what == "use_blend") {
+ if (track_get_type(track) == TYPE_AUDIO) {
+ r_ret = audio_track_is_use_blend(track);
+ }
} else if (what == "interp") {
r_ret = track_get_interpolation_type(track);
} else if (what == "loop_wrap") {
@@ -834,6 +841,9 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/loop_wrap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::ARRAY, "tracks/" + itos(i) + "/keys", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
}
+ if (track_get_type(i) == TYPE_AUDIO) {
+ p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/use_blend", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL));
+ }
}
}
@@ -3581,6 +3591,27 @@ real_t Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
return at->values[p_key].value.end_offset;
}
+void Animation::audio_track_set_use_blend(int p_track, bool p_enable) {
+ ERR_FAIL_INDEX(p_track, tracks.size());
+ Track *t = tracks[p_track];
+ ERR_FAIL_COND(t->type != TYPE_AUDIO);
+
+ AudioTrack *at = static_cast<AudioTrack *>(t);
+
+ at->use_blend = p_enable;
+ emit_changed();
+}
+
+bool Animation::audio_track_is_use_blend(int p_track) const {
+ ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
+ Track *t = tracks[p_track];
+ ERR_FAIL_COND_V(t->type != TYPE_AUDIO, false);
+
+ AudioTrack *at = static_cast<AudioTrack *>(t);
+
+ return at->use_blend;
+}
+
//
int Animation::animation_track_insert_key(int p_track, double p_time, const StringName &p_animation) {
@@ -3813,6 +3844,8 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("audio_track_get_key_stream", "track_idx", "key_idx"), &Animation::audio_track_get_key_stream);
ClassDB::bind_method(D_METHOD("audio_track_get_key_start_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_start_offset);
ClassDB::bind_method(D_METHOD("audio_track_get_key_end_offset", "track_idx", "key_idx"), &Animation::audio_track_get_key_end_offset);
+ ClassDB::bind_method(D_METHOD("audio_track_set_use_blend", "track_idx", "enable"), &Animation::audio_track_set_use_blend);
+ ClassDB::bind_method(D_METHOD("audio_track_is_use_blend", "track_idx"), &Animation::audio_track_is_use_blend);
ClassDB::bind_method(D_METHOD("animation_track_insert_key", "track_idx", "time", "animation"), &Animation::animation_track_insert_key);
ClassDB::bind_method(D_METHOD("animation_track_set_key_animation", "track_idx", "key_idx", "animation"), &Animation::animation_track_set_key_animation);
@@ -4691,6 +4724,7 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
data_tracks.resize(tracks_to_compress.size());
time_tracks.resize(tracks_to_compress.size());
+ uint32_t needed_min_page_size = base_page_size;
for (uint32_t i = 0; i < data_tracks.size(); i++) {
data_tracks[i].split_tolerance = p_split_tolerance;
if (track_get_type(tracks_to_compress[i]) == TYPE_BLEND_SHAPE) {
@@ -4698,7 +4732,12 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
} else {
data_tracks[i].components = 3;
}
+ needed_min_page_size += data_tracks[i].data.size() + data_tracks[i].get_temp_packet_size();
}
+ for (uint32_t i = 0; i < time_tracks.size(); i++) {
+ needed_min_page_size += time_tracks[i].packets.size() * 4; // time packet is 32 bits
+ }
+ ERR_FAIL_COND_MSG(p_page_size < needed_min_page_size, "Cannot compress with the given page size");
while (true) {
// Begin by finding the keyframe in all tracks with the time closest to the current time
@@ -4754,17 +4793,17 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
// The frame has advanced, time to validate the previous frame
uint32_t current_page_size = base_page_size;
- for (uint32_t i = 0; i < data_tracks.size(); i++) {
- uint32_t track_size = data_tracks[i].data.size(); // track size
- track_size += data_tracks[i].get_temp_packet_size(); // Add the temporary data
+ for (const AnimationCompressionDataState &state : data_tracks) {
+ uint32_t track_size = state.data.size(); // track size
+ track_size += state.get_temp_packet_size(); // Add the temporary data
if (track_size > Compression::MAX_DATA_TRACK_SIZE) {
rollback = true; //track to large, time track can't point to keys any longer, because key offset is 12 bits
break;
}
current_page_size += track_size;
}
- for (uint32_t i = 0; i < time_tracks.size(); i++) {
- current_page_size += time_tracks[i].packets.size() * 4; // time packet is 32 bits
+ for (const AnimationCompressionTimeState &state : time_tracks) {
+ current_page_size += state.packets.size() * 4; // time packet is 32 bits
}
if (!rollback && current_page_size > p_page_size) {
@@ -4776,22 +4815,22 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
if (rollback) {
// Not valid any longer, so rollback and commit page
- for (uint32_t i = 0; i < data_tracks.size(); i++) {
- data_tracks[i].temp_packets.resize(data_tracks[i].validated_packet_count);
+ for (AnimationCompressionDataState &state : data_tracks) {
+ state.temp_packets.resize(state.validated_packet_count);
}
- for (uint32_t i = 0; i < time_tracks.size(); i++) {
- time_tracks[i].key_index = time_tracks[i].validated_key_index; //rollback key
- time_tracks[i].packets.resize(time_tracks[i].validated_packet_count);
+ for (AnimationCompressionTimeState &state : time_tracks) {
+ state.key_index = state.validated_key_index; //rollback key
+ state.packets.resize(state.validated_packet_count);
}
} else {
// All valid, so save rollback information
- for (uint32_t i = 0; i < data_tracks.size(); i++) {
- data_tracks[i].validated_packet_count = data_tracks[i].temp_packets.size();
+ for (AnimationCompressionDataState &state : data_tracks) {
+ state.validated_packet_count = state.temp_packets.size();
}
- for (uint32_t i = 0; i < time_tracks.size(); i++) {
- time_tracks[i].validated_key_index = time_tracks[i].key_index;
- time_tracks[i].validated_packet_count = time_tracks[i].packets.size();
+ for (AnimationCompressionTimeState &state : time_tracks) {
+ state.validated_key_index = state.key_index;
+ state.validated_packet_count = state.packets.size();
}
// Accept this frame as the frame being processed (as long as it exists)
@@ -4976,8 +5015,8 @@ void Animation::compress(uint32_t p_page_size, uint32_t p_fps, float p_split_tol
}
uint32_t new_size = 0;
- for (uint32_t i = 0; i < compression.pages.size(); i++) {
- new_size += compression.pages[i].data.size();
+ for (const Compression::Page &page : compression.pages) {
+ new_size += page.data.size();
}
print_line("Original size: " + itos(orig_size) + " - Compressed size: " + itos(new_size) + " " + String::num(float(new_size) / float(orig_size) * 100, 2) + "% pages: " + itos(compression.pages.size()));
@@ -5289,8 +5328,8 @@ int Animation::_get_compressed_key_count(uint32_t p_compressed_track) const {
int key_count = 0;
- for (uint32_t i = 0; i < compression.pages.size(); i++) {
- const uint8_t *page_data = compression.pages[i].data.ptr();
+ for (const Compression::Page &page : compression.pages) {
+ const uint8_t *page_data = page.data.ptr();
// Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
@@ -5323,8 +5362,8 @@ bool Animation::_fetch_compressed_by_index(uint32_t p_compressed_track, int p_in
ERR_FAIL_COND_V(!compression.enabled, false);
ERR_FAIL_UNSIGNED_INDEX_V(p_compressed_track, compression.bounds.size(), false);
- for (uint32_t i = 0; i < compression.pages.size(); i++) {
- const uint8_t *page_data = compression.pages[i].data.ptr();
+ for (const Compression::Page &page : compression.pages) {
+ const uint8_t *page_data = page.data.ptr();
// Little endian assumed. No major big endian hardware exists any longer, but in case it does it will need to be supported.
const uint32_t *indices = (const uint32_t *)page_data;
const uint16_t *time_keys = (const uint16_t *)&page_data[indices[p_compressed_track * 3 + 0]];
@@ -5374,7 +5413,7 @@ bool Animation::_fetch_compressed_by_index(uint32_t p_compressed_track, int p_in
}
}
- r_time = compression.pages[i].time_offset + double(frame) / double(compression.fps);
+ r_time = page.time_offset + double(frame) / double(compression.fps);
for (uint32_t l = 0; l < COMPONENTS; l++) {
r_value[l] = decode[l];
}