Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 49 additions & 18 deletions 12_MeshLoaders/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
using device_base_t = MonoWindowApplication;
using asset_base_t = BuiltinResourcesApplication;

public:
inline MeshLoadersApp(const path& _localInputCWD, const path& _localOutputCWD, const path& _sharedInputCWD, const path& _sharedOutputCWD)
: IApplicationFramework(_localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD),
device_base_t({ 1280,720 }, EF_D32_SFLOAT, _localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD)
{
}
enum DrawBoundingBoxMode
{
DBBM_NONE,
DBBM_AABB,
DBBM_OBB,
DBBM_COUNT
};

public:
inline MeshLoadersApp(const path& _localInputCWD, const path& _localOutputCWD, const path& _sharedInputCWD, const path& _sharedOutputCWD)
: IApplicationFramework(_localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD),
device_base_t({1280,720}, EF_D32_SFLOAT, _localInputCWD, _localOutputCWD, _sharedInputCWD, _sharedOutputCWD) {}

inline bool onAppInitialized(smart_refctd_ptr<ISystem>&& system) override
{
Expand Down Expand Up @@ -171,7 +177,9 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
if (event.keyCode == E_KEY_CODE::EKC_R && event.action == SKeyboardEvent::ECA_RELEASED)
reload = true;
if (event.keyCode == E_KEY_CODE::EKC_B && event.action == SKeyboardEvent::ECA_RELEASED)
m_drawBBs = !m_drawBBs;
{
m_drawBBMode = DrawBoundingBoxMode((m_drawBBMode + 1) % DBBM_COUNT);
}
}
camera.keyboardProcess(events);
},
Expand All @@ -193,13 +201,13 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
m_renderer->render(cb,CSimpleDebugRenderer::SViewParams(viewMatrix,viewProjMatrix));
}
#ifdef NBL_BUILD_DEBUG_DRAW
if (m_drawBBs)
if (m_drawBBMode != DBBM_NONE)
{
const ISemaphore::SWaitInfo drawFinished = { .semaphore = m_semaphore.get(),.value = m_realFrameIx + 1u };
ext::debug_draw::DrawAABB::DrawParameters drawParams;
drawParams.commandBuffer = cb;
drawParams.cameraMat = viewProjMatrix;
m_drawAABB->render(drawParams, drawFinished, m_aabbInstances);
m_drawAABB->render(drawParams, drawFinished, m_drawBBMode == DBBM_OBB ? m_obbInstances : m_aabbInstances);
}
#endif
cb->endRenderPass();
Expand Down Expand Up @@ -460,6 +468,7 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
core::vector<hlsl::float32_t3x4> worldTforms;
const auto& converted = reservation.getGPUObjects<ICPUPolygonGeometry>();
m_aabbInstances.resize(converted.size());
m_obbInstances.resize(converted.size());
for (uint32_t i = 0; i < converted.size(); i++)
{
const auto& geom = converted[i];
Expand All @@ -472,18 +481,38 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
bound = hlsl::shapes::util::union_(transformed,bound);

#ifdef NBL_BUILD_DEBUG_DRAW
auto& inst = m_aabbInstances[i];

auto& aabbInst = m_aabbInstances[i];
const auto tmpAabb = shapes::AABB<3,float>(promoted.minVx, promoted.maxVx);
hlsl::float32_t3x4 instanceTransform = ext::debug_draw::DrawAABB::getTransformFromAABB(tmpAabb);

hlsl::float32_t3x4 aabbTransform = ext::debug_draw::DrawAABB::getTransformFromAABB(tmpAabb);
const auto tmpWorld = hlsl::float32_t3x4(promotedWorld);
inst.color = { 1,1,1,1 };
inst.transform[0] = tmpWorld[0];
inst.transform[1] = tmpWorld[1];
inst.transform[2] = tmpWorld[2];
inst.transform[3] = float32_t4(0, 0, 0, 1);
inst.transform = math::linalg::promoted_mul(inst.transform, instanceTransform);
const auto world4x4 = float32_t4x4{
tmpWorld[0],
tmpWorld[1],
tmpWorld[2],
float32_t4(0, 0, 0, 1)
};

aabbInst.color = { 1,1,1,1 };
aabbInst.transform = math::linalg::promoted_mul(world4x4, aabbTransform);

auto& obbInst = m_obbInstances[i];
const auto& cpuGeom = geometries[i].get();
const auto obb = CPolygonGeometryManipulator::calculateOBB({
.fetch = [geo = cpuGeom, &world4x4](size_t vertex_i) {
hlsl::float32_t3 pt;
geo->getPositionView().decodeElement(vertex_i, pt);
return pt;
},
.size = cpuGeom->getPositionView().getElementCount(),
});
obbInst.color = { 0, 0, 1, 1 };
const auto obbTransform = ext::debug_draw::DrawAABB::getTransformFromOBB(obb);
obbInst.transform = math::linalg::promoted_mul(world4x4, obbTransform);
#endif
}

printAABB(bound,"Total");
if (!m_renderer->addGeometries({ &converted.front().get(),converted.size() }))
return false;
Expand Down Expand Up @@ -543,10 +572,12 @@ class MeshLoadersApp final : public MonoWindowApplication, public BuiltinResourc
// mutables
std::string m_modelPath;

bool m_drawBBs = true;
DrawBoundingBoxMode m_drawBBMode;
#ifdef NBL_BUILD_DEBUG_DRAW
smart_refctd_ptr<ext::debug_draw::DrawAABB> m_drawAABB;
std::vector<ext::debug_draw::InstanceData> m_aabbInstances;
std::vector<ext::debug_draw::InstanceData> m_obbInstances;

#endif

bool m_saveGeom = false;
Expand Down
21 changes: 21 additions & 0 deletions 73_GeometryInspector/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
include(common RESULT_VARIABLE RES)
if(NOT RES)
message(FATAL_ERROR "common.cmake not found. Should be in {repo_root}/cmake directory")
endif()

if(NBL_BUILD_IMGUI AND NBL_BUILD_DEBUG_DRAW)
set(NBL_INCLUDE_SERACH_DIRECTORIES
"${CMAKE_CURRENT_SOURCE_DIR}/include"
)

list(APPEND NBL_LIBRARIES
imtestengine
imguizmo
"${NBL_EXT_IMGUI_UI_LIB}"
)

nbl_create_executable_project("" "" "${NBL_INCLUDE_SERACH_DIRECTORIES}" "${NBL_LIBRARIES}" "${NBL_EXECUTABLE_PROJECT_CREATION_PCH_TARGET}")

target_link_libraries(${EXECUTABLE_NAME} PRIVATE Nabla::ext::DebugDraw)
endif()

22 changes: 22 additions & 0 deletions 73_GeometryInspector/include/common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef _NBL_THIS_EXAMPLE_COMMON_H_INCLUDED_
#define _NBL_THIS_EXAMPLE_COMMON_H_INCLUDED_


#include "nbl/examples/examples.hpp"

using namespace nbl;
using namespace core;
using namespace hlsl;
using namespace system;
using namespace asset;
using namespace ui;
using namespace video;
using namespace scene;
using namespace nbl::examples;

#include "transform.hpp"
#include "nbl/ui/ICursorControl.h"
#include "nbl/ext/ImGui/ImGui.h"
#include "imgui/imgui_internal.h"

#endif // __NBL_THIS_EXAMPLE_COMMON_H_INCLUDED__
162 changes: 162 additions & 0 deletions 73_GeometryInspector/include/transform.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#ifndef _NBL_THIS_EXAMPLE_TRANSFORM_H_INCLUDED_
#define _NBL_THIS_EXAMPLE_TRANSFORM_H_INCLUDED_


#include "nbl/ui/ICursorControl.h"

#include "nbl/ext/ImGui/ImGui.h"

#include "imgui/imgui_internal.h"
#include "imguizmo/ImGuizmo.h"


struct TransformRequestParams
{
float camDistance = 8.f;
uint8_t sceneTexDescIx = ~0;
bool useWindow = false, editTransformDecomposition = false, enableViewManipulate = false;
};

nbl::hlsl::uint16_t2 EditTransform(float* cameraView, const float* cameraProjection, float* matrix, const TransformRequestParams& params)
{
static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::TRANSLATE);
static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::LOCAL);
static bool useSnap = false;
static float snap[3] = { 1.f, 1.f, 1.f };
static float bounds[] = { -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f };
static float boundsSnap[] = { 0.1f, 0.1f, 0.1f };
static bool boundSizing = false;
static bool boundSizingSnap = false;

if (params.editTransformDecomposition)
{
if (ImGui::IsKeyPressed(ImGuiKey_T))
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
if (ImGui::IsKeyPressed(ImGuiKey_R))
mCurrentGizmoOperation = ImGuizmo::ROTATE;
if (ImGui::IsKeyPressed(ImGuiKey_S))
mCurrentGizmoOperation = ImGuizmo::SCALE;
if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
ImGui::SameLine();
if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
mCurrentGizmoOperation = ImGuizmo::ROTATE;
ImGui::SameLine();
if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
mCurrentGizmoOperation = ImGuizmo::SCALE;
if (ImGui::RadioButton("Universal", mCurrentGizmoOperation == ImGuizmo::UNIVERSAL))
mCurrentGizmoOperation = ImGuizmo::UNIVERSAL;
float matrixTranslation[3], matrixRotation[3], matrixScale[3];
ImGuizmo::DecomposeMatrixToComponents(matrix, matrixTranslation, matrixRotation, matrixScale);
ImGui::InputFloat3("Tr", matrixTranslation);
ImGui::InputFloat3("Rt", matrixRotation);
ImGui::InputFloat3("Sc", matrixScale);
ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix);

if (mCurrentGizmoOperation != ImGuizmo::SCALE)
{
if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
mCurrentGizmoMode = ImGuizmo::LOCAL;
ImGui::SameLine();
if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
mCurrentGizmoMode = ImGuizmo::WORLD;
}
if (ImGui::IsKeyPressed(ImGuiKey_S) && ImGui::IsKeyPressed(ImGuiKey_LeftShift))
useSnap = !useSnap;
ImGui::Checkbox("##UseSnap", &useSnap);
ImGui::SameLine();

switch (mCurrentGizmoOperation)
{
case ImGuizmo::TRANSLATE:
ImGui::InputFloat3("Snap", &snap[0]);
break;
case ImGuizmo::ROTATE:
ImGui::InputFloat("Angle Snap", &snap[0]);
break;
case ImGuizmo::SCALE:
ImGui::InputFloat("Scale Snap", &snap[0]);
break;
}
ImGui::Checkbox("Bound Sizing", &boundSizing);
if (boundSizing)
{
ImGui::PushID(3);
ImGui::Checkbox("##BoundSizing", &boundSizingSnap);
ImGui::SameLine();
ImGui::InputFloat3("Snap", boundsSnap);
ImGui::PopID();
}
}

ImGuiIO& io = ImGui::GetIO();
float viewManipulateRight = io.DisplaySize.x;
float viewManipulateTop = 0;
static ImGuiWindowFlags gizmoWindowFlags = 0;

/*
for the "useWindow" case we just render to a gui area,
otherwise to fake full screen transparent window

note that for both cases we make sure gizmo being
rendered is aligned to our texture scene using
imgui "cursor" screen positions
*/
// TODO: this shouldn't be handled here I think
SImResourceInfo info;
info.textureID = params.sceneTexDescIx;
info.samplerIx = (uint16_t)nbl::ext::imgui::UI::DefaultSamplerIx::USER;

nbl::hlsl::uint16_t2 retval;
if (params.useWindow)
{
ImGui::SetNextWindowSize(ImVec2(800, 400), ImGuiCond_Appearing);
ImGui::SetNextWindowPos(ImVec2(400, 20), ImGuiCond_Appearing);
ImGui::PushStyleColor(ImGuiCol_WindowBg, (ImVec4)ImColor(0.35f, 0.3f, 0.3f));
ImGui::Begin("Gizmo", 0, gizmoWindowFlags);
ImGuizmo::SetDrawlist();

ImVec2 contentRegionSize = ImGui::GetContentRegionAvail();
ImVec2 windowPos = ImGui::GetWindowPos();
ImVec2 cursorPos = ImGui::GetCursorScreenPos();

ImGui::Image(info, contentRegionSize);
ImGuizmo::SetRect(cursorPos.x, cursorPos.y, contentRegionSize.x, contentRegionSize.y);
retval = {contentRegionSize.x,contentRegionSize.y};

viewManipulateRight = cursorPos.x + contentRegionSize.x;
viewManipulateTop = cursorPos.y;

ImGuiWindow* window = ImGui::GetCurrentWindow();
gizmoWindowFlags = (ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect(window->InnerRect.Min, window->InnerRect.Max) ? ImGuiWindowFlags_NoMove : 0);
}
else
{
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(io.DisplaySize);
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0)); // fully transparent fake window
ImGui::Begin("FullScreenWindow", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoInputs);

ImVec2 contentRegionSize = ImGui::GetContentRegionAvail();
ImVec2 cursorPos = ImGui::GetCursorScreenPos();

ImGui::Image(info, contentRegionSize);
ImGuizmo::SetRect(cursorPos.x, cursorPos.y, contentRegionSize.x, contentRegionSize.y);
retval = {contentRegionSize.x,contentRegionSize.y};

viewManipulateRight = cursorPos.x + contentRegionSize.x;
viewManipulateTop = cursorPos.y;
}

ImGuizmo::Manipulate(cameraView, cameraProjection, mCurrentGizmoOperation, mCurrentGizmoMode, matrix, NULL, useSnap ? &snap[0] : NULL, boundSizing ? bounds : NULL, boundSizingSnap ? boundsSnap : NULL);

if(params.enableViewManipulate)
ImGuizmo::ViewManipulate(cameraView, params.camDistance, ImVec2(viewManipulateRight - 128, viewManipulateTop), ImVec2(128, 128), 0x10101010);

ImGui::End();
ImGui::PopStyleColor();

return retval;
}

#endif // __NBL_THIS_EXAMPLE_TRANSFORM_H_INCLUDED__
Loading