SLProject  4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
AppDemoGui Class Reference

ImGui UI class for the UI of the demo applications. More...

#include <AppDemoGui.h>

Static Public Member Functions

static void clear ()
 
static void build (SLScene *s, SLSceneView *sv)
 This is the main building function for the GUI of the Demo apps. More...
 
static void buildMenuBar (SLScene *s, SLSceneView *sv)
 Builds the entire menu bar once per frame. More...
 
static void buildMenuEdit (SLScene *s, SLSceneView *sv)
 Builds the edit menu that can be in the menu bar and the context menu. More...
 
static void buildMenuContext (SLScene *s, SLSceneView *sv)
 Builds context menu if right mouse click is over non-imgui area. More...
 
static void buildSceneGraph (SLScene *s)
 Builds the scenegraph dialog once per frame. More...
 
static void addSceneGraphNode (SLScene *s, SLNode *node)
 Builds the node information once per frame. More...
 
static void buildProperties (SLScene *s, SLSceneView *sv)
 Builds the properties dialog once per frame. More...
 
static void showTexInfos (SLGLTexture *tex)
 Shows UI infos for a texture. More...
 
static void loadConfig (SLint dotsPerInch)
 Loads the UI configuration. More...
 
static void saveConfig ()
 Stores the UI configuration. More...
 
static void showLUTColors (SLTexColorLUT *lut)
 Displays a editable color lookup table wit ImGui widgets. More...
 
static void setActiveNamedLocation (int locIndex, SLSceneView *sv, SLVec3f lookAtPoint=SLVec3f::ZERO)
 Set the a new active named location from SLDeviceLocation. More...
 

Static Public Attributes

static SLstring configTime = "-"
 Time of stored configuration. More...
 
static SLstring infoAbout
 About info string. More...
 
static SLstring infoCredits
 Credits info string. More...
 
static SLstring infoHelp
 Help info string. More...
 
static SLstring infoCalibrate
 Calibration info string. More...
 
static SLbool hideUI = false
 Flag if menubar should be shown. More...
 
static SLbool showProgress = false
 Flag if about info should be shown. More...
 
static SLbool showDockSpace = true
 Flag if dock space should be enabled. More...
 
static SLbool showAbout = false
 Flag if about info should be shown. More...
 
static SLbool showHelp = false
 Flag if help info should be shown. More...
 
static SLbool showHelpCalibration = false
 Flag if calibration info should be shown. More...
 
static SLbool showCredits = false
 Flag if credits info should be shown. More...
 
static SLbool showStatsTiming = false
 Flag if timing info should be shown. More...
 
static SLbool showStatsScene = false
 Flag if scene info should be shown. More...
 
static SLbool showStatsVideo = false
 Flag if video info should be shown. More...
 
static SLbool showStatsWAI = false
 Flag if WAI info should be shown. More...
 
static SLbool showImGuiMetrics = false
 Flag if imgui metrics infor should be shown. More...
 
static SLbool showInfosSensors = false
 Flag if device sensors info should be shown. More...
 
static SLbool showInfosDevice = false
 Flag if device info should be shown. More...
 
static SLbool showInfosScene = false
 Flag if scene info should be shown. More...
 
static SLbool showSceneGraph = false
 Flag if scene graph should be shown. More...
 
static SLbool showProperties = false
 Flag if properties should be shown. More...
 
static SLbool showErlebAR = false
 Flag if Christoffel infos should be shown. More...
 
static SLbool showUIPrefs = false
 Flag if UI preferences. More...
 
static SLbool showTransform = false
 Flag if transform dialog should be shown. More...
 
static SLbool showDateAndTime = false
 Flag if date-time dialog should be shown. More...
 
static std::time_t adjustedTime = 0
 Adjusted GUI time for sun setting (default 0) More...
 
static SLstring loadingString = ""
 String shown during loading screens. More...
 

Static Private Member Functions

static void setTransformEditMode (SLScene *s, SLSceneView *sv, SLNodeEditMode editMode)
 Adds a transform node for the selected node and toggles the edit mode. More...
 
static void removeTransformNode (SLScene *s)
 Searches and removes the transform node. More...
 
static void showHorizon (SLScene *s, SLSceneView *sv)
 Enables calculation and visualization of horizon line (using rotation sensors) More...
 
static void hideHorizon (SLScene *s)
 Disables calculation and visualization of horizon line. More...
 
static void loadSceneWithLargeModel (SLScene *s, SLSceneView *sv, string downloadFilename, string filenameToLoad, SLSceneID sceneIDToLoad)
 
static void downloadModelAndLoadScene (SLScene *s, SLSceneView *sv, string downloadFilename, string urlFolder, string dstFolder, string filenameToLoad, SLSceneID sceneIDToLoad)
 Parallel HTTP download, unzip and load scene job scheduling. More...
 

Static Private Attributes

static SLbool _horizonVisuEnabled = false
 

Detailed Description

ImGui UI class for the UI of the demo applications.

Definition at line 32 of file AppDemoGui.h.

Member Function Documentation

◆ addSceneGraphNode()

void AppDemoGui::addSceneGraphNode ( SLScene s,
SLNode node 
)
static

Builds the node information once per frame.

Definition at line 3175 of file AppDemoGui.cpp.

3176 {
3177  PROFILE_FUNCTION();
3178 
3179  // assert(s->assetManager() && "No asset manager assigned to scene!");
3180 
3181  SLbool isSelectedNode = s->singleNodeSelected() == node;
3182  SLbool isLeafNode = node->children().empty() && !node->mesh();
3183  SLbool isHidden = node->drawBit(SL_DB_HIDDEN);
3184  bool nodeIsOpen;
3185 
3186  ImGuiTreeNodeFlags nodeFlags = 0;
3187  if (isLeafNode)
3188  nodeFlags |= ImGuiTreeNodeFlags_Leaf;
3189  else
3190  nodeFlags |= ImGuiTreeNodeFlags_OpenOnArrow;
3191 
3192  if (isSelectedNode)
3193  nodeFlags |= ImGuiTreeNodeFlags_Selected;
3194 
3195  if (isHidden)
3196  {
3197  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 1.0f, 1.0f));
3198  nodeIsOpen = ImGui::TreeNodeEx(node->name().c_str(), nodeFlags);
3199  ImGui::PopStyleColor();
3200  }
3201  else
3202  {
3203  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
3204  nodeIsOpen = ImGui::TreeNodeEx(node->name().c_str(), nodeFlags);
3205  ImGui::PopStyleColor();
3206  }
3207 
3208  if (ImGui::IsItemClicked())
3209  {
3211  s->selectNodeMesh(node, nullptr);
3212  }
3213 
3214  if (nodeIsOpen)
3215  {
3216  if (node->mesh())
3217  {
3218  SLMesh* mesh = node->mesh();
3219  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
3220 
3221  ImGuiTreeNodeFlags meshFlags = ImGuiTreeNodeFlags_Leaf;
3222  if (s->singleMeshFullSelected() == mesh)
3223  meshFlags |= ImGuiTreeNodeFlags_Selected;
3224 
3225  ImGui::TreeNodeEx(mesh, meshFlags, "%s", mesh->name().c_str());
3226 
3227  if (ImGui::IsItemClicked())
3228  {
3230  s->selectNodeMesh(node, mesh);
3231  }
3232 
3233  ImGui::TreePop();
3234  ImGui::PopStyleColor();
3235  }
3236 
3237  for (auto* child : node->children())
3238  addSceneGraphNode(s, child);
3239 
3240  ImGui::TreePop();
3241  }
3242 }
#define PROFILE_FUNCTION()
Definition: Instrumentor.h:41
bool SLbool
analog to GLbool
Definition: SL.h:202
#define SL_DB_HIDDEN
Flags an object as hidden.
Definition: SLDrawBits.h:20
static void addSceneGraphNode(SLScene *s, SLNode *node)
Builds the node information once per frame.
An SLMesh object is a triangulated mesh, drawn with one draw call.
Definition: SLMesh.h:134
SLVNode & children()
Definition: SLNode.h:306
SLbool drawBit(SLuint bit)
Definition: SLNode.h:301
SLMesh * mesh()
Definition: SLNode.h:305
void name(const SLstring &Name)
Definition: SLObject.h:34
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
void deselectAllNodesAndMeshes()
Deselects all nodes and its meshes.
Definition: SLScene.cpp:338
SLMesh * singleMeshFullSelected()
Returns the node if only one is selected. See also SLMesh::selectNodeMesh.
Definition: SLScene.h:119
void selectNodeMesh(SLNode *nodeToSelect, SLMesh *meshToSelect)
Handles the full mesh selection from double-clicks.
Definition: SLScene.cpp:234
SLNode * singleNodeSelected()
Returns the node if only one is selected. See also SLMesh::selectNodeMesh.
Definition: SLScene.h:116

◆ build()

void AppDemoGui::build ( SLScene s,
SLSceneView sv 
)
static

This is the main building function for the GUI of the Demo apps.

Is is passed to the AppDemoGui::build function in main of the app-demo app. This function will be called once per frame roughly at the end of SLSceneView::onPaint in SLSceneView::draw2DGL by calling ImGui::Render.
See also the comments on SLImGui.

Definition at line 232 of file AppDemoGui.cpp.

233 {
235 
236  // assert(s->assetManager() && "No asset manager assigned to scene!");
238 
239  if (!AppCommon::scene)
240  {
241  ImGui::Begin("Loading",
242  nullptr,
243  ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoNavInputs);
244 
245  float width = static_cast<float>(sv->viewportW());
246  float height = static_cast<float>(sv->viewportH());
247  ImGui::SetWindowSize(ImVec2(width, height));
248  ImGui::SetWindowPos(ImVec2(0, 0));
249 
250  ImVec2 center(0.5f * width, 0.5f * height);
251 
252  ImDrawList* drawList = ImGui::GetWindowDrawList();
253 
254  drawList->AddRectFilled(ImVec2(0, 0), ImVec2(width, height), IM_COL32(40, 40, 40, 255));
255  drawList->AddCircle(center, 50, IM_COL32(105, 125, 145, 255), 0, 10.0f);
256 
257  float offset = 8.0f * static_cast<float>(ImGui::GetTime());
258  drawList->PathArcTo(center, 50, offset, offset + 0.25f * 2 * PI);
259  drawList->PathStroke(IM_COL32(250, 165, 0, 255), 0, 10.0f);
260 
261  const char* text = loadingString.c_str();
262  ImGui::SetCursorPosX(0.5f * (width - ImGui::CalcTextSize(text).x));
263  ImGui::SetCursorPosY(0.5f * height + 100.0f);
264  ImGui::Text(text);
265 
266  ImGui::End();
267  return;
268  }
269 
270  if (AppDemoGui::hideUI ||
271  (sv->camera() && sv->camera()->projType() == P_stereoSideBySideD))
272  {
273  // So far no UI in distorted stereo projection
275  }
276  else
277  {
278  ///////////////////////////////////
279  // Show modeless fullscreen dialogs
280  ///////////////////////////////////
281 
282  // if parallel jobs are running show only the progress information
284  {
285  centerNextWindow(sv, 0.9f, 0.5f);
286  ImGui::Begin("Parallel Job in Progress",
287  &showProgress,
288  ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoNavInputs);
289  ImGui::Text("Parallel Job in Progress:");
290  ImGui::Separator();
291  ImGui::Text("%s", AppCommon::jobProgressMsg().c_str());
292  if (AppCommon::jobProgressMax() > 0)
293  {
294  float num = (float)AppCommon::jobProgressNum();
295  float max = (float)AppCommon::jobProgressMax();
296  ImGui::ProgressBar(num / max);
297  }
298  else
299  {
300  ImGui::Text("Progress: %c", "|/-\\"[(int)(ImGui::GetTime() / 0.05f) & 3]);
301  }
302 
303  ImGui::Separator();
304  ImGui::Text("Parallel Jobs to follow: %u",
305  (uint)AppCommon::jobsToBeThreaded.size());
306  ImGui::Text("Sequential Jobs to follow: %u",
307  (uint)AppCommon::jobsToFollowInMain.size());
308  ImGui::End();
309  return;
310  }
311  else
312  {
313  if (showDockSpace)
314  {
315  static bool opt_fullscreen_persistant = true;
316  bool opt_fullscreen = opt_fullscreen_persistant;
317  static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
318 
319  // We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
320  // because it would be confusing to have two docking targets within each others.
321  ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoNavInputs;
322  if (opt_fullscreen)
323  {
324  ImGuiViewport* viewport = ImGui::GetMainViewport();
325  ImGui::SetNextWindowPos(viewport->WorkPos);
326  ImGui::SetNextWindowSize(viewport->WorkSize);
327  ImGui::SetNextWindowViewport(viewport->ID);
328  ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
329  ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
330  window_flags |= ImGuiWindowFlags_NoTitleBar |
331  ImGuiWindowFlags_NoCollapse |
332  ImGuiWindowFlags_NoResize |
333  ImGuiWindowFlags_NoMove |
334  ImGuiWindowFlags_NoBringToFrontOnFocus |
335  ImGuiWindowFlags_NoNavFocus;
336  }
337 
338  // When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
339  // and handle the pass-thru hole, so we ask Begin() to not render a background.
340  if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
341  window_flags |= ImGuiWindowFlags_NoBackground;
342 
343  // Important: note that we proceed even if Begin() returns false (aka window is collapsed).
344  // This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
345  // all active windows docked into it will lose their parent and become undocked.
346  // We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
347  // any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
348  ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
349  ImGui::Begin("DockSpace Demo", &showDockSpace, window_flags);
350  ImGui::PopStyleVar();
351 
352  if (opt_fullscreen)
353  ImGui::PopStyleVar(2);
354 
355  // DockSpace
356  ImGuiIO& io = ImGui::GetIO();
357  if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
358  {
359  ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
360  ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
361  }
362 
363  ImGui::End();
364  }
365 
366  if (showAbout)
367  {
369  ImGui::Begin("About SLProject", &showAbout, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs);
370  ImGui::Text("Version: %s", AppCommon::version.c_str());
371  ImGui::Text("Configuration: %s", AppCommon::configuration.c_str());
372  ImGui::Separator();
373  ImGui::Text("Git Branch: %s (Commit: %s)", AppCommon::gitBranch.c_str(), AppCommon::gitCommit.c_str());
374  ImGui::Text("Git Date: %s", AppCommon::gitDate.c_str());
375  ImGui::Separator();
376  ImGui::TextWrapped("%s", infoAbout.c_str());
377  ImGui::End();
378  return;
379  }
380 
381  if (showHelp)
382  {
384  ImGui::Begin("Help on Interaction", &showHelp, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs);
385  ImGui::TextWrapped("%s", infoHelp.c_str());
386  ImGui::End();
387  return;
388  }
389 
391  {
393  ImGui::Begin("Help on Camera Calibration", &showHelpCalibration, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs);
394  ImGui::TextWrapped("%s", infoCalibrate.c_str());
395  ImGui::End();
396  return;
397  }
398 
399  if (showCredits)
400  {
402  ImGui::Begin("Credits for all Contributors and external Libraries", &showCredits, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavInputs);
403  ImGui::TextWrapped("%s", infoCredits.c_str());
404  ImGui::End();
405  return;
406  }
407 
408  //////////////////
409  // Show rest modal
410  //////////////////
411 
412  buildMenuBar(s, sv);
413 
415 
416  if (showStatsTiming)
417  {
418  SLRenderType rType = sv->renderType();
419  SLfloat ft = s->frameTimesMS().average();
421 
422  SLchar m[2550]; // message character array
423  m[0] = 0; // set zero length
424 
425  if (rType == RT_gl)
426  {
427  // Get averages from average variables (see Averaged)
428  SLfloat captureTime = CVCapture::instance()->captureTimesMS().average();
429  SLfloat updateTime = s->updateTimesMS().average();
430 #ifndef SL_EMSCRIPTEN
431  SLfloat trackingTime = CVTracked::trackingTimesMS.average();
433  SLfloat detect1Time = CVTracked::detect1TimesMS.average();
434  SLfloat detect2Time = CVTracked::detect2TimesMS.average();
436  SLfloat optFlowTime = CVTracked::optFlowTimesMS.average();
438 #endif
439  SLfloat updateAnimTime = s->updateAnimTimesMS().average();
440  SLfloat updateAABBTime = s->updateAABBTimesMS().average();
441  SLfloat shadowMapTime = sv->shadowMapTimeMS().average();
442  SLfloat cullTime = sv->cullTimesMS().average();
443  SLfloat draw3DTime = sv->draw3DTimesMS().average();
444  SLfloat draw2DTime = sv->draw2DTimesMS().average();
445 
446  // Calculate percentage from frame time
447  SLfloat captureTimePC = Utils::clamp(captureTime / ft * 100.0f, 0.0f, 100.0f);
448  SLfloat updateTimePC = Utils::clamp(updateTime / ft * 100.0f, 0.0f, 100.0f);
449 #ifndef SL_EMSCRIPTEN
450  SLfloat trackingTimePC = Utils::clamp(trackingTime / ft * 100.0f, 0.0f, 100.0f);
451  SLfloat detectTimePC = Utils::clamp(detectTime / ft * 100.0f, 0.0f, 100.0f);
452  SLfloat matchTimePC = Utils::clamp(matchTime / ft * 100.0f, 0.0f, 100.0f);
453  SLfloat optFlowTimePC = Utils::clamp(optFlowTime / ft * 100.0f, 0.0f, 100.0f);
454  SLfloat poseTimePC = Utils::clamp(poseTime / ft * 100.0f, 0.0f, 100.0f);
455 #endif
456  SLfloat updateAnimTimePC = Utils::clamp(updateAnimTime / ft * 100.0f, 0.0f, 100.0f);
457  SLfloat updateAABBTimePC = Utils::clamp(updateAABBTime / ft * 100.0f, 0.0f, 100.0f);
458  SLfloat shadowMapTimePC = Utils::clamp(shadowMapTime / ft * 100.0f, 0.0f, 100.0f);
459  SLfloat draw3DTimePC = Utils::clamp(draw3DTime / ft * 100.0f, 0.0f, 100.0f);
460  SLfloat draw2DTimePC = Utils::clamp(draw2DTime / ft * 100.0f, 0.0f, 100.0f);
461  SLfloat cullTimePC = Utils::clamp(cullTime / ft * 100.0f, 0.0f, 100.0f);
462 
463  snprintf(m + strlen(m), sizeof(m), "Renderer : OpenGL\n");
464  snprintf(m + strlen(m), sizeof(m), "Load time : %5.1f ms\n", s->loadTimeMS());
465  snprintf(m + strlen(m), sizeof(m), "Window size: %d x %d\n", sv->viewportW(), sv->viewportH());
466  snprintf(m + strlen(m), sizeof(m), "Drawcalls : %d\n", SLGLVertexArray::totalDrawCalls);
467  snprintf(m + strlen(m), sizeof(m), " Shadow : %d\n", SLShadowMap::drawCalls);
468  snprintf(m + strlen(m), sizeof(m), " Render : %d\n", SLGLVertexArray::totalDrawCalls - SLShadowMap::drawCalls);
469  snprintf(m + strlen(m), sizeof(m), "Primitives : %d\n", SLGLVertexArray::totalPrimitivesRendered);
470  snprintf(m + strlen(m), sizeof(m), "FPS : %5.1f\n", s->fps());
471  snprintf(m + strlen(m), sizeof(m), "Frame time : %5.1f ms (100%%)\n", ft);
472  snprintf(m + strlen(m), sizeof(m), " Capture : %5.1f ms (%3d%%)\n", captureTime, (SLint)captureTimePC);
473  snprintf(m + strlen(m), sizeof(m), " Update : %5.1f ms (%3d%%)\n", updateTime, (SLint)updateTimePC);
474 #ifdef SL_USE_ENTITIES
475  SLfloat updateDODTime = s->updateDODTimesMS().average();
476  SLfloat updateDODTimePC = Utils::clamp(updateDODTime / ft * 100.0f, 0.0f, 100.0f);
477  snprintf(m + strlen(m), sizeof(m), " EntityWM : %5.1f ms (%3d%%)\n", updateDODTime, (SLint)updateDODTimePC);
478 #endif
479  if (!s->animManager().animationNames().empty())
480  {
481  snprintf(m + strlen(m), sizeof(m), " Anim. : %5.1f ms (%3d%%)\n", updateAnimTime, (SLint)updateAnimTimePC);
482  snprintf(m + strlen(m), sizeof(m), " AABB : %5.1f ms (%3d%%)\n", updateAABBTime, (SLint)updateAABBTimePC);
483  }
484 
485 #ifndef SL_EMSCRIPTEN
486  if (vt != VT_NONE && gVideoTracker != nullptr && gVideoTrackedNode != nullptr)
487  {
488  snprintf(m + strlen(m), sizeof(m), " Tracking : %5.1f ms (%3d%%)\n", trackingTime, (SLint)trackingTimePC);
489  snprintf(m + strlen(m), sizeof(m), " Detect : %5.1f ms (%3d%%)\n", detectTime, (SLint)detectTimePC);
490  snprintf(m + strlen(m), sizeof(m), " Det1 : %5.1f ms\n", detect1Time);
491  snprintf(m + strlen(m), sizeof(m), " Det2 : %5.1f ms\n", detect2Time);
492  snprintf(m + strlen(m), sizeof(m), " Match : %5.1f ms (%3d%%)\n", matchTime, (SLint)matchTimePC);
493  snprintf(m + strlen(m), sizeof(m), " OptFlow : %5.1f ms (%3d%%)\n", optFlowTime, (SLint)optFlowTimePC);
494  snprintf(m + strlen(m), sizeof(m), " Pose : %5.1f ms (%3d%%)\n", poseTime, (SLint)poseTimePC);
495  }
496 #endif
497  snprintf(m + strlen(m), sizeof(m), " Shadows : %5.1f ms (%3d%%)\n", shadowMapTime, (SLint)shadowMapTimePC);
498  snprintf(m + strlen(m), sizeof(m), " Culling : %5.1f ms (%3d%%)\n", cullTime, (SLint)cullTimePC);
499  snprintf(m + strlen(m), sizeof(m), " Drawing 3D: %5.1f ms (%3d%%)\n", draw3DTime, (SLint)draw3DTimePC);
500  snprintf(m + strlen(m), sizeof(m), " Drawing 2D: %5.1f ms (%3d%%)\n", draw2DTime, (SLint)draw2DTimePC);
501  }
502  else if (rType == RT_rt)
503  {
504  SLRaytracer* rt = sv->raytracer();
505  SLint rtWidth = (SLint)((float)sv->viewportW() * rt->resolutionFactor());
506  SLint rtHeight = (SLint)((float)sv->viewportH() * rt->resolutionFactor());
507  SLuint rayPrimaries = (SLuint)(rtWidth * rtHeight);
508  SLuint rayTotal = SLRay::totalNumRays();
509  SLfloat renderSec = rt->renderSec();
510  SLfloat fps = renderSec > 0.001f ? 1.0f / rt->renderSec() : 0.0f;
511 
512  snprintf(m + strlen(m), sizeof(m), "Renderer :Ray Tracer\n");
513  snprintf(m + strlen(m), sizeof(m), "Progress :%3d%%\n", rt->progressPC());
514  snprintf(m + strlen(m), sizeof(m), "Frame size :%d x %d\n", rtWidth, rtHeight);
515  snprintf(m + strlen(m), sizeof(m), "FPS :%0.2f\n", fps);
516  snprintf(m + strlen(m), sizeof(m), "Frame Time :%0.3f sec.\n", renderSec);
517  snprintf(m + strlen(m), sizeof(m), "Rays per ms:%0.0f\n", rt->raysPerMS());
518  snprintf(m + strlen(m), sizeof(m), "AA Pixels :%d (%d%%)\n", SLRay::subsampledPixels, (int)((float)SLRay::subsampledPixels / (float)rayPrimaries * 100.0f));
519  snprintf(m + strlen(m), sizeof(m), "Threads :%d\n", rt->numThreads());
520  snprintf(m + strlen(m), sizeof(m), "-----------------------------\n");
521  snprintf(m + strlen(m), sizeof(m), "Total rays :%10u (%3d%%)\n", rayTotal, 100);
522  snprintf(m + strlen(m), sizeof(m), " Primary :%10u (%3d%%)\n", rayPrimaries, (int)((float)rayPrimaries / (float)rayTotal * 100.0f));
523  snprintf(m + strlen(m), sizeof(m), " Reflected:%10u (%3d%%)\n", SLRay::reflectedRays, (int)((float)SLRay::reflectedRays / (float)rayTotal * 100.0f));
524  snprintf(m + strlen(m), sizeof(m), " Refracted:%10u (%3d%%)\n", SLRay::refractedRays, (int)((float)SLRay::refractedRays / (float)rayTotal * 100.0f));
525  snprintf(m + strlen(m), sizeof(m), " TIR :%10u (%3d%%)\n", SLRay::tirRays, (int)((float)SLRay::tirRays / (float)rayTotal * 100.0f));
526  snprintf(m + strlen(m), sizeof(m), " Shadow :%10u (%3d%%)\n", SLRay::shadowRays, (int)((float)SLRay::shadowRays / (float)rayTotal * 100.0f));
527  snprintf(m + strlen(m), sizeof(m), " AA :%10u (%3d%%)\n", SLRay::subsampledRays, (int)((float)SLRay::subsampledRays / (float)rayTotal * 100.0f));
528  snprintf(m + strlen(m), sizeof(m), "-----------------------------\n");
529  snprintf(m + strlen(m), sizeof(m), "Max. depth :%u\n", SLRay::maxDepthReached);
530  snprintf(m + strlen(m), sizeof(m), "Avg. depth :%0.3f\n", SLRay::avgDepth / (float)rayPrimaries);
531  }
532 #if defined(SL_BUILD_WITH_OPTIX) && defined(SL_HAS_OPTIX)
533  else if (rType == RT_optix_rt)
534  {
535  SLOptixRaytracer* ort = sv->optixRaytracer();
536  snprintf(m + strlen(m), sizeof(m), "Renderer :OptiX Ray Tracer\n");
537  snprintf(m + strlen(m), sizeof(m), "Frame size :%d x %d\n", sv->scrW(), sv->scrH());
538  snprintf(m + strlen(m), sizeof(m), "FPS :%5.1f\n", s->fps());
539  snprintf(m + strlen(m), sizeof(m), "Frame Time :%0.3f sec.\n", 1.0f / s->fps());
540  }
541  else if (rType == RT_optix_pt)
542  {
543  SLOptixPathtracer* opt = sv->optixPathtracer();
544  snprintf(m + strlen(m), sizeof(m), "Renderer :OptiX Ray Tracer\n");
545  snprintf(m + strlen(m), sizeof(m), "Frame size :%d x %d\n", sv->scrW(), sv->scrH());
546  snprintf(m + strlen(m), sizeof(m), "Frame Time :%0.2f sec.\n", opt->renderSec());
547  snprintf(m + strlen(m), sizeof(m), "Denoiser Time :%0.0f ms.\n", opt->denoiserMS());
548  }
549 #endif
550  else if (rType == RT_pt)
551  {
552  SLPathtracer* pt = sv->pathtracer();
553  SLint ptWidth = (SLint)((float)sv->viewportW() * pt->resolutionFactor());
554  SLint ptHeight = (SLint)((float)sv->viewportH() * pt->resolutionFactor());
555  SLuint rayTotal = SLRay::totalNumRays();
556 
557  // The sample clamp is a float, but is only ever set to the
558  // whole numbers of the Firefly Clamp menu, and 0 means off.
559  SLchar clamp[16];
560  if (pt->sampleClamp() > 0.0f)
561  snprintf(clamp, sizeof(clamp), "%g", pt->sampleClamp());
562  else
563  snprintf(clamp, sizeof(clamp), "Off");
564 
565  snprintf(m + strlen(m), sizeof(m), "Renderer :Path Tracer\n");
566  snprintf(m + strlen(m), sizeof(m), "Progress :%3d%%\n", pt->progressPC());
567  snprintf(m + strlen(m), sizeof(m), "Frame size :%d x %d\n", ptWidth, ptHeight);
568  snprintf(m + strlen(m), sizeof(m), "FPS :%0.2f\n", 1.0f / pt->renderSec());
569  snprintf(m + strlen(m), sizeof(m), "Frame Time :%0.2f sec.\n", pt->renderSec());
570  snprintf(m + strlen(m), sizeof(m), "Rays per ms :%0.0f\n", pt->raysPerMS());
571  snprintf(m + strlen(m), sizeof(m), "Noise RSE :%0.4f\n", pt->noiseRSE());
572  snprintf(m + strlen(m), sizeof(m), "Noise p99.9 :%0.4f\n", pt->noiseRSE999());
573  snprintf(m + strlen(m), sizeof(m), "Efficiency :%0.2f\n", pt->efficiency());
574  snprintf(m + strlen(m), sizeof(m), "Firefly Clamp:%s\n", clamp);
575  snprintf(m + strlen(m), sizeof(m), "Samples/pix :%d\n", pt->aaSamples());
576  snprintf(m + strlen(m), sizeof(m), "Threads :%d\n", pt->numThreads());
577  snprintf(m + strlen(m), sizeof(m), "-------------------------------\n");
578  snprintf(m + strlen(m), sizeof(m), "Total rays :%10u (%3d%%)\n", rayTotal, 100);
579  snprintf(m + strlen(m), sizeof(m), " Reflected :%10u (%3d%%)\n", SLRay::reflectedRays, (int)((float)SLRay::reflectedRays / (float)rayTotal * 100.0f));
580  snprintf(m + strlen(m), sizeof(m), " Refracted :%10u (%3d%%)\n", SLRay::refractedRays, (int)((float)SLRay::refractedRays / (float)rayTotal * 100.0f));
581  snprintf(m + strlen(m), sizeof(m), " TIR :%10u\n", SLRay::tirRays);
582  snprintf(m + strlen(m), sizeof(m), " Shadow :%10u (%3d%%)\n", SLRay::shadowRays, (int)((float)SLRay::shadowRays / (float)rayTotal * 100.0f));
583  snprintf(m + strlen(m), sizeof(m), "-------------------------------\n");
584  }
585 
586  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
587  ImGui::Begin("Timing", &showStatsTiming, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
588  ImGui::TextUnformatted(m);
589  ImGui::End();
590  ImGui::PopFont();
591  }
592 
593  if (showStatsScene)
594  {
595  SLchar m[2550]; // message character array
596  m[0] = 0; // set zero length
597 
598  SLNodeStats& stats3D = sv->stats3D();
599  SLfloat vox = (SLfloat)stats3D.numVoxels;
600  SLfloat voxEmpty = (SLfloat)stats3D.numVoxEmpty;
601  SLfloat voxelsEmpty = vox > 0.0f ? voxEmpty / vox * 100.0f : 0.0f;
602  SLfloat numRTTria = (SLfloat)stats3D.numTriangles;
603  SLfloat avgTriPerVox = vox > 0.0f ? numRTTria / (vox - voxEmpty) : 0.0f;
604  SLint numOverdrawnNodes = (int)sv->nodesOverdrawn().size();
605  SLint numVisibleNodes = (int)(stats3D.numNodesOpaque + stats3D.numNodesBlended + numOverdrawnNodes);
606  SLint numGroupPC = stats3D.numNodes == 0 ? 0 : (SLint)((SLfloat)stats3D.numNodesGroup / (SLfloat)stats3D.numNodes * 100.0f);
607  SLint numLeafPC = stats3D.numNodes == 0 ? 0 : (SLint)((SLfloat)stats3D.numNodesLeaf / (SLfloat)stats3D.numNodes * 100.0f);
608  SLint numLightsPC = stats3D.numNodes == 0 ? 0 : (SLint)((SLfloat)stats3D.numLights / (SLfloat)stats3D.numNodes * 100.0f);
609  SLint numOpaquePC = stats3D.numNodes == 0 ? 0 : (SLint)((SLfloat)stats3D.numNodesOpaque / (SLfloat)stats3D.numNodes * 100.0f);
610  SLint numBlendedPC = stats3D.numNodes == 0 ? 0 : (SLint)((SLfloat)stats3D.numNodesBlended / (SLfloat)stats3D.numNodes * 100.0f);
611  SLint numOverdrawnPC = stats3D.numNodes == 0 ? 0 : (SLint)((SLfloat)numOverdrawnNodes / (SLfloat)stats3D.numNodes * 100.0f);
612  SLint numVisiblePC = stats3D.numNodes == 0 ? 0 : (SLint)((SLfloat)numVisibleNodes / (SLfloat)stats3D.numNodes * 100.0f);
613 
614  // Calculate total size of texture bytes on CPU
615  SLfloat cpuMBTexture = 0;
616  for (auto* t : am->textures())
617  for (auto* i : t->images())
618  cpuMBTexture += (float)i->bytesPerImage();
619  cpuMBTexture = cpuMBTexture / 1E6f;
620 
621  SLfloat cpuMBMeshes = (SLfloat)stats3D.numBytes / 1E6f;
622  SLfloat cpuMBVoxels = (SLfloat)stats3D.numBytesAccel / 1E6f;
623  SLfloat cpuMBTotal = cpuMBTexture + cpuMBMeshes + cpuMBVoxels;
624  SLint cpuMBTexturePC = std::abs(cpuMBTotal) < 1E-5f ? 0 : (SLint)(cpuMBTexture / cpuMBTotal * 100.0f);
625  SLint cpuMBMeshesPC = std::abs(cpuMBTotal) < 1E-5f ? 0 : (SLint)(cpuMBMeshes / cpuMBTotal * 100.0f);
626  SLint cpuMBVoxelsPC = std::abs(cpuMBTotal) < 1E-5f ? 0 : (SLint)(cpuMBVoxels / cpuMBTotal * 100.0f);
627  SLfloat gpuMBTexture = (SLfloat)SLGLTexture::totalNumBytesOnGPU / 1E6f;
629  SLfloat gpuMBTotal = gpuMBTexture + gpuMBVbo;
630  SLint gpuMBTexturePC = std::abs(gpuMBTotal) < 1E-5 ? 0 : (SLint)(gpuMBTexture / gpuMBTotal * 100.0f);
631  SLint gpuMBVboPC = std::abs(gpuMBTotal) < 1E-5 ? 0 : (SLint)(gpuMBVbo / gpuMBTotal * 100.0f);
632 
633  snprintf(m + strlen(m), sizeof(m), "No. of Nodes :%5d (100%%)\n", stats3D.numNodes);
634  snprintf(m + strlen(m), sizeof(m), "- Group Nodes :%5d (%3d%%)\n", stats3D.numNodesGroup, numGroupPC);
635  snprintf(m + strlen(m), sizeof(m), "- Leaf Nodes :%5d (%3d%%)\n", stats3D.numNodesLeaf, numLeafPC);
636  snprintf(m + strlen(m), sizeof(m), "- Light Nodes :%5d (%3d%%)\n", stats3D.numLights, numLightsPC);
637  snprintf(m + strlen(m), sizeof(m), "- Opaque Nodes:%5d (%3d%%)\n", stats3D.numNodesOpaque, numOpaquePC);
638  snprintf(m + strlen(m), sizeof(m), "- Blend Nodes :%5d (%3d%%)\n", stats3D.numNodesBlended, numBlendedPC);
639  snprintf(m + strlen(m), sizeof(m), "- Overdrawn N.:%5d (%3d%%)\n", numOverdrawnNodes, numOverdrawnPC);
640  snprintf(m + strlen(m), sizeof(m), "- Vis. Nodes :%5d (%3d%%)\n", numVisibleNodes, numVisiblePC);
641  snprintf(m + strlen(m), sizeof(m), "- WM Updates :%5d\n", SLNode::numWMUpdates);
642  snprintf(m + strlen(m), sizeof(m), "No. of Meshes :%5u\n", stats3D.numMeshes);
643  snprintf(m + strlen(m), sizeof(m), "No. of Tri. :%5u\n", stats3D.numTriangles);
644  snprintf(m + strlen(m), sizeof(m), "CPU MB Total :%6.2f (100%%)\n", cpuMBTotal);
645  snprintf(m + strlen(m), sizeof(m), "- MB Tex. :%6.2f (%3d%%)\n", cpuMBTexture, cpuMBTexturePC);
646  snprintf(m + strlen(m), sizeof(m), "- MB Meshes :%6.2f (%3d%%)\n", cpuMBMeshes, cpuMBMeshesPC);
647  snprintf(m + strlen(m), sizeof(m), "- MB Voxels :%6.2f (%3d%%)\n", cpuMBVoxels, cpuMBVoxelsPC);
648  snprintf(m + strlen(m), sizeof(m), "GPU MB Total :%6.2f (100%%)\n", gpuMBTotal);
649  snprintf(m + strlen(m), sizeof(m), "- MB Tex. :%6.2f (%3d%%)\n", gpuMBTexture, gpuMBTexturePC);
650  snprintf(m + strlen(m), sizeof(m), "- MB VBO :%6.2f (%3d%%)\n", gpuMBVbo, gpuMBVboPC);
651  snprintf(m + strlen(m), sizeof(m), "No. of Voxels :%d\n", stats3D.numVoxels);
652  snprintf(m + strlen(m), sizeof(m), "-empty Voxels :%4.1f%%\n", voxelsEmpty);
653  snprintf(m + strlen(m), sizeof(m), "Avg.Tri/Voxel :%4.1f\n", avgTriPerVox);
654  snprintf(m + strlen(m), sizeof(m), "Max.Tri/Voxel :%d\n", stats3D.numVoxMaxTria);
655 
656  // Switch to fixed font
657  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
658  ImGui::Begin("Scene Statistics", &showStatsScene, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
659  ImGui::Text("%s (%d)", s->name().c_str(), AppCommon::sceneID);
660  ImGui::Separator();
661  ImGui::TextUnformatted(m);
662  ImGui::Separator();
663  ImGui::Text("Global Resources:");
664 
665  string label = "Meshes (" + std::to_string(am->meshes().size()) + ")";
666  if (am->meshes().size() && ImGui::TreeNode(label.c_str()))
667  {
668  for (SLuint i = 0; i < am->meshes().size(); ++i)
669  ImGui::Text("[%d] %s (%u v.)",
670  i,
671  am->meshes()[i]->name().c_str(),
672  (SLuint)am->meshes()[i]->P.size());
673 
674  ImGui::TreePop();
675  }
676 
677  label = "Lights (" + std::to_string(s->lights().size()) + ")";
678  if (s->lights().size() && ImGui::TreeNode(label.c_str()))
679  {
680  for (SLuint i = 0; i < s->lights().size(); ++i)
681  {
682  SLNode* light = dynamic_cast<SLNode*>(s->lights()[i]);
683  ImGui::Text("[%u] %s", i, light->name().c_str());
684  }
685 
686  ImGui::TreePop();
687  }
688 
689  label = "Materials (" + std::to_string(sv->visibleMaterials3D().size()) + ")";
690  if (sv->visibleMaterials3D().size() && ImGui::TreeNode(label.c_str()))
691  {
692  for (auto* mat : sv->visibleMaterials3D())
693  {
694  SLVNode& matNodes = mat->nodesVisible3D();
695  snprintf(m,
696  sizeof(m),
697  "%s [%u n.]",
698  mat->name().c_str(),
699  (SLuint)matNodes.size());
700 
701  if (matNodes.size())
702  {
703  if (ImGui::TreeNode(m))
704  {
705  for (auto* node : matNodes)
706  ImGui::Text(node->name().c_str());
707 
708  ImGui::TreePop();
709  }
710  }
711  else
712  ImGui::Text(m);
713  }
714 
715  ImGui::TreePop();
716  }
717 
718  label = "Meshes (" + std::to_string(am->textures().size()) + ")";
719  if (am->textures().size() && ImGui::TreeNode(label.c_str()))
720  {
721  for (SLuint i = 0; i < am->textures().size(); ++i)
722  {
723  if (am->textures()[i]->images().empty())
724  ImGui::Text("[%u] %s on GPU (%s)", i, am->textures()[i]->name().c_str(), am->textures()[i]->isTexture() ? "ok" : "not ok");
725  else
726  ImGui::Text("[%u] %s (%s)", i, am->textures()[i]->name().c_str(), am->textures()[i]->isTexture() ? "ok" : "not ok");
727  }
728 
729  ImGui::TreePop();
730  }
731 
732  label = "Programs in AM (" + std::to_string(am->programs().size()) + ")";
733  if (am->programs().size() && ImGui::TreeNode(label.c_str()))
734  {
735  for (SLuint i = 0; i < am->programs().size(); ++i)
736  {
737  SLGLProgram* p = am->programs()[i];
738  ImGui::Text("[%u] %s", i, p->name().c_str());
739  }
740  ImGui::TreePop();
741  }
742 
743  label = "Programs in app (" + std::to_string(SLGLProgramManager::size()) + ")";
744  if (ImGui::TreeNode(label.c_str()))
745  {
746  for (SLuint i = 0; i < SLGLProgramManager::size(); ++i)
747  ImGui::Text("[%u] %s", i, SLGLProgramManager::get((SLStdShaderProg)i)->name().c_str());
748 
749  ImGui::TreePop();
750  }
751 
752  ImGui::End();
753  ImGui::PopFont();
754  }
755 
756  if (showStatsVideo)
757  {
758  SLchar m[2550]; // message character array
759  m[0] = 0; // set zero length
760 
765  SLstring mirrored = "None";
766  if (c->isMirroredH() && c->isMirroredV())
767  mirrored = "horizontally & vertically";
768  else if (c->isMirroredH())
769  mirrored = "horizontally";
770  else if (c->isMirroredV())
771  mirrored = "vertically";
772 
773  snprintf(m + strlen(m), sizeof(m), "Video Type : %s\n", vt == VT_NONE ? "None" : vt == VT_MAIN ? "Main Camera"
774  : vt == VT_FILE ? "File"
775  : "Secondary Camera");
776  snprintf(m + strlen(m), sizeof(m), "Display size : %d x %d\n", CVCapture::instance()->lastFrame.cols, CVCapture::instance()->lastFrame.rows);
777  snprintf(m + strlen(m), sizeof(m), "Capture size : %d x %d\n", capSize.width, capSize.height);
778  snprintf(m + strlen(m), sizeof(m), "Size Index : %d\n", ac->camSizeIndex());
779  snprintf(m + strlen(m), sizeof(m), "Mirrored : %s\n", mirrored.c_str());
780  snprintf(m + strlen(m), sizeof(m), "Chessboard : %dx%d (%3.1fmm)\n", c->boardSize().width, c->boardSize().height, c->boardSquareMM());
781  snprintf(m + strlen(m), sizeof(m), "Undistorted : %s\n", ac->showUndistorted() ? "Yes" : "No");
782  snprintf(m + strlen(m), sizeof(m), "Calibimg size: %d x %d\n", ac->calibration.imageSizeOriginal().width, ac->calibration.imageSizeOriginal().height);
783  snprintf(m + strlen(m), sizeof(m), "FOV H/V(deg.): %4.1f/%4.1f\n", c->cameraFovHDeg(), c->cameraFovVDeg());
784  snprintf(m + strlen(m), sizeof(m), "fx,fy : %4.1f,%4.1f\n", c->fx(), c->fy());
785  snprintf(m + strlen(m), sizeof(m), "cx,cy : %4.1f,%4.1f\n", c->cx(), c->cy());
786 
787  int distortionSize = c->distortion().rows;
788  const float f = 100.f;
789  snprintf(m + strlen(m), sizeof(m), "dist.(*10e-2):\n");
790  snprintf(m + strlen(m), sizeof(m), "k1,k2 : %4.2f,%4.2f\n", c->k1() * f, c->k2() * f);
791  snprintf(m + strlen(m), sizeof(m), "p1,p2 : %4.2f,%4.2f\n", c->p1() * f, c->p2() * f);
792  if (distortionSize >= 8)
793  snprintf(m + strlen(m), sizeof(m), "k3,k4,k5,k6 : %4.2f,%4.2f,%4.2f,%4.2f\n", c->k3() * f, c->k4() * f, c->k5() * f, c->k6() * f);
794  else
795  snprintf(m + strlen(m), sizeof(m), "k3 : %4.2f\n", c->k3() * f);
796 
797  if (distortionSize >= 12)
798  snprintf(m + strlen(m), sizeof(m), "s1,s2,s3,s4 : %4.2f,%4.2f,%4.2f,%4.2f\n", c->s1() * f, c->s2() * f, c->s3() * f, c->s4() * f);
799  if (distortionSize >= 14)
800  snprintf(m + strlen(m), sizeof(m), "tauX,tauY : %4.2f,%4.2f\n", c->tauX() * f, c->tauY() * f);
801 
802  snprintf(m + strlen(m), sizeof(m), "Calib. time : %s\n", c->calibrationTime().c_str());
803  snprintf(m + strlen(m), sizeof(m), "Calib. state : %s\n", c->stateStr().c_str());
804  snprintf(m + strlen(m), sizeof(m), "Num. caps : %d\n", c->numCapturedImgs());
805 
806  if (vt != VT_NONE && gVideoTracker != nullptr && gVideoTrackedNode != nullptr)
807  {
808  snprintf(m + strlen(m), sizeof(m), "-------------:\n");
809  if (typeid(*gVideoTrackedNode) == typeid(SLCamera))
810  {
812  snprintf(m + strlen(m), sizeof(m), "Dist. to zero: %4.2f\n", cameraPos.length());
813  }
814  else
815  {
816  SLVec3f cameraPos = ((SLNode*)sv->camera())->updateAndGetWM().translation();
818  SLVec3f camToObj = objectPos - cameraPos;
819  snprintf(m + strlen(m), sizeof(m), "Dist. to obj.: %4.2f\n", camToObj.length());
820  }
821  }
822 
823  // Switch to fixed font
824  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
825  ImGui::Begin("Video", &showStatsVideo, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
826  ImGui::TextUnformatted(m);
827  ImGui::End();
828  ImGui::PopFont();
829  }
830 #ifdef SL_BUILD_WAI
832  {
833  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
834  ImGui::Begin("WAI Statistics", &showStatsWAI, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
835 
836  if (!AverageTiming::instance().empty())
837  {
838  SLchar m[2550]; // message character array
839  m[0] = 0; // set zero length
840 
841  AverageTiming::getTimingMessage(m);
842 
843  // define ui elements
844  ImGui::TextUnformatted(m);
845  }
846 
847  ImGui::End();
848  ImGui::PopFont();
849  }
850 #endif
851  if (showImGuiMetrics)
852  {
853  ImGui::ShowMetricsWindow();
854  }
855 
856  if (showInfosScene)
857  {
858  // Calculate window position for dynamic status bar at the bottom of the main window
859  ImGuiWindowFlags window_flags = 0;
860  window_flags |= ImGuiWindowFlags_NoTitleBar;
861  window_flags |= ImGuiWindowFlags_NoResize;
862  window_flags |= ImGuiWindowFlags_NoScrollbar;
863  window_flags |= ImGuiWindowFlags_NoNavInputs;
864  SLfloat w = (SLfloat)sv->viewportW();
865  ImVec2 size = ImGui::CalcTextSize(s->info().c_str(),
866  nullptr,
867  true,
868  w);
869  SLfloat h = size.y + SLImGui::fontPropDots * 2.0f;
870  SLstring info = "Scene Info: " + s->info();
871 
872  ImGui::SetNextWindowPos(ImVec2(0, (float)sv->scrH() - h));
873  ImGui::SetNextWindowSize(ImVec2(w, h));
874  ImGui::Begin("Scene Information", &showInfosScene, window_flags);
875  ImGui::SetCursorPosX((w - size.x) * 0.5f);
876  ImGui::TextWrapped("%s", info.c_str());
877  ImGui::End();
878  }
879 
880  if (showTransform)
881  {
882  ImGuiWindowFlags window_flags = 0;
883  window_flags |= ImGuiWindowFlags_AlwaysAutoResize;
884  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
885  ImGui::Begin("Transform Selected Node", &showTransform, window_flags);
886 
887  if (s->singleNodeSelected())
888  {
889  SLNode* selNode = s->singleNodeSelected();
890  static SLTransformSpace tSpace = TS_object;
891  SLfloat t1 = 0.1f, t2 = 1.0f, t3 = 10.0f; // Delta translations
892  SLfloat r1 = 1.0f, r2 = 5.0f, r3 = 15.0f; // Delta rotations
893  SLfloat s1 = 1.01f, s2 = 1.1f, s3 = 1.5f; // Scale factors
894 
895  // clang-format off
896  ImGui::Text("Space:");
897  ImGui::SameLine();
898  if (ImGui::RadioButton("World", (int *) &tSpace, 0)) tSpace = TS_world;
899  ImGui::SameLine();
900  if (ImGui::RadioButton("Parent", (int *) &tSpace, 1)) tSpace = TS_parent;
901  ImGui::SameLine();
902  if (ImGui::RadioButton("Object", (int *) &tSpace, 2)) tSpace = TS_object;
903  ImGui::Separator();
904 
905  ImGui::Text("Transl. X :");
906  ImGui::SameLine();
907  if (ImGui::Button("<<<##Tx")) selNode->translate(-t3, 0, 0, tSpace);
908  ImGui::SameLine();
909  if (ImGui::Button("<<##Tx")) selNode->translate(-t2, 0, 0, tSpace);
910  ImGui::SameLine();
911  if (ImGui::Button("<##Tx")) selNode->translate(-t1, 0, 0, tSpace);
912  ImGui::SameLine();
913  if (ImGui::Button(">##Tx")) selNode->translate(t1, 0, 0, tSpace);
914  ImGui::SameLine();
915  if (ImGui::Button(">>##Tx")) selNode->translate(t2, 0, 0, tSpace);
916  ImGui::SameLine();
917  if (ImGui::Button(">>>##Tx")) selNode->translate(t3, 0, 0, tSpace);
918 
919  ImGui::Text("Transl. Y :");
920  ImGui::SameLine();
921  if (ImGui::Button("<<<##Ty")) selNode->translate(0, -t3, 0, tSpace);
922  ImGui::SameLine();
923  if (ImGui::Button("<<##Ty")) selNode->translate(0, -t2, 0, tSpace);
924  ImGui::SameLine();
925  if (ImGui::Button("<##Ty")) selNode->translate(0, -t1, 0, tSpace);
926  ImGui::SameLine();
927  if (ImGui::Button(">##Ty")) selNode->translate(0, t1, 0, tSpace);
928  ImGui::SameLine();
929  if (ImGui::Button(">>##Ty")) selNode->translate(0, t2, 0, tSpace);
930  ImGui::SameLine();
931  if (ImGui::Button(">>>##Ty")) selNode->translate(0, t3, 0, tSpace);
932 
933  ImGui::Text("Transl. Z :");
934  ImGui::SameLine();
935  if (ImGui::Button("<<<##Tz")) selNode->translate(0, 0, -t3, tSpace);
936  ImGui::SameLine();
937  if (ImGui::Button("<<##Tz")) selNode->translate(0, 0, -t2, tSpace);
938  ImGui::SameLine();
939  if (ImGui::Button("<##Tz")) selNode->translate(0, 0, -t1, tSpace);
940  ImGui::SameLine();
941  if (ImGui::Button(">##Tz")) selNode->translate(0, 0, t1, tSpace);
942  ImGui::SameLine();
943  if (ImGui::Button(">>##Tz")) selNode->translate(0, 0, t2, tSpace);
944  ImGui::SameLine();
945  if (ImGui::Button(">>>##Tz")) selNode->translate(0, 0, t3, tSpace);
946 
947  ImGui::Text("Rotation X:");
948  ImGui::SameLine();
949  if (ImGui::Button("<<<##Rx")) selNode->rotate(r3, 1, 0, 0, tSpace);
950  ImGui::SameLine();
951  if (ImGui::Button("<<##Rx")) selNode->rotate(r2, 1, 0, 0, tSpace);
952  ImGui::SameLine();
953  if (ImGui::Button("<##Rx")) selNode->rotate(r1, 1, 0, 0, tSpace);
954  ImGui::SameLine();
955  if (ImGui::Button(">##Rx")) selNode->rotate(-r1, 1, 0, 0, tSpace);
956  ImGui::SameLine();
957  if (ImGui::Button(">>##Rx")) selNode->rotate(-r2, 1, 0, 0, tSpace);
958  ImGui::SameLine();
959  if (ImGui::Button(">>>##Rx")) selNode->rotate(-r3, 1, 0, 0, tSpace);
960 
961  ImGui::Text("Rotation Y:");
962  ImGui::SameLine();
963  if (ImGui::Button("<<<##Ry")) selNode->rotate(r3, 0, 1, 0, tSpace);
964  ImGui::SameLine();
965  if (ImGui::Button("<<##Ry")) selNode->rotate(r2, 0, 1, 0, tSpace);
966  ImGui::SameLine();
967  if (ImGui::Button("<##Ry")) selNode->rotate(r1, 0, 1, 0, tSpace);
968  ImGui::SameLine();
969  if (ImGui::Button(">##Ry")) selNode->rotate(-r1, 0, 1, 0, tSpace);
970  ImGui::SameLine();
971  if (ImGui::Button(">>##Ry")) selNode->rotate(-r2, 0, 1, 0, tSpace);
972  ImGui::SameLine();
973  if (ImGui::Button(">>>##Ry")) selNode->rotate(-r3, 0, 1, 0, tSpace);
974 
975  ImGui::Text("Rotation Z:");
976  ImGui::SameLine();
977  if (ImGui::Button("<<<##Rz")) selNode->rotate(r3, 0, 0, 1, tSpace);
978  ImGui::SameLine();
979  if (ImGui::Button("<<##Rz")) selNode->rotate(r2, 0, 0, 1, tSpace);
980  ImGui::SameLine();
981  if (ImGui::Button("<##Rz")) selNode->rotate(r1, 0, 0, 1, tSpace);
982  ImGui::SameLine();
983  if (ImGui::Button(">##Rz")) selNode->rotate(-r1, 0, 0, 1, tSpace);
984  ImGui::SameLine();
985  if (ImGui::Button(">>##Rz")) selNode->rotate(-r2, 0, 0, 1, tSpace);
986  ImGui::SameLine();
987  if (ImGui::Button(">>>##Rz")) selNode->rotate(-r3, 0, 0, 1, tSpace);
988 
989  ImGui::Text("Scale :");
990  ImGui::SameLine();
991  if (ImGui::Button("<<<##S")) selNode->scale(s3);
992  ImGui::SameLine();
993  if (ImGui::Button("<<##S")) selNode->scale(s2);
994  ImGui::SameLine();
995  if (ImGui::Button("<##S")) selNode->scale(s1);
996  ImGui::SameLine();
997  if (ImGui::Button(">##S")) selNode->scale(-s1);
998  ImGui::SameLine();
999  if (ImGui::Button(">>##S")) selNode->scale(-s2);
1000  ImGui::SameLine();
1001  if (ImGui::Button(">>>##S")) selNode->scale(-s3);
1002  ImGui::Separator();
1003  // clang-format on
1004 
1005  if (ImGui::Button("Reset"))
1006  selNode->om(selNode->initialOM());
1007  }
1008  else
1009  {
1010  ImGui::Text("No node selected.");
1011  ImGui::Text("Please select a node by double clicking it.");
1012 
1013  if (transformNode)
1015  }
1016  ImGui::End();
1017  ImGui::PopFont();
1018  }
1019 
1020  if (showInfosDevice)
1021  {
1022  SLGLState* stateGL = SLGLState::instance();
1023  SLchar m[2550]; // message character array
1024  m[0] = 0; // set zero length
1025 
1026  snprintf(m + strlen(m), sizeof(m), "SLProject Version: %s\n", AppCommon::version.c_str());
1027 #ifdef _DEBUG
1028  snprintf(m + strlen(m), sizeof(m), "Build Config. : Debug\n");
1029 #else
1030  snprintf(m + strlen(m), sizeof(m), "Build Config. : Release\n");
1031 #endif
1032  snprintf(m + strlen(m), sizeof(m), "-----------------:\n");
1033  snprintf(m + strlen(m), sizeof(m), "Computer User : %s\n", Utils::ComputerInfos::user.c_str());
1034  snprintf(m + strlen(m), sizeof(m), "Computer Name : %s\n", Utils::ComputerInfos::name.c_str());
1035  snprintf(m + strlen(m), sizeof(m), "Computer Brand : %s\n", Utils::ComputerInfos::brand.c_str());
1036  snprintf(m + strlen(m), sizeof(m), "Computer Model : %s\n", Utils::ComputerInfos::model.c_str());
1037  snprintf(m + strlen(m), sizeof(m), "Computer Arch. : %s\n", Utils::ComputerInfos::arch.c_str());
1038  snprintf(m + strlen(m), sizeof(m), "Computer OS : %s\n", Utils::ComputerInfos::os.c_str());
1039  snprintf(m + strlen(m), sizeof(m), "Computer OS Ver. : %s\n", Utils::ComputerInfos::osVer.c_str());
1040  snprintf(m + strlen(m), sizeof(m), "-----------------:\n");
1041  snprintf(m + strlen(m), sizeof(m), "OpenGL Version : %s\n", stateGL->glVersionNO().c_str());
1042  snprintf(m + strlen(m), sizeof(m), "OpenGL Vendor : %s\n", stateGL->glVendor().c_str());
1043  snprintf(m + strlen(m), sizeof(m), "OpenGL Renderer : %s\n", stateGL->glRenderer().c_str());
1044  snprintf(m + strlen(m), sizeof(m), "OpenGL GLSL Ver. : %s\n", stateGL->glSLVersionNO().c_str());
1045  snprintf(m + strlen(m), sizeof(m), "-----------------:\n");
1046  snprintf(m + strlen(m), sizeof(m), "OpenCV Version : %d.%d.%d\n", CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_VERSION_REVISION);
1047  snprintf(m + strlen(m), sizeof(m), "OpenCV has OpenCL: %s\n", cv::ocl::haveOpenCL() ? "yes" : "no");
1048  snprintf(m + strlen(m), sizeof(m), "OpenCV has AVX : %s\n", cv::checkHardwareSupport(CV_AVX) ? "yes" : "no");
1049  snprintf(m + strlen(m), sizeof(m), "OpenCV has NEON : %s\n", cv::checkHardwareSupport(CV_NEON) ? "yes" : "no");
1050  snprintf(m + strlen(m), sizeof(m), "-----------------:\n");
1051 #ifdef SL_BUILD_WAI
1052  snprintf(m + strlen(m), sizeof(m), "Eigen Version : %d.%d.%d\n", EIGEN_WORLD_VERSION, EIGEN_MAJOR_VERSION, EIGEN_MINOR_VERSION);
1053 # ifdef EIGEN_VECTORIZE
1054  snprintf(m + strlen(m), sizeof(m), "Eigen vectorize : yes\n");
1055 # else
1056  snprintf(m + strlen(m), sizeof(m), "Eigen vectorize : no\n");
1057 # endif
1058 #endif
1059  snprintf(m + strlen(m), sizeof(m), "-----------------:\n");
1060  snprintf(m + strlen(m), sizeof(m), "ImGui Version : %s\n", ImGui::GetVersion());
1061 
1062  // Switch to fixed font
1063  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
1064  ImGui::Begin("Device Informations", &showInfosDevice, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1065  ImGui::TextUnformatted(m);
1066  ImGui::End();
1067  ImGui::PopFont();
1068  }
1069 
1070  if (showInfosSensors)
1071  {
1072  SLchar m[1024]; // message character array
1073  m[0] = 0; // set zero length
1075  snprintf(m + strlen(m), sizeof(m), "Uses IMU Senor : %s\n", AppCommon::devRot.isUsed() ? "yes" : "no");
1076  snprintf(m + strlen(m), sizeof(m), "Pitch (deg) : %3.1f\n", AppCommon::devRot.pitchDEG());
1077  snprintf(m + strlen(m), sizeof(m), "Yaw (deg) : %3.1f\n", AppCommon::devRot.yawDEG());
1078  snprintf(m + strlen(m), sizeof(m), "Roll (deg) : %3.1f\n", AppCommon::devRot.rollDEG());
1079  snprintf(m + strlen(m), sizeof(m), "No. averaged : %d\n", AppCommon::devRot.numAveraged());
1080  // snprintf(m + strlen(m), sizeof(m), "Pitch Offset(deg): %3.1f\n", AppCommon::devRot.pitchOffsetDEG());
1081  // snprintf(m + strlen(m), sizeof(m), "Yaw Offset(deg): %3.1f\n", AppCommon::devRot.yawOffsetDEG());
1082  snprintf(m + strlen(m), sizeof(m), "Rot. Offset mode : %s\n", AppCommon::devRot.offsetModeStr().c_str());
1083  snprintf(m + strlen(m), sizeof(m), "------------------\n");
1084  snprintf(m + strlen(m), sizeof(m), "Uses GPS Sensor : %s\n", AppCommon::devLoc.isUsed() ? "yes" : "no");
1085  snprintf(m + strlen(m), sizeof(m), "Latitude (deg) : %10.5f\n", AppCommon::devLoc.locLatLonAlt().lat);
1086  snprintf(m + strlen(m), sizeof(m), "Longitude (deg) : %10.5f\n", AppCommon::devLoc.locLatLonAlt().lon);
1087  snprintf(m + strlen(m), sizeof(m), "Alt. used (m) : %10.2f\n", AppCommon::devLoc.locLatLonAlt().alt);
1088  snprintf(m + strlen(m), sizeof(m), "Alt. GPS (m) : %10.2f\n", AppCommon::devLoc.altGpsM());
1089  snprintf(m + strlen(m), sizeof(m), "Alt. DEM (m) : %10.2f\n", AppCommon::devLoc.altDemM());
1090  snprintf(m + strlen(m), sizeof(m), "Alt. origin (m) : %10.2f\n", AppCommon::devLoc.altDemM());
1091  snprintf(m + strlen(m), sizeof(m), "Accuracy Rad.(m) : %6.1f\n", AppCommon::devLoc.locAccuracyM());
1092  snprintf(m + strlen(m), sizeof(m), "Dist. Origin (m) : %6.1f\n", offsetToOrigin.length());
1093  snprintf(m + strlen(m), sizeof(m), "Origin improve(s): %6.1f sec.\n", AppCommon::devLoc.improveTime());
1094  snprintf(m + strlen(m), sizeof(m), "Loc. Offset mode : %s\n", AppCommon::devLoc.offsetModeStr().c_str());
1095  snprintf(m + strlen(m), sizeof(m), "Loc. Offset (m) : %s\n", AppCommon::devLoc.offsetENU().toString(",", 1).c_str());
1096 
1097  // Switch to fixed font
1098  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
1099  ImGui::Begin("Sensor Information", &showInfosSensors, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1100  ImGui::TextUnformatted(m);
1101  ImGui::End();
1102  ImGui::PopFont();
1103  }
1104 
1105  if (showSceneGraph)
1106  {
1107  buildSceneGraph(s);
1108  }
1109 
1110  if (showProperties)
1111  {
1112  buildProperties(s, sv);
1113  }
1114 
1115  if (showUIPrefs)
1116  {
1117  ImGuiWindowFlags window_flags = 0;
1118  window_flags |= ImGuiWindowFlags_AlwaysAutoResize;
1119  window_flags |= ImGuiWindowFlags_NoNavInputs;
1120 
1121  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
1122  ImGui::Begin("User Interface Preferences", &showUIPrefs, window_flags);
1123  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
1124 
1125  ImGui::SliderFloat("Prop. Font Size", &SLImGui::fontPropDots, 16.f, 70.f, "%0.0f");
1126  ImGui::SliderFloat("Fixed Font Size", &SLImGui::fontFixedDots, 13.f, 50.f, "%0.0f");
1127  ImGuiStyle& style = ImGui::GetStyle();
1128 
1129  if (ImGui::SliderFloat("Item Spacing X", &style.ItemSpacing.x, 0.0f, 20.0f, "%0.0f"))
1130  style.WindowPadding.x = style.FramePadding.x = style.ItemInnerSpacing.x = style.ItemSpacing.x;
1131 
1132  if (ImGui::SliderFloat("Item Spacing Y", &style.ItemSpacing.y, 0.0f, 20.0f, "%0.0f"))
1133  {
1134  style.FramePadding.y = style.ItemInnerSpacing.y = style.ItemSpacing.y;
1135  style.WindowPadding.y = style.ItemSpacing.y * 3;
1136  }
1137 
1138  ImGui::Separator();
1139 
1140  ImGui::Checkbox("Dock-Space enabled", &showDockSpace);
1141 
1142  ImGui::Separator();
1143 
1144  SLchar reset[255];
1145  snprintf(reset, sizeof(reset), "Reset User Interface (DPI: %d)", sv->dpi());
1146  if (ImGui::MenuItem(reset))
1147  {
1148  SLstring fullPathFilename = AppCommon::configPath + "DemoGui.yml";
1149  Utils::deleteFile(fullPathFilename);
1150  loadConfig(sv->dpi());
1151  }
1152 
1153  ImGui::PopItemWidth();
1154  ImGui::End();
1155  ImGui::PopFont();
1156  }
1157 
1158  if (showDateAndTime)
1159  {
1160  if (AppCommon::devLoc.originLatLonAlt() != SLVec3d::ZERO ||
1161  AppCommon::devLoc.defaultLatLonAlt() != SLVec3d::ZERO)
1162  {
1163  ImGuiWindowFlags window_flags = 0;
1164  window_flags |= ImGuiWindowFlags_AlwaysAutoResize;
1165  window_flags |= ImGuiWindowFlags_NoNavInputs;
1166 
1167  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
1168  ImGui::Begin("Date and Time Settings", &showDateAndTime, window_flags);
1169  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
1170 
1171  tm lt{};
1172  if (adjustedTime)
1173  memcpy(&lt, std::localtime(&adjustedTime), sizeof(tm));
1174  else
1175  {
1176  std::time_t now = std::time(nullptr);
1177  memcpy(&lt, std::localtime(&now), sizeof(tm));
1178  }
1179 
1180  SLint month = lt.tm_mon + 1;
1181  if (ImGui::SliderInt("Month", &month, 1, 12))
1182  {
1183  lt.tm_mon = month - 1;
1184  adjustedTime = mktime(&lt);
1186  adjustedTime);
1187  }
1188 
1189  if (ImGui::SliderInt("Day", &lt.tm_mday, 1, 31))
1190  {
1191  adjustedTime = mktime(&lt);
1193  adjustedTime);
1194  }
1195 
1198  SLfloat nowF = (SLfloat)lt.tm_hour + (float)lt.tm_min / 60.0f;
1199  if (ImGui::SliderFloat("Hour", &nowF, SRh, SSh, "%.2f"))
1200  {
1201  lt.tm_hour = (int)nowF;
1202  lt.tm_min = (int)((nowF - floor(nowF)) * 60.0f);
1203  adjustedTime = mktime(&lt);
1205  adjustedTime);
1206  }
1207 
1208  SLchar strTime[100];
1209  std::time_t now = std::time(nullptr);
1210  tm tnow{};
1211  memcpy(&tnow, std::localtime(&now), sizeof(tm));
1212  snprintf(strTime, sizeof(strTime), "Set now (%02d.%02d.%02d %02d:%02d)", tnow.tm_mday, tnow.tm_mon + 1, tnow.tm_year + 1900, tnow.tm_hour, tnow.tm_min);
1213  if (ImGui::MenuItem(strTime))
1214  {
1215  adjustedTime = 0;
1216  memcpy(&lt, std::localtime(&now), sizeof(tm));
1218  }
1219 
1220  snprintf(strTime, sizeof(strTime), "Set highest noon (21.07.%02d 12:00)", lt.tm_year - 100);
1221  if (ImGui::MenuItem(strTime))
1222  {
1223  lt.tm_mon = 6;
1224  lt.tm_mday = 21;
1225  lt.tm_hour = 12;
1226  lt.tm_min = 0;
1227  lt.tm_sec = 0;
1228  adjustedTime = mktime(&lt);
1230  adjustedTime);
1231  }
1232 
1233  snprintf(strTime, sizeof(strTime), "Set lowest noon (21.12.%02d 12:00)", lt.tm_year - 100);
1234  if (ImGui::MenuItem(strTime))
1235  {
1236  lt.tm_mon = 11;
1237  lt.tm_mday = 21;
1238  lt.tm_hour = 12;
1239  lt.tm_min = 0;
1240  lt.tm_sec = 0;
1241  adjustedTime = mktime(&lt);
1243  adjustedTime);
1244  }
1245 
1246  SLNode* sunLightNode = AppCommon::devLoc.sunLightNode();
1247  if (sunLightNode &&
1248  typeid(*sunLightNode) == typeid(SLLightDirect) &&
1249  ((SLLightDirect*)sunLightNode)->doSunPowerAdaptation())
1250  {
1251  SLLight* light = (SLLight*)(SLLightDirect*)sunLightNode;
1252  float aP = light->ambientPower();
1253  float dP = light->diffusePower();
1254  float sum_aPdP = aP + dP;
1255  float ambiFraction = aP / sum_aPdP;
1256  ImGui::Separator();
1257  if (ImGui::SliderFloat("Direct-Indirect", &ambiFraction, 0.0f, 1.0f, "%.2f"))
1258  {
1259  light->ambientPower(ambiFraction * sum_aPdP);
1260  light->diffusePower((1.0f - ambiFraction) * sum_aPdP);
1261  }
1262  }
1263 
1264  ImGui::PopItemWidth();
1265  ImGui::End();
1266  ImGui::PopFont();
1267  }
1268  else
1269  showDateAndTime = false;
1270  }
1271 
1272  if (showErlebAR)
1273  {
1274  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
1275  SLint namedLocIndex = AppCommon::devLoc.activeNamedLocation();
1276  SLVec3f lookAtPoint = SLVec3f::ZERO;
1277 
1279  {
1280  ImGui::Begin("Christoffel",
1281  &showErlebAR,
1282  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1283 
1284  // Get scene nodes once
1285  if (!bern)
1286  {
1287  bern = s->root3D()->findChild<SLNode>("bern-christoffel.gltf");
1288  chrAlt = bern->findChild<SLNode>("Chr-Alt", true);
1289  chrNeu = bern->findChild<SLNode>("Chr-Neu", true);
1290  balda_stahl = bern->findChild<SLNode>("Baldachin-Stahl", true);
1291  balda_glas = bern->findChild<SLNode>("Baldachin-Glas", true);
1292  }
1293 
1294  SLbool chrAltIsOn = !chrAlt->drawBits()->get(SL_DB_HIDDEN);
1295  if (ImGui::Checkbox("Christoffelturm 1500-1800", &chrAltIsOn))
1296  {
1297  chrAlt->drawBits()->set(SL_DB_HIDDEN, false);
1298  chrNeu->drawBits()->set(SL_DB_HIDDEN, true);
1299  }
1300 
1301  SLbool chrNeuIsOn = !chrNeu->drawBits()->get(SL_DB_HIDDEN);
1302  if (ImGui::Checkbox("Christoffelturm 1800-1865", &chrNeuIsOn))
1303  {
1304  chrAlt->drawBits()->set(SL_DB_HIDDEN, true);
1305  chrNeu->drawBits()->set(SL_DB_HIDDEN, false);
1306  }
1307  SLbool baldachin = !balda_stahl->drawBits()->get(SL_DB_HIDDEN);
1308  if (ImGui::Checkbox("Baldachin", &baldachin))
1309  {
1310  balda_stahl->drawBits()->set(SL_DB_HIDDEN, !baldachin);
1311  balda_glas->drawBits()->set(SL_DB_HIDDEN, !baldachin);
1312  }
1313 
1314  ImGui::Separator();
1315 
1316 #if defined(SL_OS_MACIOS) || defined(SL_OS_ANDROID)
1317  bool devLocIsUsed = AppCommon::devLoc.isUsed();
1318  if (ImGui::Checkbox("Use GPS Location", &devLocIsUsed))
1319  AppCommon::devLoc.isUsed(true);
1320 #endif
1321  lookAtPoint.set(-21, 18, 6);
1322  for (int i = 1; i < AppCommon::devLoc.nameLocations().size(); ++i)
1323  {
1324  bool namedLocIsActive = namedLocIndex == i;
1325  if (ImGui::Checkbox(AppCommon::devLoc.nameLocations()[i].name.c_str(), &namedLocIsActive))
1326  setActiveNamedLocation(i, sv, lookAtPoint);
1327  }
1328 
1329  ImGui::End();
1330  }
1331  else
1332  {
1333  bern = nullptr;
1334  chrAlt = nullptr;
1335  chrNeu = nullptr;
1336  balda_stahl = nullptr;
1337  balda_glas = nullptr;
1338  }
1340  {
1341  ImGui::Begin("Biel Campus Biel/Bienne",
1342  &showErlebAR,
1343  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1344 
1345 #if defined(SL_OS_MACIOS) || defined(SL_OS_ANDROID)
1346  bool devLocIsUsed = AppCommon::devLoc.isUsed();
1347  if (ImGui::Checkbox("Use GPS Location", &devLocIsUsed))
1348  AppCommon::devLoc.isUsed(true);
1349 #endif
1350  for (int i = 1; i < AppCommon::devLoc.nameLocations().size(); ++i)
1351  {
1352  bool namedLocIsActive = namedLocIndex == i;
1353  if (ImGui::Checkbox(AppCommon::devLoc.nameLocations()[i].name.c_str(), &namedLocIsActive))
1355  }
1356 
1357  ImGui::End();
1358  }
1360  {
1361  ImGui::Begin("Augst-Theatre-Temple",
1362  &showErlebAR,
1363  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1364 
1365 #if defined(SL_OS_MACIOS) || defined(SL_OS_ANDROID)
1366  bool devLocIsUsed = AppCommon::devLoc.isUsed();
1367  if (ImGui::Checkbox("Use GPS Location", &devLocIsUsed))
1368  AppCommon::devLoc.isUsed(true);
1369 #endif
1370  for (int i = 1; i < AppCommon::devLoc.nameLocations().size(); ++i)
1371  {
1372  bool namedLocIsActive = namedLocIndex == i;
1373  if (ImGui::Checkbox(AppCommon::devLoc.nameLocations()[i].name.c_str(), &namedLocIsActive))
1375  }
1376 
1377  ImGui::End();
1378  }
1380  {
1381  ImGui::Begin("Avenche-Amphitheatre",
1382  &showErlebAR,
1383  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1384 
1385 #if defined(SL_OS_MACIOS) || defined(SL_OS_ANDROID)
1386  bool devLocIsUsed = AppCommon::devLoc.isUsed();
1387  if (ImGui::Checkbox("Use GPS Location", &devLocIsUsed))
1388  AppCommon::devLoc.isUsed(true);
1389 #endif
1390  for (int i = 1; i < AppCommon::devLoc.nameLocations().size(); ++i)
1391  {
1392  bool namedLocIsActive = namedLocIndex == i;
1393  if (ImGui::Checkbox(AppCommon::devLoc.nameLocations()[i].name.c_str(), &namedLocIsActive))
1395  }
1396 
1397  ImGui::End();
1398  }
1400  {
1401  ImGui::Begin("Avenche-Cigognier",
1402  &showErlebAR,
1403  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1404 
1405 #if defined(SL_OS_MACIOS) || defined(SL_OS_ANDROID)
1406  bool devLocIsUsed = AppCommon::devLoc.isUsed();
1407  if (ImGui::Checkbox("Use GPS Location", &devLocIsUsed))
1408  AppCommon::devLoc.isUsed(true);
1409 #endif
1410  for (int i = 1; i < AppCommon::devLoc.nameLocations().size(); ++i)
1411  {
1412  bool namedLocIsActive = namedLocIndex == i;
1413  if (ImGui::Checkbox(AppCommon::devLoc.nameLocations()[i].name.c_str(), &namedLocIsActive))
1414  setActiveNamedLocation(i, sv, lookAtPoint);
1415  }
1416  ImGui::End();
1417  }
1419  {
1420  ImGui::Begin("Avenche-Theatre",
1421  &showErlebAR,
1422  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1423 
1424 #if defined(SL_OS_MACIOS) || defined(SL_OS_ANDROID)
1425  bool devLocIsUsed = AppCommon::devLoc.isUsed();
1426  if (ImGui::Checkbox("Use GPS Location", &devLocIsUsed))
1427  AppCommon::devLoc.isUsed(true);
1428 #endif
1429  for (int i = 1; i < AppCommon::devLoc.nameLocations().size(); ++i)
1430  {
1431  bool namedLocIsActive = namedLocIndex == i;
1432  if (ImGui::Checkbox(AppCommon::devLoc.nameLocations()[i].name.c_str(), &namedLocIsActive))
1434  }
1435 
1436  ImGui::End();
1437  }
1439  {
1440  ImGui::Begin("Sutz-Kirchrain18",
1441  &showErlebAR,
1442  ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNavInputs);
1443 
1444 #if defined(SL_OS_MACIOS) || defined(SL_OS_ANDROID)
1445  bool devLocIsUsed = AppCommon::devLoc.isUsed();
1446  if (ImGui::Checkbox("Use GPS Location", &devLocIsUsed))
1447  AppCommon::devLoc.isUsed(true);
1448 #endif
1449  for (int i = 1; i < AppCommon::devLoc.nameLocations().size(); ++i)
1450  {
1451  bool namedLocIsActive = namedLocIndex == i;
1452  if (ImGui::Checkbox(AppCommon::devLoc.nameLocations()[i].name.c_str(), &namedLocIsActive))
1454  }
1455 
1456  ImGui::End();
1457  }
1458 
1459  ImGui::PopFont();
1460  }
1461  }
1462  }
1463 }
static SLNode * chrAlt
Definition: AppDemoGui.cpp:141
void centerNextWindow(SLSceneView *sv, SLfloat widthPC=0.9f, SLfloat heightPC=0.9f)
Centers the next ImGui window in the parent.
Definition: AppDemoGui.cpp:98
static SLNode * balda_stahl
Definition: AppDemoGui.cpp:139
static SLNode * bern
Definition: AppDemoGui.cpp:138
static SLNode * balda_glas
Definition: AppDemoGui.cpp:140
SLNode * gVideoTrackedNode
static SLTransformNode * transformNode
Definition: AppDemoGui.cpp:145
static SLNode * chrNeu
Definition: AppDemoGui.cpp:142
CVTracked * gVideoTracker
@ SID_ErlebAR_BielCBB
@ SID_ErlebAR_BernChristoffel
@ SID_ErlebAR_AventicumAmphiteatre
@ SID_ErlebAR_AventicumCigognier
@ SID_ErlebAR_AventicumTheatre
@ SID_ErlebAR_AugustaRauricaTmpTht
@ SID_ErlebAR_SutzKirchrain18
@ SID_VideoTrackWAI
CVVideoType
Video type if multiple exist on mobile devices.
Definition: CVCapture.h:40
@ VT_FILE
Loads a video from file with OpenCV.
Definition: CVCapture.h:44
@ VT_NONE
No camera needed.
Definition: CVCapture.h:41
@ VT_MAIN
Main camera on all on all all devices.
Definition: CVCapture.h:42
cv::Size CVSize
Definition: CVTypedefs.h:55
float SLfloat
analog to GLfloat
Definition: SL.h:200
unsigned int SLuint
analog to GLuint
Definition: SL.h:198
char SLchar
analog to GLchar (char is signed [-128 ... 127]!)
Definition: SL.h:189
string SLstring
Redefinition of standard types for platform independence.
Definition: SL.h:185
int SLint
analog to GLint
Definition: SL.h:197
@ P_stereoSideBySideD
side-by-side distorted for Oculus Rift like glasses
Definition: SLEnums.h:140
SLRenderType
Rendering type enumeration.
Definition: SLEnums.h:69
@ RT_rt
Ray Tracing.
Definition: SLEnums.h:71
@ RT_pt
Path Tracing.
Definition: SLEnums.h:72
@ RT_gl
OpenGL.
Definition: SLEnums.h:70
@ RT_optix_pt
Path Tracing with OptiX.
Definition: SLEnums.h:74
@ RT_optix_rt
Ray Tracing with OptiX.
Definition: SLEnums.h:73
SLTransformSpace
Describes the relative space a transformation is applied in.
Definition: SLEnums.h:206
@ TS_world
Definition: SLEnums.h:208
@ TS_parent
Definition: SLEnums.h:209
@ TS_object
Definition: SLEnums.h:210
SLStdShaderProg
Enumeration for standard shader programs.
deque< SLNode * > SLVNode
SLVNode typedef for a vector of SLNodes.
Definition: SLNode.h:27
static SLstring version
SLProject version string.
Definition: AppCommon.h:74
static SLDeviceRotation devRot
Mobile device rotation from IMU.
Definition: AppCommon.h:64
static int jobProgressMax()
Definition: AppCommon.h:99
static deque< function< void(void)> > jobsToBeThreaded
Queue of functions to be executed in a thread.
Definition: AppCommon.h:102
static SLstring configPath
Default path for calibration files.
Definition: AppCommon.h:81
static string jobProgressMsg()
Thread-safe getter of the progress message.
Definition: AppCommon.cpp:392
static SLAssetManager * assetManager
asset manager is the owner of all assets
Definition: AppCommon.h:59
static SLstring gitCommit
Current GIT commit short hash id.
Definition: AppCommon.h:78
static atomic< bool > jobIsRunning
True if a parallel job is running.
Definition: AppCommon.h:104
static SLDeviceLocation devLoc
Mobile device location from GPS.
Definition: AppCommon.h:65
static SLstring gitBranch
Current GIT branch.
Definition: AppCommon.h:77
static int jobProgressNum()
Definition: AppCommon.h:98
static deque< function< void(void)> > jobsToFollowInMain
Queue of function to follow in the main thread.
Definition: AppCommon.h:103
static SLstring gitDate
Current GIT commit date.
Definition: AppCommon.h:79
static SLstring configuration
Debug or Release configuration.
Definition: AppCommon.h:76
static SLSceneID sceneID
ID of currently loaded scene.
Definition: AppCommon.h:89
static SLScene * scene
Pointer to the one and only SLScene instance.
Definition: AppCommon.h:61
static void loadConfig(SLint dotsPerInch)
Loads the UI configuration.
static SLbool showImGuiMetrics
Flag if imgui metrics infor should be shown.
Definition: AppDemoGui.h:67
static SLstring infoCalibrate
Calibration info string.
Definition: AppDemoGui.h:55
static SLbool hideUI
Flag if menubar should be shown.
Definition: AppDemoGui.h:56
static SLbool showHelpCalibration
Flag if calibration info should be shown.
Definition: AppDemoGui.h:61
static SLbool showCredits
Flag if credits info should be shown.
Definition: AppDemoGui.h:62
static SLbool showDateAndTime
Flag if date-time dialog should be shown.
Definition: AppDemoGui.h:76
static SLbool showStatsTiming
Flag if timing info should be shown.
Definition: AppDemoGui.h:63
static SLbool showSceneGraph
Flag if scene graph should be shown.
Definition: AppDemoGui.h:71
static SLbool showUIPrefs
Flag if UI preferences.
Definition: AppDemoGui.h:74
static SLbool showProperties
Flag if properties should be shown.
Definition: AppDemoGui.h:72
static SLbool showErlebAR
Flag if Christoffel infos should be shown.
Definition: AppDemoGui.h:73
static SLbool showTransform
Flag if transform dialog should be shown.
Definition: AppDemoGui.h:75
static void buildSceneGraph(SLScene *s)
Builds the scenegraph dialog once per frame.
static SLstring infoCredits
Credits info string.
Definition: AppDemoGui.h:53
static void setActiveNamedLocation(int locIndex, SLSceneView *sv, SLVec3f lookAtPoint=SLVec3f::ZERO)
Set the a new active named location from SLDeviceLocation.
static void removeTransformNode(SLScene *s)
Searches and removes the transform node.
static SLstring loadingString
String shown during loading screens.
Definition: AppDemoGui.h:78
static SLbool showProgress
Flag if about info should be shown.
Definition: AppDemoGui.h:57
static SLbool showInfosSensors
Flag if device sensors info should be shown.
Definition: AppDemoGui.h:68
static SLbool showInfosDevice
Flag if device info should be shown.
Definition: AppDemoGui.h:69
static SLbool showStatsScene
Flag if scene info should be shown.
Definition: AppDemoGui.h:64
static void buildMenuBar(SLScene *s, SLSceneView *sv)
Builds the entire menu bar once per frame.
static SLbool showInfosScene
Flag if scene info should be shown.
Definition: AppDemoGui.h:70
static SLstring infoHelp
Help info string.
Definition: AppDemoGui.h:54
static void buildProperties(SLScene *s, SLSceneView *sv)
Builds the properties dialog once per frame.
static SLstring infoAbout
About info string.
Definition: AppDemoGui.h:52
static std::time_t adjustedTime
Adjusted GUI time for sun setting (default 0)
Definition: AppDemoGui.h:77
static SLbool showStatsWAI
Flag if WAI info should be shown.
Definition: AppDemoGui.h:66
static SLbool showHelp
Flag if help info should be shown.
Definition: AppDemoGui.h:60
static SLbool showStatsVideo
Flag if video info should be shown.
Definition: AppDemoGui.h:65
static void buildMenuContext(SLScene *s, SLSceneView *sv)
Builds context menu if right mouse click is over non-imgui area.
static SLbool showAbout
Flag if about info should be shown.
Definition: AppDemoGui.h:59
static SLbool showDockSpace
Flag if dock space should be enabled.
Definition: AppDemoGui.h:58
Live video camera calibration class with OpenCV an OpenCV calibration.
Definition: CVCalibration.h:71
float tauY() const
float s3() const
float fx() const
CVSize boardSize() const
float s4() const
float k4() const
float boardSquareMM() const
const CVMat & distortion() const
CVSize imageSizeOriginal() const
float s2() const
float fy() const
bool isMirroredH()
float k3() const
bool isMirroredV()
float p1() const
float cx() const
int numCapturedImgs() const
float p2() const
float cameraFovHDeg() const
float cameraFovVDeg() const
float k2() const
string stateStr() const
float k6() const
float s1() const
float k5() const
float tauX() const
float k1() const
float cy() const
string calibrationTime() const
int camSizeIndex()
Definition: CVCamera.h:27
CVCalibration calibration
Definition: CVCamera.h:36
void showUndistorted(bool su)
Definition: CVCamera.h:25
CVCamera * activeCamera
Pointer to the active camera.
Definition: CVCapture.h:136
CVSize captureSize
size of captured frame
Definition: CVCapture.h:123
void videoType(CVVideoType vt)
Setter for video type also sets the active calibration.
Definition: CVCapture.cpp:866
CVMat lastFrame
last frame grabbed in BGR
Definition: CVCapture.h:119
static CVCapture * instance()
Public static instance getter for singleton pattern.
Definition: CVCapture.h:65
AvgFloat & captureTimesMS()
get number of frames in video
Definition: CVCapture.h:109
static AvgFloat trackingTimesMS
Averaged time for video tracking in ms.
Definition: CVTracked.h:82
static AvgFloat optFlowTimesMS
Averaged time for video feature optical flow tracking in ms.
Definition: CVTracked.h:87
static AvgFloat detectTimesMS
Averaged time for video feature detection & description in ms.
Definition: CVTracked.h:83
static AvgFloat detect1TimesMS
Averaged time for video feature detection subpart 1 in ms.
Definition: CVTracked.h:84
static AvgFloat detect2TimesMS
Averaged time for video feature detection subpart 2 in ms.
Definition: CVTracked.h:85
static AvgFloat matchTimesMS
Averaged time for video feature matching in ms.
Definition: CVTracked.h:86
static AvgFloat poseTimesMS
Averaged time for video feature pose estimation in ms.
Definition: CVTracked.h:88
SLVstring & animationNames()
Definition: SLAnimManager.h:46
Toplevel holder of the assets meshes, materials, textures and shaders.
SLVMesh & meshes()
SLVGLProgram & programs()
SLVGLTexture & textures()
Active or visible camera node class.
Definition: SLCamera.h:54
SLbool calculateSolarAngles(SLVec3d locationLatLonAlt, std::time_t time)
Calculates the solar angles at origin at local time.
SLfloat originSolarSunset() const
void activeNamedLocation(SLint locIndex)
void sunLightNode(SLLightDirect *sln)
void isUsed(SLbool isUsed)
Setter that turns on the device rotation sensor.
SLVec3d originENU() const
SLVLocation & nameLocations()
SLfloat originSolarSunrise() const
SLVec3d locENU() const
SLbool get(SLuint bit)
Returns the specified bit.
Definition: SLDrawBits.h:69
void set(SLuint bit, SLbool state)
Sets the specified bit to the passed state.
Definition: SLDrawBits.h:57
Encapsulation of an OpenGL shader program object.
Definition: SLGLProgram.h:56
static size_t size()
Returns the size of the program map.
static SLGLProgramGeneric * get(SLStdShaderProg id)
Get program reference for given id.
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
SLstring glVersionNO()
Definition: SLGLState.h:128
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
SLstring glRenderer()
Definition: SLGLState.h:131
SLstring glVendor()
Definition: SLGLState.h:130
SLstring glSLVersionNO()
Definition: SLGLState.h:133
static SLuint totalNumBytesOnGPU
Total NO. of bytes used for textures on GPU.
Definition: SLGLTexture.h:293
static SLuint totalDrawCalls
static SLuint totalPrimitivesRendered
static total no. of draw calls
static SLuint totalBufferSize
static total no. of buffers in use
static SLfloat fontPropDots
Default font size of proportional font.
Definition: SLImGui.h:91
static SLfloat fontFixedDots
Default font size of fixed size font.
Definition: SLImGui.h:92
SLLightDirect class for a directional light source.
Definition: SLLightDirect.h:40
Abstract Light class for OpenGL light sources.
Definition: SLLight.h:61
void ambientPower(const SLfloat ambPow)
Definition: SLLight.h:106
void diffusePower(const SLfloat diffPow)
Definition: SLLight.h:108
SLVec3< T > translation() const
Definition: SLMat4.h:184
SLNode represents a node in a hierarchical scene graph.
Definition: SLNode.h:148
void rotate(const SLQuat4f &rot, SLTransformSpace relativeTo=TS_object)
Definition: SLNode.cpp:945
const SLMat4f & updateAndGetWM() const
Definition: SLNode.cpp:703
void scale(SLfloat s)
Definition: SLNode.h:641
static SLuint numWMUpdates
NO. of calls to updateWMRec per frame.
Definition: SLNode.h:320
T * findChild(const SLstring &name="", SLbool findRecursive=true)
Definition: SLNode.h:389
SLDrawBits * drawBits()
Definition: SLNode.h:300
void om(const SLMat4f &mat)
Definition: SLNode.h:277
const SLMat4f & initialOM()
Definition: SLNode.h:297
void translate(const SLVec3f &vec, SLTransformSpace relativeTo=TS_object)
Definition: SLNode.cpp:906
Classic Monte Carlo Pathtracing algorithm for real global illumination.
Definition: SLPathtracer.h:18
SLfloat noiseRSE() const
Mean relative standard error of the pixels of the last render.
Definition: SLPathtracer.h:53
void sampleClamp(SLfloat max)
Definition: SLPathtracer.h:41
SLfloat efficiency() const
Monte Carlo efficiency, the inverse of variance times time.
Definition: SLPathtracer.h:84
SLfloat noiseRSE999() const
Relative standard error of the noisiest 0.1% of the pixels.
Definition: SLPathtracer.h:75
static SLuint shadowRays
NO. of shadow rays.
Definition: SLRay.h:133
static SLuint tirRays
NO. of TIR refraction rays.
Definition: SLRay.h:134
static SLint maxDepthReached
max. depth reached for all rays
Definition: SLRay.h:138
static SLuint subsampledPixels
NO. of of subsampled pixels.
Definition: SLRay.h:141
static SLuint totalNumRays()
Total NO. of rays shot during RT.
Definition: SLRay.h:87
static SLuint reflectedRays
NO. of reflected rays.
Definition: SLRay.h:130
static SLfloat avgDepth
average depth reached
Definition: SLRay.h:139
static SLuint refractedRays
NO. of refracted rays.
Definition: SLRay.h:131
static SLuint subsampledRays
NO. of of subsampled rays.
Definition: SLRay.h:140
SLRaytracer hold all the methods for Whitted style Ray Tracing.
Definition: SLRaytracer.h:58
SLfloat renderSec() const
Definition: SLRaytracer.h:123
static SLuint numThreads()
Definition: SLRaytracer.h:120
SLint progressPC() const
Definition: SLRaytracer.h:121
void resolutionFactor(SLfloat rf)
Definition: SLRaytracer.h:90
void aaSamples(SLint samples)
Definition: SLRaytracer.h:102
SLfloat raysPerMS()
Rays per ms of the last completed render, for comparing machines.
Definition: SLRaytracer.h:133
AvgFloat & frameTimesMS()
Definition: SLScene.h:109
AvgFloat & updateAABBTimesMS()
Definition: SLScene.h:112
AvgFloat & updateAnimTimesMS()
Definition: SLScene.h:111
AvgFloat & updateTimesMS()
Definition: SLScene.h:110
SLVLight & lights()
Definition: SLScene.h:107
SLAnimManager & animManager()
Definition: SLScene.h:97
SLfloat fps() const
Definition: SLScene.h:108
void root3D(SLNode *root3D)
Definition: SLScene.h:78
void info(SLstring i)
Definition: SLScene.h:93
AvgFloat & updateDODTimesMS()
Definition: SLScene.h:113
void loadTimeMS(SLfloat loadTimeMS)
Definition: SLScene.h:94
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
AvgFloat & shadowMapTimeMS()
Definition: SLSceneView.h:204
AvgFloat & draw3DTimesMS()
Definition: SLSceneView.h:207
SLint viewportH() const
Definition: SLSceneView.h:184
SLNodeStats & stats3D()
Definition: SLSceneView.h:209
std::unordered_set< SLMaterial * > & visibleMaterials3D()
Definition: SLSceneView.h:213
AvgFloat & draw2DTimesMS()
Definition: SLSceneView.h:206
void camera(SLCamera *camera)
Definition: SLSceneView.h:149
SLint viewportW() const
Definition: SLSceneView.h:183
SLPathtracer * pathtracer()
Definition: SLSceneView.h:199
void renderType(SLRenderType rt)
Definition: SLSceneView.h:158
AvgFloat & cullTimesMS()
Definition: SLSceneView.h:205
SLint dpi() const
Definition: SLSceneView.h:179
SLRaytracer * raytracer()
Definition: SLSceneView.h:198
SLVNode & nodesOverdrawn()
Definition: SLSceneView.h:197
void scrW(SLint scrW)
Definition: SLSceneView.h:151
void scrH(SLint scrH)
Definition: SLSceneView.h:152
static SLuint drawCalls
NO. of draw calls for shadow mapping.
Definition: SLShadowMap.h:92
T length() const
Definition: SLVec3.h:122
void set(const T X, const T Y, const T Z)
Definition: SLVec3.h:59
static SLVec3 ZERO
Definition: SLVec3.h:285
static std::string model
Definition: Utils.h:293
static std::string brand
Definition: Utils.h:292
static std::string user
Definition: Utils.h:290
static std::string os
Definition: Utils.h:294
static std::string osVer
Definition: Utils.h:295
static std::string arch
Definition: Utils.h:296
static std::string name
Definition: Utils.h:291
T abs(T a)
Definition: Utils.h:249
T clamp(T a, T min, T max)
Definition: Utils.h:253
T floor(T a)
Definition: Utils.h:246
static const float PI
Definition: Utils.h:237
string toString(float f, int roundedDecimals)
Returns a string from a float with max. one trailing zero.
Definition: Utils.cpp:92
bool deleteFile(string &pathfilename)
Deletes a file on the filesystem.
Definition: Utils.cpp:1005
Struct for scene graph statistics.
Definition: SLNode.h:38
SLuint numVoxMaxTria
Max. no. of triangles per voxel.
Definition: SLNode.h:52
SLuint numBytesAccel
NO. of bytes in accel. structs.
Definition: SLNode.h:41
SLuint numNodesOpaque
NO. of visible opaque nodes.
Definition: SLNode.h:44
SLuint numMeshes
NO. of meshes in node.
Definition: SLNode.h:46
SLuint numNodes
NO. of children nodes.
Definition: SLNode.h:39
SLuint numLights
NO. of lights in mesh.
Definition: SLNode.h:47
SLuint numTriangles
NO. of triangles in mesh.
Definition: SLNode.h:48
SLuint numNodesBlended
NO. of visible blended nodes.
Definition: SLNode.h:45
SLuint numNodesLeaf
NO. of leaf nodes.
Definition: SLNode.h:43
SLuint numVoxels
NO. of voxels.
Definition: SLNode.h:50
SLuint numNodesGroup
NO. of group nodes.
Definition: SLNode.h:42
SLuint numBytes
NO. of bytes allocated.
Definition: SLNode.h:40
SLfloat numVoxEmpty
NO. of empty voxels.
Definition: SLNode.h:51

◆ buildMenuBar()

void AppDemoGui::buildMenuBar ( SLScene s,
SLSceneView sv 
)
static

Builds the entire menu bar once per frame.

Definition at line 1515 of file AppDemoGui.cpp.

1516 {
1517  PROFILE_FUNCTION();
1518 
1519  // assert(s->assetManager() && "No asset manager assigned to scene!");
1521 
1523  SLGLState* stateGL = SLGLState::instance();
1524  CVCapture* capture = CVCapture::instance();
1525  SLRenderType rType = sv->renderType();
1526  SLbool hasAnimations = (!s->animManager().animationNames().empty());
1527  static SLint curAnimIx = -1;
1528  if (!hasAnimations) curAnimIx = -1;
1529 
1530  // Remove transform node if no or the wrong one is selected
1533 
1534  if (ImGui::BeginMainMenuBar())
1535  {
1536  if (ImGui::BeginMenu("File"))
1537  {
1538  if (ImGui::BeginMenu("Load Test Scene"))
1539  {
1540  if (ImGui::BeginMenu("General"))
1541  {
1542  if (ImGui::MenuItem("Minimal Scene", nullptr, sid == SID_Minimal))
1544  if (ImGui::MenuItem("Figure Scene", nullptr, sid == SID_Figure))
1546  if (ImGui::MenuItem("Mesh Loader", nullptr, sid == SID_MeshLoad))
1548  if (ImGui::MenuItem("Revolver Meshes", nullptr, sid == SID_Revolver))
1550  if (ImGui::MenuItem("Texture Blending", nullptr, sid == SID_TextureBlend))
1552  if (ImGui::MenuItem("Texture Filters", nullptr, sid == SID_TextureFilter))
1554 #ifdef SL_BUILD_WITH_KTX
1555  if (ImGui::MenuItem("Texture Compression", nullptr, sid == SID_TextureCompression))
1557 #endif
1558  if (ImGui::MenuItem("Frustum Culling", nullptr, sid == SID_FrustumCull))
1560  if (ImGui::MenuItem("2D and 3D Text", nullptr, sid == SID_2Dand3DText))
1562  if (ImGui::MenuItem("Point Clouds", nullptr, sid == SID_PointClouds))
1564  if (ImGui::MenuItem("Z-Fighting", nullptr, sid == SID_ZFighting))
1566 
1567  ImGui::EndMenu();
1568  }
1569 
1570  if (ImGui::BeginMenu("Shader"))
1571  {
1572  if (ImGui::MenuItem("Per Vertex Blinn-Phong", nullptr, sid == SID_ShaderPerVertexBlinn))
1574  if (ImGui::MenuItem("Per Pixel Blinn-Phong", nullptr, sid == SID_ShaderPerPixelBlinn))
1576  if (ImGui::MenuItem("Per Pixel Cook-Torrance", nullptr, sid == SID_ShaderPerPixelCook))
1578  if (ImGui::MenuItem("Image Based Lighting", nullptr, sid == SID_ShaderIBL))
1580  if (ImGui::MenuItem("Per Vertex Wave", nullptr, sid == SID_ShaderWave))
1582  if (ImGui::MenuItem("Bump Mapping", nullptr, sid == SID_ShaderBumpNormal))
1584  if (ImGui::MenuItem("Parallax Mapping", nullptr, sid == SID_ShaderBumpParallax))
1586  if (ImGui::MenuItem("Skybox Shader", nullptr, sid == SID_ShaderSkybox))
1588  if (ImGui::MenuItem("Earth Shader", nullptr, sid == SID_ShaderEarth))
1590  ImGui::EndMenu();
1591  }
1592 
1593  if (ImGui::BeginMenu("Shadow Mapping"))
1594  {
1595  if (ImGui::MenuItem("Basic Scene", nullptr, sid == SID_ShadowMappingBasicScene))
1597  if (ImGui::MenuItem("Light Types", nullptr, sid == SID_ShadowMappingLightTypes))
1599  if (ImGui::MenuItem("8 Spot Lights", nullptr, sid == SID_ShadowMappingSpotLights))
1601  if (ImGui::MenuItem("3 Point Lights", nullptr, sid == SID_ShadowMappingPointLights))
1603  if (ImGui::MenuItem("RT Soft Shadows", nullptr, sid == SID_RTSoftShadows))
1605  if (ImGui::MenuItem("Cascaded Shadows", nullptr, sid == SID_ShadowMappingCascaded))
1607  if (ImGui::MenuItem("Columns with Cascaded Sh.", nullptr, sid == SID_Benchmark_ColumnsLOD))
1609 
1610  ImGui::EndMenu();
1611  }
1612 
1613  if (ImGui::BeginMenu("Suzanne Lighting"))
1614  {
1615  if (ImGui::MenuItem("w. per Pixel Lighting (PL)", nullptr, sid == SID_SuzannePerPixBlinn))
1617  if (ImGui::MenuItem("w. PL and Texture Mapping (TM)", nullptr, sid == SID_SuzannePerPixBlinnTm))
1619  if (ImGui::MenuItem("w. PL and Normal Mapping (NM)", nullptr, sid == SID_SuzannePerPixBlinnNm))
1621  if (ImGui::MenuItem("w. PL and Ambient Occlusion (AO)", nullptr, sid == SID_SuzannePerPixBlinnAo))
1623  if (ImGui::MenuItem("w. PL and Shadow Mapping (SM)", nullptr, sid == SID_SuzannePerPixBlinnSm))
1625  if (ImGui::MenuItem("w. PL, TM, NM", nullptr, sid == SID_SuzannePerPixBlinnTmNm))
1627  if (ImGui::MenuItem("w. PL, TM, AO", nullptr, sid == SID_SuzannePerPixBlinnTmAo))
1629  if (ImGui::MenuItem("w. PL, NM, AO", nullptr, sid == SID_SuzannePerPixBlinnNmAo))
1631  if (ImGui::MenuItem("w. PL, NM, SM", nullptr, sid == SID_SuzannePerPixBlinnNmSm))
1633  if (ImGui::MenuItem("w. PL, TM, SM", nullptr, sid == SID_SuzannePerPixBlinnTmSm))
1635  if (ImGui::MenuItem("w. PL, AO, SM", nullptr, sid == SID_SuzannePerPixBlinnAoSm))
1637  if (ImGui::MenuItem("w. PL, TM, NM, AO", nullptr, sid == SID_SuzannePerPixBlinnTmNmAo))
1639  if (ImGui::MenuItem("w. PL, TM, NM, SM", nullptr, sid == SID_SuzannePerPixBlinnTmNmSm))
1641  if (ImGui::MenuItem("w. PL, TM, NM, AO, SM", nullptr, sid == SID_SuzannePerPixBlinnTmNmAoSm))
1643  if (ImGui::MenuItem("w. PL, TM, NM, AO, SM, EM", nullptr, sid == SID_SuzannePerPixCookTmNmAoSmEm))
1645  ImGui::EndMenu();
1646  }
1647 
1648  if (ImGui::BeginMenu("glTF Sample Models"))
1649  {
1650  SLstring zip = "glTF-Sample-Models.zip";
1651 
1652  if (ImGui::MenuItem("Damaged Helmet", nullptr, sid == SID_glTF_DamagedHelmet))
1654  if (ImGui::MenuItem("Flight Helmet", nullptr, sid == SID_glTF_FlightHelmet))
1656  if (ImGui::MenuItem("Sponza Palace", nullptr, sid == SID_glTF_Sponza))
1658  if (ImGui::MenuItem("Water Bottle", nullptr, sid == SID_glTF_WaterBottle))
1660 
1661  ImGui::EndMenu();
1662  }
1663 
1664  if (ImGui::BeginMenu("Robotics"))
1665  {
1666  SLstring zip = "GLTF-FanucCRX.zip";
1667 
1668  if (ImGui::MenuItem("Fanuc-CRX", nullptr, sid == SID_Robotics_FanucCRX_FK))
1670 
1671  ImGui::EndMenu();
1672  }
1673 
1674  if (ImGui::BeginMenu("Volume Rendering"))
1675  {
1676  if (ImGui::MenuItem("Head MRI Ray Cast", nullptr, sid == SID_VolumeRayCast))
1678  if (ImGui::MenuItem("Head MRI Ray Cast Lighted", nullptr, sid == SID_VolumeRayCastLighted))
1680  /*
1681  {
1682  auto loadMRIImages = []() {
1683  AppCommon::jobProgressMsg("Load MRI Images");
1684  AppCommon::jobProgressMax(100);
1685 
1686  // Load volume data into 3D texture
1687  SLVstring mriImages;
1688  for (SLint i = 0; i < 207; ++i)
1689  mriImages.push_back(AppCommon::texturePath + Utils::formatString("i%04u_0000b.png", i));
1690 
1691  gTexMRI3D = new SLGLTexture(nullptr,
1692  mriImages,
1693  GL_LINEAR,
1694  GL_LINEAR,
1695 #ifndef SL_EMSCRIPTEN
1696  0x812D, // GL_CLAMP_TO_BORDER (GLSL 320)
1697  0x812D, // GL_CLAMP_TO_BORDER (GLSL 320)
1698 #else
1699  GL_CLAMP_TO_EDGE,
1700  GL_CLAMP_TO_EDGE,
1701 #endif
1702  "mri_head_front_to_back",
1703  true);
1704  AppCommon::jobIsRunning = false;
1705  };
1706 
1707  auto calculateGradients = []() {
1708  AppCommon::jobProgressMsg("Calculate MRI Volume Gradients");
1709  AppCommon::jobProgressMax(100);
1710  gTexMRI3D->calc3DGradients(1,
1711  [](int progress) { AppCommon::jobProgressNum(progress); });
1712  AppCommon::jobIsRunning = false;
1713  };
1714 
1715  auto smoothGradients = []() {
1716  AppCommon::jobProgressMsg("Smooth MRI Volume Gradients");
1717  AppCommon::jobProgressMax(100);
1718  gTexMRI3D->smooth3DGradients(1,
1719  [](int progress) { AppCommon::jobProgressNum(progress); });
1720  AppCommon::jobIsRunning = false;
1721  };
1722 
1723  auto followUpJob1 = [](SLAssetManager* am, SLScene* s, SLSceneView* sv) {
1724  AppCommon::sceneToLoad = SID_VolumeRayCastLighted;
1725  };
1726  function<void(void)> onLoadScene = bind(followUpJob1, am, s, sv);
1727 
1728  AppCommon::jobsToBeThreaded.emplace_back(loadMRIImages);
1729  AppCommon::jobsToBeThreaded.emplace_back(calculateGradients);
1730  // AppCommon::jobsToBeThreaded.emplace_back(smoothGradients); // very slow
1731  AppCommon::jobsToFollowInMain.push_back(onLoadScene);
1732  }
1733  */
1734  ImGui::EndMenu();
1735  }
1736 
1737  if (ImGui::BeginMenu("Animation"))
1738  {
1739  if (ImGui::MenuItem("Node Animation", nullptr, sid == SID_AnimationNode))
1741  if (ImGui::MenuItem("Mass Node Animation", nullptr, sid == SID_AnimationNodeMass))
1743  if (ImGui::MenuItem("Skinned Animation", nullptr, sid == SID_AnimationSkinned))
1745  if (ImGui::MenuItem("Mass Skinned Animation", nullptr, sid == SID_AnimationSkinnedMass))
1747  if (ImGui::MenuItem("Fanuc-CRX", nullptr, sid == SID_Robotics_FanucCRX_FK))
1749 
1750  ImGui::EndMenu();
1751  }
1752 
1753  if (ImGui::BeginMenu("Video"))
1754  {
1755  if (ImGui::MenuItem("Texture from Video Live", nullptr, sid == SID_VideoTextureLive))
1757 #ifndef SL_EMSCRIPTEN
1758  if (ImGui::MenuItem("Texture from Video File", nullptr, sid == SID_VideoTextureFile))
1760 #endif
1761  if (ImGui::MenuItem("Track ArUco Marker (Main)", nullptr, sid == SID_VideoTrackArucoMain))
1763  if (ImGui::MenuItem("Track ArUco Marker (Scnd)", nullptr, sid == SID_VideoTrackArucoScnd, capture->hasSecondaryCamera))
1765  if (ImGui::MenuItem("Track Chessboard (Main)", nullptr, sid == SID_VideoTrackChessMain))
1767  if (ImGui::MenuItem("Track Chessboard (Scnd)", nullptr, sid == SID_VideoTrackChessScnd, capture->hasSecondaryCamera))
1769  if (ImGui::MenuItem("Track Features (Main)", nullptr, sid == SID_VideoTrackFeature2DMain))
1771 #ifndef SL_EMSCRIPTEN
1772  if (ImGui::MenuItem("Track Face (Main)", nullptr, sid == SID_VideoTrackFaceMain))
1774  if (ImGui::MenuItem("Track Face (Scnd)", nullptr, sid == SID_VideoTrackFaceScnd, capture->hasSecondaryCamera))
1776 #endif
1777 #ifdef SL_BUILD_WITH_MEDIAPIPE
1778  if (ImGui::MenuItem("Track Hands w. Mediapipe (Main)", nullptr, sid == SID_VideoTrackMediaPipeHandsMain))
1780 #endif
1781  if (ImGui::MenuItem("Sensor AR (Main)", nullptr, sid == SID_VideoSensorAR))
1783 #ifdef SL_BUILD_WAI
1784  if (ImGui::MenuItem("Track WAI (Main)", nullptr, sid == SID_VideoTrackWAI))
1786 #endif
1787  ImGui::EndMenu();
1788  }
1789 
1790  if (ImGui::BeginMenu("Ray Tracing"))
1791  {
1792  if (ImGui::MenuItem("Spheres", nullptr, sid == SID_RTSpheres))
1794  if (ImGui::MenuItem("Soft Shadows", nullptr, sid == SID_RTSoftShadows))
1796  if (ImGui::MenuItem("Depth of Field", nullptr, sid == SID_RTDoF))
1798  if (ImGui::MenuItem("Lens Test", nullptr, sid == SID_RTLens))
1800 
1801  ImGui::EndMenu();
1802  }
1803 
1804  if (ImGui::BeginMenu("Path Tracing"))
1805  {
1806  if (ImGui::MenuItem("Muttenzer Box Glossy", nullptr, sid == SID_PTMuttenzerBox))
1808  if (ImGui::MenuItem("Muttenzer Box Soft", nullptr, sid == SID_PTMuttenzerBox2))
1810 
1811  ImGui::EndMenu();
1812  }
1813 
1814  if (ImGui::BeginMenu("Particle Systems"))
1815  {
1816  if (ImGui::MenuItem("First Particle System", nullptr, sid == SID_ParticleSystem_Simple))
1818  if (ImGui::MenuItem("Dust Storm Particle System", nullptr, sid == SID_ParticleSystem_DustStorm))
1820  if (ImGui::MenuItem("Fountain Particle System", nullptr, sid == SID_ParticleSystem_Fountain))
1822  if (ImGui::MenuItem("Sun Particle System", nullptr, sid == SID_ParticleSystem_Sun))
1824  if (ImGui::MenuItem("Ring of Fire Particle System", nullptr, sid == SID_ParticleSystem_RingOfFire))
1826  if (ImGui::MenuItem("Complex Fire Particle System", nullptr, sid == SID_ParticleSystem_ComplexFire))
1828  if (ImGui::MenuItem("Particle system w. 1 mio. particles", nullptr, sid == SID_ParticleSystem_Many))
1830 
1831  ImGui::EndMenu();
1832  }
1833 
1834  // Download content from pallas/home/private/projects/2020.Erleb-AR/erleb-AR-data/productive/models_for_SLProject
1835  // and copy it into AppCommon::dataPath + "erleb-AR/models/
1836  // This data is copyright protected and can only be accessed with user and password
1837  SLstring erlebarPath = AppCommon::dataPath + "erleb-AR/models/";
1838  SLstring modelBR2 = erlebarPath + "bern/bern-christoffel.gltf";
1839  SLstring modelBFH = erlebarPath + "biel/Biel-BFH-Rolex.gltf";
1840  SLstring modelCBB = erlebarPath + "biel/Biel-CBB-AR.gltf";
1841  SLstring modelAR1 = erlebarPath + "augst/augst-thtL1-tmpL2.gltf";
1842  SLstring modelAR2 = erlebarPath + "augst/augst-thtL2-tmpL1.gltf";
1843  SLstring modelAR3 = erlebarPath + "augst/augst-thtL1L2-tmpL1L2.gltf";
1844  SLstring modelAV1_AO = erlebarPath + "avenches/avenches-amphitheater.gltf";
1845  SLstring modelAV2_AO = erlebarPath + "avenches/avenches-cigognier.gltf";
1846  SLstring modelAV3 = erlebarPath + "avenches/avenches-theater.gltf";
1847  SLstring modelSU1 = erlebarPath + "sutz/Sutz-Kirchrain18.gltf";
1848 
1849  if (Utils::fileExists(modelAR1) ||
1850  Utils::fileExists(modelAR2) ||
1851  Utils::fileExists(modelAR3) ||
1852  Utils::fileExists(modelAV3) ||
1853  Utils::fileExists(modelBR2) ||
1854  Utils::fileExists(modelCBB) ||
1855  Utils::fileExists(modelSU1))
1856  {
1857  if (ImGui::BeginMenu("Erleb-AR"))
1858  {
1859  if (Utils::fileExists(modelBR2))
1860  if (ImGui::MenuItem("Bern: Christoffel Tower", nullptr, sid == SID_ErlebAR_BernChristoffel))
1862 
1863  if (Utils::fileExists(modelBFH))
1864  if (ImGui::MenuItem("Biel: BFH", nullptr, sid == SID_ErlebAR_BielBFH))
1866 
1867  if (Utils::fileExists(modelCBB))
1868  if (ImGui::MenuItem("Biel: CBB", nullptr, sid == SID_ErlebAR_BielCBB))
1870 
1871  if (Utils::fileExists(modelAR3))
1872  if (ImGui::MenuItem("Augusta Raurica Temple & Theater", nullptr, sid == SID_ErlebAR_AugustaRauricaTmpTht))
1874 
1875  if (Utils::fileExists(modelAV1_AO))
1876  if (ImGui::MenuItem("Aventicum: Amphitheatre", nullptr, sid == SID_ErlebAR_AventicumAmphiteatre))
1878 
1879  if (Utils::fileExists(modelAV2_AO))
1880  if (ImGui::MenuItem("Aventicum: Cigognier", nullptr, sid == SID_ErlebAR_AventicumCigognier))
1882 
1883  if (Utils::fileExists(modelAV3))
1884  if (ImGui::MenuItem("Aventicum: Theatre", nullptr, sid == SID_ErlebAR_AventicumTheatre))
1886 
1887  if (Utils::fileExists(modelSU1))
1888  if (ImGui::MenuItem("Sutz: Kirchrain 18", nullptr, sid == SID_ErlebAR_SutzKirchrain18))
1890 
1891  ImGui::EndMenu();
1892  }
1893  }
1894 
1895  if (ImGui::BeginMenu("Benchmarks"))
1896  {
1897 #ifndef SL_EMSCRIPTEN
1898  /* The large models are too large for emscripten
1899  if (ImGui::MenuItem("Large Model (via FTP)", nullptr, sid == SID_Benchmark_LargeModel))
1900  {
1901  SLstring largeFile = AppCommon::configPath + "models/xyzrgb_dragon/xyzrgb_dragon.ply";
1902  if (Utils::fileExists(largeFile))
1903  AppCommon::sceneToLoad = SID_Benchmark_LargeModel;
1904  else
1905  {
1906  auto downloadJobFTP = []() {
1907  AppCommon::jobProgressMsg("Downloading large dragon file via FTP:");
1908  AppCommon::jobProgressMax(100);
1909  ftplib ftp;
1910  ftp.SetConnmode(ftplib::connmode::port); // enable active mode
1911 
1912  if (ftp.Connect("pallas.ti.bfh.ch:21"))
1913  {
1914  if (ftp.Login("guest", "g2Q7Z7OkDP4!"))
1915  {
1916  ftp.SetCallbackXferFunction(ftpCallbackXfer);
1917  ftp.SetCallbackBytes(1024000);
1918  if (ftp.Chdir("data/SLProject/models"))
1919  {
1920  int remoteSize = 0;
1921  ftp.Size("xyzrgb_dragon.zip",
1922  &remoteSize,
1923  ftplib::transfermode::image);
1924  ftpXferSizeMax = remoteSize;
1925  SLstring dstDir = AppCommon::configPath;
1926  if (Utils::dirExists(dstDir))
1927  {
1928  SLstring outFile = AppCommon::configPath + "models/xyzrgb_dragon.zip";
1929  if (!ftp.Get(outFile.c_str(),
1930  "xyzrgb_dragon.zip",
1931  ftplib::transfermode::image))
1932  SL_LOG("*** ERROR: ftp.Get failed. ***");
1933  }
1934  else
1935  SL_LOG("*** ERROR: Destination directory does not exist: %s ***", dstDir.c_str());
1936  }
1937  else
1938  SL_LOG("*** ERROR: ftp.Chdir failed. ***");
1939  }
1940  else
1941  SL_LOG("*** ERROR: ftp.Login failed. ***");
1942  }
1943  else
1944  SL_LOG("*** ERROR: ftp.Connect failed. ***");
1945 
1946  ftp.Quit();
1947  AppCommon::jobIsRunning = false;
1948  };
1949 
1950  auto unzipJob = [largeFile]() {
1951  AppCommon::jobProgressMsg("Decompress dragon file:");
1952  AppCommon::jobProgressMax(-1);
1953  string zipFile = AppCommon::configPath + "models/xyzrgb_dragon.zip";
1954  if (Utils::fileExists(zipFile))
1955  {
1956  ZipUtils::unzip(zipFile, Utils::getPath(zipFile));
1957  Utils::deleteFile(zipFile);
1958  }
1959  AppCommon::jobIsRunning = false;
1960  };
1961 
1962  auto followUpJob1 = [am, s, sv, largeFile]() {
1963  if (Utils::fileExists(largeFile))
1964  AppCommon::sceneToLoad = SID_Benchmark_LargeModel;
1965  };
1966 
1967  AppCommon::jobsToBeThreaded.emplace_back(downloadJobFTP);
1968  AppCommon::jobsToBeThreaded.emplace_back(unzipJob);
1969  AppCommon::jobsToFollowInMain.emplace_back(followUpJob1);
1970  }
1971  }
1972  if (ImGui::MenuItem("Large Model (via HTTPS)", nullptr, sid == SID_Benchmark_LargeModel))
1973  {
1974  SLstring largeFile = AppCommon::configPath + "models/xyzrgb_dragon/xyzrgb_dragon.ply";
1975  loadSceneWithLargeModel(s, sv, "xyzrgb_dragon.zip", largeFile, SID_Benchmark_LargeModel);
1976  }*/
1977 #endif
1978  if (ImGui::MenuItem("Large Model", nullptr, sid == SID_Benchmark_LargeModel))
1980  if (ImGui::MenuItem("Massive Nodes", nullptr, sid == SID_Benchmark_LotsOfNodes))
1982  if (ImGui::MenuItem("Massive Node Animations", nullptr, sid == SID_Benchmark_NodeAnimations))
1984  if (ImGui::MenuItem("Jan's Universe", nullptr, sid == SID_Benchmark_JansUniverse))
1986  if (ImGui::MenuItem("Massive Skinned Animations", nullptr, sid == SID_Benchmark_SkinnedAnimations))
1988  if (ImGui::MenuItem("Columns without LOD", nullptr, sid == SID_Benchmark_ColumnsNoLOD))
1990  if (ImGui::MenuItem("Columns with LOD", nullptr, sid == SID_Benchmark_ColumnsLOD))
1992  if (ImGui::MenuItem("Particle System lot of fire complex", nullptr, sid == SID_Benchmark_ParticleSystemComplexFire))
1994  if (ImGui::MenuItem("Particle System w. 1 mio. particle", nullptr, sid == SID_ParticleSystem_Many))
1996  ImGui::EndMenu();
1997  }
1998 
1999  ImGui::EndMenu();
2000  }
2001 
2002  if (ImGui::MenuItem("Empty Scene", "Shift-Alt-0", sid == SID_Empty))
2004 
2005  if (ImGui::MenuItem("Next Scene",
2006  "Shift-Alt->",
2007  nullptr,
2010 
2011  if (ImGui::MenuItem("Previous Scene",
2012  "Shift-Alt-<",
2013  nullptr,
2016 
2017 #ifndef SL_EMSCRIPTEN
2018  ImGui::Separator();
2019 
2020  if (ImGui::MenuItem("Multi-threaded Jobs"))
2021  {
2022  auto job1 = []()
2023  {
2024  PROFILE_THREAD("Worker Thread 1");
2025  PROFILE_SCOPE("Parallel Job 1");
2026 
2027  uint maxIter = 100000;
2028  AppCommon::jobProgressMsg("Super long job 1");
2030  for (uint i = 0; i < maxIter; ++i)
2031  {
2032  SL_LOG("%u", i);
2033  int progressPC = (int)((float)i / (float)maxIter * 100.0f);
2034  AppCommon::jobProgressNum(progressPC);
2035  }
2036  AppCommon::jobIsRunning = false;
2037  };
2038 
2039  auto job2 = []()
2040  {
2041  PROFILE_THREAD("Worker Thread 2");
2042  PROFILE_SCOPE("Parallel Job 2");
2043 
2044  uint maxIter = 100000;
2045  AppCommon::jobProgressMsg("Super long job 2");
2047  for (uint i = 0; i < maxIter; ++i)
2048  {
2049  SL_LOG("%u", i);
2050  int progressPC = (int)((float)i / (float)maxIter * 100.0f);
2051  AppCommon::jobProgressNum(progressPC);
2052  }
2053  AppCommon::jobIsRunning = false;
2054  };
2055 
2056  auto followUpJob1 = []()
2057  { SL_LOG("followUpJob1"); };
2058  auto jobToFollow2 = []()
2059  { SL_LOG("JobToFollow2"); };
2060 
2061  AppCommon::jobsToBeThreaded.emplace_back(job1);
2062  AppCommon::jobsToBeThreaded.emplace_back(job2);
2063  AppCommon::jobsToFollowInMain.emplace_back(followUpJob1);
2064  AppCommon::jobsToFollowInMain.emplace_back(jobToFollow2);
2065  }
2066 #endif
2067 
2068 #if !defined(SL_OS_ANDROID) && !defined(SL_EMSCRIPTEN)
2069  ImGui::Separator();
2070 
2071  if (ImGui::MenuItem("Quit & Save"))
2072  slShouldClose(true);
2073 #endif
2074 
2075  ImGui::EndMenu();
2076  }
2077 
2078  if (ImGui::BeginMenu("Preferences"))
2079  {
2080  if (ImGui::MenuItem("Do Wait on Idle", "I", sv->doWaitOnIdle()))
2082 
2083  if (ImGui::MenuItem("Do Multi Sampling", "L", sv->doMultiSampling()))
2085 
2086  if (ImGui::MenuItem("Do Frustum Culling", "F", sv->doFrustumCulling()))
2088 
2089  if (ImGui::MenuItem("Do Alpha Sorting", "J", sv->doAlphaSorting()))
2091 
2092  if (ImGui::MenuItem("Do Depth Test", "T", sv->doDepthTest()))
2093  sv->doDepthTest(!sv->doDepthTest());
2094 
2095  if (ImGui::MenuItem("Animation off", "Space", s->stopAnimations()))
2097 
2098  ImGui::Separator();
2099 
2100  if (ImGui::BeginMenu("Viewport Aspect"))
2101  {
2102  SLVec2i videoAspect(0, 0);
2103  if (capture->videoType() != VT_NONE)
2104  {
2105  videoAspect.x = capture->captureSize.width;
2106  videoAspect.y = capture->captureSize.height;
2107  }
2108  SLchar strSameAsVideo[256];
2109  snprintf(strSameAsVideo, sizeof(strSameAsVideo), "Same as Video (%d:%d)", videoAspect.x, videoAspect.y);
2110 
2111  if (ImGui::MenuItem("Same as window", nullptr, sv->viewportRatio() == SLVec2i::ZERO))
2112  sv->setViewportFromRatio(SLVec2i(0, 0), sv->viewportAlign(), false);
2113  if (ImGui::MenuItem(strSameAsVideo, nullptr, sv->viewportSameAsVideo()))
2114  sv->setViewportFromRatio(videoAspect, sv->viewportAlign(), true);
2115  if (ImGui::MenuItem("16:9", nullptr, sv->viewportRatio() == SLVec2i(16, 9)))
2116  sv->setViewportFromRatio(SLVec2i(16, 9), sv->viewportAlign(), false);
2117  if (ImGui::MenuItem("4:3", nullptr, sv->viewportRatio() == SLVec2i(4, 3)))
2118  sv->setViewportFromRatio(SLVec2i(4, 3), sv->viewportAlign(), false);
2119  if (ImGui::MenuItem("2:1", nullptr, sv->viewportRatio() == SLVec2i(2, 1)))
2120  sv->setViewportFromRatio(SLVec2i(2, 1), sv->viewportAlign(), false);
2121  if (ImGui::MenuItem("1:1", nullptr, sv->viewportRatio() == SLVec2i(1, 1)))
2122  sv->setViewportFromRatio(SLVec2i(1, 1), sv->viewportAlign(), false);
2123 
2124  if (ImGui::BeginMenu("Alignment", sv->viewportRatio() != SLVec2i::ZERO))
2125  {
2126  if (ImGui::MenuItem("Center", nullptr, sv->viewportAlign() == VA_center))
2128  if (ImGui::MenuItem("Left or bottom", nullptr, sv->viewportAlign() == VA_leftOrBottom))
2130 
2131  ImGui::EndMenu();
2132  }
2133  ImGui::EndMenu();
2134  }
2135 
2136  ImGui::Separator();
2137 
2138  // Rotation and Location Sensor
2139 #if defined(SL_OS_ANDROID) || defined(SL_OS_MACIOS)
2140  if (ImGui::BeginMenu("Rotation Sensor"))
2141  {
2143 
2144  if (ImGui::MenuItem("Use Device Rotation (IMU)", nullptr, devRot.isUsed()))
2145  devRot.isUsed(!AppCommon::devRot.isUsed());
2146 
2147  if (devRot.isUsed())
2148  {
2149  SLint numAveraged = devRot.numAveraged();
2150  if (ImGui::SliderInt("Average length", &numAveraged, 1, 10))
2151  devRot.numAveraged(numAveraged);
2152 
2153  if (ImGui::BeginMenu("Offset Mode"))
2154  {
2155  SLRotOffsetMode om = devRot.offsetMode();
2156  if (ImGui::MenuItem("None", nullptr, om == ROM_none))
2157  devRot.offsetMode(ROM_none);
2158  if (ImGui::MenuItem("Finger rot. X", nullptr, om == ROM_oneFingerX))
2159  devRot.offsetMode(ROM_oneFingerX);
2160  if (ImGui::MenuItem("Finger rot. X and Y", nullptr, om == ROM_oneFingerXY))
2161  devRot.offsetMode(ROM_oneFingerXY);
2162 
2163  ImGui::EndMenu();
2164  }
2165 
2166  if (ImGui::MenuItem("Zero Yaw at Start", nullptr, devRot.zeroYawAtStart()))
2167  devRot.zeroYawAtStart(!devRot.zeroYawAtStart());
2168 
2169  if (ImGui::MenuItem("Reset Zero Yaw"))
2170  devRot.hasStarted(true);
2171 
2172  if (ImGui::MenuItem("Show Horizon", nullptr, _horizonVisuEnabled))
2173  {
2174  if (_horizonVisuEnabled)
2175  hideHorizon(s);
2176  else
2177  showHorizon(s, sv);
2178  }
2179  }
2180 
2181  ImGui::EndMenu();
2182  }
2183 
2184  if (ImGui::BeginMenu("Location Sensor"))
2185  {
2187 
2188  if (ImGui::MenuItem("Use Device Location (GPS)", nullptr, AppCommon::devLoc.isUsed()))
2190 
2191  if (!AppCommon::devLoc.geoTiffIsAvailableAndValid())
2192  if (ImGui::MenuItem("Use Origin Altitude", nullptr, AppCommon::devLoc.useOriginAltitude()))
2194 
2195  if (ImGui::MenuItem("Reset Origin to here"))
2197 
2198  if (ImGui::BeginMenu("Offset Mode"))
2199  {
2200  SLLocOffsetMode om = devLoc.offsetMode();
2201  if (ImGui::MenuItem("None", nullptr, om == LOM_none))
2202  devLoc.offsetMode(LOM_none);
2203  if (ImGui::MenuItem("Two Finger Y", nullptr, om == LOM_twoFingerY))
2204  devLoc.offsetMode(LOM_twoFingerY);
2205 
2206  ImGui::EndMenu();
2207  }
2208 
2209  ImGui::EndMenu();
2210  }
2211 #endif
2212 
2213  if (ImGui::BeginMenu("Video Sensor"))
2214  {
2215  CVCamera* ac = capture->activeCamera;
2216  if (ImGui::BeginMenu("Mirror Camera"))
2217  {
2218  if (ImGui::MenuItem("Horizontally", nullptr, ac->mirrorH()))
2219  {
2220  ac->toggleMirrorH();
2221  // make a guessed calibration, if there was a calibrated camera it is not valid anymore
2222  ac->calibration = guessCalibration(ac->mirrorH(), ac->mirrorV(), ac->type());
2223  }
2224 
2225  if (ImGui::MenuItem("Vertically", nullptr, ac->mirrorV()))
2226  {
2227  ac->toggleMirrorV();
2228  // make a guessed calibration, if there was a calibrated camera it is not valid anymore
2229  ac->calibration = guessCalibration(ac->mirrorH(), ac->mirrorV(), ac->type());
2230  }
2231 
2232  ImGui::EndMenu();
2233  }
2234 
2235  if (ImGui::BeginMenu("Resolution",
2236  (capture->videoType() == VT_MAIN ||
2237  capture->videoType() == VT_SCND)))
2238  {
2239  for (int i = 0; i < (int)capture->camSizes.size(); ++i)
2240  {
2241  SLchar menuStr[256];
2242  snprintf(menuStr,
2243  sizeof(menuStr),
2244  "%d x %d",
2245  capture->camSizes[(uint)i].width,
2246  capture->camSizes[(uint)i].height);
2247  if (ImGui::MenuItem(menuStr, nullptr, i == capture->activeCamSizeIndex))
2248  if (i != capture->activeCamSizeIndex)
2249  ac->camSizeIndex(i);
2250  }
2251  ImGui::EndMenu();
2252  }
2253 
2254 #ifndef SL_EMSCRIPTEN
2255  if (ImGui::BeginMenu("Calibration"))
2256  {
2257  if (ImGui::MenuItem("Start Calibration (Main Camera)"))
2258  {
2260  showHelpCalibration = false;
2261  showInfosScene = true;
2262  }
2263 
2264  if (ImGui::MenuItem("Start Calibration (Scnd. Camera)", nullptr, false, capture->hasSecondaryCamera))
2265  {
2267  showHelpCalibration = false;
2268  showInfosScene = true;
2269  }
2270 
2271  if (ImGui::MenuItem("Undistort Image", nullptr, ac->showUndistorted(), ac->calibration.state() == CS_calibrated))
2272  ac->showUndistorted(!ac->showUndistorted());
2273 
2274  if (ImGui::MenuItem("No Tangent Distortion", nullptr, AppCommon::calibrationEstimatorParams.zeroTangentDistortion))
2276 
2277  if (ImGui::MenuItem("Fix Aspect Ratio", nullptr, AppCommon::calibrationEstimatorParams.fixAspectRatio))
2279 
2280  if (ImGui::MenuItem("Fix Principal Point", nullptr, AppCommon::calibrationEstimatorParams.fixPrincipalPoint))
2282 
2283  if (ImGui::MenuItem("Use rational model", nullptr, AppCommon::calibrationEstimatorParams.calibRationalModel))
2285 
2286  if (ImGui::MenuItem("Use tilted model", nullptr, AppCommon::calibrationEstimatorParams.calibTiltedModel))
2288 
2289  if (ImGui::MenuItem("Use thin prism model", nullptr, AppCommon::calibrationEstimatorParams.calibThinPrismModel))
2291 
2292  ImGui::EndMenu();
2293  }
2294 
2295  CVTrackedFeatures* featureTracker = nullptr;
2296  if (gVideoTracker != nullptr && typeid(*gVideoTracker) == typeid(CVTrackedFeatures))
2297  featureTracker = (CVTrackedFeatures*)gVideoTracker;
2298 
2299  if (gVideoTracker != nullptr)
2300  if (ImGui::MenuItem("Draw Detection", nullptr, gVideoTracker->drawDetection()))
2302 
2303  if (ImGui::BeginMenu("Feature Tracking", featureTracker != nullptr) && featureTracker != nullptr)
2304  {
2305  if (ImGui::MenuItem("Force Relocation", nullptr, featureTracker->forceRelocation()))
2306  featureTracker->forceRelocation(!featureTracker->forceRelocation());
2307 
2308  if (ImGui::BeginMenu("Detector/Descriptor", featureTracker != nullptr))
2309  {
2310  CVDetectDescribeType type = featureTracker->type();
2311 
2312  if (ImGui::MenuItem("RAUL/RAUL", nullptr, type == DDT_RAUL_RAUL))
2313  featureTracker->type(DDT_RAUL_RAUL);
2314  if (ImGui::MenuItem("ORB/ORB", nullptr, type == DDT_ORB_ORB))
2315  featureTracker->type(DDT_ORB_ORB);
2316  if (ImGui::MenuItem("FAST/BRIEF", nullptr, type == DDT_FAST_BRIEF))
2317  featureTracker->type(DDT_FAST_BRIEF);
2318  if (ImGui::MenuItem("SURF/SURF", nullptr, type == DDT_SURF_SURF))
2319  featureTracker->type(DDT_SURF_SURF);
2320  if (ImGui::MenuItem("SIFT/SIFT", nullptr, type == DDT_SIFT_SIFT))
2321  featureTracker->type(DDT_SIFT_SIFT);
2322 
2323  ImGui::EndMenu();
2324  }
2325 
2326  ImGui::EndMenu();
2327  }
2328 #endif
2329 
2330  ImGui::EndMenu();
2331  }
2332 
2333  ImGui::Separator();
2334 
2335  ImGui::MenuItem("UI Preferences", nullptr, &showUIPrefs);
2336 
2337  ImGui::EndMenu();
2338  }
2339 
2340  if (ImGui::BeginMenu("Edit", s->singleNodeSelected() != nullptr || !sv->camera()->selectRect().isZero()))
2341  {
2342  if (s->singleNodeSelected())
2343  {
2344  buildMenuEdit(s, sv);
2345  }
2346  else
2347  {
2348  if (ImGui::MenuItem("Clear selection"))
2349  {
2350  sv->camera()->selectRect().setZero();
2351  sv->camera()->deselectRect().setZero();
2352  }
2353  }
2354 
2355  ImGui::EndMenu();
2356  }
2357 
2358  if (ImGui::BeginMenu("Renderer"))
2359  {
2360  if (ImGui::MenuItem("OpenGL", "ESC", rType == RT_gl))
2361  sv->renderType(RT_gl);
2362 
2363  if (ImGui::MenuItem("Ray Tracing", "R", rType == RT_rt))
2364  sv->startRaytracing(5);
2365 
2366  if (ImGui::MenuItem("Path Tracing", "P", rType == RT_pt))
2367  sv->startPathtracing(32, 10);
2368 
2369 #ifdef SL_HAS_OPTIX
2370  // Built with OptiX, but usable only if the driver and the GPU
2371  // actually produced a context and the kernels loaded. Greyed out
2372  // otherwise, which is exactly what a build without OptiX shows, so
2373  // the reason is in the log rather than in a dead menu entry.
2374  if (ImGui::MenuItem("Ray Tracing with OptiX",
2375  "Shift-R",
2376  rType == RT_optix_rt,
2377  SLOptix::available))
2378  sv->startOptixRaytracing(5);
2379 
2380  if (ImGui::MenuItem("Path Tracing with OptiX",
2381  "Shift-P",
2382  rType == RT_optix_pt,
2383  SLOptix::available))
2384  sv->startOptixPathtracing(5, 10);
2385 #else
2386  ImGui::MenuItem("Ray Tracing with OptiX", nullptr, false, false);
2387  ImGui::MenuItem("Path Tracing with OptiX", nullptr, false, false);
2388 #endif
2389  ImGui::EndMenu();
2390  }
2391 
2392  if (rType == RT_gl)
2393  {
2394  if (ImGui::BeginMenu("GL"))
2395  {
2396  if (ImGui::MenuItem("Mesh Wired", "M", sv->drawBits()->get(SL_DB_MESHWIRED)))
2398 
2399  if (ImGui::MenuItem("With hard edges", "H", sv->drawBits()->get(SL_DB_WITHEDGES)))
2401 
2402  if (ImGui::MenuItem("Only hard edges", "O", sv->drawBits()->get(SL_DB_ONLYEDGES)))
2404 
2405  if (ImGui::MenuItem("Normals", "N", sv->drawBits()->get(SL_DB_NORMALS)))
2407 
2408  if (ImGui::MenuItem("Bounding Rectangles", "U", sv->drawBits()->get(SL_DB_BRECT)))
2410 
2411  if (ImGui::MenuItem("Bounding Boxes", "B", sv->drawBits()->get(SL_DB_BBOX)))
2413 
2414  if (ImGui::MenuItem("Voxels", "V", sv->drawBits()->get(SL_DB_VOXELS)))
2416 
2417  if (ImGui::MenuItem("Axis", "X", sv->drawBits()->get(SL_DB_AXIS)))
2419 
2420  if (ImGui::MenuItem("Back Faces", "C", sv->drawBits()->get(SL_DB_CULLOFF)))
2422 
2423  if (ImGui::MenuItem("Skeleton", "K", sv->drawBits()->get(SL_DB_SKELETON)))
2425 
2426  if (ImGui::MenuItem("GPU Skinning", nullptr, sv->drawBits()->get(SL_DB_GPU_SKINNING)))
2428 
2429  if (ImGui::MenuItem("All off"))
2430  sv->drawBits()->allOff();
2431 
2432  if (ImGui::MenuItem("All on"))
2433  {
2437  sv->drawBits()->on(SL_DB_NORMALS);
2438  sv->drawBits()->on(SL_DB_VOXELS);
2439  sv->drawBits()->on(SL_DB_AXIS);
2440  sv->drawBits()->on(SL_DB_BBOX);
2442  sv->drawBits()->on(SL_DB_CULLOFF);
2444  }
2445 
2446  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2447  SLfloat gamma = SLLight::gamma;
2448  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2449  SLLight::gamma = gamma;
2450  ImGui::PopItemWidth();
2451 
2452  ImGui::EndMenu();
2453  }
2454  }
2455  else if (rType == RT_rt)
2456  {
2457  if (ImGui::BeginMenu("RT"))
2458  {
2459  SLRaytracer* rt = sv->raytracer();
2460 
2461  if (ImGui::BeginMenu("Resolution Factor"))
2462  {
2463  if (ImGui::MenuItem("1.00", nullptr, rt->resolutionFactorPC() == 100))
2464  {
2465  rt->resolutionFactor(1.0f);
2466  sv->startRaytracing(rt->maxDepth());
2467  }
2468  if (ImGui::MenuItem("0.50", nullptr, rt->resolutionFactorPC() == 50))
2469  {
2470  rt->resolutionFactor(0.5f);
2471  sv->startRaytracing(rt->maxDepth());
2472  }
2473  if (ImGui::MenuItem("0.25", nullptr, rt->resolutionFactorPC() == 25))
2474  {
2475  rt->resolutionFactor(0.25f);
2476  sv->startRaytracing(rt->maxDepth());
2477  }
2478 
2479  ImGui::EndMenu();
2480  }
2481 
2482  if (ImGui::MenuItem("Parallel distributed", nullptr, rt->doDistributed()))
2483  {
2484  rt->doDistributed(!rt->doDistributed());
2485  sv->startRaytracing(rt->maxDepth());
2486  }
2487 
2488  if (ImGui::MenuItem("Continuously", nullptr, rt->doContinuous()))
2489  {
2490  rt->doContinuous(!rt->doContinuous());
2491  sv->doWaitOnIdle(!rt->doContinuous());
2492  }
2493 
2494  if (ImGui::MenuItem("Fresnel Reflection", nullptr, rt->doFresnel()))
2495  {
2496  rt->doFresnel(!rt->doFresnel());
2497  sv->startRaytracing(rt->maxDepth());
2498  }
2499 
2500  if (ImGui::BeginMenu("Max. Depth"))
2501  {
2502  if (ImGui::MenuItem("1", nullptr, rt->maxDepth() == 1)) sv->startRaytracing(1);
2503  if (ImGui::MenuItem("2", nullptr, rt->maxDepth() == 2)) sv->startRaytracing(2);
2504  if (ImGui::MenuItem("3", nullptr, rt->maxDepth() == 3)) sv->startRaytracing(3);
2505  if (ImGui::MenuItem("5", nullptr, rt->maxDepth() == 5)) sv->startRaytracing(5);
2506  if (ImGui::MenuItem("Max. Contribution", nullptr, rt->maxDepth() == 0)) sv->startRaytracing(0);
2507 
2508  ImGui::EndMenu();
2509  }
2510 
2511  if (ImGui::BeginMenu("Anti-Aliasing Samples"))
2512  {
2513  if (ImGui::MenuItem("Off", nullptr, rt->aaSamples() == 1)) rt->aaSamples(1);
2514  if (ImGui::MenuItem("3x3", nullptr, rt->aaSamples() == 3)) rt->aaSamples(3);
2515  if (ImGui::MenuItem("5x5", nullptr, rt->aaSamples() == 5)) rt->aaSamples(5);
2516  if (ImGui::MenuItem("7x7", nullptr, rt->aaSamples() == 7)) rt->aaSamples(7);
2517  if (ImGui::MenuItem("9x9", nullptr, rt->aaSamples() == 9)) rt->aaSamples(9);
2518 
2519  ImGui::EndMenu();
2520  }
2521 
2522  if (ImGui::MenuItem("Save Rendered Image"))
2523  rt->saveImage();
2524 
2525  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2526  SLfloat gamma = rt->gamma();
2527  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2528  {
2529  rt->gamma(gamma);
2530  sv->startRaytracing(5);
2531  }
2532  ImGui::PopItemWidth();
2533 
2534  ImGui::EndMenu();
2535  }
2536  }
2537 
2538 #ifdef SL_HAS_OPTIX
2539  else if (rType == RT_optix_rt)
2540  {
2541  if (ImGui::BeginMenu("RT"))
2542  {
2543  SLOptixRaytracer* rt_optix = sv->optixRaytracer();
2544 
2545  if (ImGui::MenuItem("Parallel distributed", nullptr, rt_optix->doDistributed()))
2546  {
2547  rt_optix->doDistributed(!rt_optix->doDistributed());
2548  sv->startOptixRaytracing(rt_optix->maxDepth());
2549  }
2550 
2551  // if (ImGui::MenuItem("Fresnel Reflection", nullptr, rt->doFresnel()))
2552  // {
2553  // rt->doFresnel(!rt->doFresnel());
2554  // sv->startRaytracing(rt->maxDepth());
2555  // }
2556 
2557  if (ImGui::BeginMenu("Max. Depth"))
2558  {
2559  if (ImGui::MenuItem("1", nullptr, rt_optix->maxDepth() == 1))
2560  sv->startOptixRaytracing(1);
2561  if (ImGui::MenuItem("2", nullptr, rt_optix->maxDepth() == 2))
2562  sv->startOptixRaytracing(2);
2563  if (ImGui::MenuItem("3", nullptr, rt_optix->maxDepth() == 3))
2564  sv->startOptixRaytracing(3);
2565  if (ImGui::MenuItem("5", nullptr, rt_optix->maxDepth() == 5))
2566  sv->startOptixRaytracing(5);
2567  if (ImGui::MenuItem("Max. Contribution", nullptr, rt_optix->maxDepth() == 0))
2568  sv->startOptixRaytracing(0);
2569 
2570  ImGui::EndMenu();
2571  }
2572 
2573  // if (ImGui::BeginMenu("Anti-Aliasing Samples"))
2574  // {
2575  // if (ImGui::MenuItem("Off", nullptr, rt->aaSamples() == 1))
2576  // rt->aaSamples(1);
2577  // if (ImGui::MenuItem("3x3", nullptr, rt->aaSamples() == 3))
2578  // rt->aaSamples(3);
2579  // if (ImGui::MenuItem("5x5", nullptr, rt->aaSamples() == 5))
2580  // rt->aaSamples(5);
2581  // if (ImGui::MenuItem("7x7", nullptr, rt->aaSamples() == 7))
2582  // rt->aaSamples(7);
2583  // if (ImGui::MenuItem("9x9", nullptr, rt->aaSamples() == 9))
2584  // rt->aaSamples(9);
2585  //
2586  // ImGui::EndMenu();
2587  // }
2588 
2589  if (ImGui::MenuItem("Save Rendered Image"))
2590  rt_optix->saveImage();
2591 
2592  ImGui::EndMenu();
2593  }
2594  }
2595 #endif
2596  else if (rType == RT_pt)
2597  {
2598  if (ImGui::BeginMenu("PT"))
2599  {
2600  SLPathtracer* pt = sv->pathtracer();
2601 
2602  if (ImGui::BeginMenu("Resolution Factor"))
2603  {
2604  if (ImGui::MenuItem("1.00", nullptr, pt->resolutionFactorPC() == 100))
2605  {
2606  pt->resolutionFactor(1.0f);
2607  sv->startPathtracing(32, pt->aaSamples());
2608  }
2609  if (ImGui::MenuItem("0.50", nullptr, pt->resolutionFactorPC() == 50))
2610  {
2611  pt->resolutionFactor(0.5f);
2612  sv->startPathtracing(32, pt->aaSamples());
2613  }
2614  if (ImGui::MenuItem("0.25", nullptr, pt->resolutionFactorPC() == 25))
2615  {
2616  pt->resolutionFactor(0.25f);
2617  sv->startPathtracing(32, pt->aaSamples());
2618  }
2619 
2620  ImGui::EndMenu();
2621  }
2622 
2623  if (ImGui::BeginMenu("NO. of Samples"))
2624  {
2625  if (ImGui::MenuItem("1", nullptr, pt->aaSamples() == 1)) sv->startPathtracing(32, 1);
2626  if (ImGui::MenuItem("10", nullptr, pt->aaSamples() == 10)) sv->startPathtracing(32, 10);
2627  if (ImGui::MenuItem("100", nullptr, pt->aaSamples() == 100)) sv->startPathtracing(32, 100);
2628  if (ImGui::MenuItem("1000", nullptr, pt->aaSamples() == 1000)) sv->startPathtracing(32, 1000);
2629  if (ImGui::MenuItem("10000", nullptr, pt->aaSamples() == 10000)) sv->startPathtracing(32, 10000);
2630 
2631  ImGui::EndMenu();
2632  }
2633 
2634  if (ImGui::BeginMenu("Firefly Clamp"))
2635  {
2636  // Caps what a single sample may contribute. This is the
2637  // only deliberate bias in the path tracer: it darkens the
2638  // caustics it removes. The values bracket where the
2639  // fireflies of this scene actually are, between 3 and 10;
2640  // a limit of 30 was measured to do nothing at all.
2641  if (ImGui::MenuItem("Off (unbiased)", nullptr, pt->sampleClamp() == 0.0f))
2642  {
2643  pt->sampleClamp(0.0f);
2644  sv->startPathtracing(32, pt->aaSamples());
2645  }
2646  if (ImGui::MenuItem("10", nullptr, pt->sampleClamp() == 10.0f))
2647  {
2648  pt->sampleClamp(10.0f);
2649  sv->startPathtracing(32, pt->aaSamples());
2650  }
2651  if (ImGui::MenuItem("5", nullptr, pt->sampleClamp() == 5.0f))
2652  {
2653  pt->sampleClamp(5.0f);
2654  sv->startPathtracing(32, pt->aaSamples());
2655  }
2656  if (ImGui::MenuItem("3", nullptr, pt->sampleClamp() == 3.0f))
2657  {
2658  pt->sampleClamp(3.0f);
2659  sv->startPathtracing(32, pt->aaSamples());
2660  }
2661 
2662  ImGui::EndMenu();
2663  }
2664 
2665  if (ImGui::MenuItem("Direct illumination", nullptr, pt->calcDirect()))
2666  {
2667  pt->calcDirect(!pt->calcDirect());
2668  sv->startPathtracing(32, 10);
2669  }
2670 
2671  if (ImGui::MenuItem("Indirect illumination", nullptr, pt->calcIndirect()))
2672  {
2673  pt->calcIndirect(!pt->calcIndirect());
2674  sv->startPathtracing(32, 10);
2675  }
2676 
2677  if (ImGui::MenuItem("Save Rendered Image"))
2678  pt->saveImage();
2679 
2680  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2681  SLfloat gamma = pt->gamma();
2682  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2683  {
2684  pt->gamma(gamma);
2685  sv->startPathtracing(32, 1);
2686  }
2687  ImGui::PopItemWidth();
2688 
2689  ImGui::EndMenu();
2690  }
2691  }
2692 
2693 #ifdef SL_HAS_OPTIX
2694  else if (rType == RT_optix_pt)
2695  {
2696  if (ImGui::BeginMenu("PT"))
2697  {
2698  SLOptixPathtracer* pt = sv->optixPathtracer();
2699 
2700  if (ImGui::BeginMenu("NO. of Samples"))
2701  {
2702  if (ImGui::MenuItem("1", nullptr, pt->samples() == 1))
2703  sv->startOptixPathtracing(5, 1);
2704  if (ImGui::MenuItem("10", nullptr, pt->samples() == 10))
2705  sv->startOptixPathtracing(5, 10);
2706  if (ImGui::MenuItem("100", nullptr, pt->samples() == 100))
2707  sv->startOptixPathtracing(5, 100);
2708  if (ImGui::MenuItem("1000", nullptr, pt->samples() == 1000))
2709  sv->startOptixPathtracing(5, 1000);
2710  if (ImGui::MenuItem("10000", nullptr, pt->samples() == 10000))
2711  sv->startOptixPathtracing(5, 10000);
2712 
2713  ImGui::EndMenu();
2714  }
2715 
2716  if (ImGui::MenuItem("Denoiser", nullptr, pt->getDenoiserEnabled()))
2717  {
2718  pt->setDenoiserEnabled(!pt->getDenoiserEnabled());
2719  sv->startOptixPathtracing(5, pt->samples());
2720  }
2721 
2722  if (ImGui::MenuItem("Save Rendered Image"))
2723  pt->saveImage();
2724 
2725  ImGui::EndMenu();
2726  }
2727  }
2728 #endif
2729 
2730  if (ImGui::BeginMenu("Camera"))
2731  {
2732  SLCamera* cam = sv->camera();
2733  SLProjType proj = cam->projType();
2734 
2735  if (ImGui::MenuItem("Reset"))
2736  {
2737  cam->resetToInitialState();
2738  float dist = cam->translationOS().length();
2739  cam->focalDist(dist);
2740  }
2741 
2742  if (ImGui::BeginMenu("Look from"))
2743  {
2744  if (ImGui::MenuItem("Left (+X)", "3")) cam->lookFrom(SLVec3f::AXISX);
2745  if (ImGui::MenuItem("Right (-X)", "CTRL-3")) cam->lookFrom(-SLVec3f::AXISX);
2746  if (ImGui::MenuItem("Top (+Y)", "7")) cam->lookFrom(SLVec3f::AXISY, -SLVec3f::AXISZ);
2747  if (ImGui::MenuItem("Bottom (-Y)", "CTRL-7")) cam->lookFrom(-SLVec3f::AXISY, SLVec3f::AXISZ);
2748  if (ImGui::MenuItem("Front (+Z)", "1")) cam->lookFrom(SLVec3f::AXISZ);
2749  if (ImGui::MenuItem("Back (-Z)", "CTRL-1")) cam->lookFrom(-SLVec3f::AXISZ);
2750 
2751  if (s->numSceneCameras())
2752  {
2753  if (ImGui::MenuItem("Next camera in Scene", "TAB"))
2755 
2756  if (ImGui::MenuItem("Sceneview Camera", "TAB"))
2758  }
2759 
2760  ImGui::EndMenu();
2761  }
2762 
2763  if (ImGui::BeginMenu("Projection"))
2764  {
2765  static SLfloat clipN = cam->clipNear();
2766  static SLfloat clipF = cam->clipFar();
2767  static SLfloat focalDist = cam->focalDist();
2768  static SLfloat fov = cam->fovV();
2769 
2770  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2771 
2772  if (ImGui::MenuItem("Perspective", "5", proj == P_monoPerspective))
2773  {
2775  if (sv->renderType() == RT_rt && !sv->raytracer()->doContinuous() &&
2776  sv->raytracer()->state() == rtFinished)
2777  sv->raytracer()->state(rtReady);
2778  }
2779 
2780  if (ImGui::MenuItem("Orthographic", "5", proj == P_monoOrthographic))
2781  {
2783  if (sv->renderType() == RT_rt && !sv->raytracer()->doContinuous() &&
2784  sv->raytracer()->state() == rtFinished)
2785  sv->raytracer()->state(rtReady);
2786  }
2787 
2788  if (ImGui::BeginMenu("Stereo"))
2789  {
2790  for (SLint p = P_stereoSideBySide; p <= P_stereoColorYB; ++p)
2791  {
2793  if (ImGui::MenuItem(pStr.c_str(), nullptr, proj == (SLProjType)p))
2794  cam->projType((SLProjType)p);
2795  }
2796 
2797  if (proj >= P_stereoSideBySide)
2798  {
2799  ImGui::Separator();
2800  static SLfloat eyeSepar = cam->stereoEyeSeparation();
2801  if (ImGui::SliderFloat("Eye Sep.", &eyeSepar, 0.0f, focalDist / 10.f))
2802  cam->stereoEyeSeparation(eyeSepar);
2803  }
2804 
2805  ImGui::EndMenu();
2806  }
2807 
2808  ImGui::Separator();
2809 
2810  if (ImGui::SliderFloat("FOV (V)", &fov, 1.f, 179.f))
2811  cam->fov(fov);
2812 
2813  ImGui::Text("FOV (H): %3.1f ", cam->fovH());
2814 
2815  if (ImGui::SliderFloat("Near Clip", &clipN, 0.001f, 10.f))
2816  cam->clipNear(clipN);
2817 
2818  if (ImGui::SliderFloat("Focal Dist.", &focalDist, clipN, clipF))
2819  cam->focalDist(focalDist);
2820 
2821  if (ImGui::SliderFloat("Far Clip", &clipF, clipN, std::min(clipF * 1.1f, 1000000.f)))
2822  cam->clipFar(clipF);
2823 
2824  ImGui::PopItemWidth();
2825  ImGui::EndMenu();
2826  }
2827 
2828  if (ImGui::BeginMenu("Animation"))
2829  {
2830  SLCamAnim ca = cam->camAnim();
2831 
2832  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2833 
2834  if (ImGui::MenuItem("Turntable Y up", nullptr, ca == CA_turntableYUp))
2835  sv->camera()->camAnim(CA_turntableYUp);
2836 
2837  if (ImGui::MenuItem("Turntable Z up", nullptr, ca == CA_turntableZUp))
2838  sv->camera()->camAnim(CA_turntableZUp);
2839 
2840  if (ImGui::MenuItem("Trackball", nullptr, ca == CA_trackball))
2841  sv->camera()->camAnim(CA_trackball);
2842 
2843  if (ImGui::MenuItem("Walk Y up", nullptr, ca == CA_walkingYUp))
2844  sv->camera()->camAnim(CA_walkingYUp);
2845 
2846  if (ImGui::MenuItem("Walk Z up", nullptr, ca == CA_walkingZUp))
2847  sv->camera()->camAnim(CA_walkingZUp);
2848 
2849  float mouseRotFactor = sv->camera()->mouseRotationFactor();
2850  if (ImGui::SliderFloat("Mouse Sensibility", &mouseRotFactor, 0.1f, 2.0f, "%2.1f"))
2851  sv->camera()->mouseRotationFactor(mouseRotFactor);
2852 
2853  ImGui::Separator();
2854 
2855  if (ImGui::MenuItem("IMU rotated", nullptr, ca == CA_deviceRotYUp))
2856  sv->camera()->camAnim(CA_deviceRotYUp);
2857 
2858  if (ImGui::MenuItem("IMU rotated & GPS located", nullptr, ca == CA_deviceRotLocYUp))
2859  sv->camera()->camAnim(CA_deviceRotLocYUp);
2860 
2861  if (ca == CA_walkingZUp || ca == CA_walkingYUp || ca == CA_deviceRotYUp)
2862  {
2863  static SLfloat ms = cam->maxSpeed();
2864  if (ImGui::SliderFloat("Walk Speed", &ms, 0.01f, std::min(ms * 1.1f, 10000.f)))
2865  cam->maxSpeed(ms);
2866  }
2867 
2868  ImGui::PopItemWidth();
2869  ImGui::EndMenu();
2870  }
2871 
2872  if (ImGui::BeginMenu("Fog"))
2873  {
2874  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2875 
2876  if (ImGui::MenuItem("Fog is on", nullptr, cam->fogIsOn()))
2877  cam->fogIsOn(!cam->fogIsOn());
2878 
2879  if (ImGui::BeginMenu("Mode"))
2880  {
2881  if (ImGui::MenuItem("linear", nullptr, cam->fogMode() == FM_linear))
2882  cam->fogMode(FM_linear);
2883  if (ImGui::MenuItem("exp", nullptr, cam->fogMode() == FM_exp))
2884  cam->fogMode(FM_exp);
2885  if (ImGui::MenuItem("exp2", nullptr, cam->fogMode() == FM_exp2))
2886  cam->fogMode(FM_exp2);
2887  ImGui::EndMenu();
2888  }
2889 
2890  if (cam->fogMode() == FM_exp || cam->fogMode() == FM_exp2)
2891  {
2892  static SLfloat fogDensity = cam->fogDensity();
2893  if (ImGui::SliderFloat("Density", &fogDensity, 0.0f, 0.2f))
2894  cam->fogDensity(fogDensity);
2895  }
2896 
2897  ImGui::PopItemWidth();
2898  ImGui::EndMenu();
2899  }
2900 
2901  ImGui::EndMenu();
2902  }
2903 
2904  if (ImGui::BeginMenu("Animation", hasAnimations))
2905  {
2906 
2907  if (ImGui::MenuItem("Stop all", "Space", s->stopAnimations()))
2909 
2910  ImGui::Separator();
2911 
2912  SLVstring animations = s->animManager().animationNames();
2913  if (curAnimIx == -1) curAnimIx = 0;
2914  SLAnimPlayback* anim = s->animManager().animPlaybackByIndex((SLuint)curAnimIx);
2915 
2916  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.8f);
2917  if (myComboBox("##", &curAnimIx, animations))
2918  anim = s->animManager().animPlaybackByIndex((SLuint)curAnimIx);
2919  ImGui::PopItemWidth();
2920 
2921  if (ImGui::MenuItem("Play forward", nullptr, anim->isPlayingForward()))
2922  anim->playForward();
2923 
2924  if (ImGui::MenuItem("Play backward", nullptr, anim->isPlayingBackward()))
2925  anim->playBackward();
2926 
2927  if (ImGui::MenuItem("Pause", nullptr, anim->isPaused()))
2928  anim->pause();
2929 
2930  if (ImGui::MenuItem("Stop", nullptr, anim->isStopped()))
2931  anim->enabled(false);
2932 
2933  if (ImGui::MenuItem("Skip to next keyfr.", nullptr, false))
2934  anim->skipToNextKeyframe();
2935 
2936  if (ImGui::MenuItem("Skip to prev. keyfr.", nullptr, false))
2937  anim->skipToPrevKeyframe();
2938 
2939  if (ImGui::MenuItem("Skip to start", nullptr, false))
2940  anim->skipToStart();
2941 
2942  if (ImGui::MenuItem("Skip to end", nullptr, false))
2943  anim->skipToEnd();
2944 
2945  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.6f);
2946 
2947  SLfloat speed = anim->playbackRate();
2948  if (ImGui::SliderFloat("Speed", &speed, 0.f, 4.f))
2949  anim->playbackRate(speed);
2950 
2951  SLfloat lenSec = anim->parentAnimation()->lengthSec();
2952  SLfloat localTimeSec = anim->localTime();
2953  if (ImGui::SliderFloat("Time", &localTimeSec, 0.f, lenSec))
2954  anim->localTime(localTimeSec);
2955 
2956  SLint curEasing = (SLint)anim->easing();
2957  const char* easings[] = {"linear",
2958  "in quad",
2959  "out quad",
2960  "in out quad",
2961  "out in quad",
2962  "in cubic",
2963  "out cubic",
2964  "in out cubic",
2965  "out in cubic",
2966  "in quart",
2967  "out quart",
2968  "in out quart",
2969  "out in quart",
2970  "in quint",
2971  "out quint",
2972  "in out quint",
2973  "out in quint",
2974  "in sine",
2975  "out sine",
2976  "in out sine",
2977  "out in sine"};
2978  if (ImGui::Combo("Easing", &curEasing, easings, IM_ARRAYSIZE(easings)))
2979  anim->easing((SLEasingCurve)curEasing);
2980 
2981  ImGui::PopItemWidth();
2982  ImGui::EndMenu();
2983  }
2984 
2985  if (ImGui::BeginMenu("Infos"))
2986  {
2987  ImGui::MenuItem("Infos on Scene", nullptr, &showInfosScene);
2988 
2989  if (ImGui::BeginMenu("Statistics"))
2990  {
2991  ImGui::MenuItem("Stats on Timing", nullptr, &showStatsTiming);
2992  ImGui::MenuItem("Stats on Scene", nullptr, &showStatsScene);
2993  ImGui::MenuItem("Stats on Video", nullptr, &showStatsVideo);
2994 #ifdef SL_BUILD_WAI
2996  ImGui::MenuItem("Stats on WAI", nullptr, &showStatsWAI);
2997 #endif
2998  ImGui::MenuItem("Stats on ImGui", nullptr, &showImGuiMetrics);
2999  ImGui::EndMenu();
3000  }
3001 
3002  ImGui::MenuItem("Scenegraph", nullptr, &showSceneGraph);
3003  ImGui::MenuItem("Properties", nullptr, &showProperties);
3004  ImGui::MenuItem("Transform", nullptr, &showTransform);
3005  if (AppCommon::devLoc.originLatLonAlt() != SLVec3d::ZERO ||
3006  AppCommon::devLoc.defaultLatLonAlt() != SLVec3d::ZERO)
3007  ImGui::MenuItem("Date-Time", nullptr, &showDateAndTime);
3008  ImGui::MenuItem("UI-Preferences", nullptr, &showUIPrefs);
3009  ImGui::Separator();
3010  ImGui::MenuItem("Infos on Device", nullptr, &showInfosDevice);
3011  ImGui::MenuItem("Infos on Sensors", nullptr, &showInfosSensors);
3014  {
3015  ImGui::Separator();
3016  ImGui::MenuItem("ErlebAR Settings", nullptr, &showErlebAR);
3017  }
3018  ImGui::Separator();
3019  ImGui::MenuItem("Help on Interaction", nullptr, &showHelp);
3020  ImGui::MenuItem("Help on Calibration", nullptr, &showHelpCalibration);
3021  ImGui::Separator();
3022  ImGui::MenuItem("Credits", nullptr, &showCredits);
3023  ImGui::MenuItem("About SLProject", nullptr, &showAbout);
3024 
3025  ImGui::EndMenu();
3026  }
3027 
3028  ImGui::EndMainMenuBar();
3029  }
3030 }
bool myComboBox(const char *label, int *currIndex, SLVstring &values)
Combobox that allows to pass the items as a string vector.
Definition: AppDemoGui.cpp:85
CVCalibration guessCalibration(bool mirroredH, bool mirroredV, CVCameraType camType)
@ SID_SuzannePerPixBlinnNmSm
@ SID_Benchmark_SkinnedAnimations
@ SID_TextureBlend
@ SID_Minimal
@ SID_glTF_Sponza
@ SID_VideoTrackChessScnd
@ SID_ParticleSystem_Many
@ SID_SuzannePerPixBlinnTmAo
@ SID_VideoTrackMediaPipeHandsMain
@ SID_Benchmark_LargeModel
@ SID_PTMuttenzerBox
@ SID_SuzannePerPixBlinnTmSm
@ SID_SuzannePerPixBlinnAoSm
@ SID_ParticleSystem_ComplexFire
@ SID_ParticleSystem_RingOfFire
@ SID_ShaderSkybox
@ SID_RTSoftShadows
@ SID_Figure
@ SID_SuzannePerPixBlinnNm
@ SID_ShadowMappingSpotLights
@ SID_VideoTrackFaceScnd
@ SID_RTSpheres
@ SID_VideoSensorAR
@ SID_ErlebAR_BielBFH
@ SID_PointClouds
@ SID_ParticleSystem_DustStorm
@ SID_Revolver
@ SID_SuzannePerPixBlinnNmAo
@ SID_ShaderEarth
@ SID_VolumeRayCast
@ SID_VideoTextureLive
@ SID_AnimationNode
@ SID_ParticleSystem_Simple
@ SID_VideoCalibrateScnd
@ SID_Benchmark_JansUniverse
@ SID_Benchmark_ColumnsNoLOD
@ SID_MeshLoad
@ SID_PTMuttenzerBox2
@ SID_ParticleSystem_Fountain
@ SID_SuzannePerPixBlinnSm
@ SID_ShadowMappingLightTypes
@ SID_AnimationSkinnedMass
@ SID_VideoTextureFile
@ SID_SuzannePerPixBlinnTmNmSm
@ SID_ShaderPerPixelBlinn
@ SID_ZFighting
@ SID_SuzannePerPixBlinnTm
@ SID_Empty
@ SID_Benchmark_NodeAnimations
@ SID_Benchmark_ColumnsLOD
@ SID_ShadowMappingCascaded
@ SID_SuzannePerPixBlinnTmNmAoSm
@ SID_SuzannePerPixCookTmNmAoSmEm
@ SID_glTF_DamagedHelmet
@ SID_SuzannePerPixBlinn
@ SID_ShaderIBL
@ SID_ShadowMappingPointLights
@ SID_VideoTrackArucoMain
@ SID_glTF_FlightHelmet
@ SID_TextureFilter
@ SID_RTLens
@ SID_Benchmark_ParticleSystemComplexFire
@ SID_Benchmark_LotsOfNodes
@ SID_VideoTrackArucoScnd
@ SID_SuzannePerPixBlinnTmNmAo
@ SID_VideoTrackFeature2DMain
@ SID_ParticleSystem_Sun
@ SID_MaxPublicAssets
@ SID_VolumeRayCastLighted
@ SID_ShadowMappingBasicScene
@ SID_2Dand3DText
@ SID_VideoTrackFaceMain
@ SID_VideoCalibrateMain
@ SID_VideoTrackChessMain
@ SID_ShaderBumpParallax
@ SID_ShaderPerPixelCook
@ SID_ShaderWave
@ SID_SuzannePerPixBlinnAo
@ SID_SuzannePerPixBlinnTmNm
@ SID_TextureCompression
@ SID_ShaderBumpNormal
@ SID_Robotics_FanucCRX_FK
@ SID_glTF_WaterBottle
@ SID_FrustumCull
@ SID_ShaderPerVertexBlinn
@ SID_AnimationNodeMass
@ SID_AnimationSkinned
@ SID_RTDoF
static SLbool fixAspectRatio
Flag if wnd aspect ratio should be fixed.
Definition: AppGLFW.cpp:42
@ CS_calibrated
The camera is calibrated.
Definition: CVCalibration.h:33
@ VT_SCND
Selfie camera on mobile devices.
Definition: CVCapture.h:43
CVDetectDescribeType
Feature detector-decriptor types.
@ DDT_ORB_ORB
@ DDT_SURF_SURF
@ DDT_FAST_BRIEF
@ DDT_SIFT_SIFT
@ DDT_RAUL_RAUL
#define PROFILE_SCOPE(name)
Definition: Instrumentor.h:40
#define PROFILE_THREAD(name)
Definition: Profiler.h:38
#define SL_LOG(...)
Some debugging and error handling macros.
Definition: SL.h:279
vector< SLstring > SLVstring
Definition: SL.h:229
SLLocOffsetMode
Device location offset mode.
@ LOM_none
@ LOM_twoFingerY
SLRotOffsetMode
Device rotation offset mode.
@ ROM_oneFingerX
@ ROM_none
@ ROM_oneFingerXY
#define SL_DB_ONLYEDGES
Draw only hard edges.
Definition: SLDrawBits.h:31
#define SL_DB_NORMALS
Draw the vertex normals.
Definition: SLDrawBits.h:23
#define SL_DB_SKELETON
Draw the skeletons joints.
Definition: SLDrawBits.h:27
#define SL_DB_WITHEDGES
Draw faces with hard edges.
Definition: SLDrawBits.h:30
#define SL_DB_AXIS
Draw the coordinate axis of a node.
Definition: SLDrawBits.h:25
#define SL_DB_BRECT
Draw the bounding rectangle of a node.
Definition: SLDrawBits.h:32
#define SL_DB_VOXELS
Draw the voxels of the uniform grid.
Definition: SLDrawBits.h:26
#define SL_DB_GPU_SKINNING
Perform skinning on the GPU.
Definition: SLDrawBits.h:33
#define SL_DB_CULLOFF
Turn off face culling.
Definition: SLDrawBits.h:28
#define SL_DB_MESHWIRED
Draw polygons as wired mesh.
Definition: SLDrawBits.h:22
#define SL_DB_BBOX
Draw the bounding boxes of a node.
Definition: SLDrawBits.h:24
SLCamAnim
Enumeration for available camera animation types.
Definition: SLEnums.h:121
@ CA_turntableYUp
Orbiting around central object w. turntable rotation around y & right axis.
Definition: SLEnums.h:122
@ CA_walkingYUp
Walk translation with AWSD and look around rotation around y & right axis.
Definition: SLEnums.h:125
@ CA_deviceRotLocYUp
The device rotation controls the camera rotation and the GPS controls the Camera Translation.
Definition: SLEnums.h:128
@ CA_trackball
Orbiting around central object w. one rotation around one axis.
Definition: SLEnums.h:124
@ CA_deviceRotYUp
The device rotation controls the camera rotation.
Definition: SLEnums.h:127
@ CA_turntableZUp
Orbiting around central object w. turntable rotation around z & right axis.
Definition: SLEnums.h:123
@ CA_walkingZUp
Walk translation with AWSD and look around rotation around z & right axis.
Definition: SLEnums.h:126
SLProjType
Enumeration for different camera projections.
Definition: SLEnums.h:134
@ P_monoPerspective
standard mono pinhole perspective projection
Definition: SLEnums.h:135
@ P_stereoSideBySide
side-by-side
Definition: SLEnums.h:138
@ P_stereoColorYB
color masking for yellow-blue anaglyphs (ColorCode 3D)
Definition: SLEnums.h:147
@ P_monoOrthographic
standard mono orthographic projection
Definition: SLEnums.h:137
int SLSceneID
Scene identifier.
Definition: SLEnums.h:91
SLEasingCurve
Enumeration for animation easing curves.
Definition: SLEnums.h:180
@ FM_exp
Definition: SLEnums.h:265
@ FM_exp2
Definition: SLEnums.h:266
@ FM_linear
Definition: SLEnums.h:264
@ VA_leftOrBottom
Definition: SLEnums.h:256
@ VA_center
Definition: SLEnums.h:255
bool slShouldClose()
@ rtFinished
Definition: SLRaytracer.h:31
@ rtReady
Definition: SLRaytracer.h:29
SLVec2< SLint > SLVec2i
Definition: SLVec2.h:140
static optional< SLSceneID > sceneToLoad
Scene id to load at start up.
Definition: AppCommon.h:90
static CVCalibrationEstimatorParams calibrationEstimatorParams
Definition: AppCommon.h:106
static SLstring dataPath
Path to data directory (it is set platform dependent)
Definition: AppCommon.h:83
static SLbool _horizonVisuEnabled
Definition: AppDemoGui.h:88
static void showHorizon(SLScene *s, SLSceneView *sv)
Enables calculation and visualization of horizon line (using rotation sensors)
static void buildMenuEdit(SLScene *s, SLSceneView *sv)
Builds the edit menu that can be in the menu bar and the context menu.
static void hideHorizon(SLScene *s)
Disables calculation and visualization of horizon line.
CVCalibState state() const
bool mirrorH()
Definition: CVCamera.h:22
void toggleMirrorV()
Definition: CVCamera.h:34
CVCameraType type()
Definition: CVCamera.h:24
void toggleMirrorH()
Definition: CVCamera.h:33
bool mirrorV()
Definition: CVCamera.h:23
Encapsulation of the OpenCV Capture Device and holder of the last frame.
Definition: CVCapture.h:63
bool hasSecondaryCamera
flag if device has secondary camera
Definition: CVCapture.h:125
CVVSize camSizes
All possible camera sizes.
Definition: CVCapture.h:133
int activeCamSizeIndex
Currently active camera size index.
Definition: CVCapture.h:134
CVTrackedFeatures is the main part of the AR Christoffelturm scene.
CVDetectDescribeType type()
void drawDetection(bool draw)
Definition: CVTracked.h:60
SLAnimPlayback * animPlaybackByIndex(SLuint ix)
Definition: SLAnimManager.h:49
Manages the playback of an SLAnimation.
SLbool isPaused() const
SLbool enabled() const
SLfloat localTime() const
SLbool isPlayingBackward() const
SLbool isPlayingForward() const
SLbool isStopped() const
SLEasingCurve easing() const
SLfloat playbackRate() const
SLAnimation * parentAnimation()
SLfloat lengthSec() const
Definition: SLAnimation.h:72
void stereoEyeSeparation(const SLfloat es)
Definition: SLCamera.h:119
SLfloat fovV() const
Vertical field of view.
Definition: SLCamera.h:135
void clipFar(const SLfloat cFar)
Definition: SLCamera.h:109
SLfloat fovH() const
Horizontal field of view.
Definition: SLCamera.cpp:1504
void clipNear(const SLfloat cNear)
Definition: SLCamera.h:108
void focalDist(const SLfloat f)
Definition: SLCamera.h:116
void maxSpeed(const SLfloat ms)
Definition: SLCamera.h:112
void fogMode(const SLFogMode mode)
Definition: SLCamera.h:126
void projType(SLProjType p)
Definition: SLCamera.h:92
static SLstring projTypeToStr(SLProjType pt)
Returns the projection type as string.
Definition: SLCamera.cpp:419
void fogIsOn(const bool isOn)
Definition: SLCamera.h:125
void fov(const SLfloat fov)
vertical field of view
Definition: SLCamera.h:98
void lookFrom(const SLVec3f &fromDir, const SLVec3f &upDir=SLVec3f::AXISY)
Sets the view to look from a direction towards the current focal point.
Definition: SLCamera.cpp:974
void fogDensity(const float density)
Definition: SLCamera.h:127
void camAnim(SLCamAnim ca)
Definition: SLCamera.h:103
Encapsulation of a mobile device location set by the device's GPS sensor.
void useOriginAltitude(SLbool useGLA)
void offsetMode(SLLocOffsetMode lom)
void hasOrigin(SLbool hasOL)
Encapsulation of a mobile device rotation set by the device's IMU sensor.
void hasStarted(SLbool started)
void numAveraged(SLint numAvg)
Returns the device rotation averaged over multple frames.
void offsetMode(SLRotOffsetMode rom)
void zeroYawAtStart(SLbool zeroYaw)
void isUsed(SLbool isUsed)
Setter that turns on the device rotation sensor.
void toggle(SLuint bit)
Toggles the specified bit.
Definition: SLDrawBits.h:66
void allOff()
Turns all bits off.
Definition: SLDrawBits.h:48
void on(SLuint bit)
Turns the specified bit on.
Definition: SLDrawBits.h:51
static SLfloat gamma
final output gamma value
Definition: SLLight.h:204
void resetToInitialState()
Definition: SLNode.cpp:1092
SLVec3f translationOS() const
Definition: SLNode.h:469
void calcDirect(SLbool di)
Definition: SLPathtracer.h:39
void calcIndirect(SLbool ii)
Definition: SLPathtracer.h:40
void saveImage()
Saves the current PT image as PNG image.
void gamma(SLfloat g)
Definition: SLRaytracer.h:107
SLint resolutionFactorPC() const
Definition: SLRaytracer.h:127
void doContinuous(SLbool cont)
Definition: SLRaytracer.h:92
void state(SLRTState state)
Definition: SLRaytracer.h:81
void doFresnel(SLbool fresnel)
Definition: SLRaytracer.h:97
void maxDepth(SLint depth)
Definition: SLRaytracer.h:85
virtual void saveImage()
Saves the current RT image as PNG image.
void doDistributed(SLbool distrib)
Definition: SLRaytracer.h:91
SLint numSceneCameras()
Returns the number of camera nodes in the scene.
Definition: SLScene.cpp:353
void stopAnimations(SLbool stop)
Definition: SLScene.h:92
SLDrawBits * drawBits()
Definition: SLSceneView.h:202
void switchToNextCameraInScene()
Sets the active camera to the next in the scene.
void doMultiSampling(SLbool doMS)
Definition: SLSceneView.h:154
void doDepthTest(SLbool doDT)
Definition: SLSceneView.h:155
void startPathtracing(SLint maxDepth, SLint samples)
Starts the path tracer. maxDepth is only a safety net against an.
void switchToSceneViewCamera()
void viewportSameAsVideo(bool sameAsVideo)
Definition: SLSceneView.h:159
void startRaytracing(SLint maxDepth)
void doAlphaSorting(SLbool doAS)
Definition: SLSceneView.h:157
SLVec2i viewportRatio() const
Definition: SLSceneView.h:181
void setViewportFromRatio(const SLVec2i &vpRatio, SLViewportAlign vpAlignment, SLbool vpSameAsVideo)
Sets the viewport ratio and the viewport rectangle.
SLViewportAlign viewportAlign() const
Definition: SLSceneView.h:185
void doFrustumCulling(SLbool doFC)
Definition: SLSceneView.h:156
void doWaitOnIdle(SLbool doWI)
Definition: SLSceneView.h:153
SLNode * targetNode()
static SLVec2 ZERO
Definition: SLVec2.h:135
static SLVec3 AXISY
Definition: SLVec3.h:298
static SLVec3 AXISX
Definition: SLVec3.h:297
static SLVec3 AXISZ
Definition: SLVec3.h:299
bool fileExists(const string &pathfilename)
Returns true if a file exists.
Definition: Utils.cpp:894
bool zip(string path, string zipname)
Definition: ZipUtils.cpp:255

◆ buildMenuContext()

void AppDemoGui::buildMenuContext ( SLScene s,
SLSceneView sv 
)
static

Builds context menu if right mouse click is over non-imgui area.

Definition at line 3106 of file AppDemoGui.cpp.

3107 {
3108  // assert(s->assetManager() && "No asset manager assigned to scene!");
3109 
3110  if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) &&
3111  ImGui::IsMouseReleased(1))
3112  {
3113  ImGui::OpenPopup("Context Menu");
3114  }
3115 
3116  if (ImGui::BeginPopup("Context Menu"))
3117  {
3118  if (s->singleNodeSelected() != nullptr || !sv->camera()->selectRect().isZero())
3119  {
3120  if (s->singleNodeSelected())
3121  {
3122  buildMenuEdit(s, sv);
3123  ImGui::Separator();
3124 
3125  if (!showProperties)
3126  if (ImGui::MenuItem("Show Properties"))
3127  showProperties = true;
3128  }
3129  }
3130 
3131  if (AppDemoGui::hideUI)
3132  if (ImGui::MenuItem("Show user interface"))
3133  AppDemoGui::hideUI = false;
3134 
3135  if (!AppDemoGui::hideUI)
3136  if (ImGui::MenuItem("Hide user interface"))
3137  AppDemoGui::hideUI = true;
3138 
3139  if (s->root3D()->drawBits()->get(SL_DB_HIDDEN))
3140  if (ImGui::MenuItem("Show root node"))
3141  s->root3D()->drawBits()->toggle(SL_DB_HIDDEN);
3142 
3143  if (!s->root3D()->drawBits()->get(SL_DB_HIDDEN))
3144  if (ImGui::MenuItem("Hide root node"))
3145  s->root3D()->drawBits()->toggle(SL_DB_HIDDEN);
3146 
3147  if (ImGui::MenuItem("Capture Screen"))
3149 
3150  ImGui::EndPopup();
3151  }
3152 }
void screenCaptureIsRequested(bool doScreenCap)
Definition: SLSceneView.h:160

◆ buildMenuEdit()

void AppDemoGui::buildMenuEdit ( SLScene s,
SLSceneView sv 
)
static

Builds the edit menu that can be in the menu bar and the context menu.

Definition at line 3033 of file AppDemoGui.cpp.

3034 {
3035  if (ImGui::MenuItem("Deselect Node", "ESC"))
3037 
3038  ImGui::Separator();
3039 
3040  if (ImGui::MenuItem("Translate Node", nullptr, transformNode && transformNode->editMode() == NodeEditMode_Translate))
3041  {
3044  else
3046  }
3047  if (ImGui::MenuItem("Rotate Node", nullptr, transformNode && transformNode->editMode() == NodeEditMode_Rotate))
3048  {
3051  else
3053  }
3054  if (ImGui::MenuItem("Scale Node", nullptr, transformNode && transformNode->editMode() == NodeEditMode_Scale))
3055  {
3058  else
3060  }
3061 
3062  ImGui::Separator();
3063 
3064  if (ImGui::BeginMenu("Node Flags"))
3065  {
3066  SLNode* selN = s->singleNodeSelected();
3067 
3068  if (ImGui::MenuItem("Wired Mesh", nullptr, selN->drawBits()->get(SL_DB_MESHWIRED)))
3069  selN->drawBits()->toggle(SL_DB_MESHWIRED);
3070 
3071  if (ImGui::MenuItem("With hard edges", nullptr, selN->drawBits()->get(SL_DB_WITHEDGES)))
3072  selN->drawBits()->toggle(SL_DB_WITHEDGES);
3073 
3074  if (ImGui::MenuItem("Only hard edges", nullptr, selN->drawBits()->get(SL_DB_ONLYEDGES)))
3075  selN->drawBits()->toggle(SL_DB_ONLYEDGES);
3076 
3077  if (ImGui::MenuItem("Normals", nullptr, selN->drawBits()->get(SL_DB_NORMALS)))
3078  selN->drawBits()->toggle(SL_DB_NORMALS);
3079 
3080  if (ImGui::MenuItem("Bounding Rectangles", nullptr, selN->drawBits()->get(SL_DB_BRECT)))
3081  selN->drawBits()->toggle(SL_DB_BRECT);
3082 
3083  if (ImGui::MenuItem("Bounding Boxes", nullptr, selN->drawBits()->get(SL_DB_BBOX)))
3084  selN->drawBits()->toggle(SL_DB_BBOX);
3085 
3086  if (ImGui::MenuItem("Voxels", nullptr, selN->drawBits()->get(SL_DB_VOXELS)))
3087  selN->drawBits()->toggle(SL_DB_VOXELS);
3088 
3089  if (ImGui::MenuItem("Axis", nullptr, selN->drawBits()->get(SL_DB_AXIS)))
3090  selN->drawBits()->toggle(SL_DB_AXIS);
3091 
3092  if (ImGui::MenuItem("Back Faces", nullptr, selN->drawBits()->get(SL_DB_CULLOFF)))
3093  selN->drawBits()->toggle(SL_DB_CULLOFF);
3094 
3095  if (ImGui::MenuItem("Skeleton", nullptr, selN->drawBits()->get(SL_DB_SKELETON)))
3096  selN->drawBits()->toggle(SL_DB_SKELETON);
3097 
3098  if (ImGui::MenuItem("All off"))
3099  selN->drawBits()->allOff();
3100 
3101  ImGui::EndMenu();
3102  }
3103 }
@ NodeEditMode_Translate
@ NodeEditMode_Scale
@ NodeEditMode_Rotate
static void setTransformEditMode(SLScene *s, SLSceneView *sv, SLNodeEditMode editMode)
Adds a transform node for the selected node and toggles the edit mode.
virtual void editMode(SLNodeEditMode editMode)

◆ buildProperties()

void AppDemoGui::buildProperties ( SLScene s,
SLSceneView sv 
)
static

Builds the properties dialog once per frame.

Definition at line 3245 of file AppDemoGui.cpp.

3246 {
3247  PROFILE_FUNCTION();
3248 
3249  // assert(s->assetManager() && "No asset manager assigned to scene!");
3250 
3251  SLNode* singleNode = s->singleNodeSelected();
3252  SLMesh* singleFullMesh = s->singleMeshFullSelected();
3253  bool partialSelection = !s->selectedMeshes().empty() && !s->selectedMeshes()[0]->IS32.empty();
3254 
3255  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
3256  ImGui::Begin("Properties", &showProperties, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NoNavInputs);
3257  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 1.0f, 1.0f));
3258 
3259  if (ImGui::TreeNode("Scene Properties"))
3260  {
3261  if (s->lights().size() > 0)
3262  {
3263  ImGuiColorEditFlags cef = ImGuiColorEditFlags_NoInputs;
3264  SLCol4f gAC = s->lights()[0]->globalAmbient;
3265  if (ImGui::ColorEdit3("Global Ambient Color", (float*)&gAC, cef))
3266  s->lights()[0]->globalAmbient = gAC;
3267  }
3268 
3269  if (ImGui::TreeNode("Sky", "Skybox"))
3270  {
3271  if (s->skybox())
3272  {
3273  SLSkybox* sky = s->skybox();
3274 
3275  if (sky->isHDR())
3276  {
3277  float exposure = sky->exposure();
3278  if (ImGui::SliderFloat("Exposure", &exposure, 0.05f, 5.0f))
3279  sky->exposure(exposure);
3280 
3281  if (sky->environmentCubemap())
3283  if (sky->irradianceCubemap())
3285  if (sky->roughnessCubemap())
3287  if (sky->brdfLutTexture())
3288  showTexInfos(sky->brdfLutTexture());
3289  }
3290  else
3291  {
3292  ImGui::Text("No properties for skyboxes that are not used for lighting (HDR)");
3293  }
3294  }
3295  else
3296  {
3297  ImGui::Text("Skybox: None");
3298  }
3299  ImGui::TreePop();
3300  }
3301  ImGui::TreePop();
3302  }
3303 
3304  ImGui::PopStyleColor();
3305  ImGui::Separator();
3306 
3307  // Node and Mesh Properties
3308  if (sv->renderType() == RT_gl)
3309  {
3310  // Only single node and no partial mesh selection
3311  if (singleNode && !partialSelection)
3312  {
3313  if (ImGui::TreeNode("Node Properties"))
3314  {
3315  if (singleNode)
3316  {
3317  SLuint c = (SLuint)singleNode->children().size();
3318  SLuint m = singleNode->mesh() ? 1 : 0;
3319  ImGui::Text("Node name : %s", singleNode->name().c_str());
3320  ImGui::Text("# children : %u", c);
3321  ImGui::Text("# meshes : %u", m);
3322  if (ImGui::TreeNode("Drawing flags"))
3323  {
3324  SLbool db = singleNode->drawBit(SL_DB_HIDDEN);
3325  if (ImGui::Checkbox("Hide", &db))
3326  singleNode->drawBits()->set(SL_DB_HIDDEN, db);
3327 
3328  db = singleNode->drawBit(SL_DB_NOTSELECTABLE);
3329  if (ImGui::Checkbox("Not selectable", &db))
3330  singleNode->drawBits()->set(SL_DB_NOTSELECTABLE, db);
3331 
3332  db = singleNode->drawBit(SL_DB_MESHWIRED);
3333  if (ImGui::Checkbox("Show wireframe", &db))
3334  singleNode->drawBits()->set(SL_DB_MESHWIRED, db);
3335 
3336  db = singleNode->drawBit(SL_DB_WITHEDGES);
3337  if (ImGui::Checkbox("Show with hard edges", &db))
3338  singleNode->drawBits()->set(SL_DB_WITHEDGES, db);
3339 
3340  db = singleNode->drawBit(SL_DB_ONLYEDGES);
3341  if (ImGui::Checkbox("Show only hard edges", &db))
3342  singleNode->drawBits()->set(SL_DB_ONLYEDGES, db);
3343 
3344  db = singleNode->drawBit(SL_DB_NORMALS);
3345  if (ImGui::Checkbox("Show normals", &db))
3346  singleNode->drawBits()->set(SL_DB_NORMALS, db);
3347 
3348  db = singleNode->drawBit(SL_DB_VOXELS);
3349  if (ImGui::Checkbox("Show voxels", &db))
3350  singleNode->drawBits()->set(SL_DB_VOXELS, db);
3351 
3352  db = singleNode->drawBit(SL_DB_BBOX);
3353  if (ImGui::Checkbox("Show bounding boxes", &db))
3354  singleNode->drawBits()->set(SL_DB_BBOX, db);
3355 
3356  db = singleNode->drawBit(SL_DB_BRECT);
3357  if (ImGui::Checkbox("Show bounding rects", &db))
3358  singleNode->drawBits()->set(SL_DB_BRECT, db);
3359 
3360  db = singleNode->drawBit(SL_DB_AXIS);
3361  if (ImGui::Checkbox("Show axis", &db))
3362  singleNode->drawBits()->set(SL_DB_AXIS, db);
3363 
3364  db = singleNode->drawBit(SL_DB_CULLOFF);
3365  if (ImGui::Checkbox("Show back faces", &db))
3366  singleNode->drawBits()->set(SL_DB_CULLOFF, db);
3367 
3368  ImGui::TreePop();
3369  }
3370 
3371  if (ImGui::TreeNode("Local transform"))
3372  {
3373  SLMat4f om(singleNode->om());
3374  SLVec3f trn, rot, scl;
3375  om.decompose(trn, rot, scl);
3376  rot *= Utils::RAD2DEG;
3377 
3378  ImGui::Text("Translation : %s", trn.toString().c_str());
3379  ImGui::Text("Rotation : %s", rot.toString().c_str());
3380  ImGui::Text("Scaling : %s", scl.toString().c_str());
3381  ImGui::TreePop();
3382  }
3383 
3384  // Properties related to shadow mapping
3385  if (ImGui::TreeNode("Shadow mapping"))
3386  {
3387  SLbool castsShadows = singleNode->castsShadows();
3388  if (ImGui::Checkbox("Casts shadows", &castsShadows))
3389  singleNode->castsShadows(castsShadows);
3390 
3391  if (auto* light = dynamic_cast<SLLight*>(singleNode))
3392  {
3393  SLbool createsShadows = light->createsShadows();
3394  if (ImGui::Checkbox("Creates shadows", &createsShadows))
3395  light->createsShadows(createsShadows);
3396 
3397  if (createsShadows)
3398  {
3399  SLShadowMap* shadowMap = light->shadowMap();
3400 
3401  if (shadowMap != nullptr)
3402  {
3403  if (shadowMap->projection() == P_monoPerspective &&
3404  light->spotCutOffDEG() < 90.0f)
3405  {
3406  SLbool useCubemap = shadowMap->useCubemap();
3407  if (ImGui::Checkbox("Uses Cubemap", &useCubemap))
3408  shadowMap->useCubemap(useCubemap);
3409  }
3410 
3411  SLfloat clipNear = shadowMap->lightClipNear();
3412  SLfloat clipFar = shadowMap->lightClipFar();
3413  SLfloat factor = shadowMap->cascadesFactor();
3414 
3415  if (!shadowMap->useCascaded())
3416  {
3417  if (ImGui::SliderFloat("Near clipping plane", &clipNear, 0.01f, clipFar))
3418  shadowMap->clipNear(clipNear);
3419 
3420  if (ImGui::SliderFloat("Far clipping plane", &clipFar, clipNear, 200.0f))
3421  shadowMap->clipFar(clipFar);
3422  }
3423  else
3424  {
3425  SLint numCascades = shadowMap->numCascades();
3426  SLint maxCascades = shadowMap->maxCascades();
3427  if (ImGui::SliderInt("Number of cascades", &numCascades, 1, maxCascades))
3428  shadowMap->numCascades(numCascades);
3429  if (ImGui::SliderFloat("Cascades factor", &factor, 1.0, 500.0f))
3430  shadowMap->cascadesFactor(factor);
3431  }
3432 
3433  SLVec2i texSize = shadowMap->textureSize();
3434  if (ImGui::SliderInt2("Texture resolution", (int*)&texSize, 32, 4096))
3435  shadowMap->textureSize(
3436  SLVec2i((int)Utils::closestPowerOf2((unsigned)texSize.x),
3437  (int)Utils::closestPowerOf2((unsigned)texSize.y)));
3438 
3439  SLfloat shadowMinBias = light->shadowMinBias();
3440  SLfloat shadowMaxBias = light->shadowMaxBias();
3441  if (ImGui::SliderFloat("Min. shadow bias", &shadowMinBias, 0.0f, shadowMaxBias, "%.03f"))
3442  light->shadowMinBias(shadowMinBias);
3443  if (ImGui::SliderFloat("Max. shadow bias", &shadowMaxBias, shadowMinBias, 0.02f, "%.03f"))
3444  light->shadowMaxBias(shadowMaxBias);
3445 
3446  if (typeid(*singleNode) == typeid(SLLightDirect) && !shadowMap->useCascaded())
3447  {
3448  SLVec2f size = shadowMap->size();
3449  if (ImGui::InputFloat2("Size", (float*)&size))
3450  shadowMap->size(size);
3451  }
3452 
3453  if (!shadowMap->useCubemap())
3454  {
3455  SLbool doSmoothShadows = light->doSoftShadows();
3456  if (ImGui::Checkbox("Do smooth shadows", &doSmoothShadows))
3457  light->doSmoothShadows(doSmoothShadows);
3458 
3459  SLuint pcfLevel = light->softShadowLevel();
3460  if (ImGui::SliderInt("Smoothing level", (SLint*)&pcfLevel, 1, 3))
3461  light->smoothShadowLevel(pcfLevel);
3462  }
3463 
3464  SLbool doColoredShadows = SLLight::doColoredShadows;
3465  if (ImGui::Checkbox("Do colored shadows", &doColoredShadows))
3466  SLLight::doColoredShadows = doColoredShadows;
3467 #ifndef SL_GLES
3468  SLVec2i rayCount = shadowMap->rayCount();
3469  if (ImGui::InputInt2("Visualization rays", (int*)&rayCount))
3470  shadowMap->rayCount(rayCount);
3471 #endif
3472 
3473  if (shadowMap->useCascaded())
3474  {
3475  if (ImGui::TreeNode("Light cascade space matrices"))
3476  {
3477  for (SLint i = 0; i < shadowMap->numCascades(); ++i)
3478  ImGui::Text("Matrix %i:\n%s", i + 1, shadowMap->lightSpace()[i].toString().c_str());
3479 
3480  ImGui::TreePop();
3481  }
3482  }
3483  else
3484  {
3485  if (ImGui::TreeNode(shadowMap->useCubemap() ? "Light space matrices" : "Light space matrix"))
3486  {
3487  if (shadowMap->useCubemap())
3488  for (SLint i = 0; i < 6; ++i)
3489  ImGui::Text("Matrix %i:\n%s", i + 1, shadowMap->lightSpace()[i].toString().c_str());
3490  else
3491  ImGui::Text(shadowMap->lightSpace()[0].toString().c_str());
3492 
3493  ImGui::TreePop();
3494  }
3495  }
3496 
3497  if (!shadowMap->useCubemap())
3498  {
3499  if (shadowMap->useCascaded())
3500  {
3501  for (int i = 0; i < shadowMap->depthBuffers().size(); i++)
3502  {
3503  ImGui::Text(("Depth Buffer " + std::to_string(i) + ":").c_str());
3504  ImGui::Image((void*)(intptr_t)shadowMap->depthBuffers().at(i)->texID(),
3505  ImVec2(200, 200));
3506  }
3507  }
3508  else
3509  {
3510  ImGui::Text("Depth Buffer:");
3511  ImGui::Image((void*)(intptr_t)shadowMap->depthBuffer()->texID(),
3512  ImVec2(200, 200));
3513  }
3514  }
3515  }
3516  }
3517  }
3518 
3519  ImGui::TreePop();
3520  }
3521 
3522  // Show special camera properties
3523  if (typeid(*singleNode) == typeid(SLCamera))
3524  {
3525  auto* cam = (SLCamera*)singleNode;
3526 
3527  if (ImGui::TreeNode("Camera"))
3528  {
3529  SLfloat clipN = cam->clipNear();
3530  SLfloat clipF = cam->clipFar();
3531  SLfloat focalDist = cam->focalDist();
3532  SLfloat fov = cam->fovV();
3533 
3534  const char* projections[] = {"Mono Perspective",
3535  "Mono Intrinsic Calibrated",
3536  "Mono Orthographic",
3537  "Stereo Side By Side",
3538  "Stereo Side By Side Prop.",
3539  "Stereo Side By Side Dist.",
3540  "Stereo Line By Line",
3541  "Stereo Column By Column",
3542  "Stereo Pixel By Pixel",
3543  "Stereo Color Red-Cyan",
3544  "Stereo Color Red-Green",
3545  "Stereo Color Red-Blue",
3546  "Stereo Color Yellow-Blue"};
3547 
3548  int proj = cam->projType();
3549  if (ImGui::Combo("Projection", &proj, projections, IM_ARRAYSIZE(projections)))
3550  cam->projType((SLProjType)proj);
3551 
3552  if (cam->projType() > P_monoOrthographic)
3553  {
3554  SLfloat eyeSepar = cam->stereoEyeSeparation();
3555  if (ImGui::SliderFloat("Eye Sep.", &eyeSepar, 0.0f, focalDist / 10.f))
3556  cam->stereoEyeSeparation(eyeSepar);
3557  }
3558 
3559  if (ImGui::SliderFloat("FOV", &fov, 1.f, 179.f))
3560  cam->fov(fov);
3561 
3562  if (ImGui::SliderFloat("Near Clip", &clipN, 0.001f, 10.f))
3563  cam->clipNear(clipN);
3564 
3565  if (ImGui::SliderFloat("Far Clip", &clipF, clipN, std::min(clipF * 1.1f, 1000000.f)))
3566  cam->clipFar(clipF);
3567 
3568  if (ImGui::SliderFloat("Focal Dist.", &focalDist, clipN, clipF))
3569  cam->focalDist(focalDist);
3570 
3571  ImGui::TreePop();
3572  }
3573  }
3574 
3575  // Show special light properties
3576  if (typeid(*singleNode) == typeid(SLLightSpot) ||
3577  typeid(*singleNode) == typeid(SLLightRect) ||
3578  typeid(*singleNode) == typeid(SLLightDirect))
3579  {
3580  SLLight* light = nullptr;
3581  SLstring typeName;
3582  SLbool doSunPowerAdaptation = false;
3583  if (typeid(*singleNode) == typeid(SLLightSpot))
3584  {
3585  light = (SLLight*)(SLLightSpot*)singleNode;
3586  typeName = "Light (spot):";
3587  }
3588  if (typeid(*singleNode) == typeid(SLLightRect))
3589  {
3590  light = (SLLight*)(SLLightRect*)singleNode;
3591  typeName = "Light (rectangular):";
3592  }
3593  if (typeid(*singleNode) == typeid(SLLightDirect))
3594  {
3595  light = (SLLight*)(SLLightDirect*)singleNode;
3596  typeName = "Light (directional):";
3597  doSunPowerAdaptation = ((SLLightDirect*)singleNode)->doSunPowerAdaptation();
3598  }
3599 
3600  if (light && ImGui::TreeNode(typeName.c_str()))
3601  {
3602  SLbool on = light->isOn();
3603  if (ImGui::Checkbox("Is on", &on))
3604  light->isOn(on);
3605 
3606  ImGuiColorEditFlags cef = ImGuiColorEditFlags_NoInputs;
3607  SLCol4f aC = light->ambientColor();
3608  if (ImGui::ColorEdit3("Ambient color", (float*)&aC, cef))
3609  light->ambientColor(aC);
3610 
3611  float aP = light->ambientPower();
3612  float dP = light->diffusePower();
3613  if (doSunPowerAdaptation)
3614  {
3615  float sum_aPdP = aP + dP;
3616  float ambiFraction = aP / sum_aPdP;
3617  if (ImGui::SliderFloat("Diffuse-Ambient-Mix", &ambiFraction, 0.0f, 1.0f, "%.2f"))
3618  {
3619  light->ambientPower(ambiFraction * sum_aPdP);
3620  light->diffusePower((1.0f - ambiFraction) * sum_aPdP);
3621  }
3622  }
3623  else
3624  {
3625  SLCol4f dC = light->diffuseColor();
3626  if (ImGui::ColorEdit3("Diffuse color", (float*)&dC, cef))
3627  light->diffuseColor(dC);
3628 
3629  SLCol4f sC = light->specularColor();
3630  if (ImGui::ColorEdit3("Specular color", (float*)&sC, cef))
3631  light->specularColor(sC);
3632  }
3633 
3634  if (ImGui::SliderFloat("Ambient power", &aP, 0.0f, 10.0f, "%.2f"))
3635  light->ambientPower(aP);
3636 
3637  if (ImGui::SliderFloat("Diffuse power", &dP, 0.0f, 10.0f, "%.2f"))
3638  light->diffusePower(dP);
3639 
3640  float sP = light->specularPower();
3641  if (ImGui::SliderFloat("Specular power", &sP, 0.0f, 10.0f, "%.2f"))
3642  light->specularPower(sP);
3643 
3644  float cutoff = light->spotCutOffDEG();
3645  if (ImGui::SliderFloat("Spot cut off angle", &cutoff, 0.0f, 180.0f, "%.2f"))
3646  light->spotCutOffDEG(cutoff);
3647 
3648  float spotExp = light->spotExponent();
3649  if (ImGui::SliderFloat("Spot attenuation", &spotExp, 0.0f, 128.0f, "%.2f"))
3650  light->spotExponent(spotExp);
3651 
3652  float kc = light->kc();
3653  if (ImGui::SliderFloat("Constant attenuation", &kc, 0.0f, 1.0f, "%.2f"))
3654  light->kc(kc);
3655 
3656  float kl = light->kl();
3657  if (ImGui::SliderFloat("Linear attenuation", &kl, 0.0f, 1.0f, "%.2f"))
3658  light->kl(kl);
3659 
3660  float kq = light->kq();
3661  if (ImGui::SliderFloat("Quadratic attenuation", &kq, 0.0f, 1.0f, "%.2f"))
3662  light->kq(kq);
3663 
3664  if (typeid(*singleNode) == typeid(SLLightDirect))
3665  {
3666  SLLightDirect* dirLight = (SLLightDirect*)singleNode;
3667  if (ImGui::Checkbox("Do Sun Power Adaptation", &doSunPowerAdaptation))
3668  dirLight->doSunPowerAdaptation(doSunPowerAdaptation);
3669 
3670  if (doSunPowerAdaptation)
3671  {
3672  SLTexColorLUT* lut = dirLight->sunLightColorLUT();
3673  if (ImGui::TreeNode("Sun Color LUT"))
3674  {
3675  showLUTColors(lut);
3676  ImGui::TreePop();
3677  }
3678 
3679  lut->bindActive(); // This texture is not an scenegraph texture
3680  SLfloat texW =
3681  ImGui::GetWindowWidth() - 4 * ImGui::GetTreeNodeToLabelSpacing() - 10;
3682  void* tid = (ImTextureID)(uintptr_t)lut->texID();
3683  ImGui::Image(tid,
3684  ImVec2(texW, texW * 0.15f),
3685  ImVec2(0, 1),
3686  ImVec2(1, 0),
3687  ImVec4(1, 1, 1, 1),
3688  ImVec4(1, 1, 1, 1));
3689  }
3690  }
3691 
3692  ImGui::TreePop();
3693  }
3694  }
3695  }
3696  else
3697  {
3698  ImGui::Text("No single node selected.");
3699  }
3700  ImGui::TreePop();
3701  }
3702 
3703  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
3704  ImGui::Separator();
3705 
3706  if (singleFullMesh)
3707  {
3708  // See also SLScene::selectNodeMesh
3709  if (ImGui::TreeNode("Mesh Properties"))
3710  {
3711  SLuint v = (SLuint)singleFullMesh->P.size();
3712  SLuint t = (SLuint)(!singleFullMesh->I16.empty() ? singleFullMesh->I16.size() / 3 : singleFullMesh->I32.size() / 3);
3713  SLuint e = (SLuint)(!singleFullMesh->IE16.empty() ? singleFullMesh->IE16.size() / 2 : singleFullMesh->IE32.size() / 2);
3714  SLMaterial* m = singleFullMesh->mat();
3715  ImGui::Text("Mesh name : %s", singleFullMesh->name().c_str());
3716  if (m->reflectionModel() == RM_Particle)
3717  {
3718  SLParticleSystem* ps = dynamic_cast<SLParticleSystem*>(singleFullMesh);
3719  ImGui::Text("# vertices : %u", ps->amount() * 4);
3720  ImGui::Text("# triangles : %u", ps->amount() * 2);
3721  }
3722  else
3723  {
3724  ImGui::Text("# vertices : %u", v);
3725  ImGui::Text("# triangles : %u", t);
3726  ImGui::Text("# hard edges : %u", e);
3727  }
3728  ImGui::Text("Material Name: %s", m->name().c_str());
3729 
3730  if (m->reflectionModel() == RM_BlinnPhong)
3731  {
3732  if (ImGui::TreeNode("Reflection Model: Blinn-Phong"))
3733  {
3734  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
3735 
3736  ImGuiColorEditFlags cef = ImGuiColorEditFlags_NoInputs;
3737  SLCol4f ac = m->ambient();
3738  if (ImGui::ColorEdit3("Ambient color", (float*)&ac, cef))
3739  m->ambient(ac);
3740 
3741  SLCol4f dc = m->diffuse();
3742  if (ImGui::ColorEdit3("Diffuse color", (float*)&dc, cef))
3743  m->diffuse(dc);
3744 
3745  SLCol4f sc = m->specular();
3746  if (ImGui::ColorEdit3("Specular color", (float*)&sc, cef))
3747  m->specular(sc);
3748 
3749  SLCol4f ec = m->emissive();
3750  if (ImGui::ColorEdit3("Emissive color", (float*)&ec, cef))
3751  m->emissive(ec);
3752 
3753  SLfloat shine = m->shininess();
3754  if (ImGui::SliderFloat("Shininess", &shine, 0.0f, 1000.0f))
3755  m->shininess(shine);
3756 
3757  SLfloat kr = m->kr();
3758  if (ImGui::SliderFloat("kr", &kr, 0.0f, 1.0f))
3759  m->kr(kr);
3760 
3761  SLfloat kt = m->kt();
3762  if (ImGui::SliderFloat("kt", &kt, 0.0f, 1.0f))
3763  m->kt(kt);
3764 
3765  SLfloat kn = m->kn();
3766  if (ImGui::SliderFloat("kn", &kn, 1.0f, 2.5f))
3767  m->kn(kn);
3768 
3769  SLbool receivesShadows = m->getsShadows();
3770  if (ImGui::Checkbox("Receives shadows", &receivesShadows))
3771  m->getsShadows(receivesShadows);
3772 
3773  ImGui::PopItemWidth();
3774  ImGui::TreePop();
3775  }
3776  }
3777  else if (m->reflectionModel() == RM_CookTorrance)
3778  {
3779  if (ImGui::TreeNode("Reflection Model: Cook-Torrance"))
3780  {
3781  if (m->numTextures())
3782  {
3783  ImGui::Text("Controlled by textures");
3784  }
3785  else
3786  {
3787  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
3788 
3789  ImGuiColorEditFlags cef = ImGuiColorEditFlags_NoInputs;
3790  SLCol4f dc = m->diffuse();
3791  if (ImGui::ColorEdit3("Diffuse color", (float*)&dc, cef))
3792  m->diffuse(dc);
3793 
3794  SLfloat rough = m->roughness();
3795  if (ImGui::SliderFloat("Roughness", &rough, 0.0f, 1.0f))
3796  m->roughness(rough);
3797 
3798  SLfloat metal = m->metalness();
3799  if (ImGui::SliderFloat("Metalness", &metal, 0.0f, 1.0f))
3800  m->metalness(metal);
3801 
3802  ImGui::PopItemWidth();
3803  }
3804  ImGui::TreePop();
3805  }
3806  }
3807  else if (m->reflectionModel() == RM_Particle)
3808  {
3809  if (ImGui::TreeNode("Particle System"))
3810  {
3811  SLParticleSystem* ps = dynamic_cast<SLParticleSystem*>(singleFullMesh); // Need to check if good practice
3812  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
3813  int item_current;
3814 
3815  if (SLGLState::instance()->glHasGeometryShaders())
3816  {
3817  bool drawInstanced = ps->doInstancedDrawing();
3818  if (ImGui::Checkbox("Instanced draw", &drawInstanced))
3819  {
3820  ps->doInstancedDrawing(drawInstanced);
3821  ps->isGenerated(false);
3822  }
3823  }
3824 
3825  // Pause and Resume
3826  bool isPaused = ps->isPaused();
3827  if (isPaused)
3828  {
3829  if (ImGui::Button("Resume"))
3830  ps->pauseOrResume();
3831  }
3832  else
3833  {
3834  if (ImGui::Button("Pause"))
3835  ps->pauseOrResume();
3836  }
3837  ImGui::SameLine();
3838  if (ImGui::Button("Reset"))
3839  ps->isGenerated(false);
3840 
3841  if (ImGui::CollapsingHeader("Emission"))
3842  {
3843  ImGui::Indent();
3844 
3845  // Amount
3846  int amount = ps->amount();
3847  if (ImGui::InputInt("Amount of particles", &amount))
3848  {
3849  if (amount <= 0)
3850  amount = 1;
3851  ps->amount(amount);
3852  ps->isGenerated(false);
3853  }
3854 
3855  // TTL (Time to live)
3856  if (ImGui::CollapsingHeader("Time to live"))
3857  {
3858  ImGui::Indent();
3859 
3860  float timeToLive = ps->timeToLive();
3861  if (ImGui::InputFloat("Time to live (s)", &timeToLive))
3862  {
3863  ps->timeToLive(timeToLive);
3864  ps->isGenerated(false);
3865  singleNode->needAABBUpdate();
3866  }
3867  // Counter bug lag/gap
3868  bool doCounterGap = ps->doCounterGap();
3869  if (ImGui::Checkbox("Counter lag/gap", &doCounterGap))
3870  {
3871  ps->doCounterGap(doCounterGap);
3872  m->programTF(nullptr);
3873  ps->isGenerated(false);
3874  }
3875  ImGui::TextWrapped("Need to be enable by default but can create flickering with few particles, recommend to disable if few particles with no velocity ");
3876 
3877  ImGui::Unindent();
3878  }
3879 
3880  // Billboard
3881  item_current = ps->billboardType();
3882  if (ImGui::Combo("Billboard Type",
3883  &item_current,
3884  "Camera Billboard\0Vertical Billboard\0Horizontal Billboard\0"))
3885  {
3886  ps->billboardType((SLBillboardType)item_current);
3887  m->program(nullptr);
3888  if (item_current == 2)
3889  {
3890  if (!sv->drawBits()->get(SL_DB_CULLOFF))
3892  }
3893  else
3894  {
3895  if (sv->drawBits()->get(SL_DB_CULLOFF))
3897  }
3898  }
3899 
3900  // Shape
3901  SLbool shape_group = ps->doShape();
3902  if (ImGui::Checkbox("Shape", &shape_group))
3903  {
3904  ps->doShape(shape_group);
3905  m->programTF(nullptr);
3906  ps->isGenerated(false);
3907  singleNode->needAABBUpdate();
3908  }
3909  if (ImGui::CollapsingHeader("Shape", &shape_group))
3910  {
3911  ImGui::Indent();
3912  item_current = ps->shapeType();
3913  if (ImGui::Combo("Shape type",
3914  &item_current,
3915  "Sphere\0Box\0Cone\0Pyramid\0"))
3916  {
3917  ps->shapeType((SLShapeType)item_current);
3918  m->programTF(nullptr);
3919  ps->isGenerated(false);
3920  singleNode->needAABBUpdate();
3921  }
3922  if (item_current == ST_Sphere)
3923  {
3924  float radiusSphere = ps->shapeRadius();
3925  if (ImGui::InputFloat("Radius of the sphere", &radiusSphere))
3926  {
3927  ps->shapeRadius(radiusSphere);
3928  ps->isGenerated(false);
3929  singleNode->needAABBUpdate();
3930  }
3931  }
3932  if (item_current == ST_Box)
3933  {
3934  float vec3fScaleBox[3] = {ps->shapeScale().x, ps->shapeScale().y, ps->shapeScale().z};
3935  if (ImGui::InputFloat3("Scale box XYZ", vec3fScaleBox))
3936  {
3937  ps->shapeScale(vec3fScaleBox[0], vec3fScaleBox[1], vec3fScaleBox[2]);
3938  ps->isGenerated(false);
3939  singleNode->needAABBUpdate();
3940  }
3941  }
3942  if (item_current == ST_Cone)
3943  {
3944  float radius = ps->shapeRadius();
3945  if (ImGui::InputFloat("Radius", &radius))
3946  {
3947  ps->shapeRadius(radius);
3948  ps->isGenerated(false);
3949  singleNode->needAABBUpdate();
3950  }
3951  float angle = ps->shapeAngle();
3952  if (ImGui::InputFloat("Angle", &angle))
3953  {
3954  ps->shapeAngle(angle);
3955  ps->isGenerated(false);
3956  singleNode->needAABBUpdate();
3957  }
3958  float height = ps->shapeHeight();
3959  if (ImGui::InputFloat("Height", &height))
3960  {
3961  ps->shapeHeight(height);
3962  ps->isGenerated(false);
3963  singleNode->needAABBUpdate();
3964  }
3965  }
3966  if (item_current == ST_Pyramid)
3967  {
3968  float halfSide = ps->shapeWidth();
3969  if (ImGui::InputFloat("Half side", &halfSide))
3970  {
3971  ps->shapeWidth(halfSide);
3972  ps->isGenerated(false);
3973  singleNode->needAABBUpdate();
3974  }
3975  float angle = ps->shapeAngle();
3976  if (ImGui::InputFloat("Angle", &angle))
3977  {
3978  ps->shapeAngle(angle);
3979  ps->isGenerated(false);
3980  singleNode->needAABBUpdate();
3981  }
3982  float height = ps->shapeHeight();
3983  if (ImGui::InputFloat("Height", &height))
3984  {
3985  ps->shapeHeight(height);
3986  ps->isGenerated(false);
3987  singleNode->needAABBUpdate();
3988  }
3989  }
3990  // Add surface spawning check box
3991  SLbool shapeSurf = ps->doShapeSurface();
3992  if (ImGui::Checkbox("Spawn surface", &shapeSurf))
3993  {
3994  ps->doShapeSurface(shapeSurf);
3995  ps->isGenerated(false);
3996  }
3997  if (item_current == 2 || item_current == 3)
3998  {
3999  SLbool shapeSpawnBase = ps->doShapeSpawnBase();
4000  if (ImGui::Checkbox("Spawn base volume", &shapeSpawnBase))
4001  {
4002  ps->doShapeSpawnBase(shapeSpawnBase);
4003  ps->isGenerated(false);
4004  singleNode->needAABBUpdate();
4005  }
4006  }
4007 
4008  if (!ps->doDirectionSpeed())
4009  ImGui::BeginDisabled();
4010  ImGui::LabelText("Condition", "Need to have direction and speed enabled");
4011  if (item_current == 2 || item_current == 3)
4012  {
4013  SLbool shapeOverride = ps->doShapeOverride();
4014  if (ImGui::Checkbox("Follow shape direction (Override direction)",
4015  &shapeOverride))
4016  {
4017  ps->doShapeOverride(shapeOverride);
4018  ps->isGenerated(false);
4019  singleNode->needAABBUpdate();
4020  }
4021  }
4022  else if (item_current == 0 || item_current == 1)
4023  {
4024  SLbool shapeOverride = ps->doShapeOverride();
4025  if (ImGui::Checkbox("Inverse center direction (Override direction)", &shapeOverride))
4026  {
4027  ps->doShapeOverride(shapeOverride);
4028  ps->isGenerated(false);
4029  singleNode->needAABBUpdate();
4030  }
4031  }
4032 
4033  if (!ps->doDirectionSpeed())
4034  ImGui::EndDisabled();
4035  ImGui::Unindent();
4036  }
4037 
4038  // Flipbook texture
4039  if (ps->texFlipbook())
4040  {
4041  SLbool flipbookTex_group = ps->doFlipBookTexture();
4042  if (ImGui::Checkbox("Flipbook texture", &flipbookTex_group))
4043  {
4044  ps->doFlipBookTexture(flipbookTex_group);
4045  m->program(nullptr);
4046  m->programTF(nullptr);
4047  ps->changeTexture(); // Switch texture
4048  ps->isGenerated(false);
4049  }
4050  if (ImGui::CollapsingHeader("Flipbook texture", &flipbookTex_group))
4051  {
4052  ImGui::Indent();
4053  int fR = ps->frameRateFB();
4054  if (ImGui::InputInt("Frame rate (num update by s)", &fR))
4055  {
4056  ps->frameRateFB(fR);
4057  }
4058  ImGui::Unindent();
4059  }
4060  }
4061 
4062  ImGui::Unindent();
4063  }
4064 
4065  if (ImGui::CollapsingHeader("Size"))
4066  {
4067  ImGui::Indent();
4068 
4069  // Radius and Scale
4070  float radiusW = ps->radiusW();
4071  if (ImGui::InputFloat("Radius width", &radiusW))
4072  {
4073  ps->radiusW(radiusW);
4074  singleNode->needAABBUpdate();
4075  }
4076  float radiusH = ps->radiusH();
4077  if (ImGui::InputFloat("Radius height", &radiusH))
4078  {
4079  ps->radiusH(radiusH);
4080  singleNode->needAABBUpdate();
4081  }
4082  float scale = ps->scale();
4083  if (ImGui::InputFloat("Scale", &scale))
4084  {
4085  ps->scale(scale);
4086  singleNode->needAABBUpdate();
4087  }
4088 
4089  // Size over lifetime
4090  SLbool doSizeOverLT_group = ps->doSizeOverLT();
4091  if (ImGui::Checkbox("Size over lifetime", &doSizeOverLT_group))
4092  {
4093  ps->doSizeOverLT(doSizeOverLT_group);
4094  m->program(nullptr);
4095  singleNode->needAABBUpdate();
4096  }
4097  if (ImGui::CollapsingHeader("Size over lifetime", &doSizeOverLT_group))
4098  {
4099  ImGui::Indent();
4100  SLbool doSizeOverLTCurve_group = ps->doSizeOverLTCurve();
4101  if (ImGui::Checkbox("Custom curve (Unchecked --> Linear function)2", &doSizeOverLTCurve_group))
4102  {
4103  ps->doSizeOverLTCurve(doSizeOverLTCurve_group);
4104  m->program(nullptr);
4105  }
4106  if (ImGui::CollapsingHeader("Bezier curve size", &doSizeOverLTCurve_group))
4107  {
4108  ImGui::Indent();
4109  float* vSize = ps->bezierControlPointSize();
4110  float* staEndSize = ps->bezierStartEndPointSize();
4111  if (ImGui::Bezier("easeInExpo", vSize, staEndSize))
4112  ps->generateBernsteinPSize();
4113  ImGui::Unindent();
4114  }
4115  ImGui::Unindent();
4116  }
4117 
4118  ImGui::Unindent();
4119  }
4120 
4121  if (ImGui::CollapsingHeader("Movement"))
4122  {
4123  ImGui::Indent();
4124 
4125  // World space
4126  SLbool doWorldSpace = ps->doWorldSpace();
4127  if (ImGui::Checkbox("World space", &doWorldSpace))
4128  ps->doWorldSpace(doWorldSpace);
4129 
4130  // Gravity
4131  SLbool doGravity = ps->doGravity();
4132  if (ImGui::Checkbox("Gravity", &doGravity))
4133  {
4134  ps->doGravity(doGravity);
4135  m->programTF(nullptr);
4136  ps->isGenerated(false);
4137  singleNode->needAABBUpdate();
4138  }
4139  if (ImGui::CollapsingHeader("Gravity", &doGravity))
4140  {
4141  ImGui::Indent();
4142  float vec3Gravity[3] = {ps->gravity().x, ps->gravity().y, ps->gravity().z};
4143  if (ImGui::InputFloat3("Gravity XYZ", vec3Gravity))
4144  {
4145  ps->gravity(vec3Gravity[0], vec3Gravity[1], vec3Gravity[2]);
4146  singleNode->needAABBUpdate();
4147  }
4148  ImGui::Unindent();
4149  }
4150 
4151  // Acceleration
4152  SLbool acc_group = ps->doAcc();
4153  if (ImGui::Checkbox("Acceleration", &acc_group))
4154  {
4155  ps->doAcceleration(acc_group);
4156  m->programTF(nullptr);
4157  singleNode->needAABBUpdate();
4158  ps->isGenerated(false);
4159  }
4160  if (ImGui::CollapsingHeader("Acceleration", &acc_group))
4161  {
4162  ImGui::Indent();
4163  if (ps->doAccDiffDir())
4164  ImGui::BeginDisabled();
4165  float accConst = ps->accelerationConst();
4166  if (ImGui::InputFloat("Accelaration constant", &accConst))
4167  {
4168  ps->accConst(accConst);
4169  singleNode->needAABBUpdate();
4170  }
4171  if (ps->doAccDiffDir())
4172  ImGui::EndDisabled();
4173  SLbool accDiffDirection_group = ps->doAccDiffDir();
4174  if (ImGui::Checkbox("Direction vector", &accDiffDirection_group))
4175  {
4176  ps->doAccDiffDir(accDiffDirection_group);
4177  m->programTF(nullptr);
4178  singleNode->needAABBUpdate();
4179  }
4180  if (ImGui::CollapsingHeader("Direction vector", &accDiffDirection_group))
4181  {
4182  float vec3fAcc[3] = {ps->acceleration().x, ps->acceleration().y, ps->acceleration().z};
4183  ImGui::InputFloat3("input float3", vec3fAcc);
4184  ps->acceleration(vec3fAcc[0], vec3fAcc[1], vec3fAcc[2]);
4185  singleNode->needAABBUpdate();
4186  }
4187  ImGui::Unindent();
4188  }
4189 
4190  // Velocity
4191  if (ps->doDirectionSpeed())
4192  ImGui::BeginDisabled();
4193  if (ImGui::CollapsingHeader("Velocity"))
4194  {
4195  ImGui::Indent();
4196  item_current = ps->velocityType();
4197  if (ImGui::Combo("Velocity type", &item_current, "Random axes\0Constant axes\0"))
4198  {
4199  ps->velocityType(item_current);
4200  ps->isGenerated(false);
4201  singleNode->needAABBUpdate();
4202  }
4203  if (item_current == 0)
4204  {
4205  float vec3fVstart[3] = {ps->velocityRndMin().x, ps->velocityRndMin().y, ps->velocityRndMin().z};
4206  if (ImGui::InputFloat3("Min. random XYZ", vec3fVstart))
4207  {
4208  ps->velocityRndMin(vec3fVstart[0], vec3fVstart[1], vec3fVstart[2]);
4209  ps->isGenerated(false);
4210  singleNode->needAABBUpdate();
4211  }
4212  float vec3fVend[3] = {ps->velocityRndMax().x, ps->velocityRndMax().y, ps->velocityRndMax().z};
4213  if (ImGui::InputFloat3("Max. random XYZ", vec3fVend))
4214  {
4215  ps->velocityRndMax(vec3fVend[0], vec3fVend[1], vec3fVend[2]);
4216  ps->isGenerated(false);
4217  singleNode->needAABBUpdate();
4218  }
4219  }
4220  else if (item_current == 1)
4221  {
4222  float vec3fVelocity[3] = {ps->velocityConst().x, ps->velocityConst().y, ps->velocityConst().z};
4223  if (ImGui::InputFloat3("Constant XYZ", vec3fVelocity))
4224  {
4225  ps->velocityConst(vec3fVelocity[0], vec3fVelocity[1], vec3fVelocity[2]);
4226  ps->isGenerated(false);
4227  singleNode->needAABBUpdate();
4228  }
4229  }
4230  ImGui::Unindent();
4231  }
4232  if (ps->doDirectionSpeed())
4233  ImGui::EndDisabled();
4234 
4235  // Direction and speed: Add maybe later mix with velocity
4236  SLbool directionSpeed_group = ps->doDirectionSpeed();
4237  if (ImGui::Checkbox("Direction and Speed", &directionSpeed_group))
4238  {
4239  ps->doDirectionSpeed(directionSpeed_group);
4240  ps->isGenerated(false);
4241  singleNode->needAABBUpdate();
4242  }
4243 
4244  if (ImGui::CollapsingHeader("Direction and Speed", &directionSpeed_group))
4245  {
4246  ImGui::Indent();
4247  float vec3fDirection[3] = {ps->direction().x, ps->direction().y, ps->direction().z}; // Direction
4248  if (ImGui::InputFloat3("Constant XYZ", vec3fDirection))
4249  {
4250  ps->direction(vec3fDirection[0], vec3fDirection[1], vec3fDirection[2]);
4251  ps->isGenerated(false);
4252  singleNode->needAABBUpdate();
4253  }
4254  // Speed
4255  item_current = ps->doSpeedRange() ? 1 : 0;
4256  if (ImGui::Combo("Speed value",
4257  &item_current,
4258  "Constant\0Random between two constants\0"))
4259  {
4260  if (item_current == 1)
4261  ps->doSpeedRange(true);
4262  else
4263  ps->doSpeedRange(false);
4264 
4265  ps->isGenerated(false);
4266  singleNode->needAABBUpdate();
4267  }
4268  if (!ps->doSpeedRange())
4269  {
4270  float speed = ps->speed();
4271  if (ImGui::InputFloat("Constant", &speed))
4272  {
4273  ps->speed(speed);
4274  ps->isGenerated(false);
4275  singleNode->needAABBUpdate();
4276  }
4277  }
4278  else
4279  {
4280  float vec2fRange[2] = {ps->speedRange().x, ps->speedRange().y};
4281  if (ImGui::InputFloat2("Random range Speed", vec2fRange))
4282  {
4283  ps->speedRange(vec2fRange[0], vec2fRange[1]);
4284  ps->isGenerated(false);
4285  singleNode->needAABBUpdate();
4286  }
4287  }
4288 
4289  // Rotation
4290  SLbool rot_group = ps->doRotation();
4291  if (ImGui::Checkbox("Rotation", &rot_group))
4292  {
4293  ps->doRotation(rot_group);
4294  m->program(nullptr);
4295  m->programTF(nullptr);
4296  ps->isGenerated(false);
4297  }
4298  if (ImGui::CollapsingHeader("Rotation", &rot_group))
4299  {
4300  ImGui::Indent();
4301  item_current = ps->doRotRange() ? 1 : 0;
4302  if (ImGui::Combo("Angular velocity value", &item_current, "Constant\0Random between two constants\0"))
4303  {
4304  if (item_current == 1)
4305  ps->doRotRange(true);
4306  else
4307  ps->doRotRange(false);
4308 
4309  m->programTF(nullptr);
4310  ps->isGenerated(false);
4311  }
4312  if (!ps->doRotRange())
4313  {
4314  float angularVelocityConst = ps->angularVelocityConst();
4315  if (ImGui::InputFloat("Constant", &angularVelocityConst))
4316  {
4317  ps->angularVelocityConst(angularVelocityConst);
4318  }
4319  }
4320  else
4321  {
4322  float vec2fRange[2] = {ps->angularVelocityRange().x, ps->angularVelocityRange().y};
4323  if (ImGui::InputFloat2("Random range A.V", vec2fRange))
4324  {
4325  ps->angularVelocityRange(vec2fRange[0], vec2fRange[1]);
4326  ps->isGenerated(false);
4327  }
4328  }
4329  ImGui::Unindent();
4330  }
4331 
4332  ImGui::Unindent();
4333  }
4334 
4335  ImGui::Unindent();
4336  }
4337 
4338  if (ImGui::CollapsingHeader("Color"))
4339  {
4340  ImGui::Indent();
4341 
4342  // Color checkbox
4343  SLbool color_group = ps->doColor();
4344  if (ImGui::Checkbox("Color", &color_group))
4345  {
4346  ps->doColor(color_group);
4347  m->program(nullptr);
4348  }
4349  if (ImGui::CollapsingHeader("Color", &color_group))
4350  {
4351  ImGui::Indent();
4352  // Color blending brightness/glow
4353  SLbool color_bright = ps->doBlendBrightness();
4354  if (ImGui::Checkbox("Glow/Bright (blending effect)", &color_bright))
4355  {
4356  ps->doBlendBrightness(color_bright);
4357  }
4358 
4359  // Color
4360  if (ps->doColorOverLT())
4361  ImGui::BeginDisabled();
4362  ImGuiColorEditFlags cef = ImGuiColorEditFlags_NoInputs;
4363  SLCol4f c = ps->color();
4364  if (ImGui::ColorEdit4("Particle color", (float*)&c, cef))
4365  ps->color(c);
4366  if (ps->doColorOverLT())
4367  ImGui::EndDisabled();
4368 
4369  // Color over lifetime
4370  SLbool doColorOverLT_group = ps->doColorOverLT();
4371 
4372  if (ImGui::Checkbox("Color over lifetime", &doColorOverLT_group))
4373  {
4374  ps->doColorOverLT(doColorOverLT_group);
4375  //ps->colorArr(gradient.cachedValues());
4376  m->program(nullptr);
4377  }
4378 
4379  if (ImGui::CollapsingHeader("Color over lifetime", &doColorOverLT_group))
4380  {
4381  ImGui::Text("Edit gradient colors in the texture section.");
4382  }
4383  ImGui::Unindent();
4384  }
4385 
4386  // Alpha over lifetime
4387  SLbool doAlphaOverL_group = ps->doAlphaOverLT();
4388  if (ImGui::Checkbox("Alpha over lifetime", &doAlphaOverL_group))
4389  {
4390  ps->doAlphaOverLT(doAlphaOverL_group);
4391  m->program(nullptr);
4392  }
4393  if (ImGui::CollapsingHeader("Alpha over lifetime", &doAlphaOverL_group))
4394  {
4395  ImGui::Indent();
4396  SLbool doAlphaOverLCurve_group = ps->doAlphaOverLTCurve();
4397  if (ImGui::Checkbox("Custom curve (Unchecked --> Linear function)", &doAlphaOverLCurve_group))
4398  {
4399  ps->doAlphaOverLTCurve(doAlphaOverLCurve_group);
4400  m->program(nullptr);
4401  }
4402  if (ImGui::CollapsingHeader("Bezier curve alpha", &doAlphaOverLCurve_group))
4403  {
4404  ImGui::Indent();
4405  float* vAlpha = ps->bezierControlPointAlpha();
4406  float* staEndAlpha = ps->bezierStartEndPointAlpha();
4407  if (ImGui::Bezier("easeInExpo", vAlpha, staEndAlpha))
4409  ImGui::Unindent();
4410  }
4411  ImGui::Unindent();
4412  }
4413 
4414  ImGui::Unindent();
4415  }
4416 
4417  ImGui::PopItemWidth();
4418  ImGui::TreePop();
4419  }
4420  }
4421 
4422  // Textures
4423  if (m->numTextures() > 0 && ImGui::TreeNode("Tex", "Textures (%d)", m->numTextures()))
4424  {
4425  for (int tt = 0; tt < TT_numTextureType; ++tt)
4426  for (auto& tex : m->textures((SLTextureType)tt))
4427  showTexInfos(tex);
4428 
4429  ImGui::TreePop();
4430  }
4431 
4432  // Shaders
4433  size_t numShaders = m->program() ? m->program()->shaders().size() : 0;
4434  numShaders += m->programTF() ? m->programTF()->shaders().size() : 0;
4435 
4436  if (numShaders > 0 && ImGui::TreeNode("Shd", "Shaders (%d)", (int)numShaders))
4437  {
4438  if (m->program() != nullptr)
4439  {
4440  for (auto* shd : m->program()->shaders())
4441  {
4442  if (ImGui::TreeNode(shd->name().c_str()))
4443  {
4444  SLchar* text = new char[shd->code().length() + 1];
4445  strcpy(text, shd->code().c_str());
4446  ImGui::InputTextMultiline(shd->name().c_str(),
4447  text,
4448  shd->code().length() + 1,
4449  ImVec2(-1.0f, -1.0f));
4450  ImGui::TreePop();
4451  delete[] text;
4452  }
4453  }
4454  }
4455  if (m->programTF() != nullptr)
4456  {
4457  for (auto* shd : m->programTF()->shaders())
4458  {
4459  if (ImGui::TreeNode(shd->name().c_str()))
4460  {
4461  SLchar* text = new char[shd->code().length() + 1];
4462  strcpy(text, shd->code().c_str());
4463  ImGui::InputTextMultiline(shd->name().c_str(),
4464  text,
4465  shd->code().length() + 1,
4466  ImVec2(-1.0f, -1.0f));
4467  ImGui::TreePop();
4468  delete[] text;
4469  }
4470  }
4471  }
4472 
4473  ImGui::TreePop();
4474  }
4475 
4476  ImGui::TreePop();
4477  }
4478  }
4479  else
4480  {
4481  ImGui::Text("No single single mesh selected.");
4482  }
4483 
4484  ImGui::PopStyleColor();
4485  }
4486  else if (!singleFullMesh && !s->selectedMeshes().empty())
4487  {
4488  // See also SLMesh::handleRectangleSelection
4489  ImGui::Begin("Properties of Selection", &showProperties, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NoNavInputs);
4490 
4491  for (auto* selectedNode : s->selectedNodes())
4492  {
4493  if (selectedNode->mesh())
4494  {
4495  ImGui::Text("Node: %s", selectedNode->name().c_str());
4496  SLMesh* selectedMesh = selectedNode->mesh();
4497 
4498  if (!selectedMesh->IS32.empty())
4499  {
4500  ImGui::Text(" Mesh: %s {%u v.}",
4501  selectedMesh->name().c_str(),
4502  (SLuint)selectedMesh->IS32.size());
4503  ImGui::SameLine();
4504  SLstring delBtn = "DEL##" + selectedMesh->name();
4505  if (ImGui::Button(delBtn.c_str()))
4506  {
4507  selectedMesh->deleteSelected(selectedNode);
4508  }
4509  }
4510  }
4511  }
4512 
4513  ImGui::End();
4514  }
4515  else
4516  {
4517  // Nothing is selected
4518  ImGui::Text("There is nothing selected.");
4519  ImGui::Text("");
4520  ImGui::Text("Select a single node by");
4521  ImGui::Text("double-clicking it or");
4522  ImGui::Text("select multiple nodes by");
4523  ImGui::Text("SHIFT-double-clicking them.");
4524  ImGui::Text("");
4525  ImGui::Text("Select partial meshes by");
4526  ImGui::Text("CTRL-LMB rectangle drawing.");
4527  ImGui::Text("");
4528  ImGui::Text("Press ESC to deselect all.");
4529  ImGui::Text("");
4530  ImGui::Text("Be aware that a node may be");
4531  ImGui::Text("flagged as not selectable.");
4532  }
4533  }
4534  else
4535  {
4536  ImGui::Text("Node selection and the");
4537  ImGui::Text("properties of it can only");
4538  ImGui::Text("be shown in the OpenGL");
4539  ImGui::Text("renderer.");
4540  }
4541 
4542  ImGui::End();
4543  ImGui::PopFont();
4544 }
#define SL_DB_NOTSELECTABLE
Flags an object as selected.
Definition: SLDrawBits.h:21
SLShapeType
Particle system shape type.
Definition: SLEnums.h:279
@ ST_Sphere
Definition: SLEnums.h:280
@ ST_Pyramid
Definition: SLEnums.h:283
@ ST_Box
Definition: SLEnums.h:281
@ ST_Cone
Definition: SLEnums.h:282
@ RM_BlinnPhong
Definition: SLEnums.h:289
@ RM_Particle
Definition: SLEnums.h:291
@ RM_CookTorrance
Definition: SLEnums.h:290
SLBillboardType
Billboard type for its orientation used in SLParticleSystem.
Definition: SLEnums.h:271
SLTextureType
Texture type enumeration & their filename appendix for auto type detection.
Definition: SLGLTexture.h:76
@ TT_numTextureType
Definition: SLGLTexture.h:95
static void showTexInfos(SLGLTexture *tex)
Shows UI infos for a texture.
static void showLUTColors(SLTexColorLUT *lut)
Displays a editable color lookup table wit ImGui widgets.
SLuint texID() const
Definition: SLGLTexture.h:227
void bindActive(SLuint texUnit=0)
void doSunPowerAdaptation(SLbool enabled)
Definition: SLLightDirect.h:82
SLTexColorLUT * sunLightColorLUT()
Definition: SLLightDirect.h:90
void ambientColor(const SLCol4f &ambi)
Definition: SLLight.h:105
static SLbool doColoredShadows
flag if shadows should be displayed with colors for debugging
Definition: SLLight.h:205
void kl(SLfloat kl)
Definition: SLLight.cpp:80
void specularPower(const SLfloat specPow)
Definition: SLLight.h:110
void isOn(const SLbool on)
Definition: SLLight.h:71
void spotCutOffDEG(SLfloat cutOffAngleDEG)
Definition: SLLight.cpp:92
void diffuseColor(const SLCol4f &diff)
Definition: SLLight.h:107
void specularColor(const SLCol4f &spec)
Definition: SLLight.h:109
void kc(SLfloat kc)
Definition: SLLight.cpp:74
void kq(SLfloat kq)
Definition: SLLight.cpp:86
void spotExponent(const SLfloat exp)
Definition: SLLight.h:111
Light node class for a rectangular light source.
Definition: SLLightRect.h:39
SLLightSpot class for a spot light source.
Definition: SLLightSpot.h:36
SLstring toString() const
Definition: SLMat4.h:1567
Defines a standard CG material with textures and a shader program.
Definition: SLMaterial.h:56
void reflectionModel(SLReflectionModel rm)
Definition: SLMaterial.h:169
void specular(const SLCol4f &spec)
Definition: SLMaterial.h:173
void programTF(SLGLProgram *sp)
Definition: SLMaterial.h:206
void diffuse(const SLCol4f &diff)
Definition: SLMaterial.h:171
SLuint numTextures()
Definition: SLMaterial.h:226
void kt(SLfloat kt)
Definition: SLMaterial.h:190
void shininess(SLfloat shin)
Definition: SLMaterial.h:177
void ambient(const SLCol4f &ambi)
Definition: SLMaterial.h:170
SLVGLTexture & textures(SLTextureType type)
Definition: SLMaterial.h:233
void kr(SLfloat kr)
Definition: SLMaterial.h:184
void roughness(SLfloat r)
Definition: SLMaterial.h:182
void emissive(const SLCol4f &emis)
Definition: SLMaterial.h:174
void kn(SLfloat kn)
Definition: SLMaterial.h:199
void metalness(SLfloat m)
Definition: SLMaterial.h:183
void program(SLGLProgram *sp)
Definition: SLMaterial.h:205
void getsShadows(SLbool receivesShadows)
Definition: SLMaterial.h:204
SLVuint IS32
Vector of rectangle selected vertex indices 32 bit.
Definition: SLMesh.h:216
SLVuint I32
Vector of vertex indices 32 bit.
Definition: SLMesh.h:215
SLVushort I16
Vector of vertex indices 16 bit.
Definition: SLMesh.h:214
SLVuint IE32
Vector of hard edges vertex indices 32 bit (see computeHardEdgesIndices)
Definition: SLMesh.h:218
void deleteSelected(SLNode *node)
Deletes the rectangle selected vertices and the dependent triangles.
Definition: SLMesh.cpp:148
SLVushort IE16
Vector of hard edges vertex indices 16 bit (see computeHardEdgesIndices)
Definition: SLMesh.h:217
SLVVec3f P
Vector for vertex positions layout (location = 0)
Definition: SLMesh.h:203
SLMaterial * mat() const
Definition: SLMesh.h:177
void castsShadows(SLbool castsShadows)
Definition: SLNode.h:283
void needAABBUpdate()
Definition: SLNode.cpp:665
SLParticleSystem creates a particle meshes from a point primitive buffer.
SLbool doShapeSpawnBase()
SLbool doShapeOverride()
SLGLTexture * texFlipbook()
float * bezierControlPointSize()
float * bezierControlPointAlpha()
SLbool doFlipBookTexture()
SLbool doDirectionSpeed()
SLVec3f velocityRndMax()
SLShapeType shapeType()
SLfloat angularVelocityConst()
float * bezierStartEndPointSize()
SLBillboardType billboardType()
float * bezierStartEndPointAlpha()
SLbool doAlphaOverLTCurve()
SLbool doBlendBrightness()
void doAcceleration(SLbool b)
SLbool doSizeOverLTCurve()
SLVec2f angularVelocityRange()
SLVec3f velocityRndMin()
SLfloat accelerationConst()
SLVec3f acceleration()
void accConst(SLfloat f)
SLbool doInstancedDrawing()
SLVMesh & selectedMeshes()
Definition: SLScene.h:125
void skybox(SLSkybox *skybox)
Definition: SLScene.h:91
SLVNode & selectedNodes()
Definition: SLScene.h:124
Class for standard and cascaded shadow mapping.
Definition: SLShadowMap.h:39
void numCascades(int numCascades)
Definition: SLShadowMap.h:72
int maxCascades()
Definition: SLShadowMap.h:88
SLbool useCascaded() const
Definition: SLShadowMap.h:78
SLGLVDepthBuffer depthBuffers()
Definition: SLShadowMap.h:81
SLGLDepthBuffer * depthBuffer()
Definition: SLShadowMap.h:80
SLProjType projection()
Definition: SLShadowMap.h:76
void rayCount(const SLVec2i &rayCount)
Definition: SLShadowMap.h:63
void useCubemap(SLbool useCubemap)
Definition: SLShadowMap.h:62
void clipNear(SLfloat clipNear)
Definition: SLShadowMap.h:64
void size(const SLVec2f &size)
Definition: SLShadowMap.h:66
SLfloat lightClipNear()
Definition: SLShadowMap.h:83
void textureSize(const SLVec2i &textureSize)
Definition: SLShadowMap.h:71
void clipFar(SLfloat clipFar)
Definition: SLShadowMap.h:65
SLfloat lightClipFar()
Definition: SLShadowMap.h:84
void cascadesFactor(float factor)
Definition: SLShadowMap.h:73
SLMat4f * lightSpace()
Definition: SLShadowMap.h:79
Skybox node class with a SLBox mesh.
Definition: SLSkybox.h:29
SLfloat exposure()
Definition: SLSkybox.h:54
SLGLTexture * irradianceCubemap()
Definition: SLSkybox.h:51
SLGLTexture * brdfLutTexture()
Definition: SLSkybox.h:53
SLGLTexture * roughnessCubemap()
Definition: SLSkybox.h:52
SLbool isHDR()
Definition: SLSkybox.h:55
SLGLTexture * environmentCubemap()
Definition: SLSkybox.h:50
SLTexColorLUT defines a lookup table as an 1D texture of (256) RGBA values.
Definition: SLTexColorLUT.h:70
T y
Definition: SLVec2.h:30
T x
Definition: SLVec2.h:30
SLstring toString(SLstring delimiter=", ", int decimals=2)
Conversion to string.
Definition: SLVec3.h:199
T y
Definition: SLVec3.h:43
T x
Definition: SLVec3.h:43
T z
Definition: SLVec3.h:43
static const float RAD2DEG
Definition: Utils.h:238
unsigned closestPowerOf2(unsigned num)
Returns the closest power of 2 to a passed number.
Definition: Utils.cpp:1218

◆ buildSceneGraph()

void AppDemoGui::buildSceneGraph ( SLScene s)
static

Builds the scenegraph dialog once per frame.

Definition at line 3155 of file AppDemoGui.cpp.

3156 {
3157  PROFILE_FUNCTION();
3158 
3159  // assert(s->assetManager() && "No asset manager assigned to scene!");
3160 
3161  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
3162  ImGui::Begin("Scenegraph", &showSceneGraph, ImGuiWindowFlags_NoNavInputs);
3163 
3164  if (s->root3D())
3165  addSceneGraphNode(s, s->root3D());
3166 
3167  if (s->root2D())
3168  addSceneGraphNode(s, s->root2D());
3169 
3170  ImGui::End();
3171  ImGui::PopFont();
3172 }
void root2D(SLNode *root2D)
Definition: SLScene.h:90

◆ clear()

void AppDemoGui::clear ( )
static

Definition at line 221 of file AppDemoGui.cpp.

222 {
223  _horizonVisuEnabled = false;
224 }

◆ downloadModelAndLoadScene()

void AppDemoGui::downloadModelAndLoadScene ( SLScene s,
SLSceneView sv,
string  downloadFilename,
string  urlFolder,
string  dstFolder,
string  filenameToLoad,
SLSceneID  sceneIDToLoad 
)
staticprivate

Parallel HTTP download, unzip and load scene job scheduling.

Definition at line 4995 of file AppDemoGui.cpp.

5002 {
5003 #ifndef SL_EMSCRIPTEN
5004  assert(s->assetManager() && "No asset manager assigned to scene!");
5005  SLAssetManager* am = s->assetManager();
5006 
5007  auto progressCallback = [](size_t curr, size_t filesize)
5008  {
5009  if (filesize > 0)
5010  {
5011  int transferredPC = (int)((float)curr / (float)filesize * 100.0f);
5012  AppCommon::jobProgressNum(transferredPC);
5013  }
5014  else
5015  cout << "Bytes transferred: " << curr << endl;
5016 
5017  return 0; // Return Non-Zero to cancel
5018  };
5019 
5020  auto downloadJobHTTP = [=]()
5021  {
5022  PROFILE_FUNCTION();
5023  string jobMsg = "Downloading file via HTTPS: " + downloadFilename;
5024  AppCommon::jobProgressMsg(jobMsg);
5026  string fileToDownload = urlFolder + downloadFilename;
5027  if (HttpUtils::download(fileToDownload, dstFolder, progressCallback) != 0)
5028  {
5029  SL_LOG("*** Nothing downloaded from: %s ***", fileToDownload.c_str());
5030  SL_LOG("*** PLEASE RETRY DOWNLOAD ***", fileToDownload.c_str());
5031  }
5032  AppCommon::jobIsRunning = false;
5033  };
5034 
5035  auto unzipJob = [=]()
5036  {
5037  string jobMsg = "Decompressing file: " + downloadFilename;
5038  AppCommon::jobProgressMsg(jobMsg);
5040  string zipFile = dstFolder + downloadFilename;
5041  if (Utils::fileExists(zipFile))
5042  {
5043  string extension = Utils::getFileExt(zipFile);
5044  if (extension == "zip")
5045  {
5046  ZipUtils::unzip(zipFile, Utils::getPath(zipFile));
5047  Utils::deleteFile(zipFile);
5048  }
5049  }
5050  else
5051  SL_LOG("*** File do decompress doesn't exist: %s ***",
5052  zipFile.c_str());
5053  AppCommon::jobIsRunning = false;
5054  };
5055 
5056  auto followUpJob1 = [=]()
5057  {
5058  if (Utils::fileExists(pathAndFileToLoad))
5059  AppCommon::sceneToLoad = sceneIDToLoad;
5060  else
5061  SL_LOG("*** File do load doesn't exist: %s ***",
5062  pathAndFileToLoad.c_str());
5063  };
5064 
5065  AppCommon::jobsToBeThreaded.emplace_back(downloadJobHTTP);
5066  AppCommon::jobsToBeThreaded.emplace_back(unzipJob);
5067  AppCommon::jobsToFollowInMain.push_back(followUpJob1);
5068 #endif
5069 }
SLAssetManager * assetManager()
Definition: SLScene.h:98
string getPath(const string &pathFilename)
Returns the path w. '\' of path-filename string.
Definition: Utils.cpp:391
string getFileExt(const string &filename)
Returns the file extension without dot in lower case.
Definition: Utils.cpp:628
bool unzip(string zipfile, function< bool(string path, string filename)> processFile, function< bool(const char *data, size_t len)> writeChunk, function< bool(string path)> processDir, function< int(int currentFile, int totalFiles)> progress=nullptr)
Definition: ZipUtils.cpp:150

◆ hideHorizon()

void AppDemoGui::hideHorizon ( SLScene s)
staticprivate

Disables calculation and visualization of horizon line.

Definition at line 4927 of file AppDemoGui.cpp.

4928 {
4929  if (s->root2D())
4930  {
4931  SLstring horizonName = "Horizon";
4932  SLHorizonNode* horizonNode = s->root2D()->findChild<SLHorizonNode>(horizonName);
4933  if (horizonNode)
4934  {
4935  s->root2D()->deleteChild(horizonNode);
4936  }
4937  }
4938  _horizonVisuEnabled = false;
4939 }
Scene node that visualises the horizon estimated from the device rotation.
Definition: SLHorizonNode.h:33

◆ loadConfig()

void AppDemoGui::loadConfig ( SLint  dotsPerInch)
static

Loads the UI configuration.

Definition at line 4670 of file AppDemoGui.cpp.

4671 {
4672  ImGuiStyle& style = ImGui::GetStyle();
4673  SLstring fullPathAndFilename = AppCommon::configPath +
4674  AppCommon::name + ".yml";
4675 
4676  if (!SLFileStorage::exists(fullPathAndFilename, IOK_config))
4677  {
4678  SL_LOG("No config file %s: ", fullPathAndFilename.c_str());
4679 
4680  // Scale for proportional and fixed size fonts
4681  SLfloat dpiScaleProp = (float)dotsPerInch / 142.0f;
4682  SLfloat dpiScaleFixed = (float)dotsPerInch / 142.0f;
4683 
4684  // Default settings for the first time
4685  SLImGui::fontPropDots = std::max(16.0f * dpiScaleProp, 16.0f);
4686  SLImGui::fontFixedDots = std::max(13.0f * dpiScaleFixed, 13.0f);
4687 
4688  // Store dialog show states
4689  AppDemoGui::showAbout = true;
4700 
4701  // Adjust UI padding on DPI
4702  style.WindowPadding.x = style.FramePadding.x = style.ItemInnerSpacing.x = std::max(8.0f * dpiScaleFixed, 8.0f);
4703  style.FramePadding.y = style.ItemInnerSpacing.y = std::max(4.0f * dpiScaleFixed, 4.0f);
4704  style.WindowPadding.y = style.ItemSpacing.y * 3;
4705  style.ScrollbarSize = std::max(16.0f * dpiScaleFixed, 16.0f);
4706 
4707  // HSM4: Bugfix in some unknown cases ScrollbarSize gets INT::MIN
4708  if (style.ScrollbarSize < 0.0f)
4709  style.ScrollbarSize = 16.0f;
4710 
4711  style.ScrollbarRounding = std::floor(style.ScrollbarSize / 2);
4712  }
4713  else
4714  {
4715  try
4716  {
4717  SLstring configString = SLFileStorage::readIntoString(fullPathAndFilename, IOK_config);
4718  CVFileStorage fs(configString, CVFileStorage::READ | CVFileStorage::MEMORY);
4719 
4720  if (fs.isOpened())
4721  {
4722  // clang-format off
4723  SLint i = 0;
4724  SLbool b = false;
4725  fs["configTime"] >> AppDemoGui::configTime;
4726  fs["fontPropDots"] >> i; SLImGui::fontPropDots = (SLfloat) i;
4727  fs["fontFixedDots"] >> i; SLImGui::fontFixedDots = (SLfloat) i;
4728  fs["ItemSpacingX"] >> i; style.ItemSpacing.x = (SLfloat) i;
4729  fs["ItemSpacingY"] >> i; style.ItemSpacing.y = (SLfloat) i;
4730  style.WindowPadding.x = style.FramePadding.x = style.ItemInnerSpacing.x = style.ItemSpacing.x;
4731  style.FramePadding.y = style.ItemInnerSpacing.y = style.ItemSpacing.y;
4732  style.WindowPadding.y = style.ItemSpacing.y * 3;
4733  fs["ScrollbarSize"] >> i; style.ScrollbarSize = (SLfloat) i;
4734  // HSM4: Bugfix in some unknown cases ScrollbarSize gets INT::MIN
4735  if (style.ScrollbarSize < 0.0f)
4736  style.ScrollbarSize = 16.0f;
4737 
4738  fs["ScrollbarRounding"] >> i; style.ScrollbarRounding = (SLfloat) i;
4739  fs["sceneID"] >> i; AppCommon::sceneID = (SLSceneID) i;
4740  fs["showInfosScene"] >> b; AppDemoGui::showInfosScene = b;
4741  fs["showStatsTiming"] >> b; AppDemoGui::showStatsTiming = b;
4742  fs["showStatsMemory"] >> b; AppDemoGui::showStatsScene = b;
4743  fs["showStatsVideo"] >> b; AppDemoGui::showStatsVideo = b;
4744  fs["showStatsWAI"] >> b; AppDemoGui::showStatsWAI = b;
4745  fs["showInfosFrameworks"] >> b; AppDemoGui::showInfosDevice = b;
4746  fs["showInfosSensors"] >> b; AppDemoGui::showInfosSensors = b;
4747  fs["showSceneGraph"] >> b; AppDemoGui::showSceneGraph = b;
4748  fs["showProperties"] >> b; AppDemoGui::showProperties = b;
4749  fs["showErlebAR"] >> b; AppDemoGui::showErlebAR = b;
4750  fs["showTransform"] >> b; AppDemoGui::showTransform = b;
4751  fs["showUIPrefs"] >> b; AppDemoGui::showUIPrefs = b;
4752  fs["showDateAndTime"] >> b; AppDemoGui::showDateAndTime = b;
4753  fs["showDockSpace"] >> b; AppDemoGui::showDockSpace = b;
4754  // clang-format on
4755 
4756  fs.release();
4757  SL_LOG("Config. loaded : %s", fullPathAndFilename.c_str());
4758  SL_LOG("Config. date : %s", AppDemoGui::configTime.c_str());
4759  SL_LOG("fontPropDots : %f", SLImGui::fontPropDots);
4760  SL_LOG("fontFixedDots : %f", SLImGui::fontFixedDots);
4761  }
4762  else
4763  {
4764  SL_LOG("****** Failed to open file for reading: %s", fullPathAndFilename.c_str());
4765  }
4766  }
4767  catch (...)
4768  {
4769  SL_LOG("****** Parsing of file failed: %s", fullPathAndFilename.c_str());
4770  }
4771 
4772  // check font sizes for HDPI displays
4773  if (dotsPerInch > 300)
4774  {
4775  if (SLImGui::fontPropDots < 16.1f &&
4776  SLImGui::fontFixedDots < 13.1)
4777  {
4778  // Scale for proportional and fixed size fonts
4779  SLfloat dpiScaleProp = (float)dotsPerInch / 120.0f;
4780  SLfloat dpiScaleFixed = (float)dotsPerInch / 142.0f;
4781 
4782  // Default settings for the first time
4783  SLImGui::fontPropDots = std::max(16.0f * dpiScaleProp, 16.0f);
4784  SLImGui::fontFixedDots = std::max(13.0f * dpiScaleFixed, 13.0f);
4785  }
4786  }
4787  }
4788 
4789 #ifdef SL_EMSCRIPTEN
4790  // Overwrite config with URL parameters
4791  // clang-format off
4792  int sceneId = EM_ASM_INT(
4793  let params = new URL(window.location).searchParams;
4794  return params.get("scene") ?? -1;
4795  );
4796  // clang-format on
4797 
4798  if (sceneId != -1)
4799  AppCommon::sceneID = (SLSceneID)sceneId;
4800 #endif
4801 }
static GLFWwindow * window
The global glfw window handle.
Definition: AppGLFW.cpp:35
cv::FileStorage CVFileStorage
Definition: CVTypedefs.h:61
@ IOK_config
Definition: SLFileStorage.h:44
static SLstring name
Application name.
Definition: AppCommon.h:72
static SLstring configTime
Time of stored configuration.
Definition: AppDemoGui.h:51
bool exists(std::string path, SLIOStreamKind kind)
Checks whether a given file exists.
std::string readIntoString(std::string path, SLIOStreamKind kind)
Reads an entire file into a string.

◆ loadSceneWithLargeModel()

void AppDemoGui::loadSceneWithLargeModel ( SLScene s,
SLSceneView sv,
string  downloadFilename,
string  filenameToLoad,
SLSceneID  sceneIDToLoad 
)
staticprivate

Definition at line 4975 of file AppDemoGui.cpp.

4980 {
4981  SLstring pathSrc = "https://pallas.ti.bfh.ch/data/SLProject/models/";
4982  SLstring pathDst = AppCommon::configPath + "models/";
4983 
4984 #ifndef SL_EMSCRIPTEN
4985  if (Utils::fileExists(filenameToLoad))
4986  AppCommon::sceneToLoad = sceneIDToLoad;
4987  else
4988  downloadModelAndLoadScene(s, sv, downloadFilename, pathSrc, pathDst, filenameToLoad, sceneIDToLoad);
4989 #else
4990  AppCommon::sceneToLoad = sceneIDToLoad;
4991 #endif
4992 }
static void downloadModelAndLoadScene(SLScene *s, SLSceneView *sv, string downloadFilename, string urlFolder, string dstFolder, string filenameToLoad, SLSceneID sceneIDToLoad)
Parallel HTTP download, unzip and load scene job scheduling.

◆ removeTransformNode()

void AppDemoGui::removeTransformNode ( SLScene s)
staticprivate

Searches and removes the transform node.

Definition at line 4878 of file AppDemoGui.cpp.

4879 {
4880  SLTransformNode* tN = s->root3D()->findChild<SLTransformNode>("Edit Gizmos");
4881  if (tN)
4882  {
4883  auto it = find(s->eventHandlers().begin(),
4884  s->eventHandlers().end(),
4885  tN);
4886  if (it != s->eventHandlers().end())
4887  s->eventHandlers().erase(it);
4888 
4889  s->root3D()->deleteChild(tN);
4890 
4891  // Reset currentMaterial pointer that have pointed to temp. materials of transform nodes
4893  }
4894  transformNode = nullptr;
4895 }
void currentMaterial(SLMaterial *mat)
Definition: SLGLState.h:120
SLVEventHandler & eventHandlers()
Definition: SLScene.h:105
Class that holds all visible gizmo node during mouse transforms.

◆ saveConfig()

void AppDemoGui::saveConfig ( )
static

Stores the UI configuration.

Definition at line 4804 of file AppDemoGui.cpp.

4805 {
4806  ImGuiStyle& style = ImGui::GetStyle();
4807  SLstring fullPathAndFilename = AppCommon::configPath +
4808  AppCommon::name + ".yml";
4809 
4810  if (!SLFileStorage::exists(fullPathAndFilename, IOK_config))
4811  SL_LOG("New config file will be written: %s",
4812  fullPathAndFilename.c_str());
4813 
4814  CVFileStorage fs(fullPathAndFilename,
4815  CVFileStorage::WRITE | CVFileStorage::MEMORY);
4816 
4817  if (!fs.isOpened())
4818  {
4819  SL_LOG("Failed to open file for writing: %s",
4820  fullPathAndFilename.c_str());
4821  SL_EXIT_MSG("Exit in AppDemoGui::saveConfig");
4822  }
4823 
4824  fs << "configTime" << Utils::getLocalTimeString();
4825  fs << "fontPropDots" << (SLint)SLImGui::fontPropDots;
4826  fs << "fontFixedDots" << (SLint)SLImGui::fontFixedDots;
4829  fs << "sceneID" << (SLint)SID_Minimal;
4830  else
4831  fs << "sceneID" << (SLint)AppCommon::sceneID;
4832  fs << "ItemSpacingX" << (SLint)style.ItemSpacing.x;
4833  fs << "ItemSpacingY" << (SLint)style.ItemSpacing.y;
4834  fs << "ScrollbarSize" << (SLfloat)style.ScrollbarSize;
4835  fs << "ScrollbarRounding" << (SLfloat)style.ScrollbarRounding;
4836  fs << "showStatsTiming" << AppDemoGui::showStatsTiming;
4837  fs << "showStatsMemory" << AppDemoGui::showStatsScene;
4838  fs << "showStatsVideo" << AppDemoGui::showStatsVideo;
4839  fs << "showStatsWAI" << AppDemoGui::showStatsWAI;
4840  fs << "showInfosFrameworks" << AppDemoGui::showInfosDevice;
4841  fs << "showInfosScene" << AppDemoGui::showInfosScene;
4842  fs << "showInfosSensors" << AppDemoGui::showInfosSensors;
4843  fs << "showSceneGraph" << AppDemoGui::showSceneGraph;
4844  fs << "showProperties" << AppDemoGui::showProperties;
4845  fs << "showErlebAR" << AppDemoGui::showErlebAR;
4846  fs << "showTransform" << AppDemoGui::showTransform;
4847  fs << "showUIPrefs" << AppDemoGui::showUIPrefs;
4848  fs << "showDateAndTime" << AppDemoGui::showDateAndTime;
4849  fs << "showDockSpace" << AppDemoGui::showDockSpace;
4850 
4851  std::string configString = fs.releaseAndGetString();
4852  SLFileStorage::writeString(fullPathAndFilename,
4853  IOK_config,
4854  configString);
4855  SL_LOG("Config. saved : %s", fullPathAndFilename.c_str());
4856 }
#define SL_EXIT_MSG(message)
Definition: SL.h:288
void writeString(std::string path, SLIOStreamKind kind, const std::string &string)
Writes a string to a file.
string getLocalTimeString()
Returns local time as string like "Wed Feb 13 15:46:11 2019".
Definition: Utils.cpp:258

◆ setActiveNamedLocation()

void AppDemoGui::setActiveNamedLocation ( int  locIndex,
SLSceneView sv,
SLVec3f  lookAtPoint = SLVec3f::ZERO 
)
static

Set the a new active named location from SLDeviceLocation.

Definition at line 5072 of file AppDemoGui.cpp.

5075 {
5077 
5078 #if !defined(SL_OS_MACIOS) && !defined(SL_OS_ANDROID)
5080  SLVec3f pos_f((SLfloat)pos_d.x, (SLfloat)pos_d.y + 1.7f, (SLfloat)pos_d.z);
5081  SLCamera* cam = sv->camera();
5082  cam->translation(pos_f);
5083  SLVec3f camToLookAt = pos_f - lookAtPoint;
5084  cam->focalDist(camToLookAt.length());
5085  cam->lookAt(lookAtPoint);
5087 #endif
5088 }
SLVec3d defaultENU() const
void translation(const SLVec3f &pos, SLTransformSpace relativeTo=TS_parent)
Definition: SLNode.cpp:828
void lookAt(SLfloat targetX, SLfloat targetY, SLfloat targetZ, SLfloat upX=0, SLfloat upY=1, SLfloat upZ=0, SLTransformSpace relativeTo=TS_world)
Definition: SLNode.h:653

◆ setTransformEditMode()

void AppDemoGui::setTransformEditMode ( SLScene s,
SLSceneView sv,
SLNodeEditMode  editMode 
)
staticprivate

Adds a transform node for the selected node and toggles the edit mode.

Definition at line 4859 of file AppDemoGui.cpp.

4862 {
4863  SLTransformNode* tN = s->root3D()->findChild<SLTransformNode>("Edit Gizmos");
4864 
4865  if (!tN)
4866  {
4867  tN = new SLTransformNode(sv,
4868  s->singleNodeSelected(),
4870  s->root3D()->addChild(tN);
4871  }
4872 
4873  tN->editMode(editMode);
4874  transformNode = tN;
4875 }
static SLstring shaderPath
Path to GLSL shader programs.
Definition: AppCommon.h:84

◆ showHorizon()

void AppDemoGui::showHorizon ( SLScene s,
SLSceneView sv 
)
staticprivate

Enables calculation and visualization of horizon line (using rotation sensors)

Definition at line 4898 of file AppDemoGui.cpp.

4899 {
4900  assert(s->assetManager() && "No asset manager assigned to scene!");
4901  SLAssetManager* am = s->assetManager();
4902 
4903  // todo: why is root2D not always valid?
4904  if (!s->root2D())
4905  {
4906  SLNode* scene2D = new SLNode("root2D");
4907  s->root2D(scene2D);
4908  }
4909 
4910  SLstring horizonName = "Horizon";
4911  SLHorizonNode* horizonNode = s->root2D()->findChild<SLHorizonNode>(horizonName);
4912 
4913  if (!horizonNode)
4914  {
4915  horizonNode = new SLHorizonNode(horizonName,
4917  am->font16,
4919  sv->scrW(),
4920  sv->scrH());
4921  s->root2D()->addChild(horizonNode);
4922  _horizonVisuEnabled = true;
4923  }
4924 }
static SLTexFont * font16
16 pixel high fixed size font

◆ showLUTColors()

void AppDemoGui::showLUTColors ( SLTexColorLUT lut)
static

Displays a editable color lookup table wit ImGui widgets.

Definition at line 4942 of file AppDemoGui.cpp.

4943 {
4944  ImGuiColorEditFlags cef = ImGuiColorEditFlags_NoInputs;
4945  for (SLulong c = 0; c < lut->colors().size(); ++c)
4946  {
4947  SLCol3f color = lut->colors()[c].color;
4948  SLchar label[20];
4949  snprintf(label, sizeof(label), "Color %lu", c);
4950  if (ImGui::ColorEdit3(label, (float*)&color, cef))
4951  {
4952  lut->colors()[c].color = color;
4953  lut->generateTexture();
4954  }
4955  ImGui::SameLine();
4956  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
4957  snprintf(label, sizeof(label), "Pos. %lu", c);
4958  SLfloat pos = lut->colors()[c].pos;
4959  if (c > 0 && c < lut->colors().size() - 1)
4960  {
4961  SLfloat min = lut->colors()[c - 1].pos + 2.0f / (SLfloat)lut->length();
4962  SLfloat max = lut->colors()[c + 1].pos - 2.0f / (SLfloat)lut->length();
4963  if (ImGui::SliderFloat(label, &pos, min, max, "%3.2f"))
4964  {
4965  lut->colors()[c].pos = pos;
4966  lut->generateTexture();
4967  }
4968  }
4969  else
4970  ImGui::Text("%3.2f Pos. %lu", pos, c);
4971  ImGui::PopItemWidth();
4972  }
4973 }
unsigned long SLulong
analog to GLulong
Definition: SL.h:192
void colors(SLColorLUTType lut)
Colors setter function by predefined color LUT.
SLuint length()
Definition: SLTexColorLUT.h:93
void generateTexture()
Generates the full 256 value LUT as 1x256 RGBA texture.

◆ showTexInfos()

void AppDemoGui::showTexInfos ( SLGLTexture tex)
static

Shows UI infos for a texture.

Definition at line 4547 of file AppDemoGui.cpp.

4548 {
4549  // SLfloat lineH = ImGui::GetTextLineHeightWithSpacing();
4550  SLfloat texW = ImGui::GetWindowWidth() - 4 * ImGui::GetTreeNodeToLabelSpacing() - 10;
4551  void* tid = (ImTextureID)(intptr_t)tex->texID();
4552  SLfloat w = (SLfloat)tex->width();
4553  SLfloat h = (SLfloat)tex->height();
4554  SLfloat h_to_w = h / w;
4555 
4556  if (ImGui::TreeNode(tex->name().c_str()))
4557  {
4558  float mbCPU = 0.0f;
4559  for (auto img : tex->images())
4560  mbCPU += (float)img->bytesPerImage();
4561  float mbGPU = (float)tex->bytesOnGPU();
4562  float mbDSK = (float)tex->bytesInFile();
4563 
4564  mbDSK /= 1E6f;
4565  mbCPU /= 1E6f;
4566  mbGPU /= 1E6f;
4567 
4568  ImGui::Text("Size(PX): %dx%dx%d", tex->width(), tex->height(), tex->depth());
4569  ImGui::Text("Size(MB): GPU:%4.2f, CPU:%4.2f, DSK:%4.2f", mbGPU, mbCPU, mbDSK);
4570  ImGui::Text("TexID : %u (%s)", tex->texID(), tex->isTexture() ? "ok" : "not ok");
4571  ImGui::Text("Type : %s", tex->typeName().c_str());
4572  if (!tex->images().empty() && tex->images()[0])
4573  ImGui::Text("Format : %s", tex->images()[0]->formatString().c_str());
4574  else
4575  ImGui::Text("Format : %s", "n/a (GPU only)");
4576 #ifdef SL_BUILD_WITH_KTX
4577  ImGui::Text("Compr. : %s", tex->compressionFormatStr(tex->compressionFormat()).c_str());
4578 #endif
4579  ImGui::Text("Min.Flt : %s", tex->minificationFilterName().c_str());
4580  ImGui::Text("Mag.Flt : %s", tex->magnificationFilterName().c_str());
4581 
4582  if (tex->target() == GL_TEXTURE_2D)
4583  {
4584  if (typeid(*tex) == typeid(SLTexColorLUT))
4585  {
4586  SLTexColorLUT* lut = (SLTexColorLUT*)tex;
4587  if (ImGui::TreeNode("Color Points in Gradient"))
4588  {
4589  showLUTColors(lut);
4590  ImGui::TreePop();
4591  }
4592 
4593  if (ImGui::TreeNode("Alpha Points in Gradient"))
4594  {
4595  for (SLulong a = 0; a < lut->alphas().size(); ++a)
4596  {
4597  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.25f);
4598  SLfloat alpha = lut->alphas()[a].alpha;
4599  SLchar label[20];
4600  snprintf(label, sizeof(label), "Alpha %lu", a);
4601  if (ImGui::SliderFloat(label, &alpha, 0.0f, 1.0f, "%3.2f"))
4602  {
4603  lut->alphas()[a].alpha = alpha;
4604  lut->generateTexture();
4605  }
4606  ImGui::SameLine();
4607  snprintf(label, sizeof(label), "Pos. %lu", a);
4608  SLfloat pos = lut->alphas()[a].pos;
4609  if (a > 0 && a < lut->alphas().size() - 1)
4610  {
4611  SLfloat min = lut->alphas()[a - 1].pos +
4612  2.0f / (SLfloat)lut->length();
4613  SLfloat max = lut->alphas()[a + 1].pos -
4614  2.0f / (SLfloat)lut->length();
4615  if (ImGui::SliderFloat(label, &pos, min, max, "%3.2f"))
4616  {
4617  lut->alphas()[a].pos = pos;
4618  lut->generateTexture();
4619  }
4620  }
4621  else
4622  ImGui::Text("%3.2f Pos. %lu", pos, a);
4623 
4624  ImGui::PopItemWidth();
4625  }
4626 
4627  ImGui::TreePop();
4628  }
4629 
4630  ImGui::Image(tid,
4631  ImVec2(texW, texW * 0.15f),
4632  ImVec2(0, 1),
4633  ImVec2(1, 0),
4634  ImVec4(1, 1, 1, 1),
4635  ImVec4(1, 1, 1, 1));
4636 
4637  SLVfloat allAlpha = lut->allAlphas();
4638  ImGui::PlotLines("",
4639  allAlpha.data(),
4640  (SLint)allAlpha.size(),
4641  0,
4642  nullptr,
4643  0.0f,
4644  1.0f,
4645  ImVec2(texW, texW * 0.25f));
4646  }
4647  else
4648  {
4649  ImGui::Image(tid,
4650  ImVec2(texW, texW * h_to_w),
4651  ImVec2(0, 1),
4652  ImVec2(1, 0),
4653  ImVec4(1, 1, 1, 1),
4654  ImVec4(1, 1, 1, 1));
4655  }
4656  }
4657  else
4658  {
4659  if (tex->target() == GL_TEXTURE_CUBE_MAP)
4660  ImGui::Text("Cube maps can not be displayed.");
4661  else if (tex->target() == GL_TEXTURE_3D)
4662  ImGui::Text("3D textures can not be displayed.");
4663  }
4664 
4665  ImGui::TreePop();
4666  }
4667 }
vector< SLfloat > SLVfloat
Definition: SL.h:228
SLuint height()
Definition: SLGLTexture.h:219
CVVImage & images()
Definition: SLGLTexture.h:225
SLint bytesOnGPU()
Definition: SLGLTexture.h:223
SLenum target() const
Definition: SLGLTexture.h:226
SLuint width()
Definition: SLGLTexture.h:218
SLint bytesInFile()
Definition: SLGLTexture.h:224
SLstring minificationFilterName()
Definition: SLGLTexture.h:242
SLstring typeName()
Returns the texture type as string.
SLuint depth()
Definition: SLGLTexture.h:220
SLstring magnificationFilterName()
Definition: SLGLTexture.h:243
bool isTexture()
Definition: SLGLTexture.h:241
SLVfloat allAlphas()
Returns all alpha values of the transfer function as a float vector.
SLVAlphaLUTPoint & alphas()
Definition: SLTexColorLUT.h:95

Member Data Documentation

◆ _horizonVisuEnabled

SLbool AppDemoGui::_horizonVisuEnabled = false
staticprivate

Definition at line 88 of file AppDemoGui.h.

◆ adjustedTime

std::time_t AppDemoGui::adjustedTime = 0
static

Adjusted GUI time for sun setting (default 0)

Definition at line 77 of file AppDemoGui.h.

◆ configTime

SLstring AppDemoGui::configTime = "-"
static

Time of stored configuration.

Definition at line 51 of file AppDemoGui.h.

◆ hideUI

SLbool AppDemoGui::hideUI = false
static

Flag if menubar should be shown.

Definition at line 56 of file AppDemoGui.h.

◆ infoAbout

SLstring AppDemoGui::infoAbout
static
Initial value:
= R"(
Welcome to the SLProject demo app. It is developed at the Computer Science Department of the Bern University of Applied Sciences.
The app shows what you can learn in two semesters about 3D computer graphics in real time rendering and ray tracing.
The framework is developed in C++ with OpenGL ES so that it can run also on mobile devices.
Ray tracing and path tracing provide additional high quality transparencies, reflections and soft shadows.
Click the X to close and use the menu File > Load Demo Scenes to choose other scenes that each show-case a specific feature of SLProject.
For more information please visit: https://github.com/cpvrlab/SLProject/wiki
)"

About info string.

Definition at line 52 of file AppDemoGui.h.

◆ infoCalibrate

SLstring AppDemoGui::infoCalibrate
static
Initial value:
= R"(
The calibration process requires a chessboard image to be printed and glued on a flat board. You can find the PDF with the chessboard image on:
https://github.com/cpvrlab/SLProject/tree/master/data/calibrations/
For a calibration you have to take 20 images with detected inner chessboard corners. To take an image you have to click with the mouse
or tap with finger into the screen. View the chessboard from the side so that the inner corners cover the full image. Hold the camera or board really still
before taking the picture.
You can mirror the video image under Preferences > Video. You can check the distance to the chessboard in the dialog Stats. on Video.
After calibration the yellow wireframe cube should stick on the chessboard. Please close first this info dialog on the top-left.
)"

Calibration info string.

Definition at line 55 of file AppDemoGui.h.

◆ infoCredits

SLstring AppDemoGui::infoCredits
static
Initial value:
= R"(
Contributors since 2005 in alphabetic order:
Marc Affolter, Martin Christen, Jan Dellsperger, Manuel Frischknecht, Luc Girod, Michael Goettlicher, Michael Schertenleib, Thomas Schneiter, Stefan Thoeni, Timo Tschanz, Marino von Wattenwyl, Marc Wacker, Pascal Zingg
Credits for external libraries:
- assimp: assimp.sourceforge.net
- eigen: eigen.tuxfamily.org
- emscripten: emscripten.org
- imgui: github.com/ocornut/imgui
- gl3w: https://github.com/skaslev/gl3w
- glfw: glfw.org
- g2o: github.com/RainerKuemmerle/g2o
- ktx: khronos.org/ktx
- libigl: libigl.github.io
- mediapipe: developers.google.com/mediapipe
- ORB-SLAM2: github.com/raulmur/ORB_SLAM2
- OpenCV: opencv.org
- OpenGL: opengl.org
- OpenSSL: openssl.org
- spa: midcdmz.nrel.gov/spa
- stb: single file image library
- zlib: zlib.net
)"

Credits info string.

Definition at line 53 of file AppDemoGui.h.

◆ infoHelp

SLstring AppDemoGui::infoHelp
static
Initial value:
= R"(
Help for mouse or finger control:
- Use left mouse or your finger to rotate the scene
- Use mouse-wheel or pinch 2 fingers to go forward/backward
- Use middle-mouse or 2 fingers to move sidewards/up-down
- Double click or double tap to select object
- CTRL-mouse to select vertices of objects
- See keyboard shortcuts behind menu commands
- Check out the different test scenes under File > Load Test Scene
- You can open and dock additional windows from the menu Infos.
)"

Help info string.

Definition at line 54 of file AppDemoGui.h.

◆ loadingString

SLstring AppDemoGui::loadingString = ""
static

String shown during loading screens.

Definition at line 78 of file AppDemoGui.h.

◆ showAbout

SLbool AppDemoGui::showAbout = false
static

Flag if about info should be shown.

Definition at line 59 of file AppDemoGui.h.

◆ showCredits

SLbool AppDemoGui::showCredits = false
static

Flag if credits info should be shown.

Definition at line 62 of file AppDemoGui.h.

◆ showDateAndTime

SLbool AppDemoGui::showDateAndTime = false
static

Flag if date-time dialog should be shown.

Definition at line 76 of file AppDemoGui.h.

◆ showDockSpace

SLbool AppDemoGui::showDockSpace = true
static

Flag if dock space should be enabled.

Definition at line 58 of file AppDemoGui.h.

◆ showErlebAR

SLbool AppDemoGui::showErlebAR = false
static

Flag if Christoffel infos should be shown.

Definition at line 73 of file AppDemoGui.h.

◆ showHelp

SLbool AppDemoGui::showHelp = false
static

Flag if help info should be shown.

Definition at line 60 of file AppDemoGui.h.

◆ showHelpCalibration

SLbool AppDemoGui::showHelpCalibration = false
static

Flag if calibration info should be shown.

Definition at line 61 of file AppDemoGui.h.

◆ showImGuiMetrics

SLbool AppDemoGui::showImGuiMetrics = false
static

Flag if imgui metrics infor should be shown.

Definition at line 67 of file AppDemoGui.h.

◆ showInfosDevice

SLbool AppDemoGui::showInfosDevice = false
static

Flag if device info should be shown.

Definition at line 69 of file AppDemoGui.h.

◆ showInfosScene

SLbool AppDemoGui::showInfosScene = false
static

Flag if scene info should be shown.

Definition at line 70 of file AppDemoGui.h.

◆ showInfosSensors

SLbool AppDemoGui::showInfosSensors = false
static

Flag if device sensors info should be shown.

Definition at line 68 of file AppDemoGui.h.

◆ showProgress

SLbool AppDemoGui::showProgress = false
static

Flag if about info should be shown.

Definition at line 57 of file AppDemoGui.h.

◆ showProperties

SLbool AppDemoGui::showProperties = false
static

Flag if properties should be shown.

Definition at line 72 of file AppDemoGui.h.

◆ showSceneGraph

SLbool AppDemoGui::showSceneGraph = false
static

Flag if scene graph should be shown.

Definition at line 71 of file AppDemoGui.h.

◆ showStatsScene

SLbool AppDemoGui::showStatsScene = false
static

Flag if scene info should be shown.

Definition at line 64 of file AppDemoGui.h.

◆ showStatsTiming

SLbool AppDemoGui::showStatsTiming = false
static

Flag if timing info should be shown.

Definition at line 63 of file AppDemoGui.h.

◆ showStatsVideo

SLbool AppDemoGui::showStatsVideo = false
static

Flag if video info should be shown.

Definition at line 65 of file AppDemoGui.h.

◆ showStatsWAI

SLbool AppDemoGui::showStatsWAI = false
static

Flag if WAI info should be shown.

Definition at line 66 of file AppDemoGui.h.

◆ showTransform

SLbool AppDemoGui::showTransform = false
static

Flag if transform dialog should be shown.

Definition at line 75 of file AppDemoGui.h.

◆ showUIPrefs

SLbool AppDemoGui::showUIPrefs = false
static

Flag if UI preferences.

Definition at line 74 of file AppDemoGui.h.


The documentation for this class was generated from the following files: