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

3100 {
3101  PROFILE_FUNCTION();
3102 
3103  // assert(s->assetManager() && "No asset manager assigned to scene!");
3104 
3105  SLbool isSelectedNode = s->singleNodeSelected() == node;
3106  SLbool isLeafNode = node->children().empty() && !node->mesh();
3107  SLbool isHidden = node->drawBit(SL_DB_HIDDEN);
3108  bool nodeIsOpen;
3109 
3110  ImGuiTreeNodeFlags nodeFlags = 0;
3111  if (isLeafNode)
3112  nodeFlags |= ImGuiTreeNodeFlags_Leaf;
3113  else
3114  nodeFlags |= ImGuiTreeNodeFlags_OpenOnArrow;
3115 
3116  if (isSelectedNode)
3117  nodeFlags |= ImGuiTreeNodeFlags_Selected;
3118 
3119  if (isHidden)
3120  {
3121  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 1.0f, 1.0f));
3122  nodeIsOpen = ImGui::TreeNodeEx(node->name().c_str(), nodeFlags);
3123  ImGui::PopStyleColor();
3124  }
3125  else
3126  {
3127  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
3128  nodeIsOpen = ImGui::TreeNodeEx(node->name().c_str(), nodeFlags);
3129  ImGui::PopStyleColor();
3130  }
3131 
3132  if (ImGui::IsItemClicked())
3133  {
3135  s->selectNodeMesh(node, nullptr);
3136  }
3137 
3138  if (nodeIsOpen)
3139  {
3140  if (node->mesh())
3141  {
3142  SLMesh* mesh = node->mesh();
3143  ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
3144 
3145  ImGuiTreeNodeFlags meshFlags = ImGuiTreeNodeFlags_Leaf;
3146  if (s->singleMeshFullSelected() == mesh)
3147  meshFlags |= ImGuiTreeNodeFlags_Selected;
3148 
3149  ImGui::TreeNodeEx(mesh, meshFlags, "%s", mesh->name().c_str());
3150 
3151  if (ImGui::IsItemClicked())
3152  {
3154  s->selectNodeMesh(node, mesh);
3155  }
3156 
3157  ImGui::TreePop();
3158  ImGui::PopStyleColor();
3159  }
3160 
3161  for (auto* child : node->children())
3162  addSceneGraphNode(s, child);
3163 
3164  ImGui::TreePop();
3165  }
3166 }
#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 modelCBB = erlebarPath + "biel/Biel-CBB-AR.gltf";
1806  SLstring modelAR1 = erlebarPath + "augst/augst-thtL1-tmpL2.gltf";
1807  SLstring modelAR2 = erlebarPath + "augst/augst-thtL2-tmpL1.gltf";
1808  SLstring modelAR3 = erlebarPath + "augst/augst-thtL1L2-tmpL1L2.gltf";
1809  SLstring modelAV1_AO = erlebarPath + "avenches/avenches-amphitheater.gltf";
1810  SLstring modelAV2_AO = erlebarPath + "avenches/avenches-cigognier.gltf";
1811  SLstring modelAV3 = erlebarPath + "avenches/avenches-theater.gltf";
1812  SLstring modelSU1 = erlebarPath + "sutz/Sutz-Kirchrain18.gltf";
1813 
1814  if (Utils::fileExists(modelAR1) ||
1815  Utils::fileExists(modelAR2) ||
1816  Utils::fileExists(modelAR3) ||
1817  Utils::fileExists(modelAV3) ||
1818  Utils::fileExists(modelBR2) ||
1819  Utils::fileExists(modelCBB) ||
1820  Utils::fileExists(modelSU1))
1821  {
1822  if (ImGui::BeginMenu("Erleb-AR"))
1823  {
1824  if (Utils::fileExists(modelBR2))
1825  if (ImGui::MenuItem("Bern: Christoffel Tower", nullptr, sid == SID_ErlebAR_BernChristoffel))
1827 
1828  if (Utils::fileExists(modelBFH))
1829  if (ImGui::MenuItem("Biel: BFH", nullptr, sid == SID_ErlebAR_BielBFH))
1831 
1832  if (Utils::fileExists(modelCBB))
1833  if (ImGui::MenuItem("Biel: CBB", nullptr, sid == SID_ErlebAR_BielCBB))
1835 
1836  if (Utils::fileExists(modelAR3))
1837  if (ImGui::MenuItem("Augusta Raurica Temple & Theater", nullptr, sid == SID_ErlebAR_AugustaRauricaTmpTht))
1839 
1840  if (Utils::fileExists(modelAV1_AO))
1841  if (ImGui::MenuItem("Aventicum: Amphitheatre", nullptr, sid == SID_ErlebAR_AventicumAmphiteatre))
1843 
1844  if (Utils::fileExists(modelAV2_AO))
1845  if (ImGui::MenuItem("Aventicum: Cigognier", nullptr, sid == SID_ErlebAR_AventicumCigognier))
1847 
1848  if (Utils::fileExists(modelAV3))
1849  if (ImGui::MenuItem("Aventicum: Theatre", nullptr, sid == SID_ErlebAR_AventicumTheatre))
1851 
1852  if (Utils::fileExists(modelSU1))
1853  if (ImGui::MenuItem("Sutz: Kirchrain 18", nullptr, sid == SID_ErlebAR_SutzKirchrain18))
1855 
1856  ImGui::EndMenu();
1857  }
1858  }
1859 
1860  if (ImGui::BeginMenu("Benchmarks"))
1861  {
1862 #ifndef SL_EMSCRIPTEN
1863  /* The large models are too large for emscripten
1864  if (ImGui::MenuItem("Large Model (via FTP)", nullptr, sid == SID_Benchmark_LargeModel))
1865  {
1866  SLstring largeFile = AppCommon::configPath + "models/xyzrgb_dragon/xyzrgb_dragon.ply";
1867  if (Utils::fileExists(largeFile))
1868  AppCommon::sceneToLoad = SID_Benchmark_LargeModel;
1869  else
1870  {
1871  auto downloadJobFTP = []() {
1872  AppCommon::jobProgressMsg("Downloading large dragon file via FTP:");
1873  AppCommon::jobProgressMax(100);
1874  ftplib ftp;
1875  ftp.SetConnmode(ftplib::connmode::port); // enable active mode
1876 
1877  if (ftp.Connect("pallas.ti.bfh.ch:21"))
1878  {
1879  if (ftp.Login("guest", "g2Q7Z7OkDP4!"))
1880  {
1881  ftp.SetCallbackXferFunction(ftpCallbackXfer);
1882  ftp.SetCallbackBytes(1024000);
1883  if (ftp.Chdir("data/SLProject/models"))
1884  {
1885  int remoteSize = 0;
1886  ftp.Size("xyzrgb_dragon.zip",
1887  &remoteSize,
1888  ftplib::transfermode::image);
1889  ftpXferSizeMax = remoteSize;
1890  SLstring dstDir = AppCommon::configPath;
1891  if (Utils::dirExists(dstDir))
1892  {
1893  SLstring outFile = AppCommon::configPath + "models/xyzrgb_dragon.zip";
1894  if (!ftp.Get(outFile.c_str(),
1895  "xyzrgb_dragon.zip",
1896  ftplib::transfermode::image))
1897  SL_LOG("*** ERROR: ftp.Get failed. ***");
1898  }
1899  else
1900  SL_LOG("*** ERROR: Destination directory does not exist: %s ***", dstDir.c_str());
1901  }
1902  else
1903  SL_LOG("*** ERROR: ftp.Chdir failed. ***");
1904  }
1905  else
1906  SL_LOG("*** ERROR: ftp.Login failed. ***");
1907  }
1908  else
1909  SL_LOG("*** ERROR: ftp.Connect failed. ***");
1910 
1911  ftp.Quit();
1912  AppCommon::jobIsRunning = false;
1913  };
1914 
1915  auto unzipJob = [largeFile]() {
1916  AppCommon::jobProgressMsg("Decompress dragon file:");
1917  AppCommon::jobProgressMax(-1);
1918  string zipFile = AppCommon::configPath + "models/xyzrgb_dragon.zip";
1919  if (Utils::fileExists(zipFile))
1920  {
1921  ZipUtils::unzip(zipFile, Utils::getPath(zipFile));
1922  Utils::deleteFile(zipFile);
1923  }
1924  AppCommon::jobIsRunning = false;
1925  };
1926 
1927  auto followUpJob1 = [am, s, sv, largeFile]() {
1928  if (Utils::fileExists(largeFile))
1929  AppCommon::sceneToLoad = SID_Benchmark_LargeModel;
1930  };
1931 
1932  AppCommon::jobsToBeThreaded.emplace_back(downloadJobFTP);
1933  AppCommon::jobsToBeThreaded.emplace_back(unzipJob);
1934  AppCommon::jobsToFollowInMain.emplace_back(followUpJob1);
1935  }
1936  }
1937  if (ImGui::MenuItem("Large Model (via HTTPS)", nullptr, sid == SID_Benchmark_LargeModel))
1938  {
1939  SLstring largeFile = AppCommon::configPath + "models/xyzrgb_dragon/xyzrgb_dragon.ply";
1940  loadSceneWithLargeModel(s, sv, "xyzrgb_dragon.zip", largeFile, SID_Benchmark_LargeModel);
1941  }*/
1942 #endif
1943  if (ImGui::MenuItem("Large Model", nullptr, sid == SID_Benchmark_LargeModel))
1945  if (ImGui::MenuItem("Massive Nodes", nullptr, sid == SID_Benchmark_LotsOfNodes))
1947  if (ImGui::MenuItem("Massive Node Animations", nullptr, sid == SID_Benchmark_NodeAnimations))
1949  if (ImGui::MenuItem("Jan's Universe", nullptr, sid == SID_Benchmark_JansUniverse))
1951  if (ImGui::MenuItem("Massive Skinned Animations", nullptr, sid == SID_Benchmark_SkinnedAnimations))
1953  if (ImGui::MenuItem("Columns without LOD", nullptr, sid == SID_Benchmark_ColumnsNoLOD))
1955  if (ImGui::MenuItem("Columns with LOD", nullptr, sid == SID_Benchmark_ColumnsLOD))
1957  if (ImGui::MenuItem("Particle System lot of fire complex", nullptr, sid == SID_Benchmark_ParticleSystemComplexFire))
1959  if (ImGui::MenuItem("Particle System w. 1 mio. particle", nullptr, sid == SID_ParticleSystem_Many))
1961  ImGui::EndMenu();
1962  }
1963 
1964  ImGui::EndMenu();
1965  }
1966 
1967  if (ImGui::MenuItem("Empty Scene", "Shift-Alt-0", sid == SID_Empty))
1969 
1970  if (ImGui::MenuItem("Next Scene",
1971  "Shift-Alt->",
1972  nullptr,
1975 
1976  if (ImGui::MenuItem("Previous Scene",
1977  "Shift-Alt-<",
1978  nullptr,
1981 
1982 #ifndef SL_EMSCRIPTEN
1983  ImGui::Separator();
1984 
1985  if (ImGui::MenuItem("Multi-threaded Jobs"))
1986  {
1987  auto job1 = []()
1988  {
1989  PROFILE_THREAD("Worker Thread 1");
1990  PROFILE_SCOPE("Parallel Job 1");
1991 
1992  uint maxIter = 100000;
1993  AppCommon::jobProgressMsg("Super long job 1");
1995  for (uint i = 0; i < maxIter; ++i)
1996  {
1997  SL_LOG("%u", i);
1998  int progressPC = (int)((float)i / (float)maxIter * 100.0f);
1999  AppCommon::jobProgressNum(progressPC);
2000  }
2001  AppCommon::jobIsRunning = false;
2002  };
2003 
2004  auto job2 = []()
2005  {
2006  PROFILE_THREAD("Worker Thread 2");
2007  PROFILE_SCOPE("Parallel Job 2");
2008 
2009  uint maxIter = 100000;
2010  AppCommon::jobProgressMsg("Super long job 2");
2012  for (uint i = 0; i < maxIter; ++i)
2013  {
2014  SL_LOG("%u", i);
2015  int progressPC = (int)((float)i / (float)maxIter * 100.0f);
2016  AppCommon::jobProgressNum(progressPC);
2017  }
2018  AppCommon::jobIsRunning = false;
2019  };
2020 
2021  auto followUpJob1 = []()
2022  { SL_LOG("followUpJob1"); };
2023  auto jobToFollow2 = []()
2024  { SL_LOG("JobToFollow2"); };
2025 
2026  AppCommon::jobsToBeThreaded.emplace_back(job1);
2027  AppCommon::jobsToBeThreaded.emplace_back(job2);
2028  AppCommon::jobsToFollowInMain.emplace_back(followUpJob1);
2029  AppCommon::jobsToFollowInMain.emplace_back(jobToFollow2);
2030  }
2031 #endif
2032 
2033 #if !defined(SL_OS_ANDROID) && !defined(SL_EMSCRIPTEN)
2034  ImGui::Separator();
2035 
2036  if (ImGui::MenuItem("Quit & Save"))
2037  slShouldClose(true);
2038 #endif
2039 
2040  ImGui::EndMenu();
2041  }
2042 
2043  if (ImGui::BeginMenu("Preferences"))
2044  {
2045  if (ImGui::MenuItem("Do Wait on Idle", "I", sv->doWaitOnIdle()))
2047 
2048  if (ImGui::MenuItem("Do Multi Sampling", "L", sv->doMultiSampling()))
2050 
2051  if (ImGui::MenuItem("Do Frustum Culling", "F", sv->doFrustumCulling()))
2053 
2054  if (ImGui::MenuItem("Do Alpha Sorting", "J", sv->doAlphaSorting()))
2056 
2057  if (ImGui::MenuItem("Do Depth Test", "T", sv->doDepthTest()))
2058  sv->doDepthTest(!sv->doDepthTest());
2059 
2060  if (ImGui::MenuItem("Animation off", "Space", s->stopAnimations()))
2062 
2063  ImGui::Separator();
2064 
2065  if (ImGui::BeginMenu("Viewport Aspect"))
2066  {
2067  SLVec2i videoAspect(0, 0);
2068  if (capture->videoType() != VT_NONE)
2069  {
2070  videoAspect.x = capture->captureSize.width;
2071  videoAspect.y = capture->captureSize.height;
2072  }
2073  SLchar strSameAsVideo[256];
2074  snprintf(strSameAsVideo, sizeof(strSameAsVideo), "Same as Video (%d:%d)", videoAspect.x, videoAspect.y);
2075 
2076  if (ImGui::MenuItem("Same as window", nullptr, sv->viewportRatio() == SLVec2i::ZERO))
2077  sv->setViewportFromRatio(SLVec2i(0, 0), sv->viewportAlign(), false);
2078  if (ImGui::MenuItem(strSameAsVideo, nullptr, sv->viewportSameAsVideo()))
2079  sv->setViewportFromRatio(videoAspect, sv->viewportAlign(), true);
2080  if (ImGui::MenuItem("16:9", nullptr, sv->viewportRatio() == SLVec2i(16, 9)))
2081  sv->setViewportFromRatio(SLVec2i(16, 9), sv->viewportAlign(), false);
2082  if (ImGui::MenuItem("4:3", nullptr, sv->viewportRatio() == SLVec2i(4, 3)))
2083  sv->setViewportFromRatio(SLVec2i(4, 3), sv->viewportAlign(), false);
2084  if (ImGui::MenuItem("2:1", nullptr, sv->viewportRatio() == SLVec2i(2, 1)))
2085  sv->setViewportFromRatio(SLVec2i(2, 1), sv->viewportAlign(), false);
2086  if (ImGui::MenuItem("1:1", nullptr, sv->viewportRatio() == SLVec2i(1, 1)))
2087  sv->setViewportFromRatio(SLVec2i(1, 1), sv->viewportAlign(), false);
2088 
2089  if (ImGui::BeginMenu("Alignment", sv->viewportRatio() != SLVec2i::ZERO))
2090  {
2091  if (ImGui::MenuItem("Center", nullptr, sv->viewportAlign() == VA_center))
2093  if (ImGui::MenuItem("Left or bottom", nullptr, sv->viewportAlign() == VA_leftOrBottom))
2095 
2096  ImGui::EndMenu();
2097  }
2098  ImGui::EndMenu();
2099  }
2100 
2101  ImGui::Separator();
2102 
2103  // Rotation and Location Sensor
2104 #if defined(SL_OS_ANDROID) || defined(SL_OS_MACIOS)
2105  if (ImGui::BeginMenu("Rotation Sensor"))
2106  {
2108 
2109  if (ImGui::MenuItem("Use Device Rotation (IMU)", nullptr, devRot.isUsed()))
2110  devRot.isUsed(!AppCommon::devRot.isUsed());
2111 
2112  if (devRot.isUsed())
2113  {
2114  SLint numAveraged = devRot.numAveraged();
2115  if (ImGui::SliderInt("Average length", &numAveraged, 1, 10))
2116  devRot.numAveraged(numAveraged);
2117 
2118  if (ImGui::BeginMenu("Offset Mode"))
2119  {
2120  SLRotOffsetMode om = devRot.offsetMode();
2121  if (ImGui::MenuItem("None", nullptr, om == ROM_none))
2122  devRot.offsetMode(ROM_none);
2123  if (ImGui::MenuItem("Finger rot. X", nullptr, om == ROM_oneFingerX))
2124  devRot.offsetMode(ROM_oneFingerX);
2125  if (ImGui::MenuItem("Finger rot. X and Y", nullptr, om == ROM_oneFingerXY))
2126  devRot.offsetMode(ROM_oneFingerXY);
2127 
2128  ImGui::EndMenu();
2129  }
2130 
2131  if (ImGui::MenuItem("Zero Yaw at Start", nullptr, devRot.zeroYawAtStart()))
2132  devRot.zeroYawAtStart(!devRot.zeroYawAtStart());
2133 
2134  if (ImGui::MenuItem("Reset Zero Yaw"))
2135  devRot.hasStarted(true);
2136 
2137  if (ImGui::MenuItem("Show Horizon", nullptr, _horizonVisuEnabled))
2138  {
2139  if (_horizonVisuEnabled)
2140  hideHorizon(s);
2141  else
2142  showHorizon(s, sv);
2143  }
2144  }
2145 
2146  ImGui::EndMenu();
2147  }
2148 
2149  if (ImGui::BeginMenu("Location Sensor"))
2150  {
2152 
2153  if (ImGui::MenuItem("Use Device Location (GPS)", nullptr, AppCommon::devLoc.isUsed()))
2155 
2156  if (!AppCommon::devLoc.geoTiffIsAvailableAndValid())
2157  if (ImGui::MenuItem("Use Origin Altitude", nullptr, AppCommon::devLoc.useOriginAltitude()))
2159 
2160  if (ImGui::MenuItem("Reset Origin to here"))
2162 
2163  if (ImGui::BeginMenu("Offset Mode"))
2164  {
2165  SLLocOffsetMode om = devLoc.offsetMode();
2166  if (ImGui::MenuItem("None", nullptr, om == LOM_none))
2167  devLoc.offsetMode(LOM_none);
2168  if (ImGui::MenuItem("Two Finger Y", nullptr, om == LOM_twoFingerY))
2169  devLoc.offsetMode(LOM_twoFingerY);
2170 
2171  ImGui::EndMenu();
2172  }
2173 
2174  ImGui::EndMenu();
2175  }
2176 #endif
2177 
2178  if (ImGui::BeginMenu("Video Sensor"))
2179  {
2180  CVCamera* ac = capture->activeCamera;
2181  if (ImGui::BeginMenu("Mirror Camera"))
2182  {
2183  if (ImGui::MenuItem("Horizontally", nullptr, ac->mirrorH()))
2184  {
2185  ac->toggleMirrorH();
2186  // make a guessed calibration, if there was a calibrated camera it is not valid anymore
2187  ac->calibration = guessCalibration(ac->mirrorH(), ac->mirrorV(), ac->type());
2188  }
2189 
2190  if (ImGui::MenuItem("Vertically", nullptr, ac->mirrorV()))
2191  {
2192  ac->toggleMirrorV();
2193  // make a guessed calibration, if there was a calibrated camera it is not valid anymore
2194  ac->calibration = guessCalibration(ac->mirrorH(), ac->mirrorV(), ac->type());
2195  }
2196 
2197  ImGui::EndMenu();
2198  }
2199 
2200  if (ImGui::BeginMenu("Resolution",
2201  (capture->videoType() == VT_MAIN ||
2202  capture->videoType() == VT_SCND)))
2203  {
2204  for (int i = 0; i < (int)capture->camSizes.size(); ++i)
2205  {
2206  SLchar menuStr[256];
2207  snprintf(menuStr,
2208  sizeof(menuStr),
2209  "%d x %d",
2210  capture->camSizes[(uint)i].width,
2211  capture->camSizes[(uint)i].height);
2212  if (ImGui::MenuItem(menuStr, nullptr, i == capture->activeCamSizeIndex))
2213  if (i != capture->activeCamSizeIndex)
2214  ac->camSizeIndex(i);
2215  }
2216  ImGui::EndMenu();
2217  }
2218 
2219 #ifndef SL_EMSCRIPTEN
2220  if (ImGui::BeginMenu("Calibration"))
2221  {
2222  if (ImGui::MenuItem("Start Calibration (Main Camera)"))
2223  {
2225  showHelpCalibration = false;
2226  showInfosScene = true;
2227  }
2228 
2229  if (ImGui::MenuItem("Start Calibration (Scnd. Camera)", nullptr, false, capture->hasSecondaryCamera))
2230  {
2232  showHelpCalibration = false;
2233  showInfosScene = true;
2234  }
2235 
2236  if (ImGui::MenuItem("Undistort Image", nullptr, ac->showUndistorted(), ac->calibration.state() == CS_calibrated))
2237  ac->showUndistorted(!ac->showUndistorted());
2238 
2239  if (ImGui::MenuItem("No Tangent Distortion", nullptr, AppCommon::calibrationEstimatorParams.zeroTangentDistortion))
2241 
2242  if (ImGui::MenuItem("Fix Aspect Ratio", nullptr, AppCommon::calibrationEstimatorParams.fixAspectRatio))
2244 
2245  if (ImGui::MenuItem("Fix Principal Point", nullptr, AppCommon::calibrationEstimatorParams.fixPrincipalPoint))
2247 
2248  if (ImGui::MenuItem("Use rational model", nullptr, AppCommon::calibrationEstimatorParams.calibRationalModel))
2250 
2251  if (ImGui::MenuItem("Use tilted model", nullptr, AppCommon::calibrationEstimatorParams.calibTiltedModel))
2253 
2254  if (ImGui::MenuItem("Use thin prism model", nullptr, AppCommon::calibrationEstimatorParams.calibThinPrismModel))
2256 
2257  ImGui::EndMenu();
2258  }
2259 
2260  CVTrackedFeatures* featureTracker = nullptr;
2261  if (gVideoTracker != nullptr && typeid(*gVideoTracker) == typeid(CVTrackedFeatures))
2262  featureTracker = (CVTrackedFeatures*)gVideoTracker;
2263 
2264  if (gVideoTracker != nullptr)
2265  if (ImGui::MenuItem("Draw Detection", nullptr, gVideoTracker->drawDetection()))
2267 
2268  if (ImGui::BeginMenu("Feature Tracking", featureTracker != nullptr) && featureTracker != nullptr)
2269  {
2270  if (ImGui::MenuItem("Force Relocation", nullptr, featureTracker->forceRelocation()))
2271  featureTracker->forceRelocation(!featureTracker->forceRelocation());
2272 
2273  if (ImGui::BeginMenu("Detector/Descriptor", featureTracker != nullptr))
2274  {
2275  CVDetectDescribeType type = featureTracker->type();
2276 
2277  if (ImGui::MenuItem("RAUL/RAUL", nullptr, type == DDT_RAUL_RAUL))
2278  featureTracker->type(DDT_RAUL_RAUL);
2279  if (ImGui::MenuItem("ORB/ORB", nullptr, type == DDT_ORB_ORB))
2280  featureTracker->type(DDT_ORB_ORB);
2281  if (ImGui::MenuItem("FAST/BRIEF", nullptr, type == DDT_FAST_BRIEF))
2282  featureTracker->type(DDT_FAST_BRIEF);
2283  if (ImGui::MenuItem("SURF/SURF", nullptr, type == DDT_SURF_SURF))
2284  featureTracker->type(DDT_SURF_SURF);
2285  if (ImGui::MenuItem("SIFT/SIFT", nullptr, type == DDT_SIFT_SIFT))
2286  featureTracker->type(DDT_SIFT_SIFT);
2287 
2288  ImGui::EndMenu();
2289  }
2290 
2291  ImGui::EndMenu();
2292  }
2293 #endif
2294 
2295  ImGui::EndMenu();
2296  }
2297 
2298  ImGui::Separator();
2299 
2300  ImGui::MenuItem("UI Preferences", nullptr, &showUIPrefs);
2301 
2302  ImGui::EndMenu();
2303  }
2304 
2305  if (ImGui::BeginMenu("Edit", s->singleNodeSelected() != nullptr || !sv->camera()->selectRect().isZero()))
2306  {
2307  if (s->singleNodeSelected())
2308  {
2309  buildMenuEdit(s, sv);
2310  }
2311  else
2312  {
2313  if (ImGui::MenuItem("Clear selection"))
2314  {
2315  sv->camera()->selectRect().setZero();
2316  sv->camera()->deselectRect().setZero();
2317  }
2318  }
2319 
2320  ImGui::EndMenu();
2321  }
2322 
2323  if (ImGui::BeginMenu("Renderer"))
2324  {
2325  if (ImGui::MenuItem("OpenGL", "ESC", rType == RT_gl))
2326  sv->renderType(RT_gl);
2327 
2328  if (ImGui::MenuItem("Ray Tracing", "R", rType == RT_rt))
2329  sv->startRaytracing(5);
2330 
2331  if (ImGui::MenuItem("Path Tracing", "P", rType == RT_pt))
2332  sv->startPathtracing(5, 10);
2333 
2334 #ifdef SL_HAS_OPTIX
2335  if (ImGui::MenuItem("Ray Tracing with OptiX", "Shift-R", rType == RT_optix_rt))
2336  sv->startOptixRaytracing(5);
2337 
2338  if (ImGui::MenuItem("Path Tracing with OptiX", "Shift-P", rType == RT_optix_pt))
2339  sv->startOptixPathtracing(5, 10);
2340 #else
2341  ImGui::MenuItem("Ray Tracing with OptiX", nullptr, false, false);
2342  ImGui::MenuItem("Path Tracing with OptiX", nullptr, false, false);
2343 #endif
2344  ImGui::EndMenu();
2345  }
2346 
2347  if (rType == RT_gl)
2348  {
2349  if (ImGui::BeginMenu("GL"))
2350  {
2351  if (ImGui::MenuItem("Mesh Wired", "M", sv->drawBits()->get(SL_DB_MESHWIRED)))
2353 
2354  if (ImGui::MenuItem("With hard edges", "H", sv->drawBits()->get(SL_DB_WITHEDGES)))
2356 
2357  if (ImGui::MenuItem("Only hard edges", "O", sv->drawBits()->get(SL_DB_ONLYEDGES)))
2359 
2360  if (ImGui::MenuItem("Normals", "N", sv->drawBits()->get(SL_DB_NORMALS)))
2362 
2363  if (ImGui::MenuItem("Bounding Rectangles", "U", sv->drawBits()->get(SL_DB_BRECT)))
2365 
2366  if (ImGui::MenuItem("Bounding Boxes", "B", sv->drawBits()->get(SL_DB_BBOX)))
2368 
2369  if (ImGui::MenuItem("Voxels", "V", sv->drawBits()->get(SL_DB_VOXELS)))
2371 
2372  if (ImGui::MenuItem("Axis", "X", sv->drawBits()->get(SL_DB_AXIS)))
2374 
2375  if (ImGui::MenuItem("Back Faces", "C", sv->drawBits()->get(SL_DB_CULLOFF)))
2377 
2378  if (ImGui::MenuItem("Skeleton", "K", sv->drawBits()->get(SL_DB_SKELETON)))
2380 
2381  if (ImGui::MenuItem("GPU Skinning", nullptr, sv->drawBits()->get(SL_DB_GPU_SKINNING)))
2383 
2384  if (ImGui::MenuItem("All off"))
2385  sv->drawBits()->allOff();
2386 
2387  if (ImGui::MenuItem("All on"))
2388  {
2392  sv->drawBits()->on(SL_DB_NORMALS);
2393  sv->drawBits()->on(SL_DB_VOXELS);
2394  sv->drawBits()->on(SL_DB_AXIS);
2395  sv->drawBits()->on(SL_DB_BBOX);
2397  sv->drawBits()->on(SL_DB_CULLOFF);
2399  }
2400 
2401  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2402  SLfloat gamma = SLLight::gamma;
2403  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2404  SLLight::gamma = gamma;
2405  ImGui::PopItemWidth();
2406 
2407  ImGui::EndMenu();
2408  }
2409  }
2410  else if (rType == RT_rt)
2411  {
2412  if (ImGui::BeginMenu("RT"))
2413  {
2414  SLRaytracer* rt = sv->raytracer();
2415 
2416  if (ImGui::BeginMenu("Resolution Factor"))
2417  {
2418  if (ImGui::MenuItem("1.00", nullptr, rt->resolutionFactorPC() == 100))
2419  {
2420  rt->resolutionFactor(1.0f);
2421  sv->startRaytracing(rt->maxDepth());
2422  }
2423  if (ImGui::MenuItem("0.50", nullptr, rt->resolutionFactorPC() == 50))
2424  {
2425  rt->resolutionFactor(0.5f);
2426  sv->startRaytracing(rt->maxDepth());
2427  }
2428  if (ImGui::MenuItem("0.25", nullptr, rt->resolutionFactorPC() == 25))
2429  {
2430  rt->resolutionFactor(0.25f);
2431  sv->startRaytracing(rt->maxDepth());
2432  }
2433 
2434  ImGui::EndMenu();
2435  }
2436 
2437  if (ImGui::MenuItem("Parallel distributed", nullptr, rt->doDistributed()))
2438  {
2439  rt->doDistributed(!rt->doDistributed());
2440  sv->startRaytracing(rt->maxDepth());
2441  }
2442 
2443  if (ImGui::MenuItem("Continuously", nullptr, rt->doContinuous()))
2444  {
2445  rt->doContinuous(!rt->doContinuous());
2446  sv->doWaitOnIdle(!rt->doContinuous());
2447  }
2448 
2449  if (ImGui::MenuItem("Fresnel Reflection", nullptr, rt->doFresnel()))
2450  {
2451  rt->doFresnel(!rt->doFresnel());
2452  sv->startRaytracing(rt->maxDepth());
2453  }
2454 
2455  if (ImGui::BeginMenu("Max. Depth"))
2456  {
2457  if (ImGui::MenuItem("1", nullptr, rt->maxDepth() == 1)) sv->startRaytracing(1);
2458  if (ImGui::MenuItem("2", nullptr, rt->maxDepth() == 2)) sv->startRaytracing(2);
2459  if (ImGui::MenuItem("3", nullptr, rt->maxDepth() == 3)) sv->startRaytracing(3);
2460  if (ImGui::MenuItem("5", nullptr, rt->maxDepth() == 5)) sv->startRaytracing(5);
2461  if (ImGui::MenuItem("Max. Contribution", nullptr, rt->maxDepth() == 0)) sv->startRaytracing(0);
2462 
2463  ImGui::EndMenu();
2464  }
2465 
2466  if (ImGui::BeginMenu("Anti-Aliasing Samples"))
2467  {
2468  if (ImGui::MenuItem("Off", nullptr, rt->aaSamples() == 1)) rt->aaSamples(1);
2469  if (ImGui::MenuItem("3x3", nullptr, rt->aaSamples() == 3)) rt->aaSamples(3);
2470  if (ImGui::MenuItem("5x5", nullptr, rt->aaSamples() == 5)) rt->aaSamples(5);
2471  if (ImGui::MenuItem("7x7", nullptr, rt->aaSamples() == 7)) rt->aaSamples(7);
2472  if (ImGui::MenuItem("9x9", nullptr, rt->aaSamples() == 9)) rt->aaSamples(9);
2473 
2474  ImGui::EndMenu();
2475  }
2476 
2477  if (ImGui::MenuItem("Save Rendered Image"))
2478  rt->saveImage();
2479 
2480  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2481  SLfloat gamma = rt->gamma();
2482  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2483  {
2484  rt->gamma(gamma);
2485  sv->startRaytracing(5);
2486  }
2487  ImGui::PopItemWidth();
2488 
2489  ImGui::EndMenu();
2490  }
2491  }
2492 
2493 #ifdef SL_HAS_OPTIX
2494  else if (rType == RT_optix_rt)
2495  {
2496  if (ImGui::BeginMenu("RT"))
2497  {
2498  SLOptixRaytracer* rt_optix = sv->optixRaytracer();
2499 
2500  if (ImGui::MenuItem("Parallel distributed", nullptr, rt_optix->doDistributed()))
2501  {
2502  rt_optix->doDistributed(!rt_optix->doDistributed());
2503  sv->startOptixRaytracing(rt_optix->maxDepth());
2504  }
2505 
2506  // if (ImGui::MenuItem("Fresnel Reflection", nullptr, rt->doFresnel()))
2507  // {
2508  // rt->doFresnel(!rt->doFresnel());
2509  // sv->startRaytracing(rt->maxDepth());
2510  // }
2511 
2512  if (ImGui::BeginMenu("Max. Depth"))
2513  {
2514  if (ImGui::MenuItem("1", nullptr, rt_optix->maxDepth() == 1))
2515  sv->startOptixRaytracing(1);
2516  if (ImGui::MenuItem("2", nullptr, rt_optix->maxDepth() == 2))
2517  sv->startOptixRaytracing(2);
2518  if (ImGui::MenuItem("3", nullptr, rt_optix->maxDepth() == 3))
2519  sv->startOptixRaytracing(3);
2520  if (ImGui::MenuItem("5", nullptr, rt_optix->maxDepth() == 5))
2521  sv->startOptixRaytracing(5);
2522  if (ImGui::MenuItem("Max. Contribution", nullptr, rt_optix->maxDepth() == 0))
2523  sv->startOptixRaytracing(0);
2524 
2525  ImGui::EndMenu();
2526  }
2527 
2528  // if (ImGui::BeginMenu("Anti-Aliasing Samples"))
2529  // {
2530  // if (ImGui::MenuItem("Off", nullptr, rt->aaSamples() == 1))
2531  // rt->aaSamples(1);
2532  // if (ImGui::MenuItem("3x3", nullptr, rt->aaSamples() == 3))
2533  // rt->aaSamples(3);
2534  // if (ImGui::MenuItem("5x5", nullptr, rt->aaSamples() == 5))
2535  // rt->aaSamples(5);
2536  // if (ImGui::MenuItem("7x7", nullptr, rt->aaSamples() == 7))
2537  // rt->aaSamples(7);
2538  // if (ImGui::MenuItem("9x9", nullptr, rt->aaSamples() == 9))
2539  // rt->aaSamples(9);
2540  //
2541  // ImGui::EndMenu();
2542  // }
2543 
2544  if (ImGui::MenuItem("Save Rendered Image"))
2545  rt_optix->saveImage();
2546 
2547  ImGui::EndMenu();
2548  }
2549  }
2550 #endif
2551  else if (rType == RT_pt)
2552  {
2553  if (ImGui::BeginMenu("PT"))
2554  {
2555  SLPathtracer* pt = sv->pathtracer();
2556 
2557  if (ImGui::BeginMenu("Resolution Factor"))
2558  {
2559  if (ImGui::MenuItem("1.00", nullptr, pt->resolutionFactorPC() == 100))
2560  {
2561  pt->resolutionFactor(1.0f);
2562  sv->startPathtracing(5, pt->aaSamples());
2563  }
2564  if (ImGui::MenuItem("0.50", nullptr, pt->resolutionFactorPC() == 50))
2565  {
2566  pt->resolutionFactor(0.5f);
2567  sv->startPathtracing(5, pt->aaSamples());
2568  }
2569  if (ImGui::MenuItem("0.25", nullptr, pt->resolutionFactorPC() == 25))
2570  {
2571  pt->resolutionFactor(0.25f);
2572  sv->startPathtracing(5, pt->aaSamples());
2573  }
2574 
2575  ImGui::EndMenu();
2576  }
2577 
2578  if (ImGui::BeginMenu("NO. of Samples"))
2579  {
2580  if (ImGui::MenuItem("1", nullptr, pt->aaSamples() == 1)) sv->startPathtracing(5, 1);
2581  if (ImGui::MenuItem("10", nullptr, pt->aaSamples() == 10)) sv->startPathtracing(5, 10);
2582  if (ImGui::MenuItem("100", nullptr, pt->aaSamples() == 100)) sv->startPathtracing(5, 100);
2583  if (ImGui::MenuItem("1000", nullptr, pt->aaSamples() == 1000)) sv->startPathtracing(5, 1000);
2584  if (ImGui::MenuItem("10000", nullptr, pt->aaSamples() == 10000)) sv->startPathtracing(5, 10000);
2585 
2586  ImGui::EndMenu();
2587  }
2588 
2589  if (ImGui::MenuItem("Direct illumination", nullptr, pt->calcDirect()))
2590  {
2591  pt->calcDirect(!pt->calcDirect());
2592  sv->startPathtracing(5, 10);
2593  }
2594 
2595  if (ImGui::MenuItem("Indirect illumination", nullptr, pt->calcIndirect()))
2596  {
2597  pt->calcIndirect(!pt->calcIndirect());
2598  sv->startPathtracing(5, 10);
2599  }
2600 
2601  if (ImGui::MenuItem("Save Rendered Image"))
2602  pt->saveImage();
2603 
2604  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);
2605  SLfloat gamma = pt->gamma();
2606  if (ImGui::SliderFloat("Gamma", &gamma, 0.1f, 3.0f, "%.1f"))
2607  {
2608  pt->gamma(gamma);
2609  sv->startPathtracing(5, 1);
2610  }
2611  ImGui::PopItemWidth();
2612 
2613  ImGui::EndMenu();
2614  }
2615  }
2616 
2617 #ifdef SL_HAS_OPTIX
2618  else if (rType == RT_optix_pt)
2619  {
2620  if (ImGui::BeginMenu("PT"))
2621  {
2622  SLOptixPathtracer* pt = sv->optixPathtracer();
2623 
2624  if (ImGui::BeginMenu("NO. of Samples"))
2625  {
2626  if (ImGui::MenuItem("1", nullptr, pt->samples() == 1))
2627  sv->startOptixPathtracing(5, 1);
2628  if (ImGui::MenuItem("10", nullptr, pt->samples() == 10))
2629  sv->startOptixPathtracing(5, 10);
2630  if (ImGui::MenuItem("100", nullptr, pt->samples() == 100))
2631  sv->startOptixPathtracing(5, 100);
2632  if (ImGui::MenuItem("1000", nullptr, pt->samples() == 1000))
2633  sv->startOptixPathtracing(5, 1000);
2634  if (ImGui::MenuItem("10000", nullptr, pt->samples() == 10000))
2635  sv->startOptixPathtracing(5, 10000);
2636 
2637  ImGui::EndMenu();
2638  }
2639 
2640  if (ImGui::MenuItem("Denoiser", nullptr, pt->getDenoiserEnabled()))
2641  {
2642  pt->setDenoiserEnabled(!pt->getDenoiserEnabled());
2643  sv->startOptixPathtracing(5, pt->samples());
2644  }
2645 
2646  if (ImGui::MenuItem("Save Rendered Image"))
2647  pt->saveImage();
2648 
2649  ImGui::EndMenu();
2650  }
2651  }
2652 #endif
2653 
2654  if (ImGui::BeginMenu("Camera"))
2655  {
2656  SLCamera* cam = sv->camera();
2657  SLProjType proj = cam->projType();
2658 
2659  if (ImGui::MenuItem("Reset"))
2660  {
2661  cam->resetToInitialState();
2662  float dist = cam->translationOS().length();
2663  cam->focalDist(dist);
2664  }
2665 
2666  if (ImGui::BeginMenu("Look from"))
2667  {
2668  if (ImGui::MenuItem("Left (+X)", "3")) cam->lookFrom(SLVec3f::AXISX);
2669  if (ImGui::MenuItem("Right (-X)", "CTRL-3")) cam->lookFrom(-SLVec3f::AXISX);
2670  if (ImGui::MenuItem("Top (+Y)", "7")) cam->lookFrom(SLVec3f::AXISY, -SLVec3f::AXISZ);
2671  if (ImGui::MenuItem("Bottom (-Y)", "CTRL-7")) cam->lookFrom(-SLVec3f::AXISY, SLVec3f::AXISZ);
2672  if (ImGui::MenuItem("Front (+Z)", "1")) cam->lookFrom(SLVec3f::AXISZ);
2673  if (ImGui::MenuItem("Back (-Z)", "CTRL-1")) cam->lookFrom(-SLVec3f::AXISZ);
2674 
2675  if (s->numSceneCameras())
2676  {
2677  if (ImGui::MenuItem("Next camera in Scene", "TAB"))
2679 
2680  if (ImGui::MenuItem("Sceneview Camera", "TAB"))
2682  }
2683 
2684  ImGui::EndMenu();
2685  }
2686 
2687  if (ImGui::BeginMenu("Projection"))
2688  {
2689  static SLfloat clipN = cam->clipNear();
2690  static SLfloat clipF = cam->clipFar();
2691  static SLfloat focalDist = cam->focalDist();
2692  static SLfloat fov = cam->fovV();
2693 
2694  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2695 
2696  if (ImGui::MenuItem("Perspective", "5", proj == P_monoPerspective))
2697  {
2699  if (sv->renderType() == RT_rt && !sv->raytracer()->doContinuous() &&
2700  sv->raytracer()->state() == rtFinished)
2701  sv->raytracer()->state(rtReady);
2702  }
2703 
2704  if (ImGui::MenuItem("Orthographic", "5", proj == P_monoOrthographic))
2705  {
2707  if (sv->renderType() == RT_rt && !sv->raytracer()->doContinuous() &&
2708  sv->raytracer()->state() == rtFinished)
2709  sv->raytracer()->state(rtReady);
2710  }
2711 
2712  if (ImGui::BeginMenu("Stereo"))
2713  {
2714  for (SLint p = P_stereoSideBySide; p <= P_stereoColorYB; ++p)
2715  {
2717  if (ImGui::MenuItem(pStr.c_str(), nullptr, proj == (SLProjType)p))
2718  cam->projType((SLProjType)p);
2719  }
2720 
2721  if (proj >= P_stereoSideBySide)
2722  {
2723  ImGui::Separator();
2724  static SLfloat eyeSepar = cam->stereoEyeSeparation();
2725  if (ImGui::SliderFloat("Eye Sep.", &eyeSepar, 0.0f, focalDist / 10.f))
2726  cam->stereoEyeSeparation(eyeSepar);
2727  }
2728 
2729  ImGui::EndMenu();
2730  }
2731 
2732  ImGui::Separator();
2733 
2734  if (ImGui::SliderFloat("FOV (V)", &fov, 1.f, 179.f))
2735  cam->fov(fov);
2736 
2737  ImGui::Text("FOV (H): %3.1f ", cam->fovH());
2738 
2739  if (ImGui::SliderFloat("Near Clip", &clipN, 0.001f, 10.f))
2740  cam->clipNear(clipN);
2741 
2742  if (ImGui::SliderFloat("Focal Dist.", &focalDist, clipN, clipF))
2743  cam->focalDist(focalDist);
2744 
2745  if (ImGui::SliderFloat("Far Clip", &clipF, clipN, std::min(clipF * 1.1f, 1000000.f)))
2746  cam->clipFar(clipF);
2747 
2748  ImGui::PopItemWidth();
2749  ImGui::EndMenu();
2750  }
2751 
2752  if (ImGui::BeginMenu("Animation"))
2753  {
2754  SLCamAnim ca = cam->camAnim();
2755 
2756  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2757 
2758  if (ImGui::MenuItem("Turntable Y up", nullptr, ca == CA_turntableYUp))
2759  sv->camera()->camAnim(CA_turntableYUp);
2760 
2761  if (ImGui::MenuItem("Turntable Z up", nullptr, ca == CA_turntableZUp))
2762  sv->camera()->camAnim(CA_turntableZUp);
2763 
2764  if (ImGui::MenuItem("Trackball", nullptr, ca == CA_trackball))
2765  sv->camera()->camAnim(CA_trackball);
2766 
2767  if (ImGui::MenuItem("Walk Y up", nullptr, ca == CA_walkingYUp))
2768  sv->camera()->camAnim(CA_walkingYUp);
2769 
2770  if (ImGui::MenuItem("Walk Z up", nullptr, ca == CA_walkingZUp))
2771  sv->camera()->camAnim(CA_walkingZUp);
2772 
2773  float mouseRotFactor = sv->camera()->mouseRotationFactor();
2774  if (ImGui::SliderFloat("Mouse Sensibility", &mouseRotFactor, 0.1f, 2.0f, "%2.1f"))
2775  sv->camera()->mouseRotationFactor(mouseRotFactor);
2776 
2777  ImGui::Separator();
2778 
2779  if (ImGui::MenuItem("IMU rotated", nullptr, ca == CA_deviceRotYUp))
2780  sv->camera()->camAnim(CA_deviceRotYUp);
2781 
2782  if (ImGui::MenuItem("IMU rotated & GPS located", nullptr, ca == CA_deviceRotLocYUp))
2783  sv->camera()->camAnim(CA_deviceRotLocYUp);
2784 
2785  if (ca == CA_walkingZUp || ca == CA_walkingYUp || ca == CA_deviceRotYUp)
2786  {
2787  static SLfloat ms = cam->maxSpeed();
2788  if (ImGui::SliderFloat("Walk Speed", &ms, 0.01f, std::min(ms * 1.1f, 10000.f)))
2789  cam->maxSpeed(ms);
2790  }
2791 
2792  ImGui::PopItemWidth();
2793  ImGui::EndMenu();
2794  }
2795 
2796  if (ImGui::BeginMenu("Fog"))
2797  {
2798  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.66f);
2799 
2800  if (ImGui::MenuItem("Fog is on", nullptr, cam->fogIsOn()))
2801  cam->fogIsOn(!cam->fogIsOn());
2802 
2803  if (ImGui::BeginMenu("Mode"))
2804  {
2805  if (ImGui::MenuItem("linear", nullptr, cam->fogMode() == FM_linear))
2806  cam->fogMode(FM_linear);
2807  if (ImGui::MenuItem("exp", nullptr, cam->fogMode() == FM_exp))
2808  cam->fogMode(FM_exp);
2809  if (ImGui::MenuItem("exp2", nullptr, cam->fogMode() == FM_exp2))
2810  cam->fogMode(FM_exp2);
2811  ImGui::EndMenu();
2812  }
2813 
2814  if (cam->fogMode() == FM_exp || cam->fogMode() == FM_exp2)
2815  {
2816  static SLfloat fogDensity = cam->fogDensity();
2817  if (ImGui::SliderFloat("Density", &fogDensity, 0.0f, 0.2f))
2818  cam->fogDensity(fogDensity);
2819  }
2820 
2821  ImGui::PopItemWidth();
2822  ImGui::EndMenu();
2823  }
2824 
2825  ImGui::EndMenu();
2826  }
2827 
2828  if (ImGui::BeginMenu("Animation", hasAnimations))
2829  {
2830 
2831  if (ImGui::MenuItem("Stop all", "Space", s->stopAnimations()))
2833 
2834  ImGui::Separator();
2835 
2836  SLVstring animations = s->animManager().animationNames();
2837  if (curAnimIx == -1) curAnimIx = 0;
2838  SLAnimPlayback* anim = s->animManager().animPlaybackByIndex((SLuint)curAnimIx);
2839 
2840  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.8f);
2841  if (myComboBox("##", &curAnimIx, animations))
2842  anim = s->animManager().animPlaybackByIndex((SLuint)curAnimIx);
2843  ImGui::PopItemWidth();
2844 
2845  if (ImGui::MenuItem("Play forward", nullptr, anim->isPlayingForward()))
2846  anim->playForward();
2847 
2848  if (ImGui::MenuItem("Play backward", nullptr, anim->isPlayingBackward()))
2849  anim->playBackward();
2850 
2851  if (ImGui::MenuItem("Pause", nullptr, anim->isPaused()))
2852  anim->pause();
2853 
2854  if (ImGui::MenuItem("Stop", nullptr, anim->isStopped()))
2855  anim->enabled(false);
2856 
2857  if (ImGui::MenuItem("Skip to next keyfr.", nullptr, false))
2858  anim->skipToNextKeyframe();
2859 
2860  if (ImGui::MenuItem("Skip to prev. keyfr.", nullptr, false))
2861  anim->skipToPrevKeyframe();
2862 
2863  if (ImGui::MenuItem("Skip to start", nullptr, false))
2864  anim->skipToStart();
2865 
2866  if (ImGui::MenuItem("Skip to end", nullptr, false))
2867  anim->skipToEnd();
2868 
2869  ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.6f);
2870 
2871  SLfloat speed = anim->playbackRate();
2872  if (ImGui::SliderFloat("Speed", &speed, 0.f, 4.f))
2873  anim->playbackRate(speed);
2874 
2875  SLfloat lenSec = anim->parentAnimation()->lengthSec();
2876  SLfloat localTimeSec = anim->localTime();
2877  if (ImGui::SliderFloat("Time", &localTimeSec, 0.f, lenSec))
2878  anim->localTime(localTimeSec);
2879 
2880  SLint curEasing = (SLint)anim->easing();
2881  const char* easings[] = {"linear",
2882  "in quad",
2883  "out quad",
2884  "in out quad",
2885  "out in quad",
2886  "in cubic",
2887  "out cubic",
2888  "in out cubic",
2889  "out in cubic",
2890  "in quart",
2891  "out quart",
2892  "in out quart",
2893  "out in quart",
2894  "in quint",
2895  "out quint",
2896  "in out quint",
2897  "out in quint",
2898  "in sine",
2899  "out sine",
2900  "in out sine",
2901  "out in sine"};
2902  if (ImGui::Combo("Easing", &curEasing, easings, IM_ARRAYSIZE(easings)))
2903  anim->easing((SLEasingCurve)curEasing);
2904 
2905  ImGui::PopItemWidth();
2906  ImGui::EndMenu();
2907  }
2908 
2909  if (ImGui::BeginMenu("Infos"))
2910  {
2911  ImGui::MenuItem("Infos on Scene", nullptr, &showInfosScene);
2912 
2913  if (ImGui::BeginMenu("Statistics"))
2914  {
2915  ImGui::MenuItem("Stats on Timing", nullptr, &showStatsTiming);
2916  ImGui::MenuItem("Stats on Scene", nullptr, &showStatsScene);
2917  ImGui::MenuItem("Stats on Video", nullptr, &showStatsVideo);
2918 #ifdef SL_BUILD_WAI
2920  ImGui::MenuItem("Stats on WAI", nullptr, &showStatsWAI);
2921 #endif
2922  ImGui::MenuItem("Stats on ImGui", nullptr, &showImGuiMetrics);
2923  ImGui::EndMenu();
2924  }
2925 
2926  ImGui::MenuItem("Scenegraph", nullptr, &showSceneGraph);
2927  ImGui::MenuItem("Properties", nullptr, &showProperties);
2928  ImGui::MenuItem("Transform", nullptr, &showTransform);
2929  if (AppCommon::devLoc.originLatLonAlt() != SLVec3d::ZERO ||
2930  AppCommon::devLoc.defaultLatLonAlt() != SLVec3d::ZERO)
2931  ImGui::MenuItem("Date-Time", nullptr, &showDateAndTime);
2932  ImGui::MenuItem("UI-Preferences", nullptr, &showUIPrefs);
2933  ImGui::Separator();
2934  ImGui::MenuItem("Infos on Device", nullptr, &showInfosDevice);
2935  ImGui::MenuItem("Infos on Sensors", nullptr, &showInfosSensors);
2938  {
2939  ImGui::Separator();
2940  ImGui::MenuItem("ErlebAR Settings", nullptr, &showErlebAR);
2941  }
2942  ImGui::Separator();
2943  ImGui::MenuItem("Help on Interaction", nullptr, &showHelp);
2944  ImGui::MenuItem("Help on Calibration", nullptr, &showHelpCalibration);
2945  ImGui::Separator();
2946  ImGui::MenuItem("Credits", nullptr, &showCredits);
2947  ImGui::MenuItem("About SLProject", nullptr, &showAbout);
2948 
2949  ImGui::EndMenu();
2950  }
2951 
2952  ImGui::EndMainMenuBar();
2953  }
2954 }
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_ErlebAR_BielCBB
@ 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 3030 of file AppDemoGui.cpp.

3031 {
3032  // assert(s->assetManager() && "No asset manager assigned to scene!");
3033 
3034  if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) &&
3035  ImGui::IsMouseReleased(1))
3036  {
3037  ImGui::OpenPopup("Context Menu");
3038  }
3039 
3040  if (ImGui::BeginPopup("Context Menu"))
3041  {
3042  if (s->singleNodeSelected() != nullptr || !sv->camera()->selectRect().isZero())
3043  {
3044  if (s->singleNodeSelected())
3045  {
3046  buildMenuEdit(s, sv);
3047  ImGui::Separator();
3048 
3049  if (!showProperties)
3050  if (ImGui::MenuItem("Show Properties"))
3051  showProperties = true;
3052  }
3053  }
3054 
3055  if (AppDemoGui::hideUI)
3056  if (ImGui::MenuItem("Show user interface"))
3057  AppDemoGui::hideUI = false;
3058 
3059  if (!AppDemoGui::hideUI)
3060  if (ImGui::MenuItem("Hide user interface"))
3061  AppDemoGui::hideUI = true;
3062 
3063  if (s->root3D()->drawBits()->get(SL_DB_HIDDEN))
3064  if (ImGui::MenuItem("Show root node"))
3065  s->root3D()->drawBits()->toggle(SL_DB_HIDDEN);
3066 
3067  if (!s->root3D()->drawBits()->get(SL_DB_HIDDEN))
3068  if (ImGui::MenuItem("Hide root node"))
3069  s->root3D()->drawBits()->toggle(SL_DB_HIDDEN);
3070 
3071  if (ImGui::MenuItem("Capture Screen"))
3073 
3074  ImGui::EndPopup();
3075  }
3076 }
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 2957 of file AppDemoGui.cpp.

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

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

3080 {
3081  PROFILE_FUNCTION();
3082 
3083  // assert(s->assetManager() && "No asset manager assigned to scene!");
3084 
3085  ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[1]);
3086  ImGui::Begin("Scenegraph", &showSceneGraph, ImGuiWindowFlags_NoNavInputs);
3087 
3088  if (s->root3D())
3089  addSceneGraphNode(s, s->root3D());
3090 
3091  if (s->root2D())
3092  addSceneGraphNode(s, s->root2D());
3093 
3094  ImGui::End();
3095  ImGui::PopFont();
3096 }
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 4919 of file AppDemoGui.cpp.

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

4852 {
4853  if (s->root2D())
4854  {
4855  SLstring horizonName = "Horizon";
4856  SLHorizonNode* horizonNode = s->root2D()->findChild<SLHorizonNode>(horizonName);
4857  if (horizonNode)
4858  {
4859  s->root2D()->deleteChild(horizonNode);
4860  }
4861  }
4862  _horizonVisuEnabled = false;
4863 }

◆ loadConfig()

void AppDemoGui::loadConfig ( SLint  dotsPerInch)
static

Loads the UI configuration.

Definition at line 4594 of file AppDemoGui.cpp.

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

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

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

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

4999 {
5001 
5002 #if !defined(SL_OS_MACIOS) && !defined(SL_OS_ANDROID)
5004  SLVec3f pos_f((SLfloat)pos_d.x, (SLfloat)pos_d.y, (SLfloat)pos_d.z);
5005  SLCamera* cam = sv->camera();
5006  cam->translation(pos_f);
5007  SLVec3f camToLookAt = pos_f - lookAtPoint;
5008  cam->focalDist(camToLookAt.length());
5009  cam->lookAt(lookAtPoint);
5011 #endif
5012 }
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 4783 of file AppDemoGui.cpp.

4786 {
4787  SLTransformNode* tN = s->root3D()->findChild<SLTransformNode>("Edit Gizmos");
4788 
4789  if (!tN)
4790  {
4791  tN = new SLTransformNode(sv,
4792  s->singleNodeSelected(),
4794  s->root3D()->addChild(tN);
4795  }
4796 
4797  tN->editMode(editMode);
4798  transformNode = tN;
4799 }
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 4822 of file AppDemoGui.cpp.

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

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

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