Skip to content

Commit c38fd70

Browse files
committed
tweak viewport camera UI to not flicker when changing types
1 parent d3bd610 commit c38fd70

File tree

4 files changed

+92
-49
lines changed

4 files changed

+92
-49
lines changed

tsd/apps/interactive/common/AppCore.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright 2024-2025 NVIDIA Corporation
22
// SPDX-License-Identifier: Apache-2.0
33

4+
#define ANARI_EXTENSION_UTILITY_IMPL
5+
46
#include "AppCore.h"
57
#include "windows/Log.h"
68

@@ -175,11 +177,11 @@ void AppCore::setupSceneFromCommandLine(bool hdriOnly)
175177

176178
anari::Device AppCore::loadDevice(const std::string &libraryName)
177179
{
178-
anari::Device dev = this->anari.loadedDevices[libraryName];
179-
180180
if (libraryName.empty() || libraryName == "{none}")
181181
return nullptr;
182-
else if (dev) {
182+
183+
anari::Device dev = this->anari.loadedDevices[libraryName];
184+
if (dev) {
183185
anari::retain(dev, dev);
184186
return dev;
185187
}
@@ -193,6 +195,9 @@ anari::Device AppCore::loadDevice(const std::string &libraryName)
193195

194196
dev = anari::newDevice(library, "default");
195197

198+
this->anari.loadedDeviceExtensions[libraryName] =
199+
anari::extension::getDeviceExtensionStruct(library, "default");
200+
196201
anari::unloadLibrary(library);
197202

198203
if (this->commandLine.enableDebug)
@@ -224,6 +229,16 @@ anari::Device AppCore::loadDevice(const std::string &libraryName)
224229
return dev;
225230
}
226231

232+
const anari::Extensions *AppCore::loadDeviceExtensions(
233+
const std::string &libName)
234+
{
235+
auto d = loadDevice(libName);
236+
if (!d)
237+
return nullptr;
238+
anari::release(d, d);
239+
return &this->anari.loadedDeviceExtensions[libName];
240+
}
241+
227242
tsd::RenderIndex *AppCore::acquireRenderIndex(anari::Device d)
228243
{
229244
auto &liveIdx = this->anari.rIdxs[d];

tsd/apps/interactive/common/AppCore.h

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct AppCore
6262
std::map<anari::Device, LiveAnariIndex> rIdxs;
6363
tsd::MultiUpdateDelegate delegate;
6464
std::map<std::string, anari::Device> loadedDevices;
65+
std::map<std::string, anari::Extensions> loadedDeviceExtensions;
6566
} anari;
6667

6768
struct LogState
@@ -86,6 +87,7 @@ struct AppCore
8687
void setupSceneFromCommandLine(bool hdriOnly = false);
8788

8889
anari::Device loadDevice(const std::string &libName);
90+
const anari::Extensions *loadDeviceExtensions(const std::string &libName);
8991
tsd::RenderIndex *acquireRenderIndex(anari::Device device);
9092
void releaseRenderIndex(anari::Device device);
9193
void releaseAllDevices();

tsd/apps/interactive/common/windows/Viewport.cpp

+70-38
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ void Viewport::setLibrary(const std::string &libName, bool doAsync)
147147
if (d) {
148148
anari::retain(d, d);
149149

150+
m_device = d;
151+
if (auto *exts = m_core->loadDeviceExtensions(libName); exts != nullptr)
152+
m_extensions = *exts;
153+
else
154+
m_extensions = {};
155+
150156
tsd::logStatus("[viewport] getting renderer params...");
151157

152158
const char **r_subtypes = anariGetObjectSubtypes(d, ANARI_RENDERER);
@@ -171,8 +177,11 @@ void Viewport::setLibrary(const std::string &libName, bool doAsync)
171177
}
172178

173179
m_perspCamera = anari::newObject<anari::Camera>(d, "perspective");
174-
m_orthoCamera = anari::newObject<anari::Camera>(d, "orthographic");
175-
m_omniCamera = anari::newObject<anari::Camera>(d, "omnidirectional");
180+
m_currentCamera = m_perspCamera;
181+
if (m_extensions.ANARI_KHR_CAMERA_ORTHOGRAPHIC)
182+
m_orthoCamera = anari::newObject<anari::Camera>(d, "orthographic");
183+
if (m_extensions.ANARI_KHR_CAMERA_OMNIDIRECTIONAL)
184+
m_omniCamera = anari::newObject<anari::Camera>(d, "omnidirectional");
176185

177186
tsd::logStatus("[viewport] populating render index...");
178187

@@ -181,8 +190,6 @@ void Viewport::setLibrary(const std::string &libName, bool doAsync)
181190

182191
tsd::logStatus("[viewport] getting scene bounds...");
183192

184-
m_device = d;
185-
186193
if (g_firstFrame || m_arcball->distance() == inf) {
187194
resetView(true);
188195
g_firstFrame = false;
@@ -327,12 +334,7 @@ void Viewport::updateFrame()
327334
return;
328335

329336
m_rud.r = m_renderers[m_currentRenderer];
330-
if (m_cameraModel == CameraModel::Orthographic)
331-
m_anariPass->setCamera(m_orthoCamera);
332-
else if (m_cameraModel == CameraModel::Omnidirectional)
333-
m_anariPass->setCamera(m_omniCamera);
334-
else
335-
m_anariPass->setCamera(m_perspCamera);
337+
m_anariPass->setCamera(m_currentCamera);
336338
m_anariPass->setRenderer(m_rud.r);
337339
m_anariPass->setWorld(m_rIdx->world());
338340
}
@@ -345,39 +347,47 @@ void Viewport::updateCamera(bool force)
345347
if ((!force && !m_arcball->hasChanged(m_cameraToken)))
346348
return;
347349

350+
// perspective camera //
351+
348352
anari::setParameter(m_device, m_perspCamera, "position", m_arcball->eye());
349353
anari::setParameter(m_device, m_perspCamera, "direction", m_arcball->dir());
350354
anari::setParameter(m_device, m_perspCamera, "up", m_arcball->up());
351-
352-
anari::setParameter(
353-
m_device, m_orthoCamera, "position", m_arcball->eye_FixedDistance());
354-
anari::setParameter(m_device, m_orthoCamera, "direction", m_arcball->dir());
355-
anari::setParameter(m_device, m_orthoCamera, "up", m_arcball->up());
356-
anari::setParameter(
357-
m_device, m_orthoCamera, "height", m_arcball->distance() * 0.75f);
358-
359-
anari::setParameter(m_device, m_omniCamera, "position", m_arcball->eye());
360-
anari::setParameter(m_device, m_omniCamera, "direction", m_arcball->dir());
361-
anari::setParameter(m_device, m_omniCamera, "up", m_arcball->up());
362-
363355
anari::setParameter(m_device,
364356
m_perspCamera,
365357
"aspect",
366358
m_viewportSize.x / float(m_viewportSize.y));
367-
anari::setParameter(m_device,
368-
m_orthoCamera,
369-
"aspect",
370-
m_viewportSize.x / float(m_viewportSize.y));
371359
anari::setParameter(
372360
m_device, m_perspCamera, "apertureRadius", m_apertureRadius);
373361
anari::setParameter(
374362
m_device, m_perspCamera, "focusDistance", m_focusDistance);
375363

376364
anari::setParameter(m_device, m_perspCamera, "fovy", anari::radians(m_fov));
377-
378365
anari::commitParameters(m_device, m_perspCamera);
379-
anari::commitParameters(m_device, m_orthoCamera);
380-
anari::commitParameters(m_device, m_omniCamera);
366+
367+
// orthographic camera //
368+
369+
if (m_orthoCamera) {
370+
anari::setParameter(
371+
m_device, m_orthoCamera, "position", m_arcball->eye_FixedDistance());
372+
anari::setParameter(m_device, m_orthoCamera, "direction", m_arcball->dir());
373+
anari::setParameter(m_device, m_orthoCamera, "up", m_arcball->up());
374+
anari::setParameter(
375+
m_device, m_orthoCamera, "height", m_arcball->distance() * 0.75f);
376+
anari::setParameter(m_device,
377+
m_orthoCamera,
378+
"aspect",
379+
m_viewportSize.x / float(m_viewportSize.y));
380+
anari::commitParameters(m_device, m_orthoCamera);
381+
}
382+
383+
// omnidirectional camera //
384+
385+
if (m_omniCamera) {
386+
anari::setParameter(m_device, m_omniCamera, "position", m_arcball->eye());
387+
anari::setParameter(m_device, m_omniCamera, "direction", m_arcball->dir());
388+
anari::setParameter(m_device, m_omniCamera, "up", m_arcball->up());
389+
anari::commitParameters(m_device, m_omniCamera);
390+
}
381391

382392
if (m_echoCameraConfig)
383393
echoCameraConfig();
@@ -517,7 +527,7 @@ void Viewport::ui_picking()
517527

518528
// Pick view center //
519529

520-
const bool shouldPickCenter = m_cameraModel == CameraModel::Perspective
530+
const bool shouldPickCenter = m_currentCamera == m_perspCamera
521531
&& ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)
522532
&& io.KeysDown[GLFW_KEY_LEFT_SHIFT];
523533
if (shouldPickCenter && ImGui::IsWindowHovered()) {
@@ -650,15 +660,37 @@ void Viewport::ui_contextMenu()
650660
ImGui::Text("Camera:");
651661
ImGui::Indent(INDENT_AMOUNT);
652662

653-
if (ImGui::RadioButton(
654-
"perspective", &m_cameraModel, CameraModel::Perspective)
655-
|| ImGui::RadioButton(
656-
"orthographic", &m_cameraModel, CameraModel::Orthographic)
657-
|| ImGui::RadioButton(
658-
"omnidirectional", &m_cameraModel, CameraModel::Omnidirectional))
659-
updateFrame();
663+
if (ImGui::BeginMenu("type")) {
664+
bool changeType = false;
665+
if (ImGui::RadioButton(
666+
"perspective", m_currentCamera == m_perspCamera)) {
667+
m_currentCamera = m_perspCamera;
668+
changeType = true;
669+
}
670+
671+
ImGui::BeginDisabled(!m_orthoCamera);
672+
if (ImGui::RadioButton("orthographic",
673+
m_orthoCamera && m_currentCamera == m_orthoCamera)) {
674+
m_currentCamera = m_orthoCamera;
675+
changeType = true;
676+
}
677+
ImGui::EndDisabled();
678+
679+
ImGui::BeginDisabled(!m_omniCamera);
680+
if (ImGui::RadioButton("omnidirectional",
681+
m_omniCamera && m_currentCamera == m_omniCamera)) {
682+
m_currentCamera = m_omniCamera;
683+
changeType = true;
684+
}
685+
ImGui::EndDisabled();
686+
687+
if (changeType)
688+
updateFrame();
689+
690+
ImGui::EndMenu();
691+
}
660692

661-
ImGui::BeginDisabled(m_cameraModel != CameraModel::Perspective);
693+
ImGui::BeginDisabled(m_currentCamera != m_perspCamera);
662694

663695
if (ImGui::SliderFloat("fov", &m_fov, 0.1f, 180.f))
664696
updateCamera(true);

tsd/apps/interactive/common/windows/Viewport.h

+2-8
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@
2525

2626
namespace tsd_viewer {
2727

28-
struct CameraModel
29-
{
30-
constexpr static int Perspective{0};
31-
constexpr static int Orthographic{1};
32-
constexpr static int Omnidirectional{2};
33-
};
34-
3528
struct Viewport : public anari_viewer::windows::Window
3629
{
3730
Viewport(
@@ -82,7 +75,6 @@ struct Viewport : public anari_viewer::windows::Window
8275
bool m_highlightSelection{true};
8376
bool m_showOnlySelected{false};
8477
int m_frameSamples{0};
85-
int m_cameraModel{CameraModel::Perspective};
8678

8779
bool m_visualizeDepth{false};
8880
float m_depthVisualMaximum{1.f};
@@ -93,7 +85,9 @@ struct Viewport : public anari_viewer::windows::Window
9385

9486
anari::DataType m_format{ANARI_UFIXED8_RGBA_SRGB};
9587

88+
anari::Extensions m_extensions{};
9689
anari::Device m_device{nullptr};
90+
anari::Camera m_currentCamera{nullptr};
9791
anari::Camera m_perspCamera{nullptr};
9892
anari::Camera m_orthoCamera{nullptr};
9993
anari::Camera m_omniCamera{nullptr};

0 commit comments

Comments
 (0)