diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/seq_compiler.cc | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/tools/seq_compiler.cc b/tools/seq_compiler.cc index 4a671f4..ecb9908 100644 --- a/tools/seq_compiler.cc +++ b/tools/seq_compiler.cc @@ -7,6 +7,7 @@ #include <fstream> #include <iomanip> #include <iostream> +#include <map> #include <numeric> #include <sstream> #include <string> @@ -58,6 +59,25 @@ parse_parameters(const std::string& args) { return params; } +// Check if an effect is a post-process effect +bool is_post_process_effect(const std::string& class_name) { + // List of known post-process effects + static const std::vector<std::string> post_process_effects = { + "FadeEffect", + "FlashEffect", + "GaussianBlurEffect", + "SolarizeEffect", + "VignetteEffect", + "ChromaAberrationEffect", + "DistortEffect", + "ThemeModulationEffect", + "CNNEffect", + "PassthroughEffect", + "CircleMaskEffect"}; + return std::find(post_process_effects.begin(), post_process_effects.end(), + class_name) != post_process_effects.end(); +} + // Calculate adaptive tick interval based on timeline duration int calculate_tick_interval(float max_time) { if (max_time <= 5) @@ -882,6 +902,76 @@ int main(int argc, char* argv[]) { }); } + // Validate: detect priority collisions among post-process effects + for (size_t seq_idx = 0; seq_idx < sequences.size(); ++seq_idx) { + const auto& seq = sequences[seq_idx]; + std::map<int, std::vector<std::string>> priority_map; + + // Group post-process effects by priority + for (const auto& eff : seq.effects) { + if (is_post_process_effect(eff.class_name)) { + int prio = std::stoi(eff.priority); + priority_map[prio].push_back(eff.class_name); + } + } + + // Check for collisions + for (const auto& [prio, effects] : priority_map) { + if (effects.size() > 1) { + std::cerr << "Warning: Priority collision detected in sequence at time " + << seq.start_time << "s\n"; + std::cerr << " Multiple post-process effects have priority " << prio + << ":\n"; + for (const auto& effect : effects) { + std::cerr << " - " << effect << "\n"; + } + std::cerr << " This may cause unexpected render order. Consider " + "adjusting priorities.\n"; + } + } + } + + // Validate: detect cross-sequence priority collisions for concurrent sequences + std::map<std::string, std::vector<size_t>> time_groups; + for (size_t i = 0; i < sequences.size(); ++i) { + time_groups[sequences[i].start_time].push_back(i); + } + + for (const auto& [start_time, seq_indices] : time_groups) { + if (seq_indices.size() > 1) { + // Multiple sequences start at the same time + std::map<int, std::vector<std::pair<std::string, size_t>>> cross_priority_map; + + for (size_t seq_idx : seq_indices) { + const auto& seq = sequences[seq_idx]; + for (const auto& eff : seq.effects) { + if (is_post_process_effect(eff.class_name)) { + int prio = std::stoi(eff.priority); + cross_priority_map[prio].push_back({eff.class_name, seq_idx}); + } + } + } + + // Check for cross-sequence collisions + for (const auto& [prio, effects] : cross_priority_map) { + if (effects.size() > 1) { + std::cerr << "Warning: Cross-sequence priority collision at time " + << start_time << "s\n"; + std::cerr << " Multiple post-process effects across sequences have " + "priority " + << prio << ":\n"; + for (const auto& [effect, seq_idx] : effects) { + std::cerr << " - " << effect << " (sequence #" << seq_idx << ")\n"; + } + std::cerr << " Post-process effects from different sequences at the " + "same time will be\n"; + std::cerr << " merged into a single render chain. Consider adjusting " + "priorities to clarify order.\n"; + } + } + } + } + // Generate C++ code if output file is specified if (!output_cc.empty()) { std::ofstream out_file(output_cc); @@ -995,6 +1085,38 @@ int main(int argc, char* argv[]) { << eff.class_name << ">(ctx, p), " << eff.start << "f, " << eff.end << "f, " << eff.priority << ");\n"; out_file << " }\n"; + } else if (!eff.params.empty() && eff.class_name == "CNNEffect") { + // Generate parameter struct initialization for CNNEffect + // If layers>1, expand into multiple chained effect instances + int num_layers = 1; + float blend_amount = 1.0f; + + for (const auto& [key, value] : eff.params) { + if (key == "layers") { + num_layers = std::stoi(value); + } else if (key == "blend") { + blend_amount = std::stof(value); + } + } + + // Generate one effect per layer + for (int layer = 0; layer < num_layers; ++layer) { + out_file << " {\n"; + out_file << " CNNEffectParams p;\n"; + out_file << " p.layer_index = " << layer << ";\n"; + out_file << " p.total_layers = " << num_layers << ";\n"; + // Only apply blend_amount on the last layer + if (layer == num_layers - 1) { + out_file << " p.blend_amount = " << blend_amount << "f;\n"; + } else { + out_file << " p.blend_amount = 1.0f;\n"; + } + out_file << " seq->add_effect(std::make_shared<" + << eff.class_name << ">(ctx, p), " << eff.start << "f, " + << eff.end << "f, " << (std::stoi(eff.priority) + layer) + << ");\n"; + out_file << " }\n"; + } } else { // No parameters or unsupported effect - use default constructor out_file << " seq->add_effect(std::make_shared<" << eff.class_name |
