SLProject  4.2.000
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 3093 of file AppDemoGui.cpp.

3094 {
3095  PROFILE_FUNCTION();
3096 
3097  // assert(s->assetManager() && "No asset manager assigned to scene!");
3098 
3099  SLbool isSelectedNode = s->singleNodeSelected() == node;
3100  SLbool isLeafNode = node->children().empty() && !node->mesh();
3101  SLbool isHidden = node->drawBit(SL_DB_HIDDEN);
3102  bool nodeIsOpen;
3103 
3104  ImGuiTreeNodeFlags nodeFlags = 0;
3105  if (isLeafNode)
3106  nodeFlags |= ImGuiTreeNodeFlags_Leaf;
3107  else
3108  nodeFlags |= ImGuiTreeNodeFlags_OpenOnArrow;
3109 
3110  if (isSelectedNode)
3111  nodeFlags |= ImGuiTreeNodeFlags_Selected;
3112 
3113  if (isHidden)
3114  {
3115  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 1.0f, 1.0f));
3116  nodeIsOpen = ImGui::TreeNodeEx(node->name().c_str(), nodeFlags);
3117  ImGui::PopStyleColor();
3118  }
3119  else
3120  {
3121  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
3122  nodeIsOpen = ImGui::TreeNodeEx(node->name().c_str(), nodeFlags);
3123  ImGui::PopStyleColor();
3124  }
3125 
3126  if (ImGui::IsItemClicked())
3127  {
3129  s->selectNodeMesh(node, nullptr);
3130  }
3131 
3132  if (nodeIsOpen)
3133  {
3134  if (node->mesh())
3135  {
3136  SLMesh* mesh = node->mesh();
3137  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
3138 
3139  ImGuiTreeNodeFlags meshFlags = ImGuiTreeNodeFlags_Leaf;
3140  if (s->singleMeshFullSelected() == mesh)
3141  meshFlags |= ImGuiTreeNodeFlags_Selected;
3142 
3143  ImGui::TreeNodeEx(mesh, meshFlags, "%s", mesh->name().c_str());
3144 
3145  if (ImGui::IsItemClicked())
3146  {
3148  s->selectNodeMesh(node, mesh);
3149  }
3150 
3151  ImGui::TreePop();
3152  ImGui::PopStyleColor();
3153  }
3154 
3155  for (auto* child : node->children())
3156  addSceneGraphNode(s, child);
3157 
3158  ImGui::TreePop();
3159  }
3160 }
#define PROFILE_FUNCTION()
Definition: Instrumentor.h:41
bool SLbool
Definition: SL.h:175
#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:305
SLbool drawBit(SLuint bit)
Definition: SLNode.h:300
SLMesh * mesh()
Definition: SLNode.h:304
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 229 of file AppDemoGui.cpp.

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

◆ buildMenuBar()

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

Builds the entire menu bar once per frame.

Definition at line 1480 of file AppDemoGui.cpp.

1481 {
1482  PROFILE_FUNCTION();
1483 
1484  // assert(s->assetManager() && "No asset manager assigned to scene!");
1486 
1488  SLGLState* stateGL = SLGLState::instance();
1489  CVCapture* capture = CVCapture::instance();
1490  SLRenderType rType = sv->renderType();
1491  SLbool hasAnimations = (!s->animManager().animationNames().empty());
1492  static SLint curAnimIx = -1;
1493  if (!hasAnimations) curAnimIx = -1;
1494 
1495  // Remove transform node if no or the wrong one is selected
1498 
1499  if (ImGui::BeginMainMenuBar())
1500  {
1501  if (ImGui::BeginMenu("File"))
1502  {
1503  if (ImGui::BeginMenu("Load Test Scene"))
1504  {
1505  if (ImGui::BeginMenu("General"))
1506  {
1507  if (ImGui::MenuItem("Minimal Scene", nullptr, sid == SID_Minimal))
1509  if (ImGui::MenuItem("Figure Scene", nullptr, sid == SID_Figure))
1511  if (ImGui::MenuItem("Mesh Loader", nullptr, sid == SID_MeshLoad))
1513  if (ImGui::MenuItem("Revolver Meshes", nullptr, sid == SID_Revolver))
1515  if (ImGui::MenuItem("Texture Blending", nullptr, sid == SID_TextureBlend))
1517  if (ImGui::MenuItem("Texture Filters", nullptr, sid == SID_TextureFilter))
1519 #ifdef SL_BUILD_WITH_KTX
1520  if (ImGui::MenuItem("Texture Compression", nullptr, sid == SID_TextureCompression))
1522 #endif
1523  if (ImGui::MenuItem("Frustum Culling", nullptr, sid == SID_FrustumCull))
1525  if (ImGui::MenuItem("2D and 3D Text", nullptr, sid == SID_2Dand3DText))
1527  if (ImGui::MenuItem("Point Clouds", nullptr, sid == SID_PointClouds))
1529  if (ImGui::MenuItem("Z-Fighting", nullptr, sid == SID_ZFighting))
1531 
1532  ImGui::EndMenu();
1533  }
1534 
1535  if (ImGui::BeginMenu("Shader"))
1536  {
1537  if (ImGui::MenuItem("Per Vertex Blinn-Phong", nullptr, sid == SID_ShaderPerVertexBlinn))
1539  if (ImGui::MenuItem("Per Pixel Blinn-Phong", nullptr, sid == SID_ShaderPerPixelBlinn))
1541  if (ImGui::MenuItem("Per Pixel Cook-Torrance", nullptr, sid == SID_ShaderPerPixelCook))
1543  if (ImGui::MenuItem("Image Based Lighting", nullptr, sid == SID_ShaderIBL))
1545  if (ImGui::MenuItem("Per Vertex Wave", nullptr, sid == SID_ShaderWave))
1547  if (ImGui::MenuItem("Bump Mapping", nullptr, sid == SID_ShaderBumpNormal))
1549  if (ImGui::MenuItem("Parallax Mapping", nullptr, sid == SID_ShaderBumpParallax))
1551  if (ImGui::MenuItem("Skybox Shader", nullptr, sid == SID_ShaderSkybox))
1553  if (ImGui::MenuItem("Earth Shader", nullptr, sid == SID_ShaderEarth))
1555  ImGui::EndMenu();
1556  }
1557 
1558  if (ImGui::BeginMenu("Shadow Mapping"))
1559  {
1560  if (ImGui::MenuItem("Basic Scene", nullptr, sid == SID_ShadowMappingBasicScene))
1562  if (ImGui::MenuItem("Light Types", nullptr, sid == SID_ShadowMappingLightTypes))
1564  if (ImGui::MenuItem("8 Spot Lights", nullptr, sid == SID_ShadowMappingSpotLights))
1566  if (ImGui::MenuItem("3 Point Lights", nullptr, sid == SID_ShadowMappingPointLights))
1568  if (ImGui::MenuItem("RT Soft Shadows", nullptr, sid == SID_RTSoftShadows))
1570  if (ImGui::MenuItem("Cascaded Shadows", nullptr, sid == SID_ShadowMappingCascaded))
1572  if (ImGui::MenuItem("Columns with Cascaded Sh.", nullptr, sid == SID_Benchmark_ColumnsLOD))
1574 
1575  ImGui::EndMenu();
1576  }
1577 
1578  if (ImGui::BeginMenu("Suzanne Lighting"))
1579  {
1580  if (ImGui::MenuItem("w. per Pixel Lighting (PL)", nullptr, sid == SID_SuzannePerPixBlinn))
1582  if (ImGui::MenuItem("w. PL and Texture Mapping (TM)", nullptr, sid == SID_SuzannePerPixBlinnTm))
1584  if (ImGui::MenuItem("w. PL and Normal Mapping (NM)", nullptr, sid == SID_SuzannePerPixBlinnNm))
1586  if (ImGui::MenuItem("w. PL and Ambient Occlusion (AO)", nullptr, sid == SID_SuzannePerPixBlinnAo))
1588  if (ImGui::MenuItem("w. PL and Shadow Mapping (SM)", nullptr, sid == SID_SuzannePerPixBlinnSm))
1590  if (ImGui::MenuItem("w. PL, TM, NM", nullptr, sid == SID_SuzannePerPixBlinnTmNm))
1592  if (ImGui::MenuItem("w. PL, TM, AO", nullptr, sid == SID_SuzannePerPixBlinnTmAo))
1594  if (ImGui::MenuItem("w. PL, NM, AO", nullptr, sid == SID_SuzannePerPixBlinnNmAo))
1596  if (ImGui::MenuItem("w. PL, NM, SM", nullptr, sid == SID_SuzannePerPixBlinnNmSm))
1598  if (ImGui::MenuItem("w. PL, TM, SM", nullptr, sid == SID_SuzannePerPixBlinnTmSm))
1600  if (ImGui::MenuItem("w. PL, AO, SM", nullptr, sid == SID_SuzannePerPixBlinnAoSm))
1602  if (ImGui::MenuItem("w. PL, TM, NM, AO", nullptr, sid == SID_SuzannePerPixBlinnTmNmAo))
1604  if (ImGui::MenuItem("w. PL, TM, NM, SM", nullptr, sid == SID_SuzannePerPixBlinnTmNmSm))
1606  if (ImGui::MenuItem("w. PL, TM, NM, AO, SM", nullptr, sid == SID_SuzannePerPixBlinnTmNmAoSm))
1608  if (ImGui::MenuItem("w. PL, TM, NM, AO, SM, EM", nullptr, sid == SID_SuzannePerPixCookTmNmAoSmEm))
1610  ImGui::EndMenu();
1611  }
1612 
1613  if (ImGui::BeginMenu("glTF Sample Models"))
1614  {
1615  SLstring zip = "glTF-Sample-Models.zip";
1616 
1617  if (ImGui::MenuItem("Damaged Helmet", nullptr, sid == SID_glTF_DamagedHelmet))
1619  if (ImGui::MenuItem("Flight Helmet", nullptr, sid == SID_glTF_FlightHelmet))
1621  if (ImGui::MenuItem("Sponza Palace", nullptr, sid == SID_glTF_Sponza))
1623  if (ImGui::MenuItem("Water Bottle", nullptr, sid == SID_glTF_WaterBottle))
1625 
1626  ImGui::EndMenu();
1627  }
1628 
1629  if (ImGui::BeginMenu("Robotics"))
1630  {
1631  SLstring zip = "GLTF-FanucCRX.zip";
1632 
1633  if (ImGui::MenuItem("Fanuc-CRX", nullptr, sid == SID_Robotics_FanucCRX_FK))
1635 
1636  ImGui::EndMenu();
1637  }
1638 
1639  if (ImGui::BeginMenu("Volume Rendering"))
1640  {
1641  if (ImGui::MenuItem("Head MRI Ray Cast", nullptr, sid == SID_VolumeRayCast))
1643  if (ImGui::MenuItem("Head MRI Ray Cast Lighted", nullptr, sid == SID_VolumeRayCastLighted))
1645  /*
1646  {
1647  auto loadMRIImages = []() {
1648  AppCommon::jobProgressMsg("Load MRI Images");
1649  AppCommon::jobProgressMax(100);
1650 
1651  // Load volume data into 3D texture
1652  SLVstring mriImages;
1653  for (SLint i = 0; i < 207; ++i)
1654  mriImages.push_back(AppCommon::texturePath + Utils::formatString("i%04u_0000b.png", i));
1655 
1656  gTexMRI3D = new SLGLTexture(nullptr,
1657  mriImages,
1658  GL_LINEAR,
1659  GL_LINEAR,
1660 #ifndef SL_EMSCRIPTEN
1661  0x812D, // GL_CLAMP_TO_BORDER (GLSL 320)
1662  0x812D, // GL_CLAMP_TO_BORDER (GLSL 320)
1663 #else
1664  GL_CLAMP_TO_EDGE,
1665  GL_CLAMP_TO_EDGE,
1666 #endif
1667  "mri_head_front_to_back",
1668  true);
1669  AppCommon::jobIsRunning = false;
1670  };
1671 
1672  auto calculateGradients = []() {
1673  AppCommon::jobProgressMsg("Calculate MRI Volume Gradients");
1674  AppCommon::jobProgressMax(100);
1675  gTexMRI3D->calc3DGradients(1,
1676  [](int progress) { AppCommon::jobProgressNum(progress); });
1677  AppCommon::jobIsRunning = false;
1678  };
1679 
1680  auto smoothGradients = []() {
1681  AppCommon::jobProgressMsg("Smooth MRI Volume Gradients");
1682  AppCommon::jobProgressMax(100);
1683  gTexMRI3D->smooth3DGradients(1,
1684  [](int progress) { AppCommon::jobProgressNum(progress); });
1685  AppCommon::jobIsRunning = false;
1686  };
1687 
1688  auto followUpJob1 = [](SLAssetManager* am, SLScene* s, SLSceneView* sv) {
1689  AppCommon::sceneToLoad = SID_VolumeRayCastLighted;
1690  };
1691  function<void(void)> onLoadScene = bind(followUpJob1, am, s, sv);
1692 
1693  AppCommon::jobsToBeThreaded.emplace_back(loadMRIImages);
1694  AppCommon::jobsToBeThreaded.emplace_back(calculateGradients);
1695  // AppCommon::jobsToBeThreaded.emplace_back(smoothGradients); // very slow
1696  AppCommon::jobsToFollowInMain.push_back(onLoadScene);
1697  }
1698  */
1699  ImGui::EndMenu();
1700  }
1701 
1702  if (ImGui::BeginMenu("Animation"))
1703  {
1704  if (ImGui::MenuItem("Node Animation", nullptr, sid == SID_AnimationNode))
1706  if (ImGui::MenuItem("Mass Node Animation", nullptr, sid == SID_AnimationNodeMass))
1708  if (ImGui::MenuItem("Skinned Animation", nullptr, sid == SID_AnimationSkinned))
1710  if (ImGui::MenuItem("Mass Skinned Animation", nullptr, sid == SID_AnimationSkinnedMass))
1712  if (ImGui::MenuItem("Fanuc-CRX", nullptr, sid == SID_Robotics_FanucCRX_FK))
1714 
1715  ImGui::EndMenu();
1716  }
1717 
1718  if (ImGui::BeginMenu("Video"))
1719  {
1720  if (ImGui::MenuItem("Texture from Video Live", nullptr, sid == SID_VideoTextureLive))
1722 #ifndef SL_EMSCRIPTEN
1723  if (ImGui::MenuItem("Texture from Video File", nullptr, sid == SID_VideoTextureFile))
1725 #endif
1726  if (ImGui::MenuItem("Track ArUco Marker (Main)", nullptr, sid == SID_VideoTrackArucoMain))
1728  if (ImGui::MenuItem("Track ArUco Marker (Scnd)", nullptr, sid == SID_VideoTrackArucoScnd, capture->hasSecondaryCamera))
1730  if (ImGui::MenuItem("Track Chessboard (Main)", nullptr, sid == SID_VideoTrackChessMain))
1732  if (ImGui::MenuItem("Track Chessboard (Scnd)", nullptr, sid == SID_VideoTrackChessScnd, capture->hasSecondaryCamera))
1734  if (ImGui::MenuItem("Track Features (Main)", nullptr, sid == SID_VideoTrackFeature2DMain))
1736 #ifndef SL_EMSCRIPTEN
1737  if (ImGui::MenuItem("Track Face (Main)", nullptr, sid == SID_VideoTrackFaceMain))
1739  if (ImGui::MenuItem("Track Face (Scnd)", nullptr, sid == SID_VideoTrackFaceScnd, capture->hasSecondaryCamera))
1741 #endif
1742 #ifdef SL_BUILD_WITH_MEDIAPIPE
1743  if (ImGui::MenuItem("Track Hands w. Mediapipe (Main)", nullptr, sid == SID_VideoTrackMediaPipeHandsMain))
1745 #endif
1746  if (ImGui::MenuItem("Sensor AR (Main)", nullptr, sid == SID_VideoSensorAR))
1748 #ifdef SL_BUILD_WAI
1749  if (ImGui::MenuItem("Track WAI (Main)", nullptr, sid == SID_VideoTrackWAI))
1751 #endif
1752  ImGui::EndMenu();
1753  }
1754 
1755  if (ImGui::BeginMenu("Ray Tracing"))
1756  {
1757  if (ImGui::MenuItem("Spheres", nullptr, sid == SID_RTSpheres))
1759  if (ImGui::MenuItem("Muttenzer Box", nullptr, sid == SID_RTMuttenzerBox))
1761  if (ImGui::MenuItem("Soft Shadows", nullptr, sid == SID_RTSoftShadows))
1763  if (ImGui::MenuItem("Depth of Field", nullptr, sid == SID_RTDoF))
1765  if (ImGui::MenuItem("Lens Test", nullptr, sid == SID_RTLens))
1767 
1768  ImGui::EndMenu();
1769  }
1770 
1771  if (ImGui::BeginMenu("Path Tracing"))
1772  {
1773  if (ImGui::MenuItem("Muttenzer Box", nullptr, sid == SID_RTMuttenzerBox))
1775 
1776  ImGui::EndMenu();
1777  }
1778 
1779  if (ImGui::BeginMenu("Particle Systems"))
1780  {
1781  if (ImGui::MenuItem("First Particle System", nullptr, sid == SID_ParticleSystem_Simple))
1783  if (ImGui::MenuItem("Dust Storm Particle System", nullptr, sid == SID_ParticleSystem_DustStorm))
1785  if (ImGui::MenuItem("Fountain Particle System", nullptr, sid == SID_ParticleSystem_Fountain))
1787  if (ImGui::MenuItem("Sun Particle System", nullptr, sid == SID_ParticleSystem_Sun))
1789  if (ImGui::MenuItem("Ring of Fire Particle System", nullptr, sid == SID_ParticleSystem_RingOfFire))
1791  if (ImGui::MenuItem("Complex Fire Particle System", nullptr, sid == SID_ParticleSystem_ComplexFire))
1793  if (ImGui::MenuItem("Particle system w. 1 mio. particles", nullptr, sid == SID_ParticleSystem_Many))
1795 
1796  ImGui::EndMenu();
1797  }
1798 
1799  // Download content from pallas/home/private/projects/2020.Erleb-AR/erleb-AR-data/productive/models_for_SLProject
1800  // and copy it into AppCommon::dataPath + "erleb-AR/models/
1801  // This data is copyright protected and can only be accessed with user and password
1802  SLstring erlebarPath = AppCommon::dataPath + "erleb-AR/models/";
1803  SLstring modelBR2 = erlebarPath + "bern/bern-christoffel.gltf";
1804  SLstring modelBFH = erlebarPath + "biel/Biel-BFH-Rolex.gltf";
1805  SLstring modelAR1 = erlebarPath + "augst/augst-thtL1-tmpL2.gltf";
1806  SLstring modelAR2 = erlebarPath + "augst/augst-thtL2-tmpL1.gltf";
1807  SLstring modelAR3 = erlebarPath + "augst/augst-thtL1L2-tmpL1L2.gltf";
1808  SLstring modelAV1_AO = erlebarPath + "avenches/avenches-amphitheater.gltf";
1809  SLstring modelAV2_AO = erlebarPath + "avenches/avenches-cigognier.gltf";
1810  SLstring modelAV3 = erlebarPath + "avenches/avenches-theater.gltf";
1811  SLstring modelSU1 = erlebarPath + "sutz/Sutz-Kirchrain18.gltf";
1812 
1813  if (Utils::fileExists(modelAR1) ||
1814  Utils::fileExists(modelAR2) ||
1815  Utils::fileExists(modelAR3) ||
1816  Utils::fileExists(modelAV3) ||
1817  Utils::fileExists(modelBR2) ||
1818  Utils::fileExists(modelSU1))
1819  {
1820  if (ImGui::BeginMenu("Erleb-AR"))
1821  {
1822  if (Utils::fileExists(modelBR2))
1823  if (ImGui::MenuItem("Bern: Christoffel Tower", nullptr, sid == SID_ErlebAR_BernChristoffel))
1825 
1826  if (Utils::fileExists(modelBFH))
1827  if (ImGui::MenuItem("Biel: BFH", nullptr, sid == SID_ErlebAR_BielBFH))
1829 
1830  if (Utils::fileExists(modelAR3))
1831  if (ImGui::MenuItem("Augusta Raurica Temple & Theater", nullptr, sid == SID_ErlebAR_AugustaRauricaTmpTht))
1833 
1834  if (Utils::fileExists(modelAV1_AO))
1835  if (ImGui::MenuItem("Aventicum: Amphitheatre", nullptr, sid == SID_ErlebAR_AventicumAmphiteatre))
1837 
1838  if (Utils::fileExists(modelAV2_AO))
1839  if (ImGui::MenuItem("Aventicum: Cigognier", nullptr, sid == SID_ErlebAR_AventicumCigognier))
1841 
1842  if (Utils::fileExists(modelAV3))
1843  if (ImGui::MenuItem("Aventicum: Theatre", nullptr, sid == SID_ErlebAR_AventicumTheatre))
1845 
1846  if (Utils::fileExists(modelSU1))
1847  if (ImGui::MenuItem("Sutz: Kirchrain 18", nullptr, sid == SID_ErlebAR_SutzKirchrain18))
1849 
1850  ImGui::EndMenu();
1851  }
1852  }
1853 
1854  if (ImGui::BeginMenu("Benchmarks"))
1855  {
1856 #ifndef SL_EMSCRIPTEN
1857  /* The large models are too large for emscripten
1858  if (ImGui::MenuItem("Large Model (via FTP)", nullptr, sid == SID_Benchmark_LargeModel))
1859  {
1860  SLstring largeFile = AppCommon::configPath + "models/xyzrgb_dragon/xyzrgb_dragon.ply";
1861  if (Utils::fileExists(largeFile))
1862  AppCommon::sceneToLoad = SID_Benchmark_LargeModel;
1863  else
1864  {
1865  auto downloadJobFTP = []() {
1866  AppCommon::jobProgressMsg("Downloading large dragon file via FTP:");
1867  AppCommon::jobProgressMax(100);
1868  ftplib ftp;
1869  ftp.SetConnmode(ftplib::connmode::port); // enable active mode
1870 
1871  if (ftp.Connect("pallas.ti.bfh.ch:21"))
1872  {
1873  if (ftp.Login("guest", "g2Q7Z7OkDP4!"))
1874  {
1875  ftp.SetCallbackXferFunction(ftpCallbackXfer);
1876  ftp.SetCallbackBytes(1024000);
1877  if (ftp.Chdir("data/SLProject/models"))
1878  {
1879  int remoteSize = 0;
1880  ftp.Size("xyzrgb_dragon.zip",
1881  &remoteSize,
1882  ftplib::transfermode::image);
1883  ftpXferSizeMax = remoteSize;
1884  SLstring dstDir = AppCommon::configPath;
1885  if (Utils::dirExists(dstDir))
1886  {
1887  SLstring outFile = AppCommon::configPath + "models/xyzrgb_dragon.zip";
1888  if (!ftp.Get(outFile.c_str(),
1889  "xyzrgb_dragon.zip",
1890  ftplib::transfermode::image))
1891  SL_LOG("*** ERROR: ftp.Get failed. ***");
1892  }
1893  else
1894  SL_LOG("*** ERROR: Destination directory does not exist: %s ***", dstDir.c_str());
1895  }
1896  else
1897  SL_LOG("*** ERROR: ftp.Chdir failed. ***");
1898  }
1899  else
1900  SL_LOG("*** ERROR: ftp.Login failed. ***");
1901  }
1902  else
1903  SL_LOG("*** ERROR: ftp.Connect failed. ***");
1904 
1905  ftp.Quit();
1906  AppCommon::jobIsRunning = false;
1907  };
1908 
1909  auto unzipJob = [largeFile]() {
1910  AppCommon::jobProgressMsg("Decompress dragon file:");
1911  AppCommon::jobProgressMax(-1);
1912  string zipFile = AppCommon::configPath + "models/xyzrgb_dragon.zip";
1913  if (Utils::fileExists(zipFile))
1914  {
1915  ZipUtils::unzip(zipFile, Utils::getPath(zipFile));
1916  Utils::deleteFile(zipFile);
1917  }
1918  AppCommon::jobIsRunning = false;
1919  };
1920 
1921  auto followUpJob1 = [am, s, sv, largeFile]() {
1922  if (Utils::fileExists(largeFile))
1923  AppCommon::sceneToLoad = SID_Benchmark_LargeModel;
1924  };
1925 
1926  AppCommon::jobsToBeThreaded.emplace_back(downloadJobFTP);
1927  AppCommon::jobsToBeThreaded.emplace_back(unzipJob);
1928  AppCommon::jobsToFollowInMain.emplace_back(followUpJob1);
1929  }
1930  }
1931  if (ImGui::MenuItem("Large Model (via HTTPS)", nullptr, sid == SID_Benchmark_LargeModel))
1932  {
1933  SLstring largeFile = AppCommon::configPath + "models/xyzrgb_dragon/xyzrgb_dragon.ply";
1934  loadSceneWithLargeModel(s, sv, "xyzrgb_dragon.zip", largeFile, SID_Benchmark_LargeModel);
1935  }*/
1936 #endif
1937  if (ImGui::MenuItem("Large Model", nullptr, sid == SID_Benchmark_LargeModel))
1939  if (ImGui::MenuItem("Massive Nodes", nullptr, sid == SID_Benchmark_LotsOfNodes))
1941  if (ImGui::MenuItem("Massive Node Animations", nullptr, sid == SID_Benchmark_NodeAnimations))
1943  if (ImGui::MenuItem("Jan's Universe", nullptr, sid == SID_Benchmark_JansUniverse))
1945  if (ImGui::MenuItem("Massive Skinned Animations", nullptr, sid == SID_Benchmark_SkinnedAnimations))
1947  if (ImGui::MenuItem("Columns without LOD", nullptr, sid == SID_Benchmark_ColumnsNoLOD))
1949  if (ImGui::MenuItem("Columns with LOD", nullptr, sid == SID_Benchmark_ColumnsLOD))
1951  if (ImGui::MenuItem("Particle System lot of fire complex", nullptr, sid == SID_Benchmark_ParticleSystemComplexFire))
1953  if (ImGui::MenuItem("Particle System w. 1 mio. particle", nullptr, sid == SID_ParticleSystem_Many))
1955  ImGui::EndMenu();
1956  }
1957 
1958  ImGui::EndMenu();
1959  }
1960 
1961  if (ImGui::MenuItem("Empty Scene", "Shift-Alt-0", sid == SID_Empty))
1963 
1964  if (ImGui::MenuItem("Next Scene",
1965  "Shift-Alt->",
1966  nullptr,
1969 
1970  if (ImGui::MenuItem("Previous Scene",
1971  "Shift-Alt-<",
1972  nullptr,
1975 
1976 #ifndef SL_EMSCRIPTEN
1977  ImGui::Separator();
1978 
1979  if (ImGui::MenuItem("Multi-threaded Jobs"))
1980  {
1981  auto job1 = []()
1982  {
1983  PROFILE_THREAD("Worker Thread 1");
1984  PROFILE_SCOPE("Parallel Job 1");
1985 
1986  uint maxIter = 100000;
1987  AppCommon::jobProgressMsg("Super long job 1");
1989  for (uint i = 0; i < maxIter; ++i)
1990  {
1991  SL_LOG("%u", i);
1992  int progressPC = (int)((float)i / (float)maxIter * 100.0f);
1993  AppCommon::jobProgressNum(progressPC);
1994  }
1995  AppCommon::jobIsRunning = false;
1996  };
1997 
1998  auto job2 = []()
1999  {
2000  PROFILE_THREAD("Worker Thread 2");
2001  PROFILE_SCOPE("Parallel Job 2");
2002 
2003  uint maxIter = 100000;
2004  AppCommon::jobProgressMsg("Super long job 2");
2006  for (uint i = 0; i < maxIter; ++i)
2007  {
2008  SL_LOG("%u", i);
2009  int progressPC = (int)((float)i / (float)maxIter * 100.0f);
2010  AppCommon::jobProgressNum(progressPC);
2011  }
2012  AppCommon::jobIsRunning = false;
2013  };
2014 
2015  auto followUpJob1 = []()
2016  { SL_LOG("followUpJob1"); };
2017  auto jobToFollow2 = []()
2018  { SL_LOG("JobToFollow2"); };
2019 
2020  AppCommon::jobsToBeThreaded.emplace_back(job1);
2021  AppCommon::jobsToBeThreaded.emplace_back(job2);
2022  AppCommon::jobsToFollowInMain.emplace_back(followUpJob1);
2023  AppCommon::jobsToFollowInMain.emplace_back(jobToFollow2);
2024  }
2025 #endif
2026 
2027 #if !defined(SL_OS_ANDROID) && !defined(SL_EMSCRIPTEN)
2028  ImGui::Separator();
2029 
2030  if (ImGui::MenuItem("Quit & Save"))
2031  slShouldClose(true);
2032 #endif
2033 
2034  ImGui::EndMenu();
2035  }
2036 
2037  if (ImGui::BeginMenu("Preferences"))
2038  {
2039  if (ImGui::MenuItem("Do Wait on Idle", "I", sv->doWaitOnIdle()))
2041 
2042  if (ImGui::MenuItem("Do Multi Sampling", "L", sv->doMultiSampling()))
2044 
2045  if (ImGui::MenuItem("Do Frustum Culling", "F", sv->doFrustumCulling()))
2047 
2048  if (ImGui::MenuItem("Do Alpha Sorting", "J", sv->doAlphaSorting()))
2050 
2051  if (ImGui::MenuItem("Do Depth Test", "T", sv->doDepthTest()))
2052  sv->doDepthTest(!sv->doDepthTest());
2053 
2054  if (ImGui::MenuItem("Animation off", "Space", s->stopAnimations()))
2056 
2057  ImGui::Separator();
2058 
2059  if (ImGui::BeginMenu("Viewport Aspect"))
2060  {
2061  SLVec2i videoAspect(0, 0);
2062  if (capture->videoType() != VT_NONE)
2063  {
2064  videoAspect.x = capture->captureSize.width;
2065  videoAspect.y = capture->captureSize.height;
2066  }
2067  SLchar strSameAsVideo[256];
2068  snprintf(strSameAsVideo, sizeof(strSameAsVideo), "Same as Video (%d:%d)", videoAspect.x, videoAspect.y);
2069 
2070  if (ImGui::MenuItem("Same as window", nullptr, sv->viewportRatio() == SLVec2i::ZERO))
2071  sv->setViewportFromRatio(SLVec2i(0, 0), sv->viewportAlign(), false);
2072  if (ImGui::MenuItem(strSameAsVideo, nullptr, sv->viewportSameAsVideo()))
2073  sv->setViewportFromRatio(videoAspect, sv->viewportAlign(), true);
2074  if (ImGui::MenuItem("16:9", nullptr, sv->viewportRatio() == SLVec2i(16, 9)))
2075  sv->setViewportFromRatio(SLVec2i(16, 9), sv->viewportAlign(), false);
2076  if (ImGui::MenuItem("4:3", nullptr, sv->viewportRatio() == SLVec2i(4, 3)))
2077  sv->setViewportFromRatio(SLVec2i(4, 3), sv->viewportAlign(), false);
2078  if (ImGui::MenuItem("2:1", nullptr, sv->viewportRatio() == SLVec2i(2, 1)))
2079  sv->setViewportFromRatio(SLVec2i(2, 1), sv->viewportAlign(), false);
2080  if (ImGui::MenuItem("1:1", nullptr, sv->viewportRatio() == SLVec2i(1, 1)))
2081  sv->setViewportFromRatio(SLVec2i(1, 1), sv->viewportAlign(), false);
2082 
2083  if (ImGui::BeginMenu("Alignment", sv->viewportRatio() != SLVec2i::ZERO))
2084  {
2085  if (ImGui::MenuItem("Center", nullptr, sv->viewportAlign() == VA_center))
2087  if (ImGui::MenuItem("Left or bottom", nullptr, sv->viewportAlign() == VA_leftOrBottom))
2089 
2090  ImGui::EndMenu();
2091  }
2092  ImGui::EndMenu();
2093  }
2094 
2095  ImGui::Separator();
2096 
2097  // Rotation and Location Sensor
2098 #if defined(SL_OS_ANDROID) || defined(SL_OS_MACIOS)
2099  if (ImGui::BeginMenu("Rotation Sensor"))
2100  {
2102 
2103  if (ImGui::MenuItem("Use Device Rotation (IMU)", nullptr, devRot.isUsed()))
2104  devRot.isUsed(!AppCommon::devRot.isUsed());
2105 
2106  if (devRot.isUsed())
2107  {
2108  SLint numAveraged = devRot.numAveraged();
2109  if (ImGui::SliderInt("Average length", &numAveraged, 1, 10))
2110  devRot.numAveraged(numAveraged);
2111 
2112  if (ImGui::BeginMenu("Offset Mode"))
2113  {
2114  SLRotOffsetMode om = devRot.offsetMode();
2115  if (ImGui::MenuItem("None", nullptr, om == ROM_none))
2116  devRot.offsetMode(ROM_none);
2117  if (ImGui::MenuItem("Finger rot. X", nullptr, om == ROM_oneFingerX))
2118  devRot.offsetMode(ROM_oneFingerX);
2119  if (ImGui::MenuItem("Finger rot. X and Y", nullptr, om == ROM_oneFingerXY))
2120  devRot.offsetMode(ROM_oneFingerXY);
2121 
2122  ImGui::EndMenu();
2123  }
2124 
2125  if (ImGui::MenuItem("Zero Yaw at Start", nullptr, devRot.zeroYawAtStart()))
2126  devRot.zeroYawAtStart(!devRot.zeroYawAtStart());
2127 
2128  if (ImGui::MenuItem("Reset Zero Yaw"))
2129  devRot.hasStarted(true);
2130 
2131  if (ImGui::MenuItem("Show Horizon", nullptr, _horizonVisuEnabled))
2132  {
2133  if (_horizonVisuEnabled)
2134  hideHorizon(s);
2135  else
2136  showHorizon(s, sv);
2137  }
2138  }
2139 
2140  ImGui::EndMenu();
2141  }
2142 
2143  if (ImGui::BeginMenu("Location Sensor"))
2144  {
2146 
2147  if (ImGui::MenuItem("Use Device Location (GPS)", nullptr, AppCommon::devLoc.isUsed()))
2149 
2150  if (!AppCommon::devLoc.geoTiffIsAvailableAndValid())
2151  if (ImGui::MenuItem("Use Origin Altitude", nullptr, AppCommon::devLoc.useOriginAltitude()))
2153 
2154  if (ImGui::MenuItem("Reset Origin to here"))
2156 
2157  if (ImGui::BeginMenu("Offset Mode"))
2158  {
2159  SLLocOffsetMode om = devLoc.offsetMode();
2160  if (ImGui::MenuItem("None", nullptr, om == LOM_none))
2161  devLoc.offsetMode(LOM_none);
2162  if (ImGui::MenuItem("Two Finger Y", nullptr, om == LOM_twoFingerY))
2163  devLoc.offsetMode(LOM_twoFingerY);
2164 
2165  ImGui::EndMenu();
2166  }
2167 
2168  ImGui::EndMenu();
2169  }
2170 #endif
2171 
2172  if (ImGui::BeginMenu("Video Sensor"))
2173  {
2174  CVCamera* ac = capture->activeCamera;
2175  if (ImGui::BeginMenu("Mirror Camera"))
2176  {
2177  if (ImGui::MenuItem("Horizontally", nullptr, ac->mirrorH()))
2178  {
2179  ac->toggleMirrorH();
2180  // make a guessed calibration, if there was a calibrated camera it is not valid anymore
2181  ac->calibration = guessCalibration(ac->mirrorH(), ac->mirrorV(), ac->type());
2182  }
2183 
2184  if (ImGui::MenuItem("Vertically", nullptr, ac->mirrorV()))
2185  {
2186  ac->toggleMirrorV();
2187  // make a guessed calibration, if there was a calibrated camera it is not valid anymore
2188  ac->calibration = guessCalibration(ac->mirrorH(), ac->mirrorV(), ac->type());
2189  }
2190 
2191  ImGui::EndMenu();
2192  }
2193 
2194  if (ImGui::BeginMenu("Resolution",
2195  (capture->videoType() == VT_MAIN ||
2196  capture->videoType() == VT_SCND)))
2197  {
2198  for (int i = 0; i < (int)capture->camSizes.size(); ++i)
2199  {
2200  SLchar menuStr[256];
2201  snprintf(menuStr,
2202  sizeof(menuStr),
2203  "%d x %d",
2204  capture->camSizes[(uint)i].width,
2205  capture->camSizes[(uint)i].height);
2206  if (ImGui::MenuItem(menuStr, nullptr, i == capture->activeCamSizeIndex))
2207  if (i != capture->activeCamSizeIndex)
2208  ac->camSizeIndex(i);
2209  }
2210  ImGui::EndMenu();
2211  }
2212 
2213 #ifndef SL_EMSCRIPTEN
2214  if (ImGui::BeginMenu("Calibration"))
2215  {
2216  if (ImGui::MenuItem("Start Calibration (Main Camera)"))
2217  {
2219  showHelpCalibration = false;
2220  showInfosScene = true;
2221  }
2222 
2223  if (ImGui::MenuItem("Start Calibration (Scnd. Camera)", nullptr, false, capture->hasSecondaryCamera))
2224  {
2226  showHelpCalibration = false;
2227  showInfosScene = true;
2228  }
2229 
2230  if (ImGui::MenuItem("Undistort Image", nullptr, ac->showUndistorted(), ac->calibration.state() == CS_calibrated))
2231  ac->showUndistorted(!ac->showUndistorted());
2232 
2233  if (ImGui::MenuItem("No Tangent Distortion", nullptr, AppCommon::calibrationEstimatorParams.zeroTangentDistortion))
2235 
2236  if (ImGui::MenuItem("Fix Aspect Ratio", nullptr, AppCommon::calibrationEstimatorParams.fixAspectRatio))
2238 
2239  if (ImGui::MenuItem("Fix Principal Point", nullptr, AppCommon::calibrationEstimatorParams.fixPrincipalPoint))
2241 
2242  if (ImGui::MenuItem("Use rational model", nullptr, AppCommon::calibrationEstimatorParams.calibRationalModel))
2244 
2245  if (ImGui::MenuItem("Use tilted model", nullptr, AppCommon::calibrationEstimatorParams.calibTiltedModel))
2247 
2248  if (ImGui::MenuItem("Use thin prism model", nullptr, AppCommon::calibrationEstimatorParams.calibThinPrismModel))
2250 
2251  ImGui::EndMenu();
2252  }
2253 
2254  CVTrackedFeatures* featureTracker = nullptr;
2255  if (gVideoTracker != nullptr && typeid(*gVideoTracker) == typeid(CVTrackedFeatures))
2256  featureTracker = (CVTrackedFeatures*)gVideoTracker;
2257 
2258  if (gVideoTracker != nullptr)
2259  if (ImGui::MenuItem("Draw Detection", nullptr, gVideoTracker->drawDetection()))
2261 
2262  if (ImGui::BeginMenu("Feature Tracking", featureTracker != nullptr) && featureTracker != nullptr)
2263  {
2264  if (ImGui::MenuItem("Force Relocation", nullptr, featureTracker->forceRelocation()))
2265  featureTracker->forceRelocation(!featureTracker->forceRelocation());
2266 
2267  if (ImGui::BeginMenu("Detector/Descriptor", featureTracker != nullptr))
2268  {
2269  CVDetectDescribeType type = featureTracker->type();
2270 
2271  if (ImGui::MenuItem("RAUL/RAUL", nullptr, type == DDT_RAUL_RAUL))
2272  featureTracker->type(DDT_RAUL_RAUL);
2273  if (ImGui::MenuItem("ORB/ORB", nullptr, type == DDT_ORB_ORB))
2274  featureTracker->type(DDT_ORB_ORB);
2275  if (ImGui::MenuItem("FAST/BRIEF", nullptr, type == DDT_FAST_BRIEF))
2276  featureTracker->type(DDT_FAST_BRIEF);
2277  if (ImGui::MenuItem("SURF/SURF", nullptr, type == DDT_SURF_SURF))
2278  featureTracker->type(DDT_SURF_SURF);
2279  if (ImGui::MenuItem("SIFT/SIFT", nullptr, type == DDT_SIFT_SIFT))
2280  featureTracker->type(DDT_SIFT_SIFT);
2281 
2282  ImGui::EndMenu();
2283  }
2284 
2285  ImGui::EndMenu();
2286  }
2287 #endif
2288 
2289  ImGui::EndMenu();
2290  }
2291 
2292  ImGui::Separator();
2293 
2294  ImGui::MenuItem("UI Preferences", nullptr, &showUIPrefs);
2295 
2296  ImGui::EndMenu();
2297  }
2298 
2299  if (ImGui::BeginMenu("Edit", s->singleNodeSelected() != nullptr || !sv->camera()->selectRect().isZero()))
2300  {
2301  if (s->singleNodeSelected())
2302  {
2303  buildMenuEdit(s, sv);
2304  }
2305  else
2306  {
2307  if (ImGui::MenuItem("Clear selection"))
2308  {
2309  sv->camera()->selectRect().setZero();
2310  sv->camera()->deselectRect().setZero();
2311  }
2312  }
2313 
2314  ImGui::EndMenu();
2315  }
2316 
2317  if (ImGui::BeginMenu("Renderer"))
2318  {
2319  if (ImGui::MenuItem("OpenGL", "ESC", rType == RT_gl))
2320  sv->renderType(RT_gl);
2321 
2322  if (ImGui::MenuItem("Ray Tracing", "R", rType == RT_rt))
2323  sv->startRaytracing(5);
2324 
2325  if (ImGui::MenuItem("Path Tracing", "P", rType == RT_pt))
2326  sv->startPathtracing(5, 10);
2327 
2328 #ifdef SL_HAS_OPTIX
2329  if (ImGui::MenuItem("Ray Tracing with OptiX", "Shift-R", rType == RT_optix_rt))
2330  sv->startOptixRaytracing(5);
2331 
2332  if (ImGui::MenuItem("Path Tracing with OptiX", "Shift-P", rType == RT_optix_pt))
2333  sv->startOptixPathtracing(5, 10);
2334 #else
2335  ImGui::MenuItem("Ray Tracing with OptiX", nullptr, false, false);
2336  ImGui::MenuItem("Path Tracing with OptiX", nullptr, false, false);
2337 #endif
2338  ImGui::EndMenu();
2339  }
2340 
2341  if (rType == RT_gl)
2342  {
2343  if (ImGui::BeginMenu("GL"))
2344  {
2345  if (ImGui::MenuItem("Mesh Wired", "M", sv->drawBits()->get(SL_DB_MESHWIRED)))
2347 
2348  if (ImGui::MenuItem("With hard edges", "H", sv->drawBits()->get(SL_DB_WITHEDGES)))
2350 
2351  if (ImGui::MenuItem("Only hard edges", "O", sv->drawBits()->get(SL_DB_ONLYEDGES)))
2353 
2354  if (ImGui::MenuItem("Normals", "N", sv->drawBits()->get(SL_DB_NORMALS)))
2356 
2357  if (ImGui::MenuItem("Bounding Rectangles", "U", sv->drawBits()->get(SL_DB_BRECT)))
2359 
2360  if (ImGui::MenuItem("Bounding Boxes", "B", sv->drawBits()->get(SL_DB_BBOX)))
2362 
2363  if (ImGui::MenuItem("Voxels", "V", sv->drawBits()->get(SL_DB_VOXELS)))
2365 
2366  if (ImGui::MenuItem("Axis", "X", sv->drawBits()->get(SL_DB_AXIS)))
2368 
2369  if (ImGui::MenuItem("Back Faces", "C", sv->drawBits()->get(SL_DB_CULLOFF)))
2371 
2372  if (ImGui::MenuItem("Skeleton", "K", sv->drawBits()->get(SL_DB_SKELETON)))
2374 
2375  if (ImGui::MenuItem("GPU Skinning", nullptr, sv->drawBits()->get(SL_DB_GPU_SKINNING)))
2377 
2378  if (ImGui::MenuItem("All off"))
2379  sv->drawBits()->allOff();
2380 
2381  if (ImGui::MenuItem("All on"))
2382  {
2386  sv->drawBits()->on(SL_DB_NORMALS);
2387  sv->drawBits()->on(SL_DB_VOXELS);
2388  sv->drawBits()->on(SL_DB_AXIS);
2389  sv->drawBits()->on(SL_DB_BBOX);
2391  sv->drawBits()->on(SL_DB_CULLOFF);
2393  }
2394 
2395  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2396  SLfloat gamma = SLLight::gamma;
2397  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2398  SLLight::gamma = gamma;
2399  ImGui::PopItemWidth();
2400 
2401  ImGui::EndMenu();
2402  }
2403  }
2404  else if (rType == RT_rt)
2405  {
2406  if (ImGui::BeginMenu("RT"))
2407  {
2408  SLRaytracer* rt = sv->raytracer();
2409 
2410  if (ImGui::BeginMenu("Resolution Factor"))
2411  {
2412  if (ImGui::MenuItem("1.00", nullptr, rt->resolutionFactorPC() == 100))
2413  {
2414  rt->resolutionFactor(1.0f);
2415  sv->startRaytracing(rt->maxDepth());
2416  }
2417  if (ImGui::MenuItem("0.50", nullptr, rt->resolutionFactorPC() == 50))
2418  {
2419  rt->resolutionFactor(0.5f);
2420  sv->startRaytracing(rt->maxDepth());
2421  }
2422  if (ImGui::MenuItem("0.25", nullptr, rt->resolutionFactorPC() == 25))
2423  {
2424  rt->resolutionFactor(0.25f);
2425  sv->startRaytracing(rt->maxDepth());
2426  }
2427 
2428  ImGui::EndMenu();
2429  }
2430 
2431  if (ImGui::MenuItem("Parallel distributed", nullptr, rt->doDistributed()))
2432  {
2433  rt->doDistributed(!rt->doDistributed());
2434  sv->startRaytracing(rt->maxDepth());
2435  }
2436 
2437  if (ImGui::MenuItem("Continuously", nullptr, rt->doContinuous()))
2438  {
2439  rt->doContinuous(!rt->doContinuous());
2440  sv->doWaitOnIdle(!rt->doContinuous());
2441  }
2442 
2443  if (ImGui::MenuItem("Fresnel Reflection", nullptr, rt->doFresnel()))
2444  {
2445  rt->doFresnel(!rt->doFresnel());
2446  sv->startRaytracing(rt->maxDepth());
2447  }
2448 
2449  if (ImGui::BeginMenu("Max. Depth"))
2450  {
2451  if (ImGui::MenuItem("1", nullptr, rt->maxDepth() == 1)) sv->startRaytracing(1);
2452  if (ImGui::MenuItem("2", nullptr, rt->maxDepth() == 2)) sv->startRaytracing(2);
2453  if (ImGui::MenuItem("3", nullptr, rt->maxDepth() == 3)) sv->startRaytracing(3);
2454  if (ImGui::MenuItem("5", nullptr, rt->maxDepth() == 5)) sv->startRaytracing(5);
2455  if (ImGui::MenuItem("Max. Contribution", nullptr, rt->maxDepth() == 0)) sv->startRaytracing(0);
2456 
2457  ImGui::EndMenu();
2458  }
2459 
2460  if (ImGui::BeginMenu("Anti-Aliasing Samples"))
2461  {
2462  if (ImGui::MenuItem("Off", nullptr, rt->aaSamples() == 1)) rt->aaSamples(1);
2463  if (ImGui::MenuItem("3x3", nullptr, rt->aaSamples() == 3)) rt->aaSamples(3);
2464  if (ImGui::MenuItem("5x5", nullptr, rt->aaSamples() == 5)) rt->aaSamples(5);
2465  if (ImGui::MenuItem("7x7", nullptr, rt->aaSamples() == 7)) rt->aaSamples(7);
2466  if (ImGui::MenuItem("9x9", nullptr, rt->aaSamples() == 9)) rt->aaSamples(9);
2467 
2468  ImGui::EndMenu();
2469  }
2470 
2471  if (ImGui::MenuItem("Save Rendered Image"))
2472  rt->saveImage();
2473 
2474  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2475  SLfloat gamma = rt->gamma();
2476  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2477  {
2478  rt->gamma(gamma);
2479  sv->startRaytracing(5);
2480  }
2481  ImGui::PopItemWidth();
2482 
2483  ImGui::EndMenu();
2484  }
2485  }
2486 
2487 #ifdef SL_HAS_OPTIX
2488  else if (rType == RT_optix_rt)
2489  {
2490  if (ImGui::BeginMenu("RT"))
2491  {
2492  SLOptixRaytracer* rt_optix = sv->optixRaytracer();
2493 
2494  if (ImGui::MenuItem("Parallel distributed", nullptr, rt_optix->doDistributed()))
2495  {
2496  rt_optix->doDistributed(!rt_optix->doDistributed());
2497  sv->startOptixRaytracing(rt_optix->maxDepth());
2498  }
2499 
2500  // if (ImGui::MenuItem("Fresnel Reflection", nullptr, rt->doFresnel()))
2501  // {
2502  // rt->doFresnel(!rt->doFresnel());
2503  // sv->startRaytracing(rt->maxDepth());
2504  // }
2505 
2506  if (ImGui::BeginMenu("Max. Depth"))
2507  {
2508  if (ImGui::MenuItem("1", nullptr, rt_optix->maxDepth() == 1))
2509  sv->startOptixRaytracing(1);
2510  if (ImGui::MenuItem("2", nullptr, rt_optix->maxDepth() == 2))
2511  sv->startOptixRaytracing(2);
2512  if (ImGui::MenuItem("3", nullptr, rt_optix->maxDepth() == 3))
2513  sv->startOptixRaytracing(3);
2514  if (ImGui::MenuItem("5", nullptr, rt_optix->maxDepth() == 5))
2515  sv->startOptixRaytracing(5);
2516  if (ImGui::MenuItem("Max. Contribution", nullptr, rt_optix->maxDepth() == 0))
2517  sv->startOptixRaytracing(0);
2518 
2519  ImGui::EndMenu();
2520  }
2521 
2522  // if (ImGui::BeginMenu("Anti-Aliasing Samples"))
2523  // {
2524  // if (ImGui::MenuItem("Off", nullptr, rt->aaSamples() == 1))
2525  // rt->aaSamples(1);
2526  // if (ImGui::MenuItem("3x3", nullptr, rt->aaSamples() == 3))
2527  // rt->aaSamples(3);
2528  // if (ImGui::MenuItem("5x5", nullptr, rt->aaSamples() == 5))
2529  // rt->aaSamples(5);
2530  // if (ImGui::MenuItem("7x7", nullptr, rt->aaSamples() == 7))
2531  // rt->aaSamples(7);
2532  // if (ImGui::MenuItem("9x9", nullptr, rt->aaSamples() == 9))
2533  // rt->aaSamples(9);
2534  //
2535  // ImGui::EndMenu();
2536  // }
2537 
2538  if (ImGui::MenuItem("Save Rendered Image"))
2539  rt_optix->saveImage();
2540 
2541  ImGui::EndMenu();
2542  }
2543  }
2544 #endif
2545  else if (rType == RT_pt)
2546  {
2547  if (ImGui::BeginMenu("PT"))
2548  {
2549  SLPathtracer* pt = sv->pathtracer();
2550 
2551  if (ImGui::BeginMenu("Resolution Factor"))
2552  {
2553  if (ImGui::MenuItem("1.00", nullptr, pt->resolutionFactorPC() == 100))
2554  {
2555  pt->resolutionFactor(1.0f);
2556  sv->startPathtracing(5, pt->aaSamples());
2557  }
2558  if (ImGui::MenuItem("0.50", nullptr, pt->resolutionFactorPC() == 50))
2559  {
2560  pt->resolutionFactor(0.5f);
2561  sv->startPathtracing(5, pt->aaSamples());
2562  }
2563  if (ImGui::MenuItem("0.25", nullptr, pt->resolutionFactorPC() == 25))
2564  {
2565  pt->resolutionFactor(0.25f);
2566  sv->startPathtracing(5, pt->aaSamples());
2567  }
2568 
2569  ImGui::EndMenu();
2570  }
2571 
2572  if (ImGui::BeginMenu("NO. of Samples"))
2573  {
2574  if (ImGui::MenuItem("1", nullptr, pt->aaSamples() == 1)) sv->startPathtracing(5, 1);
2575  if (ImGui::MenuItem("10", nullptr, pt->aaSamples() == 10)) sv->startPathtracing(5, 10);
2576  if (ImGui::MenuItem("100", nullptr, pt->aaSamples() == 100)) sv->startPathtracing(5, 100);
2577  if (ImGui::MenuItem("1000", nullptr, pt->aaSamples() == 1000)) sv->startPathtracing(5, 1000);
2578  if (ImGui::MenuItem("10000", nullptr, pt->aaSamples() == 10000)) sv->startPathtracing(5, 10000);
2579 
2580  ImGui::EndMenu();
2581  }
2582 
2583  if (ImGui::MenuItem("Direct illumination", nullptr, pt->calcDirect()))
2584  {
2585  pt->calcDirect(!pt->calcDirect());
2586  sv->startPathtracing(5, 10);
2587  }
2588 
2589  if (ImGui::MenuItem("Indirect illumination", nullptr, pt->calcIndirect()))
2590  {
2591  pt->calcIndirect(!pt->calcIndirect());
2592  sv->startPathtracing(5, 10);
2593  }
2594 
2595  if (ImGui::MenuItem("Save Rendered Image"))
2596  pt->saveImage();
2597 
2598  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2599  SLfloat gamma = pt->gamma();
2600  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2601  {
2602  pt->gamma(gamma);
2603  sv->startPathtracing(5, 1);
2604  }
2605  ImGui::PopItemWidth();
2606 
2607  ImGui::EndMenu();
2608  }
2609  }
2610 
2611 #ifdef SL_HAS_OPTIX
2612  else if (rType == RT_optix_pt)
2613  {
2614  if (ImGui::BeginMenu("PT"))
2615  {
2616  SLOptixPathtracer* pt = sv->optixPathtracer();
2617 
2618  if (ImGui::BeginMenu("NO. of Samples"))
2619  {
2620  if (ImGui::MenuItem("1", nullptr, pt->samples() == 1))
2621  sv->startOptixPathtracing(5, 1);
2622  if (ImGui::MenuItem("10", nullptr, pt->samples() == 10))
2623  sv->startOptixPathtracing(5, 10);
2624  if (ImGui::MenuItem("100", nullptr, pt->samples() == 100))
2625  sv->startOptixPathtracing(5, 100);
2626  if (ImGui::MenuItem("1000", nullptr, pt->samples() == 1000))
2627  sv->startOptixPathtracing(5, 1000);
2628  if (ImGui::MenuItem("10000", nullptr, pt->samples() == 10000))
2629  sv->startOptixPathtracing(5, 10000);
2630 
2631  ImGui::EndMenu();
2632  }
2633 
2634  if (ImGui::MenuItem("Denoiser", nullptr, pt->getDenoiserEnabled()))
2635  {
2636  pt->setDenoiserEnabled(!pt->getDenoiserEnabled());
2637  sv->startOptixPathtracing(5, pt->samples());
2638  }
2639 
2640  if (ImGui::MenuItem("Save Rendered Image"))
2641  pt->saveImage();
2642 
2643  ImGui::EndMenu();
2644  }
2645  }
2646 #endif
2647 
2648  if (ImGui::BeginMenu("Camera"))
2649  {
2650  SLCamera* cam = sv->camera();
2651  SLProjType proj = cam->projType();
2652 
2653  if (ImGui::MenuItem("Reset"))
2654  {
2655  cam->resetToInitialState();
2656  float dist = cam->translationOS().length();
2657  cam->focalDist(dist);
2658  }
2659 
2660  if (ImGui::BeginMenu("Look from"))
2661  {
2662  if (ImGui::MenuItem("Left (+X)", "3")) cam->lookFrom(SLVec3f::AXISX);
2663  if (ImGui::MenuItem("Right (-X)", "CTRL-3")) cam->lookFrom(-SLVec3f::AXISX);
2664  if (ImGui::MenuItem("Top (+Y)", "7")) cam->lookFrom(SLVec3f::AXISY, -SLVec3f::AXISZ);
2665  if (ImGui::MenuItem("Bottom (-Y)", "CTRL-7")) cam->lookFrom(-SLVec3f::AXISY, SLVec3f::AXISZ);
2666  if (ImGui::MenuItem("Front (+Z)", "1")) cam->lookFrom(SLVec3f::AXISZ);
2667  if (ImGui::MenuItem("Back (-Z)", "CTRL-1")) cam->lookFrom(-SLVec3f::AXISZ);
2668 
2669  if (s->numSceneCameras())
2670  {
2671  if (ImGui::MenuItem("Next camera in Scene", "TAB"))
2673 
2674  if (ImGui::MenuItem("Sceneview Camera", "TAB"))
2676  }
2677 
2678  ImGui::EndMenu();
2679  }
2680 
2681  if (ImGui::BeginMenu("Projection"))
2682  {
2683  static SLfloat clipN = cam->clipNear();
2684  static SLfloat clipF = cam->clipFar();
2685  static SLfloat focalDist = cam->focalDist();
2686  static SLfloat fov = cam->fovV();
2687 
2688  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2689 
2690  if (ImGui::MenuItem("Perspective", "5", proj == P_monoPerspective))
2691  {
2693  if (sv->renderType() == RT_rt && !sv->raytracer()->doContinuous() &&
2694  sv->raytracer()->state() == rtFinished)
2695  sv->raytracer()->state(rtReady);
2696  }
2697 
2698  if (ImGui::MenuItem("Orthographic", "5", proj == P_monoOrthographic))
2699  {
2701  if (sv->renderType() == RT_rt && !sv->raytracer()->doContinuous() &&
2702  sv->raytracer()->state() == rtFinished)
2703  sv->raytracer()->state(rtReady);
2704  }
2705 
2706  if (ImGui::BeginMenu("Stereo"))
2707  {
2708  for (SLint p = P_stereoSideBySide; p <= P_stereoColorYB; ++p)
2709  {
2711  if (ImGui::MenuItem(pStr.c_str(), nullptr, proj == (SLProjType)p))
2712  cam->projType((SLProjType)p);
2713  }
2714 
2715  if (proj >= P_stereoSideBySide)
2716  {
2717  ImGui::Separator();
2718  static SLfloat eyeSepar = cam->stereoEyeSeparation();
2719  if (ImGui::SliderFloat("Eye Sep.", &eyeSepar, 0.0f, focalDist / 10.f))
2720  cam->stereoEyeSeparation(eyeSepar);
2721  }
2722 
2723  ImGui::EndMenu();
2724  }
2725 
2726  ImGui::Separator();
2727 
2728  if (ImGui::SliderFloat("FOV (V)", &fov, 1.f, 179.f))
2729  cam->fov(fov);
2730 
2731  ImGui::Text("FOV (H): %3.1f ", cam->fovH());
2732 
2733  if (ImGui::SliderFloat("Near Clip", &clipN, 0.001f, 10.f))
2734  cam->clipNear(clipN);
2735 
2736  if (ImGui::SliderFloat("Focal Dist.", &focalDist, clipN, clipF))
2737  cam->focalDist(focalDist);
2738 
2739  if (ImGui::SliderFloat("Far Clip", &clipF, clipN, std::min(clipF * 1.1f, 1000000.f)))
2740  cam->clipFar(clipF);
2741 
2742  ImGui::PopItemWidth();
2743  ImGui::EndMenu();
2744  }
2745 
2746  if (ImGui::BeginMenu("Animation"))
2747  {
2748  SLCamAnim ca = cam->camAnim();
2749 
2750  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2751 
2752  if (ImGui::MenuItem("Turntable Y up", nullptr, ca == CA_turntableYUp))
2753  sv->camera()->camAnim(CA_turntableYUp);
2754 
2755  if (ImGui::MenuItem("Turntable Z up", nullptr, ca == CA_turntableZUp))
2756  sv->camera()->camAnim(CA_turntableZUp);
2757 
2758  if (ImGui::MenuItem("Trackball", nullptr, ca == CA_trackball))
2759  sv->camera()->camAnim(CA_trackball);
2760 
2761  if (ImGui::MenuItem("Walk Y up", nullptr, ca == CA_walkingYUp))
2762  sv->camera()->camAnim(CA_walkingYUp);
2763 
2764  if (ImGui::MenuItem("Walk Z up", nullptr, ca == CA_walkingZUp))
2765  sv->camera()->camAnim(CA_walkingZUp);
2766 
2767  float mouseRotFactor = sv->camera()->mouseRotationFactor();
2768  if (ImGui::SliderFloat("Mouse Sensibility", &mouseRotFactor, 0.1f, 2.0f, "%2.1f"))
2769  sv->camera()->mouseRotationFactor(mouseRotFactor);
2770 
2771  ImGui::Separator();
2772 
2773  if (ImGui::MenuItem("IMU rotated", nullptr, ca == CA_deviceRotYUp))
2774  sv->camera()->camAnim(CA_deviceRotYUp);
2775 
2776  if (ImGui::MenuItem("IMU rotated & GPS located", nullptr, ca == CA_deviceRotLocYUp))
2777  sv->camera()->camAnim(CA_deviceRotLocYUp);
2778 
2779  if (ca == CA_walkingZUp || ca == CA_walkingYUp || ca == CA_deviceRotYUp)
2780  {
2781  static SLfloat ms = cam->maxSpeed();
2782  if (ImGui::SliderFloat("Walk Speed", &ms, 0.01f, std::min(ms * 1.1f, 10000.f)))
2783  cam->maxSpeed(ms);
2784  }
2785 
2786  ImGui::PopItemWidth();
2787  ImGui::EndMenu();
2788  }
2789 
2790  if (ImGui::BeginMenu("Fog"))
2791  {
2792  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2793 
2794  if (ImGui::MenuItem("Fog is on", nullptr, cam->fogIsOn()))
2795  cam->fogIsOn(!cam->fogIsOn());
2796 
2797  if (ImGui::BeginMenu("Mode"))
2798  {
2799  if (ImGui::MenuItem("linear", nullptr, cam->fogMode() == FM_linear))
2800  cam->fogMode(FM_linear);
2801  if (ImGui::MenuItem("exp", nullptr, cam->fogMode() == FM_exp))
2802  cam->fogMode(FM_exp);
2803  if (ImGui::MenuItem("exp2", nullptr, cam->fogMode() == FM_exp2))
2804  cam->fogMode(FM_exp2);
2805  ImGui::EndMenu();
2806  }
2807 
2808  if (cam->fogMode() == FM_exp || cam->fogMode() == FM_exp2)
2809  {
2810  static SLfloat fogDensity = cam->fogDensity();
2811  if (ImGui::SliderFloat("Density", &fogDensity, 0.0f, 0.2f))
2812  cam->fogDensity(fogDensity);
2813  }
2814 
2815  ImGui::PopItemWidth();
2816  ImGui::EndMenu();
2817  }
2818 
2819  ImGui::EndMenu();
2820  }
2821 
2822  if (ImGui::BeginMenu("Animation", hasAnimations))
2823  {
2824 
2825  if (ImGui::MenuItem("Stop all", "Space", s->stopAnimations()))
2827 
2828  ImGui::Separator();
2829 
2830  SLVstring animations = s->animManager().animationNames();
2831  if (curAnimIx == -1) curAnimIx = 0;
2832  SLAnimPlayback* anim = s->animManager().animPlaybackByIndex((SLuint)curAnimIx);
2833 
2834  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.8f);
2835  if (myComboBox("##", &curAnimIx, animations))
2836  anim = s->animManager().animPlaybackByIndex((SLuint)curAnimIx);
2837  ImGui::PopItemWidth();
2838 
2839  if (ImGui::MenuItem("Play forward", nullptr, anim->isPlayingForward()))
2840  anim->playForward();
2841 
2842  if (ImGui::MenuItem("Play backward", nullptr, anim->isPlayingBackward()))
2843  anim->playBackward();
2844 
2845  if (ImGui::MenuItem("Pause", nullptr, anim->isPaused()))
2846  anim->pause();
2847 
2848  if (ImGui::MenuItem("Stop", nullptr, anim->isStopped()))
2849  anim->enabled(false);
2850 
2851  if (ImGui::MenuItem("Skip to next keyfr.", nullptr, false))
2852  anim->skipToNextKeyframe();
2853 
2854  if (ImGui::MenuItem("Skip to prev. keyfr.", nullptr, false))
2855  anim->skipToPrevKeyframe();
2856 
2857  if (ImGui::MenuItem("Skip to start", nullptr, false))
2858  anim->skipToStart();
2859 
2860  if (ImGui::MenuItem("Skip to end", nullptr, false))
2861  anim->skipToEnd();
2862 
2863  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.6f);
2864 
2865  SLfloat speed = anim->playbackRate();
2866  if (ImGui::SliderFloat("Speed", &speed, 0.f, 4.f))
2867  anim->playbackRate(speed);
2868 
2869  SLfloat lenSec = anim->parentAnimation()->lengthSec();
2870  SLfloat localTimeSec = anim->localTime();
2871  if (ImGui::SliderFloat("Time", &localTimeSec, 0.f, lenSec))
2872  anim->localTime(localTimeSec);
2873 
2874  SLint curEasing = (SLint)anim->easing();
2875  const char* easings[] = {"linear",
2876  "in quad",
2877  "out quad",
2878  "in out quad",
2879  "out in quad",
2880  "in cubic",
2881  "out cubic",
2882  "in out cubic",
2883  "out in cubic",
2884  "in quart",
2885  "out quart",
2886  "in out quart",
2887  "out in quart",
2888  "in quint",
2889  "out quint",
2890  "in out quint",
2891  "out in quint",
2892  "in sine",
2893  "out sine",
2894  "in out sine",
2895  "out in sine"};
2896  if (ImGui::Combo("Easing", &curEasing, easings, IM_ARRAYSIZE(easings)))
2897  anim->easing((SLEasingCurve)curEasing);
2898 
2899  ImGui::PopItemWidth();
2900  ImGui::EndMenu();
2901  }
2902 
2903  if (ImGui::BeginMenu("Infos"))
2904  {
2905  ImGui::MenuItem("Infos on Scene", nullptr, &showInfosScene);
2906 
2907  if (ImGui::BeginMenu("Statistics"))
2908  {
2909  ImGui::MenuItem("Stats on Timing", nullptr, &showStatsTiming);
2910  ImGui::MenuItem("Stats on Scene", nullptr, &showStatsScene);
2911  ImGui::MenuItem("Stats on Video", nullptr, &showStatsVideo);
2912 #ifdef SL_BUILD_WAI
2914  ImGui::MenuItem("Stats on WAI", nullptr, &showStatsWAI);
2915 #endif
2916  ImGui::MenuItem("Stats on ImGui", nullptr, &showImGuiMetrics);
2917  ImGui::EndMenu();
2918  }
2919 
2920  ImGui::MenuItem("Scenegraph", nullptr, &showSceneGraph);
2921  ImGui::MenuItem("Properties", nullptr, &showProperties);
2922  ImGui::MenuItem("Transform", nullptr, &showTransform);
2923  if (AppCommon::devLoc.originLatLonAlt() != SLVec3d::ZERO ||
2924  AppCommon::devLoc.defaultLatLonAlt() != SLVec3d::ZERO)
2925  ImGui::MenuItem("Date-Time", nullptr, &showDateAndTime);
2926  ImGui::MenuItem("UI-Preferences", nullptr, &showUIPrefs);
2927  ImGui::Separator();
2928  ImGui::MenuItem("Infos on Device", nullptr, &showInfosDevice);
2929  ImGui::MenuItem("Infos on Sensors", nullptr, &showInfosSensors);
2932  {
2933  ImGui::Separator();
2934  ImGui::MenuItem("ErlebAR Settings", nullptr, &showErlebAR);
2935  }
2936  ImGui::Separator();
2937  ImGui::MenuItem("Help on Interaction", nullptr, &showHelp);
2938  ImGui::MenuItem("Help on Calibration", nullptr, &showHelpCalibration);
2939  ImGui::Separator();
2940  ImGui::MenuItem("Credits", nullptr, &showCredits);
2941  ImGui::MenuItem("About SLProject", nullptr, &showAbout);
2942 
2943  ImGui::EndMenu();
2944  }
2945 
2946  ImGui::EndMainMenuBar();
2947  }
2948 }
bool myComboBox(const char *label, int *currIndex, SLVstring &values)
Combobox that allows to pass the items as a string vector.
Definition: AppDemoGui.cpp:82
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_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_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_RTMuttenzerBox
@ 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(...)
Definition: SL.h:233
vector< SLstring > SLVstring
Definition: SL.h:201
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:468
void calcDirect(SLbool di)
Definition: SLPathtracer.h:33
void calcIndirect(SLbool ii)
Definition: SLPathtracer.h:34
void saveImage()
Saves the current PT image as PNG image.
void gamma(SLfloat g)
Definition: SLRaytracer.h:106
SLint resolutionFactorPC() const
Definition: SLRaytracer.h:126
void doContinuous(SLbool cont)
Definition: SLRaytracer.h:91
void state(SLRTState state)
Definition: SLRaytracer.h:80
void doFresnel(SLbool fresnel)
Definition: SLRaytracer.h:96
void maxDepth(SLint depth)
Definition: SLRaytracer.h:84
virtual void saveImage()
Saves the current RT image as PNG image.
void doDistributed(SLbool distrib)
Definition: SLRaytracer.h:90
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:198
void switchToNextCameraInScene()
Sets the active camera to the next in the scene.
void doMultiSampling(SLbool doMS)
Definition: SLSceneView.h:150
void doDepthTest(SLbool doDT)
Definition: SLSceneView.h:151
void startPathtracing(SLint maxDepth, SLint samples)
void switchToSceneViewCamera()
void viewportSameAsVideo(bool sameAsVideo)
Definition: SLSceneView.h:155
void startRaytracing(SLint maxDepth)
void doAlphaSorting(SLbool doAS)
Definition: SLSceneView.h:153
SLVec2i viewportRatio() const
Definition: SLSceneView.h:177
void setViewportFromRatio(const SLVec2i &vpRatio, SLViewportAlign vpAlignment, SLbool vpSameAsVideo)
Sets the viewport ratio and the viewport rectangle.
SLViewportAlign viewportAlign() const
Definition: SLSceneView.h:181
void doFrustumCulling(SLbool doFC)
Definition: SLSceneView.h:152
void doWaitOnIdle(SLbool doWI)
Definition: SLSceneView.h:149
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:897
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 3024 of file AppDemoGui.cpp.

3025 {
3026  // assert(s->assetManager() && "No asset manager assigned to scene!");
3027 
3028  if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) &&
3029  ImGui::IsMouseReleased(1))
3030  {
3031  ImGui::OpenPopup("Context Menu");
3032  }
3033 
3034  if (ImGui::BeginPopup("Context Menu"))
3035  {
3036  if (s->singleNodeSelected() != nullptr || !sv->camera()->selectRect().isZero())
3037  {
3038  if (s->singleNodeSelected())
3039  {
3040  buildMenuEdit(s, sv);
3041  ImGui::Separator();
3042 
3043  if (!showProperties)
3044  if (ImGui::MenuItem("Show Properties"))
3045  showProperties = true;
3046  }
3047  }
3048 
3049  if (AppDemoGui::hideUI)
3050  if (ImGui::MenuItem("Show user interface"))
3051  AppDemoGui::hideUI = false;
3052 
3053  if (!AppDemoGui::hideUI)
3054  if (ImGui::MenuItem("Hide user interface"))
3055  AppDemoGui::hideUI = true;
3056 
3057  if (s->root3D()->drawBits()->get(SL_DB_HIDDEN))
3058  if (ImGui::MenuItem("Show root node"))
3059  s->root3D()->drawBits()->toggle(SL_DB_HIDDEN);
3060 
3061  if (!s->root3D()->drawBits()->get(SL_DB_HIDDEN))
3062  if (ImGui::MenuItem("Hide root node"))
3063  s->root3D()->drawBits()->toggle(SL_DB_HIDDEN);
3064 
3065  if (ImGui::MenuItem("Capture Screen"))
3067 
3068  ImGui::EndPopup();
3069  }
3070 }
void screenCaptureIsRequested(bool doScreenCap)
Definition: SLSceneView.h:156

◆ 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 2951 of file AppDemoGui.cpp.

2952 {
2953  if (ImGui::MenuItem("Deselect Node", "ESC"))
2955 
2956  ImGui::Separator();
2957 
2958  if (ImGui::MenuItem("Translate Node", nullptr, transformNode && transformNode->editMode() == NodeEditMode_Translate))
2959  {
2962  else
2964  }
2965  if (ImGui::MenuItem("Rotate Node", nullptr, transformNode && transformNode->editMode() == NodeEditMode_Rotate))
2966  {
2969  else
2971  }
2972  if (ImGui::MenuItem("Scale Node", nullptr, transformNode && transformNode->editMode() == NodeEditMode_Scale))
2973  {
2976  else
2978  }
2979 
2980  ImGui::Separator();
2981 
2982  if (ImGui::BeginMenu("Node Flags"))
2983  {
2984  SLNode* selN = s->singleNodeSelected();
2985 
2986  if (ImGui::MenuItem("Wired Mesh", nullptr, selN->drawBits()->get(SL_DB_MESHWIRED)))
2987  selN->drawBits()->toggle(SL_DB_MESHWIRED);
2988 
2989  if (ImGui::MenuItem("With hard edges", nullptr, selN->drawBits()->get(SL_DB_WITHEDGES)))
2990  selN->drawBits()->toggle(SL_DB_WITHEDGES);
2991 
2992  if (ImGui::MenuItem("Only hard edges", nullptr, selN->drawBits()->get(SL_DB_ONLYEDGES)))
2993  selN->drawBits()->toggle(SL_DB_ONLYEDGES);
2994 
2995  if (ImGui::MenuItem("Normals", nullptr, selN->drawBits()->get(SL_DB_NORMALS)))
2996  selN->drawBits()->toggle(SL_DB_NORMALS);
2997 
2998  if (ImGui::MenuItem("Bounding Rectangles", nullptr, selN->drawBits()->get(SL_DB_BRECT)))
2999  selN->drawBits()->toggle(SL_DB_BRECT);
3000 
3001  if (ImGui::MenuItem("Bounding Boxes", nullptr, selN->drawBits()->get(SL_DB_BBOX)))
3002  selN->drawBits()->toggle(SL_DB_BBOX);
3003 
3004  if (ImGui::MenuItem("Voxels", nullptr, selN->drawBits()->get(SL_DB_VOXELS)))
3005  selN->drawBits()->toggle(SL_DB_VOXELS);
3006 
3007  if (ImGui::MenuItem("Axis", nullptr, selN->drawBits()->get(SL_DB_AXIS)))
3008  selN->drawBits()->toggle(SL_DB_AXIS);
3009 
3010  if (ImGui::MenuItem("Back Faces", nullptr, selN->drawBits()->get(SL_DB_CULLOFF)))
3011  selN->drawBits()->toggle(SL_DB_CULLOFF);
3012 
3013  if (ImGui::MenuItem("Skeleton", nullptr, selN->drawBits()->get(SL_DB_SKELETON)))
3014  selN->drawBits()->toggle(SL_DB_SKELETON);
3015 
3016  if (ImGui::MenuItem("All off"))
3017  selN->drawBits()->allOff();
3018 
3019  ImGui::EndMenu();
3020  }
3021 }
@ 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 3163 of file AppDemoGui.cpp.

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

◆ buildSceneGraph()

void AppDemoGui::buildSceneGraph ( SLScene s)
static

Builds the scenegraph dialog once per frame.

Definition at line 3073 of file AppDemoGui.cpp.

3074 {
3075  PROFILE_FUNCTION();
3076 
3077  // assert(s->assetManager() && "No asset manager assigned to scene!");
3078 
3079  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
3080  ImGui::Begin("Scenegraph", &showSceneGraph, ImGuiWindowFlags_NoNavInputs);
3081 
3082  if (s->root3D())
3083  addSceneGraphNode(s, s->root3D());
3084 
3085  if (s->root2D())
3086  addSceneGraphNode(s, s->root2D());
3087 
3088  ImGui::End();
3089  ImGui::PopFont();
3090 }
void root2D(SLNode *root2D)
Definition: SLScene.h:90

◆ clear()

void AppDemoGui::clear ( )
static

Definition at line 218 of file AppDemoGui.cpp.

219 {
220  _horizonVisuEnabled = false;
221 }

◆ 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 4913 of file AppDemoGui.cpp.

4920 {
4921 #ifndef SL_EMSCRIPTEN
4922  assert(s->assetManager() && "No asset manager assigned to scene!");
4923  SLAssetManager* am = s->assetManager();
4924 
4925  auto progressCallback = [](size_t curr, size_t filesize)
4926  {
4927  if (filesize > 0)
4928  {
4929  int transferredPC = (int)((float)curr / (float)filesize * 100.0f);
4930  AppCommon::jobProgressNum(transferredPC);
4931  }
4932  else
4933  cout << "Bytes transferred: " << curr << endl;
4934 
4935  return 0; // Return Non-Zero to cancel
4936  };
4937 
4938  auto downloadJobHTTP = [=]()
4939  {
4940  PROFILE_FUNCTION();
4941  string jobMsg = "Downloading file via HTTPS: " + downloadFilename;
4942  AppCommon::jobProgressMsg(jobMsg);
4944  string fileToDownload = urlFolder + downloadFilename;
4945  if (HttpUtils::download(fileToDownload, dstFolder, progressCallback) != 0)
4946  {
4947  SL_LOG("*** Nothing downloaded from: %s ***", fileToDownload.c_str());
4948  SL_LOG("*** PLEASE RETRY DOWNLOAD ***", fileToDownload.c_str());
4949  }
4950  AppCommon::jobIsRunning = false;
4951  };
4952 
4953  auto unzipJob = [=]()
4954  {
4955  string jobMsg = "Decompressing file: " + downloadFilename;
4956  AppCommon::jobProgressMsg(jobMsg);
4958  string zipFile = dstFolder + downloadFilename;
4959  if (Utils::fileExists(zipFile))
4960  {
4961  string extension = Utils::getFileExt(zipFile);
4962  if (extension == "zip")
4963  {
4964  ZipUtils::unzip(zipFile, Utils::getPath(zipFile));
4965  Utils::deleteFile(zipFile);
4966  }
4967  }
4968  else
4969  SL_LOG("*** File do decompress doesn't exist: %s ***",
4970  zipFile.c_str());
4971  AppCommon::jobIsRunning = false;
4972  };
4973 
4974  auto followUpJob1 = [=]()
4975  {
4976  if (Utils::fileExists(pathAndFileToLoad))
4977  AppCommon::sceneToLoad = sceneIDToLoad;
4978  else
4979  SL_LOG("*** File do load doesn't exist: %s ***",
4980  pathAndFileToLoad.c_str());
4981  };
4982 
4983  AppCommon::jobsToBeThreaded.emplace_back(downloadJobHTTP);
4984  AppCommon::jobsToBeThreaded.emplace_back(unzipJob);
4985  AppCommon::jobsToFollowInMain.push_back(followUpJob1);
4986 #endif
4987 }
SLAssetManager * assetManager()
Definition: SLScene.h:98
string getPath(const string &pathFilename)
Returns the path w. '\' of path-filename string.
Definition: Utils.cpp:392
string getFileExt(const string &filename)
Returns the file extension without dot in lower case.
Definition: Utils.cpp:629
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 4845 of file AppDemoGui.cpp.

4846 {
4847  if (s->root2D())
4848  {
4849  SLstring horizonName = "Horizon";
4850  SLHorizonNode* horizonNode = s->root2D()->findChild<SLHorizonNode>(horizonName);
4851  if (horizonNode)
4852  {
4853  s->root2D()->deleteChild(horizonNode);
4854  }
4855  }
4856  _horizonVisuEnabled = false;
4857 }

◆ loadConfig()

void AppDemoGui::loadConfig ( SLint  dotsPerInch)
static

Loads the UI configuration.

Definition at line 4588 of file AppDemoGui.cpp.

4589 {
4590  ImGuiStyle& style = ImGui::GetStyle();
4591  SLstring fullPathAndFilename = AppCommon::configPath +
4592  AppCommon::name + ".yml";
4593 
4594  if (!SLFileStorage::exists(fullPathAndFilename, IOK_config))
4595  {
4596  SL_LOG("No config file %s: ", fullPathAndFilename.c_str());
4597 
4598  // Scale for proportional and fixed size fonts
4599  SLfloat dpiScaleProp = (float)dotsPerInch / 142.0f;
4600  SLfloat dpiScaleFixed = (float)dotsPerInch / 142.0f;
4601 
4602  // Default settings for the first time
4603  SLImGui::fontPropDots = std::max(16.0f * dpiScaleProp, 16.0f);
4604  SLImGui::fontFixedDots = std::max(13.0f * dpiScaleFixed, 13.0f);
4605 
4606  // Store dialog show states
4607  AppDemoGui::showAbout = true;
4618 
4619  // Adjust UI padding on DPI
4620  style.WindowPadding.x = style.FramePadding.x = style.ItemInnerSpacing.x = std::max(8.0f * dpiScaleFixed, 8.0f);
4621  style.FramePadding.y = style.ItemInnerSpacing.y = std::max(4.0f * dpiScaleFixed, 4.0f);
4622  style.WindowPadding.y = style.ItemSpacing.y * 3;
4623  style.ScrollbarSize = std::max(16.0f * dpiScaleFixed, 16.0f);
4624 
4625  // HSM4: Bugfix in some unknown cases ScrollbarSize gets INT::MIN
4626  if (style.ScrollbarSize < 0.0f)
4627  style.ScrollbarSize = 16.0f;
4628 
4629  style.ScrollbarRounding = std::floor(style.ScrollbarSize / 2);
4630  }
4631  else
4632  {
4633  try
4634  {
4635  SLstring configString = SLFileStorage::readIntoString(fullPathAndFilename, IOK_config);
4636  CVFileStorage fs(configString, CVFileStorage::READ | CVFileStorage::MEMORY);
4637 
4638  if (fs.isOpened())
4639  {
4640  // clang-format off
4641  SLint i = 0;
4642  SLbool b = false;
4643  fs["configTime"] >> AppDemoGui::configTime;
4644  fs["fontPropDots"] >> i; SLImGui::fontPropDots = (SLfloat) i;
4645  fs["fontFixedDots"] >> i; SLImGui::fontFixedDots = (SLfloat) i;
4646  fs["ItemSpacingX"] >> i; style.ItemSpacing.x = (SLfloat) i;
4647  fs["ItemSpacingY"] >> i; style.ItemSpacing.y = (SLfloat) i;
4648  style.WindowPadding.x = style.FramePadding.x = style.ItemInnerSpacing.x = style.ItemSpacing.x;
4649  style.FramePadding.y = style.ItemInnerSpacing.y = style.ItemSpacing.y;
4650  style.WindowPadding.y = style.ItemSpacing.y * 3;
4651  fs["ScrollbarSize"] >> i; style.ScrollbarSize = (SLfloat) i;
4652  // HSM4: Bugfix in some unknown cases ScrollbarSize gets INT::MIN
4653  if (style.ScrollbarSize < 0.0f)
4654  style.ScrollbarSize = 16.0f;
4655 
4656  fs["ScrollbarRounding"] >> i; style.ScrollbarRounding = (SLfloat) i;
4657  fs["sceneID"] >> i; AppCommon::sceneID = (SLSceneID) i;
4658  fs["showInfosScene"] >> b; AppDemoGui::showInfosScene = b;
4659  fs["showStatsTiming"] >> b; AppDemoGui::showStatsTiming = b;
4660  fs["showStatsMemory"] >> b; AppDemoGui::showStatsScene = b;
4661  fs["showStatsVideo"] >> b; AppDemoGui::showStatsVideo = b;
4662  fs["showStatsWAI"] >> b; AppDemoGui::showStatsWAI = b;
4663  fs["showInfosFrameworks"] >> b; AppDemoGui::showInfosDevice = b;
4664  fs["showInfosSensors"] >> b; AppDemoGui::showInfosSensors = b;
4665  fs["showSceneGraph"] >> b; AppDemoGui::showSceneGraph = b;
4666  fs["showProperties"] >> b; AppDemoGui::showProperties = b;
4667  fs["showErlebAR"] >> b; AppDemoGui::showErlebAR = b;
4668  fs["showTransform"] >> b; AppDemoGui::showTransform = b;
4669  fs["showUIPrefs"] >> b; AppDemoGui::showUIPrefs = b;
4670  fs["showDateAndTime"] >> b; AppDemoGui::showDateAndTime = b;
4671  fs["showDockSpace"] >> b; AppDemoGui::showDockSpace = b;
4672  // clang-format on
4673 
4674  fs.release();
4675  SL_LOG("Config. loaded : %s", fullPathAndFilename.c_str());
4676  SL_LOG("Config. date : %s", AppDemoGui::configTime.c_str());
4677  SL_LOG("fontPropDots : %f", SLImGui::fontPropDots);
4678  SL_LOG("fontFixedDots : %f", SLImGui::fontFixedDots);
4679  }
4680  else
4681  {
4682  SL_LOG("****** Failed to open file for reading: %s", fullPathAndFilename.c_str());
4683  }
4684  }
4685  catch (...)
4686  {
4687  SL_LOG("****** Parsing of file failed: %s", fullPathAndFilename.c_str());
4688  }
4689 
4690  // check font sizes for HDPI displays
4691  if (dotsPerInch > 300)
4692  {
4693  if (SLImGui::fontPropDots < 16.1f &&
4694  SLImGui::fontFixedDots < 13.1)
4695  {
4696  // Scale for proportional and fixed size fonts
4697  SLfloat dpiScaleProp = (float)dotsPerInch / 120.0f;
4698  SLfloat dpiScaleFixed = (float)dotsPerInch / 142.0f;
4699 
4700  // Default settings for the first time
4701  SLImGui::fontPropDots = std::max(16.0f * dpiScaleProp, 16.0f);
4702  SLImGui::fontFixedDots = std::max(13.0f * dpiScaleFixed, 13.0f);
4703  }
4704  }
4705  }
4706 
4707 #ifdef SL_EMSCRIPTEN
4708  // Overwrite config with URL parameters
4709  // clang-format off
4710  int sceneId = EM_ASM_INT(
4711  let params = new URL(window.location).searchParams;
4712  return params.get("scene") ?? -1;
4713  );
4714  // clang-format on
4715 
4716  if (sceneId != -1)
4717  AppCommon::sceneID = (SLSceneID)sceneId;
4718 #endif
4719 }
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 4893 of file AppDemoGui.cpp.

4898 {
4899  SLstring pathSrc = "https://pallas.ti.bfh.ch/data/SLProject/models/";
4900  SLstring pathDst = AppCommon::configPath + "models/";
4901 
4902 #ifndef SL_EMSCRIPTEN
4903  if (Utils::fileExists(filenameToLoad))
4904  AppCommon::sceneToLoad = sceneIDToLoad;
4905  else
4906  downloadModelAndLoadScene(s, sv, downloadFilename, pathSrc, pathDst, filenameToLoad, sceneIDToLoad);
4907 #else
4908  AppCommon::sceneToLoad = sceneIDToLoad;
4909 #endif
4910 }
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 4796 of file AppDemoGui.cpp.

4797 {
4798  SLTransformNode* tN = s->root3D()->findChild<SLTransformNode>("Edit Gizmos");
4799  if (tN)
4800  {
4801  auto it = find(s->eventHandlers().begin(),
4802  s->eventHandlers().end(),
4803  tN);
4804  if (it != s->eventHandlers().end())
4805  s->eventHandlers().erase(it);
4806 
4807  s->root3D()->deleteChild(tN);
4808 
4809  // Reset currentMaterial pointer that have pointed to temp. materials of transform nodes
4811  }
4812  transformNode = nullptr;
4813 }
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 4722 of file AppDemoGui.cpp.

4723 {
4724  ImGuiStyle& style = ImGui::GetStyle();
4725  SLstring fullPathAndFilename = AppCommon::configPath +
4726  AppCommon::name + ".yml";
4727 
4728  if (!SLFileStorage::exists(fullPathAndFilename, IOK_config))
4729  SL_LOG("New config file will be written: %s",
4730  fullPathAndFilename.c_str());
4731 
4732  CVFileStorage fs(fullPathAndFilename,
4733  CVFileStorage::WRITE | CVFileStorage::MEMORY);
4734 
4735  if (!fs.isOpened())
4736  {
4737  SL_LOG("Failed to open file for writing: %s",
4738  fullPathAndFilename.c_str());
4739  SL_EXIT_MSG("Exit in AppDemoGui::saveConfig");
4740  }
4741 
4742  fs << "configTime" << Utils::getLocalTimeString();
4743  fs << "fontPropDots" << (SLint)SLImGui::fontPropDots;
4744  fs << "fontFixedDots" << (SLint)SLImGui::fontFixedDots;
4747  fs << "sceneID" << (SLint)SID_Minimal;
4748  else
4749  fs << "sceneID" << (SLint)AppCommon::sceneID;
4750  fs << "ItemSpacingX" << (SLint)style.ItemSpacing.x;
4751  fs << "ItemSpacingY" << (SLint)style.ItemSpacing.y;
4752  fs << "ScrollbarSize" << (SLfloat)style.ScrollbarSize;
4753  fs << "ScrollbarRounding" << (SLfloat)style.ScrollbarRounding;
4754  fs << "showStatsTiming" << AppDemoGui::showStatsTiming;
4755  fs << "showStatsMemory" << AppDemoGui::showStatsScene;
4756  fs << "showStatsVideo" << AppDemoGui::showStatsVideo;
4757  fs << "showStatsWAI" << AppDemoGui::showStatsWAI;
4758  fs << "showInfosFrameworks" << AppDemoGui::showInfosDevice;
4759  fs << "showInfosScene" << AppDemoGui::showInfosScene;
4760  fs << "showInfosSensors" << AppDemoGui::showInfosSensors;
4761  fs << "showSceneGraph" << AppDemoGui::showSceneGraph;
4762  fs << "showProperties" << AppDemoGui::showProperties;
4763  fs << "showErlebAR" << AppDemoGui::showErlebAR;
4764  fs << "showTransform" << AppDemoGui::showTransform;
4765  fs << "showUIPrefs" << AppDemoGui::showUIPrefs;
4766  fs << "showDateAndTime" << AppDemoGui::showDateAndTime;
4767  fs << "showDockSpace" << AppDemoGui::showDockSpace;
4768 
4769  std::string configString = fs.releaseAndGetString();
4770  SLFileStorage::writeString(fullPathAndFilename,
4771  IOK_config,
4772  configString);
4773  SL_LOG("Config. saved : %s", fullPathAndFilename.c_str());
4774 }
#define SL_EXIT_MSG(message)
Definition: SL.h:240
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 4990 of file AppDemoGui.cpp.

4993 {
4995 
4996 #if !defined(SL_OS_MACIOS) && !defined(SL_OS_ANDROID)
4998  SLVec3f pos_f((SLfloat)pos_d.x, (SLfloat)pos_d.y, (SLfloat)pos_d.z);
4999  SLCamera* cam = sv->camera();
5000  cam->translation(pos_f);
5001  SLVec3f camToLookAt = pos_f - lookAtPoint;
5002  cam->focalDist(camToLookAt.length());
5003  cam->lookAt(lookAtPoint);
5005 #endif
5006 }
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:652

◆ 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 4777 of file AppDemoGui.cpp.

4780 {
4781  SLTransformNode* tN = s->root3D()->findChild<SLTransformNode>("Edit Gizmos");
4782 
4783  if (!tN)
4784  {
4785  tN = new SLTransformNode(sv,
4786  s->singleNodeSelected(),
4788  s->root3D()->addChild(tN);
4789  }
4790 
4791  tN->editMode(editMode);
4792  transformNode = tN;
4793 }
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 4816 of file AppDemoGui.cpp.

4817 {
4818  assert(s->assetManager() && "No asset manager assigned to scene!");
4819  SLAssetManager* am = s->assetManager();
4820 
4821  // todo: why is root2D not always valid?
4822  if (!s->root2D())
4823  {
4824  SLNode* scene2D = new SLNode("root2D");
4825  s->root2D(scene2D);
4826  }
4827 
4828  SLstring horizonName = "Horizon";
4829  SLHorizonNode* horizonNode = s->root2D()->findChild<SLHorizonNode>(horizonName);
4830 
4831  if (!horizonNode)
4832  {
4833  horizonNode = new SLHorizonNode(horizonName,
4835  am->font16,
4837  sv->scrW(),
4838  sv->scrH());
4839  s->root2D()->addChild(horizonNode);
4840  _horizonVisuEnabled = true;
4841  }
4842 }
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 4860 of file AppDemoGui.cpp.

4861 {
4862  ImGuiColorEditFlags cef = ImGuiColorEditFlags_NoInputs;
4863  for (SLulong c = 0; c < lut->colors().size(); ++c)
4864  {
4865  SLCol3f color = lut->colors()[c].color;
4866  SLchar label[20];
4867  snprintf(label, sizeof(label), "Color %lu", c);
4868  if (ImGui::ColorEdit3(label, (float*)&color, cef))
4869  {
4870  lut->colors()[c].color = color;
4871  lut->generateTexture();
4872  }
4873  ImGui::SameLine();
4874  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
4875  snprintf(label, sizeof(label), "Pos. %lu", c);
4876  SLfloat pos = lut->colors()[c].pos;
4877  if (c > 0 && c < lut->colors().size() - 1)
4878  {
4879  SLfloat min = lut->colors()[c - 1].pos + 2.0f / (SLfloat)lut->length();
4880  SLfloat max = lut->colors()[c + 1].pos - 2.0f / (SLfloat)lut->length();
4881  if (ImGui::SliderFloat(label, &pos, min, max, "%3.2f"))
4882  {
4883  lut->colors()[c].pos = pos;
4884  lut->generateTexture();
4885  }
4886  }
4887  else
4888  ImGui::Text("%3.2f Pos. %lu", pos, c);
4889  ImGui::PopItemWidth();
4890  }
4891 }
unsigned long SLulong
Definition: SL.h:165
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 4465 of file AppDemoGui.cpp.

4466 {
4467  // SLfloat lineH = ImGui::GetTextLineHeightWithSpacing();
4468  SLfloat texW = ImGui::GetWindowWidth() - 4 * ImGui::GetTreeNodeToLabelSpacing() - 10;
4469  void* tid = (ImTextureID)(intptr_t)tex->texID();
4470  SLfloat w = (SLfloat)tex->width();
4471  SLfloat h = (SLfloat)tex->height();
4472  SLfloat h_to_w = h / w;
4473 
4474  if (ImGui::TreeNode(tex->name().c_str()))
4475  {
4476  float mbCPU = 0.0f;
4477  for (auto img : tex->images())
4478  mbCPU += (float)img->bytesPerImage();
4479  float mbGPU = (float)tex->bytesOnGPU();
4480  float mbDSK = (float)tex->bytesInFile();
4481 
4482  mbDSK /= 1E6f;
4483  mbCPU /= 1E6f;
4484  mbGPU /= 1E6f;
4485 
4486  ImGui::Text("Size(PX): %dx%dx%d", tex->width(), tex->height(), tex->depth());
4487  ImGui::Text("Size(MB): GPU:%4.2f, CPU:%4.2f, DSK:%4.2f", mbGPU, mbCPU, mbDSK);
4488  ImGui::Text("TexID : %u (%s)", tex->texID(), tex->isTexture() ? "ok" : "not ok");
4489  ImGui::Text("Type : %s", tex->typeName().c_str());
4490  if (!tex->images().empty() && tex->images()[0])
4491  ImGui::Text("Format : %s", tex->images()[0]->formatString().c_str());
4492  else
4493  ImGui::Text("Format : %s", "n/a (GPU only)");
4494 #ifdef SL_BUILD_WITH_KTX
4495  ImGui::Text("Compr. : %s", tex->compressionFormatStr(tex->compressionFormat()).c_str());
4496 #endif
4497  ImGui::Text("Min.Flt : %s", tex->minificationFilterName().c_str());
4498  ImGui::Text("Mag.Flt : %s", tex->magnificationFilterName().c_str());
4499 
4500  if (tex->target() == GL_TEXTURE_2D)
4501  {
4502  if (typeid(*tex) == typeid(SLTexColorLUT))
4503  {
4504  SLTexColorLUT* lut = (SLTexColorLUT*)tex;
4505  if (ImGui::TreeNode("Color Points in Gradient"))
4506  {
4507  showLUTColors(lut);
4508  ImGui::TreePop();
4509  }
4510 
4511  if (ImGui::TreeNode("Alpha Points in Gradient"))
4512  {
4513  for (SLulong a = 0; a < lut->alphas().size(); ++a)
4514  {
4515  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.25f);
4516  SLfloat alpha = lut->alphas()[a].alpha;
4517  SLchar label[20];
4518  snprintf(label, sizeof(label), "Alpha %lu", a);
4519  if (ImGui::SliderFloat(label, &alpha, 0.0f, 1.0f, "%3.2f"))
4520  {
4521  lut->alphas()[a].alpha = alpha;
4522  lut->generateTexture();
4523  }
4524  ImGui::SameLine();
4525  snprintf(label, sizeof(label), "Pos. %lu", a);
4526  SLfloat pos = lut->alphas()[a].pos;
4527  if (a > 0 && a < lut->alphas().size() - 1)
4528  {
4529  SLfloat min = lut->alphas()[a - 1].pos +
4530  2.0f / (SLfloat)lut->length();
4531  SLfloat max = lut->alphas()[a + 1].pos -
4532  2.0f / (SLfloat)lut->length();
4533  if (ImGui::SliderFloat(label, &pos, min, max, "%3.2f"))
4534  {
4535  lut->alphas()[a].pos = pos;
4536  lut->generateTexture();
4537  }
4538  }
4539  else
4540  ImGui::Text("%3.2f Pos. %lu", pos, a);
4541 
4542  ImGui::PopItemWidth();
4543  }
4544 
4545  ImGui::TreePop();
4546  }
4547 
4548  ImGui::Image(tid,
4549  ImVec2(texW, texW * 0.15f),
4550  ImVec2(0, 1),
4551  ImVec2(1, 0),
4552  ImVec4(1, 1, 1, 1),
4553  ImVec4(1, 1, 1, 1));
4554 
4555  SLVfloat allAlpha = lut->allAlphas();
4556  ImGui::PlotLines("",
4557  allAlpha.data(),
4558  (SLint)allAlpha.size(),
4559  0,
4560  nullptr,
4561  0.0f,
4562  1.0f,
4563  ImVec2(texW, texW * 0.25f));
4564  }
4565  else
4566  {
4567  ImGui::Image(tid,
4568  ImVec2(texW, texW * h_to_w),
4569  ImVec2(0, 1),
4570  ImVec2(1, 0),
4571  ImVec4(1, 1, 1, 1),
4572  ImVec4(1, 1, 1, 1));
4573  }
4574  }
4575  else
4576  {
4577  if (tex->target() == GL_TEXTURE_CUBE_MAP)
4578  ImGui::Text("Cube maps can not be displayed.");
4579  else if (tex->target() == GL_TEXTURE_3D)
4580  ImGui::Text("3D textures can not be displayed.");
4581  }
4582 
4583  ImGui::TreePop();
4584  }
4585 }
vector< SLfloat > SLVfloat
Definition: SL.h:200
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: