Implicit surface rendering via ray tracing
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

428 lines
14 KiB

/*
* Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-FileCopyrightText: Copyright (c) 2014-2021 NVIDIA CORPORATION
* SPDX-License-Identifier: Apache-2.0
*/
//--------------------------------------------------------------------
#include <nvpwindow.hpp>
#ifdef WIN32
#include <windows.h>
#endif
#include "nvh/camerainertia.hpp"
#include "nvh/timesampler.hpp"
#include <imgui/imgui_helper.h>
#ifdef NVP_SUPPORTS_NVTOOLSEXT
#include "nvh/nsightevents.h"
#else
// Note: they are defined inside "nsightevents.h"
// but let's define them again here as empty defines for the case when NSIGHT is not needed at all
#define NX_RANGE int
#define NX_MARK(name)
#define NX_RANGESTART(name) 0
#define NX_RANGEEND(id)
#define NX_RANGEPUSH(name)
#define NX_RANGEPUSHCOL(name, c)
#define NX_RANGEPOP()
#define NXPROFILEFUNC(name)
#define NXPROFILEFUNCCOL(name, c)
#define NXPROFILEFUNCCOL2(name, c, a)
#endif
#include <map>
using std::map;
#define KEYTAU 0.10f
//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
#ifndef WIN32
struct POINT
{
int x;
int y;
};
#endif
struct ToggleInfo
{
bool* p;
bool addToUI;
std::string desc;
};
#ifdef WINDOWINERTIACAMERA_EXTERN
extern std::map<char, ToggleInfo> g_toggleMap;
#else
std::map<char, ToggleInfo> g_toggleMap;
#endif
inline void addToggleKey(char c, bool* target, const char* desc, bool addToUI = true)
{
LOGI("%s", desc);
g_toggleMap[c].desc = desc;
g_toggleMap[c].p = target;
g_toggleMap[c].addToUI = addToUI;
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
inline void DrawToggles()
{
for(auto& it : g_toggleMap)
{
if(!it.second.addToUI)
continue;
bool* pB = it.second.p;
bool prevValue = *pB;
ImGui::Checkbox(it.second.desc.c_str(), pB);
}
}
//-----------------------------------------------------------------------------
/// \class AppWindowCameraInertia
/// \brief AppWindowCameraInertia is a Window base for samples, adding a camera with inertia
///
/// It derives the Window for this sample
//-----------------------------------------------------------------------------
class AppWindowCameraInertia : public NVPWindow
{
public:
AppWindowCameraInertia(const vec3f eye = vec3f(0.0f, 1.0f, -3.0f),
const vec3f focus = vec3f(0, 0, 0),
const vec3f object = vec3f(0, 0, 0),
float fov_ = 50.0,
float near_ = 0.01f,
float far_ = 10.0)
: m_camera(eye, focus, object)
{
m_renderCnt = 1;
m_bCameraMode = true;
m_bContinue = true;
m_moveStep = 0.2f;
m_ptLastMousePosit.x = m_ptLastMousePosit.y = 0;
m_ptCurrentMousePosit.x = m_ptCurrentMousePosit.y = 0;
m_ptOriginalMousePosit.x = m_ptOriginalMousePosit.y = 0;
m_bMousing = false;
m_bRMousing = false;
m_bMMousing = false;
m_bNewTiming = false;
m_bAdjustTimeScale = true;
m_fov = fov_;
m_near = near_;
m_far = far_;
}
bool m_bCameraMode;
bool m_bContinue;
float m_moveStep;
POINT m_ptLastMousePosit;
POINT m_ptCurrentMousePosit;
POINT m_ptOriginalMousePosit;
bool m_bMousing;
bool m_bRMousing;
bool m_bMMousing;
bool m_bNewTiming;
bool m_bAdjustTimeScale;
int m_renderCnt;
TimeSampler m_realtime;
bool m_timingGlitch;
InertiaCamera m_camera;
mat4f m_projection;
float m_fov, m_near, m_far;
public:
inline mat4f& projMat() { return m_projection; }
inline mat4f& viewMat() { return m_camera.m4_view; }
inline bool& nonStopRendering() { return m_realtime.bNonStopRendering; }
bool open(int posX, int posY, int width, int height, const char* title, bool requireGLContext) override;
virtual void onWindowClose() override;
virtual void onWindowResize(int w, int h) override;
virtual void onWindowRefresh() override;
virtual void onMouseMotion(int x, int y) override;
virtual void onMouseWheel(int delta) override;
virtual void onMouseButton(NVPWindow::MouseButton button, ButtonAction action, int mods, int x, int y) override;
virtual void onKeyboard(AppWindowCameraInertia::KeyCode key, ButtonAction action, int mods, int x, int y) override;
virtual void onKeyboardChar(unsigned char key, int mods, int x, int y) override;
virtual int idle();
const char* getHelpText(int* lines = NULL)
{
if(lines)
*lines = 7;
return "Left mouse button: rotate around the target\n"
"Right mouse button: translate target forward backward (+ Y axis rotate)\n"
"Middle mouse button: Pan target along view plane\n"
"Mouse wheel or PgUp/PgDn: zoom in/out\n"
"Arrow keys: rotate around the target\n"
"Ctrl+Arrow keys: Pan target\n"
"Ctrl+PgUp/PgDn: translate target forward/backward\n";
}
};
#ifndef WINDOWINERTIACAMERA_EXTERN
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
bool AppWindowCameraInertia::open(int posX, int posY, int width, int height, const char* title, bool requireGLContext)
{
m_realtime.bNonStopRendering = true;
float r = (float)width / (float)height;
m_projection = perspective(m_fov, r, m_near, m_far);
ImGuiH::Init(width, height, this);
return NVPWindow::open(posX, posY, width, height, title, requireGLContext);
}
void AppWindowCameraInertia::onWindowClose()
{
ImGuiH::Deinit();
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
#define CAMERATAU 0.03f
void AppWindowCameraInertia::onMouseMotion(int x, int y)
{
m_ptCurrentMousePosit.x = x;
m_ptCurrentMousePosit.y = y;
if(ImGuiH::mouse_pos(x, y))
return;
//---------------------------- LEFT
if(m_bMousing)
{
float hval = 2.0f * (float)(m_ptCurrentMousePosit.x - m_ptLastMousePosit.x) / (float)getWidth();
float vval = 2.0f * (float)(m_ptCurrentMousePosit.y - m_ptLastMousePosit.y) / (float)getHeight();
m_camera.tau = CAMERATAU;
m_camera.rotateH(hval);
m_camera.rotateV(vval);
m_renderCnt++;
}
//---------------------------- MIDDLE
if(m_bMMousing)
{
float hval = 2.0f * (float)(m_ptCurrentMousePosit.x - m_ptLastMousePosit.x) / (float)getWidth();
float vval = 2.0f * (float)(m_ptCurrentMousePosit.y - m_ptLastMousePosit.y) / (float)getHeight();
m_camera.tau = CAMERATAU;
m_camera.rotateH(hval, true);
m_camera.rotateV(vval, true);
m_renderCnt++;
}
//---------------------------- RIGHT
if(m_bRMousing)
{
float hval = 2.0f * (float)(m_ptCurrentMousePosit.x - m_ptLastMousePosit.x) / (float)getWidth();
float vval = -2.0f * (float)(m_ptCurrentMousePosit.y - m_ptLastMousePosit.y) / (float)getHeight();
m_camera.tau = CAMERATAU;
m_camera.rotateH(hval, !!(getKeyModifiers() & KMOD_CONTROL));
m_camera.move(vval, !!(getKeyModifiers() & KMOD_CONTROL));
m_renderCnt++;
}
m_ptLastMousePosit.x = m_ptCurrentMousePosit.x;
m_ptLastMousePosit.y = m_ptCurrentMousePosit.y;
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void AppWindowCameraInertia::onMouseWheel(int delta)
{
if(ImGuiH::mouse_wheel(delta))
return;
m_camera.tau = KEYTAU;
m_camera.move(delta > 0 ? m_moveStep : -m_moveStep, !!(getKeyModifiers() & KMOD_CONTROL));
m_renderCnt++;
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void AppWindowCameraInertia::onMouseButton(NVPWindow::MouseButton button, NVPWindow::ButtonAction state, int mods, int x, int y)
{
if(ImGuiH::mouse_button(button, state))
return;
switch(button)
{
case NVPWindow::MOUSE_BUTTON_LEFT:
if(state == NVPWindow::BUTTON_PRESS)
{
m_renderCnt++;
// TODO: equivalent of glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED/NORMAL);
m_bMousing = true;
m_renderCnt++;
if(getKeyModifiers() & KMOD_CONTROL)
{
}
else if(getKeyModifiers() & KMOD_SHIFT)
{
}
}
else
{
m_bMousing = false;
m_renderCnt++;
}
break;
case NVPWindow::MOUSE_BUTTON_RIGHT:
if(state == NVPWindow::BUTTON_PRESS)
{
m_ptLastMousePosit.x = m_ptCurrentMousePosit.x = x;
m_ptLastMousePosit.y = m_ptCurrentMousePosit.y = y;
m_bRMousing = true;
m_renderCnt++;
if(getKeyModifiers() & KMOD_CONTROL)
{
}
}
else
{
m_bRMousing = false;
m_renderCnt++;
}
break;
case NVPWindow::MOUSE_BUTTON_MIDDLE:
if(state == NVPWindow::BUTTON_PRESS)
{
m_ptLastMousePosit.x = m_ptCurrentMousePosit.x = x;
m_ptLastMousePosit.y = m_ptCurrentMousePosit.y = y;
m_bMMousing = true;
m_renderCnt++;
}
else
{
m_bMMousing = false;
m_renderCnt++;
}
break;
}
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void AppWindowCameraInertia::onKeyboard(NVPWindow::KeyCode key, NVPWindow::ButtonAction action, int mods, int x, int y)
{
m_renderCnt++;
if(ImGuiH::key_button(key, action, mods))
return;
if(action == NVPWindow::BUTTON_RELEASE)
return;
switch(key)
{
case NVPWindow::KEY_F1:
break;
case NVPWindow::KEY_F2:
break;
case NVPWindow::KEY_F3:
case NVPWindow::KEY_F4:
case NVPWindow::KEY_F5:
case NVPWindow::KEY_F6:
case NVPWindow::KEY_F7:
case NVPWindow::KEY_F8:
case NVPWindow::KEY_F9:
case NVPWindow::KEY_F10:
case NVPWindow::KEY_F11:
break;
case NVPWindow::KEY_F12:
break;
case NVPWindow::KEY_LEFT:
m_camera.tau = KEYTAU;
m_camera.rotateH(m_moveStep, !!(getKeyModifiers() & KMOD_CONTROL));
break;
case NVPWindow::KEY_UP:
m_camera.tau = KEYTAU;
m_camera.rotateV(m_moveStep, !!(getKeyModifiers() & KMOD_CONTROL));
break;
case NVPWindow::KEY_RIGHT:
m_camera.tau = KEYTAU;
m_camera.rotateH(-m_moveStep, !!(getKeyModifiers() & KMOD_CONTROL));
break;
case NVPWindow::KEY_DOWN:
m_camera.tau = KEYTAU;
m_camera.rotateV(-m_moveStep, !!(getKeyModifiers() & KMOD_CONTROL));
break;
case NVPWindow::KEY_PAGE_UP:
m_camera.tau = KEYTAU;
m_camera.move(m_moveStep, !!(getKeyModifiers() & KMOD_CONTROL));
break;
case NVPWindow::KEY_PAGE_DOWN:
m_camera.tau = KEYTAU;
m_camera.move(-m_moveStep, !!(getKeyModifiers() & KMOD_CONTROL));
break;
case NVPWindow::KEY_ESCAPE:
close();
break;
}
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void AppWindowCameraInertia::onKeyboardChar(unsigned char key, int mods, int x, int y)
{
m_renderCnt++;
if(ImGuiH::key_char(key))
return;
// check registered toggles
auto it = g_toggleMap.find(key);
if(it != g_toggleMap.end())
{
it->second.p[0] = it->second.p[0] ? false : true;
}
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
int AppWindowCameraInertia::idle()
{
//
// Camera motion
//
m_bContinue = m_camera.update((float)m_realtime.getFrameDT());
//
// time sampling
//
m_realtime.update(m_bContinue, &m_timingGlitch);
//
// if requested: trigger again the next frame for rendering
//
if(m_bContinue || m_realtime.bNonStopRendering)
m_renderCnt++;
return m_renderCnt;
}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void AppWindowCameraInertia::onWindowRefresh() {}
//------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
void AppWindowCameraInertia::onWindowResize(int w, int h)
{
NVPWindow::onWindowResize(w, h);
auto& imgui_io = ImGui::GetIO();
imgui_io.DisplaySize = ImVec2(float(w), float(h));
float r = (float)w / (float)h;
m_projection = perspective(m_fov, r, m_near, m_far);
m_renderCnt++;
}
#endif //WINDOWINERTIACAMERA_EXTERN