45 halp_meta(name,
"Camera Array")
46 halp_meta(c_name,
"camera_array_avnd")
47 halp_meta(category,
"Visuals/3D/Scene")
48 halp_meta(description,
"Create six cameras oriented along cubemap faces for multiview rendering.")
49 halp_meta(authors,
"ossia team")
50 halp_meta(uuid,
"7a3e8d2f-1b94-4c6a-b7f5-8e2d0c1a4b93")
60 struct : halp::xyz_spinboxes_f32<
"Origin", halp::range{-10000., 10000., 0.}>
61 {
void update(
CameraArray& n) { n.rebuild(); } } origin;
62 struct : halp::hslider_f32<
"Near", halp::range{0.001, 10., 0.1}>
63 {
void update(
CameraArray& n) { n.rebuild(); } } near_plane;
64 struct : halp::hslider_f32<
"Far", halp::range{1., 100000., 1000.}>
65 {
void update(
CameraArray& n) { n.rebuild(); } } far_plane;
72 halp_meta(name,
"Scene");
73 ossia::scene_spec scene;
89 std::array<ossia::scene_node_id, 6> m_ids{};
90 std::shared_ptr<ossia::scene_state> m_state;
92 uint8_t m_pending_dirty{ossia::scene_port::dirty_transform};
98 m_state = std::make_shared<ossia::scene_state>();
101 const auto base =
reinterpret_cast<std::uintptr_t
>(
this);
102 for(
int i = 0; i < 6; ++i)
103 m_ids[std::size_t(i)].value = (base ^ (std::uintptr_t(i + 1) << 1)) | 0x1u;
106 static constexpr std::array<Face, 6> kFaces{{
107 {{ 1.f, 0.f, 0.f}, {0.f, -1.f, 0.f}},
108 {{-1.f, 0.f, 0.f}, {0.f, -1.f, 0.f}},
109 {{ 0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}},
110 {{ 0.f, -1.f, 0.f}, {0.f, 0.f, -1.f}},
111 {{ 0.f, 0.f, 1.f}, {0.f, -1.f, 0.f}},
112 {{ 0.f, 0.f, -1.f}, {0.f, -1.f, 0.f}},
115 const float near_f = inputs.near_plane.value;
116 const float far_f = inputs.far_plane.value;
118 = {inputs.origin.value.x, inputs.origin.value.y,
119 inputs.origin.value.z};
122 = std::make_shared<std::vector<ossia::scene_node_ptr>>();
125 for(
int i = 0; i < 6; ++i)
127 auto cam = std::make_shared<ossia::camera_component>();
128 cam->projection = ossia::camera_projection::perspective;
129 cam->yfov = float(M_PI) / 2.f;
130 cam->aspect_ratio = 1.f;
131 cam->aspect_ratio_set =
true;
135 if(m_array_ref[std::size_t(i)].valid())
137 cam->raw_slot = m_array_ref[std::size_t(i)];
141 ossia::scene_transform xform;
142 xform.translation[0] = eye[0];
143 xform.translation[1] = eye[1];
144 xform.translation[2] = eye[2];
151 kFaces[std::size_t(i)].forward[0], kFaces[std::size_t(i)].forward[1],
152 kFaces[std::size_t(i)].forward[2]);
154 kFaces[std::size_t(i)].up[0], kFaces[std::size_t(i)].up[1],
155 kFaces[std::size_t(i)].up[2]);
156 QQuaternion q = QQuaternion::fromDirection(-fwd, up);
157 xform.rotation[0] = q.x();
158 xform.rotation[1] = q.y();
159 xform.rotation[2] = q.z();
160 xform.rotation[3] = q.scalar();
161 xform.scale[0] = 1.f;
162 xform.scale[1] = 1.f;
163 xform.scale[2] = 1.f;
166 if(m_xform_array_ref[std::size_t(i)].valid())
168 xform.raw_slot = m_xform_array_ref[std::size_t(i)];
174 = std::make_shared<std::vector<ossia::scene_payload>>();
175 children->push_back(xform);
176 children->push_back(ossia::camera_component_ptr(std::move(cam)));
178 auto node = std::make_shared<ossia::scene_node>();
179 node->id = m_ids[std::size_t(i)];
180 node->children = std::move(children);
182 roots->push_back(std::move(node));
185 m_state->roots = std::move(roots);
189 m_state->active_camera_id = m_ids[0];
191 m_state->version = m_version;
192 m_pending_dirty = ossia::scene_port::dirty_transform;
199 outputs.scene_out.scene.state = m_state;
200 outputs.scene_out.dirty = m_pending_dirty;
216 ossia::gpu_slot_ref m_array_ref[6]{};
217 ossia::gpu_slot_ref m_xform_array_ref[6]{};