Files
Renderive/Core/plottable/Afterglow.h
T
2026-08-02 03:43:39 +08:00

110 lines
4.1 KiB
C++

#pragma once
#include <cstddef>
#include <memory_resource>
#include <span>
#include <utility>
#include <vector>
#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>, frequency_axis)
/// @brief 绑定功率轴。
PROP(std::shared_ptr<Axis>, 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> color_bar() const;
/// @brief 写入一帧功率数据。
void append_spectrum(std::span<const double> power_range_data);
/// @brief 移动写入一帧功率数据。
void append_spectrum(std::pmr::vector<double>&& power_range_data);
/// @brief 用 writer 填充并写入一帧功率数据。
template <typename Writer>
void write_data(std::size_t count, Writer&& writer) {
std::pmr::vector<double> values(memory_resource(Memory_Domain::Afterglow));
values.resize(count);
std::forward<Writer>(writer)(std::span<double>(values.data(), values.size()));
append_spectrum(std::move(values));
}
template <typename That>
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> frequency_axis{};
std::weak_ptr<Axis> 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 <typename That>
struct Afterglow::Builder_T {
PROP_BT(std::shared_ptr<Frequency_Axis>, frequency_axis)
PROP_BT(std::shared_ptr<Axis>, power_axis)
PROP_BT(Range, frequency_range)
That& set_power_range(Range value) {
static_cast<That*>(this)->color_scale.set_range(value);
return *static_cast<That*>(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<That*>(this)->color_scale.set_color_map(std::move(value));
return *static_cast<That*>(this);
}
PROP_BT(Color_Scale, color_scale)
PROP_BT(bool, color_bar_enabled)
/// 初始化残影构造器。
void init(std::shared_ptr<Renderable> parent, std::shared_ptr<Frequency_Axis> frequency_axis, std::shared_ptr<Axis> power_axis);
/// 把构造参数写入目标对象。
void set(Afterglow* t);
std::shared_ptr<Renderable> parent{};
};
/// @brief 残影频谱构造器。
struct LIB_DECL Afterglow::Builder : Afterglow::Builder_T<Afterglow::Builder>, Afterglow_Prop {
/// @brief 构建并返回残影对象。
std::shared_ptr<Afterglow> build();
/// @brief 创建残影构造器。
Builder(std::shared_ptr<Renderable> parent, std::shared_ptr<Frequency_Axis> frequency_axis, std::shared_ptr<Axis> power_axis);
};
} // namespace renderive