Loading...
Searching...
No Matches
SceneSwitch.hpp
1#pragma once
2#include <halp/controls.hpp>
3#include <halp/meta.hpp>
4
5#include <ossia/dataflow/geometry_port.hpp>
6
7#include <cstdint>
8
9namespace Threedim
10{
11
12// N-way scene_spec switch. Pick one of up to 4 scene inputs to pass
13// through by index; live VJ-style A/B/C/D scene cutting.
14//
15// Unwired inputs are skipped — if `index` points at an empty slot, the
16// node emits an empty scene, which downstream treats as "nothing to
17// render" (no error). This makes it safe to leave slots open during
18// authoring and fill them in incrementally.
19//
20// Blending between scenes does not happen at the scene-graph level:
21// scene-level blending has no meaningful semantics for arbitrarily
22// different scene trees. Render each scene to its own texture
23// (ScenePreprocessor → classic_pbr → BackgroundNode with a texture
24// output) and ISF-crossfade the textures instead.
26{
27public:
28 halp_meta(name, "Scene Switch")
29 halp_meta(category, "Visuals/3D/Scene")
30 halp_meta(c_name, "scene_switch")
31 halp_meta(description, "Select one of four scene inputs by index without blending their contents.")
32 halp_meta(authors, "ossia team")
33 halp_meta(
34 manual_url,
35 "https://ossia.io/score-docs/processes/scene-switch.html")
36 halp_meta(uuid, "7d5c3f8a-2e9b-4a1c-8f6d-5b3e0d9a7c4f")
37
38 struct ins
39 {
40 struct
41 {
42 halp_meta(name, "Scene 0");
43 ossia::scene_spec scene;
44 uint8_t dirty{0};
45 } scene0;
46 struct
47 {
48 halp_meta(name, "Scene 1");
49 ossia::scene_spec scene;
50 uint8_t dirty{0};
51 } scene1;
52 struct
53 {
54 halp_meta(name, "Scene 2");
55 ossia::scene_spec scene;
56 uint8_t dirty{0};
57 } scene2;
58 struct
59 {
60 halp_meta(name, "Scene 3");
61 ossia::scene_spec scene;
62 uint8_t dirty{0};
63 } scene3;
64
65 halp::spinbox_i32<"Index", halp::irange{0, 3, 0}> index;
66 } inputs;
67
68 // Cache for upstream-change detection (mirrors CameraSwitch.Select).
69 const ossia::scene_state* m_cached_state{};
70 int64_t m_cached_version{-1};
71 int m_cached_index{-1};
72
73 struct outs
74 {
75 struct
76 {
77 halp_meta(name, "Scene Out");
78 ossia::scene_spec scene;
79 uint8_t dirty{0};
80 } scene_out;
81 } outputs;
82
83 void operator()()
84 {
85 const int idx = inputs.index.value;
86 const ossia::scene_spec* picked = nullptr;
87 switch(idx)
88 {
89 case 0: picked = &inputs.scene0.scene; break;
90 case 1: picked = &inputs.scene1.scene; break;
91 case 2: picked = &inputs.scene2.scene; break;
92 case 3: picked = &inputs.scene3.scene; break;
93 default: picked = &inputs.scene0.scene; break;
94 }
95 outputs.scene_out.scene = *picked;
96
97 // Dirty flag drives downstream re-evaluation. Raise it only on
98 // real change: index switch, picked-input pointer change, or
99 // picked-input version bump. Empty slots stay quiet.
100 const auto* s = picked->state.get();
101 const int64_t v = s ? s->version : -1;
102 const bool changed = (idx != m_cached_index) || (s != m_cached_state)
103 || (v != m_cached_version);
104 outputs.scene_out.dirty = (s && changed) ? 0xFF : 0;
105 m_cached_index = idx;
106 m_cached_state = s;
107 m_cached_version = v;
108 }
109};
110
111}
Definition SceneSwitch.hpp:26
Definition SceneSwitch.hpp:39
Definition SceneSwitch.hpp:74