#pragma once #include #include #include #include #include #include "../base/Memory.h" #include "global.h" #include "../primitive/Color_Bar.h" #include "../primitive/Color_Scale.h" namespace renderive { class Frequency_Axis; class Afterglow_Plot; struct Afterglow_Private; /// @brief 残影频谱图元,按强度衰减显示历史能量。 class LIB_DECL Afterglow : public Renderable { public: /// @brief 创建残影频谱图元。 Afterglow(); /// @brief 绑定频率轴。 PROP(std::shared_ptr, frequency_axis) /// @brief 绑定功率轴。 PROP(std::shared_ptr, power_axis) /// @brief 频率数据范围。 PROP(Range, frequency_range) /// @brief 功率数据范围。 PROP(Range, power_range) /// @brief 每帧频率采样点数。 PROP(int, frequency_point_size) /// @brief 功率方向采样点数。 PROP(int, power_point_size) /// @brief 残影累计缓冲大小。 /// @brief 是否在功率方向做线性补点。 PROP(bool, interpolate) /// @brief 历史残影衰减率。 PROP(double, attenuation_rate) /// @brief 初始强度累计阈值。 PROP(int, init_strong_value) /// @brief 颜色映射表。 PROP(Color_Map, color_map) /// @brief 返回构造时启用的颜色条。 std::shared_ptr color_bar() const; /// @brief 写入一帧功率数据。 void append_spectrum(std::span power_range_data); /// @brief 移动写入一帧功率数据。 void append_spectrum(std::pmr::vector&& power_range_data); /// @brief 用 writer 填充并写入一帧功率数据。 template void write_data(std::size_t count, Writer&& writer) { std::pmr::vector values(memory_resource(Memory_Domain::Afterglow)); values.resize(count); std::forward(writer)(std::span(values.data(), values.size())); append_spectrum(std::move(values)); } template struct Builder_T; struct Builder; private: Afterglow_Private* d(); Render_Object_Owner create_render_data() override; Render_Object_Owner create_render_state() override; Render_Object_Owner create_input_data() override; }; struct Afterglow_Prop { std::weak_ptr frequency_axis{}; std::weak_ptr power_axis{}; Range frequency_range{0, 10}; int frequency_bin_count{}; int power_bin_count{}; bool interpolate_power_bins = true; double decay_rate = 0.2; int initial_intensity_threshold = 100; Color_Scale color_scale{Color_Map{}, Range{0, 10}}; bool color_bar_enabled = false; }; template struct Afterglow::Builder_T { PROP_BT(std::shared_ptr, frequency_axis) PROP_BT(std::shared_ptr, power_axis) PROP_BT(Range, frequency_range) That& set_power_range(Range value) { static_cast(this)->color_scale.set_range(value); return *static_cast(this); } PROP_BT(int, frequency_bin_count) PROP_BT(int, power_bin_count) PROP_BT(bool, interpolate_power_bins) PROP_BT(double, decay_rate) PROP_BT(int, initial_intensity_threshold) That& set_color_map(Color_Map value) { static_cast(this)->color_scale.set_color_map(std::move(value)); return *static_cast(this); } PROP_BT(Color_Scale, color_scale) PROP_BT(bool, color_bar_enabled) /// 初始化残影构造器。 void init(std::shared_ptr parent, std::shared_ptr frequency_axis, std::shared_ptr power_axis); /// 把构造参数写入目标对象。 void set(Afterglow* t); std::shared_ptr parent{}; }; /// @brief 残影频谱构造器。 struct LIB_DECL Afterglow::Builder : Afterglow::Builder_T, Afterglow_Prop { /// @brief 构建并返回残影对象。 std::shared_ptr build(); /// @brief 创建残影构造器。 Builder(std::shared_ptr parent, std::shared_ptr frequency_axis, std::shared_ptr power_axis); }; } // namespace renderive