Route onion frame planning through app core
This commit is contained in:
@@ -62,6 +62,14 @@ struct DocumentAnimationOperationPlan {
|
||||
bool resets_playback_timer = false;
|
||||
};
|
||||
|
||||
struct DocumentAnimationOnionFrameRange {
|
||||
int frame_count = 1;
|
||||
int current_frame = 0;
|
||||
int onion_size = 0;
|
||||
int first_frame = 0;
|
||||
int last_frame = 0;
|
||||
};
|
||||
|
||||
class DocumentAnimationServices {
|
||||
public:
|
||||
virtual ~DocumentAnimationServices() = default;
|
||||
@@ -122,6 +130,56 @@ public:
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Result<DocumentAnimationOnionFrameRange> plan_animation_onion_frame_range(
|
||||
int frame_count,
|
||||
int current_frame,
|
||||
int onion_size)
|
||||
{
|
||||
const auto index_status = validate_animation_frame_index(frame_count, current_frame);
|
||||
if (!index_status.ok()) {
|
||||
return pp::foundation::Result<DocumentAnimationOnionFrameRange>::failure(index_status);
|
||||
}
|
||||
|
||||
if (onion_size < 0) {
|
||||
return pp::foundation::Result<DocumentAnimationOnionFrameRange>::failure(
|
||||
pp::foundation::Status::invalid_argument("animation onion size must not be negative"));
|
||||
}
|
||||
|
||||
const auto first = std::max<std::int64_t>(
|
||||
static_cast<std::int64_t>(current_frame) - static_cast<std::int64_t>(onion_size),
|
||||
0);
|
||||
const auto last = std::min<std::int64_t>(
|
||||
static_cast<std::int64_t>(current_frame) + static_cast<std::int64_t>(onion_size),
|
||||
static_cast<std::int64_t>(frame_count) - 1);
|
||||
|
||||
return pp::foundation::Result<DocumentAnimationOnionFrameRange>::success(
|
||||
DocumentAnimationOnionFrameRange {
|
||||
.frame_count = frame_count,
|
||||
.current_frame = current_frame,
|
||||
.onion_size = onion_size,
|
||||
.first_frame = static_cast<int>(first),
|
||||
.last_frame = static_cast<int>(last),
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] inline float animation_onion_frame_alpha(
|
||||
const DocumentAnimationOnionFrameRange& range,
|
||||
int frame) noexcept
|
||||
{
|
||||
if (frame < range.first_frame || frame > range.last_frame) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const int distance = frame >= range.current_frame
|
||||
? frame - range.current_frame
|
||||
: range.current_frame - frame;
|
||||
if (distance > range.onion_size) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return 1.0f - static_cast<float>(distance) / static_cast<float>(range.onion_size + 1);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline pp::foundation::Result<DocumentAnimationOperationPlan> plan_animation_add_frame(
|
||||
int frame_count,
|
||||
int current_frame)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "app_core/canvas_hotkey.h"
|
||||
#include "app_core/canvas_tool_ui.h"
|
||||
#include "app_core/document_animation.h"
|
||||
#include "app.h"
|
||||
#include "legacy_canvas_tool_services.h"
|
||||
#include "legacy_history_services.h"
|
||||
@@ -514,12 +515,17 @@ void NodeCanvas::draw()
|
||||
auto layer_index = i;
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
int onion_size = App::I->animation->get_onion_size();
|
||||
int frame_current = m_canvas->m_layers[layer_index]->m_frame_index;
|
||||
int frame_start = glm::max<int>(frame_current - onion_size, 0);
|
||||
int frame_end = glm::min<int>(frame_current + onion_size, m_canvas->m_layers[layer_index]->frames_count() - 1);
|
||||
const auto onion_range_result = pp::app::plan_animation_onion_frame_range(
|
||||
m_canvas->m_layers[layer_index]->frames_count(),
|
||||
m_canvas->m_layers[layer_index]->m_frame_index,
|
||||
App::I->animation->get_onion_size());
|
||||
if (!onion_range_result) {
|
||||
LOG("NodeCanvas onion frame range failed: %s", onion_range_result.status().message);
|
||||
continue;
|
||||
}
|
||||
const auto onion_range = onion_range_result.value();
|
||||
bool faces = false;
|
||||
for (int frame = frame_start; frame <= frame_end; frame++)
|
||||
for (int frame = onion_range.first_frame; frame <= onion_range.last_frame; frame++)
|
||||
faces |= m_canvas->m_layers[layer_index]->face(plane_index, frame);
|
||||
if (!(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) &&
|
||||
(!m_canvas->m_layers[layer_index]->m_visible ||
|
||||
@@ -557,9 +563,9 @@ void NodeCanvas::draw()
|
||||
m_canvas->m_tmp[plane_index].bindTexture();
|
||||
set_active_texture_unit(2);
|
||||
m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
for (int frame = frame_start; frame <= frame_end; frame++)
|
||||
for (int frame = onion_range.first_frame; frame <= onion_range.last_frame; frame++)
|
||||
{
|
||||
float onion_alpha = 1.f - (float)glm::abs(frame - frame_current) / (float)(onion_size + 1);
|
||||
const float onion_alpha = pp::app::animation_onion_frame_alpha(onion_range, frame);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity* onion_alpha);
|
||||
set_active_texture_unit(0);
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index, frame).bindTexture();
|
||||
@@ -619,9 +625,9 @@ void NodeCanvas::draw()
|
||||
b->m_pattern_texture ?
|
||||
b->m_pattern_texture->bind() :
|
||||
unbind_texture_2d();
|
||||
for (int frame = frame_start; frame <= frame_end; frame++)
|
||||
for (int frame = onion_range.first_frame; frame <= onion_range.last_frame; frame++)
|
||||
{
|
||||
float onion_alpha = 1.f - (float)glm::abs(frame - frame_current) / (float)(onion_size + 1);
|
||||
const float onion_alpha = pp::app::animation_onion_frame_alpha(onion_range, frame);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity * onion_alpha);
|
||||
set_active_texture_unit(0);
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index, frame).bindTexture();
|
||||
@@ -645,9 +651,9 @@ void NodeCanvas::draw()
|
||||
ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index]->m_hightlight);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
|
||||
for (int frame = frame_start; frame <= frame_end; frame++)
|
||||
for (int frame = onion_range.first_frame; frame <= onion_range.last_frame; frame++)
|
||||
{
|
||||
float onion_alpha = 1.f - (float)glm::abs(frame - frame_current) / (float)(onion_size + 1);
|
||||
const float onion_alpha = pp::app::animation_onion_frame_alpha(onion_range, frame);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity * onion_alpha);
|
||||
set_active_texture_unit(0);
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index, frame).bindTexture();
|
||||
|
||||
Reference in New Issue
Block a user