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(authors, "ossia team")
32 halp_meta(
33 manual_url,
34 "https://ossia.io/score-docs/processes/scene-switch.html")
35 halp_meta(uuid, "7d5c3f8a-2e9b-4a1c-8f6d-5b3e0d9a7c4f")
36
37 struct ins
38 {
39 struct
40 {
41 halp_meta(name, "Scene 0");
42 ossia::scene_spec scene;
43 uint8_t dirty{0};
44 } scene0;
45 struct
46 {
47 halp_meta(name, "Scene 1");
48 ossia::scene_spec scene;
49 uint8_t dirty{0};
50 } scene1;
51 struct
52 {
53 halp_meta(name, "Scene 2");
54 ossia::scene_spec scene;
55 uint8_t dirty{0};
56 } scene2;
57 struct
58 {
59 halp_meta(name, "Scene 3");
60 ossia::scene_spec scene;
61 uint8_t dirty{0};
62 } scene3;
63
64 halp::spinbox_i32<"Index", halp::irange{0, 3, 0}> index;
65 } inputs;
66
67 // Cache for upstream-change detection (mirrors CameraSwitch.Select).
68 const ossia::scene_state* m_cached_state{};
69 int64_t m_cached_version{-1};
70 int m_cached_index{-1};
71
72 struct outs
73 {
74 struct
75 {
76 halp_meta(name, "Scene Out");
77 ossia::scene_spec scene;
78 uint8_t dirty{0};
79 } scene_out;
80 } outputs;
81
82 void operator()()
83 {
84 const int idx = inputs.index.value;
85 const ossia::scene_spec* picked = nullptr;
86 switch(idx)
87 {
88 case 0: picked = &inputs.scene0.scene; break;
89 case 1: picked = &inputs.scene1.scene; break;
90 case 2: picked = &inputs.scene2.scene; break;
91 case 3: picked = &inputs.scene3.scene; break;
92 default: picked = &inputs.scene0.scene; break;
93 }
94 outputs.scene_out.scene = *picked;
95
96 // Dirty flag drives downstream re-evaluation. Raise it only on
97 // real change: index switch, picked-input pointer change, or
98 // picked-input version bump. Empty slots stay quiet.
99 const auto* s = picked->state.get();
100 const int64_t v = s ? s->version : -1;
101 const bool changed = (idx != m_cached_index) || (s != m_cached_state)
102 || (v != m_cached_version);
103 outputs.scene_out.dirty = (s && changed) ? 0xFF : 0;
104 m_cached_index = idx;
105 m_cached_state = s;
106 m_cached_version = v;
107 }
108};
109
110}
Definition SceneSwitch.hpp:26
Definition SceneSwitch.hpp:38
Definition SceneSwitch.hpp:73