Skip to content
Merged
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
33 changes: 6 additions & 27 deletions apps/camera_lidar_calibration/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// glad function pointers are compiled into raylib; the header only declares them
#include "RendererShaders.h"
#include "external/glad.h"
#include <RaylibWidgets/PointBufferParts.h>
#include <algorithm>
#include <cmath>
#include <string>
Expand Down Expand Up @@ -134,32 +135,14 @@ void Renderer::uploadCloud(const PointCloud& cloud)
data.push_back(p.intensity);
}

cloudVAO = rlLoadVertexArray();
rlEnableVertexArray(cloudVAO);
cloudVBO = rlLoadVertexBuffer(data.data(), static_cast<int>(data.size() * sizeof(float)), false);
const int stride = 4 * sizeof(float);
// locations fixed by layout() qualifiers in both shaders
rlSetVertexAttribute(0, 3, RL_FLOAT, false, stride, 0);
rlEnableVertexAttribute(0);
rlSetVertexAttribute(1, 1, RL_FLOAT, false, stride, 3 * sizeof(float));
rlEnableVertexAttribute(1);
rlDisableVertexArray();

cloudCount = static_cast<int>(cloud.points.size());
cloudCount = cloud.points.size();
cloudParts = raylib_widgets::uploadPointBufferParts(data.data(), cloudCount, { 3, 1 });
}

void Renderer::unloadCloudGPU()
{
if (cloudVAO)
{
rlUnloadVertexArray(cloudVAO);
cloudVAO = 0;
}
if (cloudVBO)
{
rlUnloadVertexBuffer(cloudVBO);
cloudVBO = 0;
}
raylib_widgets::unloadPointBufferParts(cloudParts);
cloudCount = 0;
}

Expand Down Expand Up @@ -219,9 +202,7 @@ void Renderer::renderImageOverlay(
rlSetUniform(locPrjColorMode, &vp.colorMode, RL_SHADER_UNIFORM_INT, 1);
rlSetUniform(locPrjDecim, &vp.drawDecim, RL_SHADER_UNIFORM_INT, 1);

rlEnableVertexArray(cloudVAO);
glDrawArrays(GL_POINTS, 0, cloudCount);
rlDisableVertexArray();
raylib_widgets::drawPointBufferParts(cloudParts);
rlDisableShader();
}

Expand Down Expand Up @@ -283,9 +264,7 @@ void Renderer::draw3DCloud(
rlSetUniform(locCamTex, &slot, RL_SHADER_UNIFORM_INT, 1);
}

rlEnableVertexArray(cloudVAO);
glDrawArrays(GL_POINTS, 0, cloudCount);
rlDisableVertexArray();
raylib_widgets::drawPointBufferParts(cloudParts);
rlDisableShader();
}

Expand Down
6 changes: 3 additions & 3 deletions apps/camera_lidar_calibration/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <CalibCore/Camera.h>
#include <CalibCore/PointCloud.h>
#include <RaylibWidgets/OrbitCamera.h>
#include <RaylibWidgets/PointBufferPart.h>
#include <vector>

using namespace calib;
Expand Down Expand Up @@ -78,9 +79,8 @@ class Renderer
// GPU point cloud (VAO shared by both shaders via fixed attrib locations)
Shader pointShader = {};
bool shaderValid = false;
unsigned int cloudVAO = 0;
unsigned int cloudVBO = 0;
int cloudCount = 0;
std::vector<raylib_widgets::PointBufferPart> cloudParts;
size_t cloudCount = 0;
// 3D view shader uniforms
int locMVP = -1, locColorMode = -1, locHeightRange = -1;
int locMaxDist = -1, locOpacity = -1, locPointSize = -1, locDecim = -1;
Expand Down
42 changes: 11 additions & 31 deletions apps/camera_lidar_trajectory_viewer/TrajectoryViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <RaylibWidgets/CenterOfRotationWindow.h>
#include <RaylibWidgets/CompassRuler.h>
#include <RaylibWidgets/OrbitCamera.h>
#include <RaylibWidgets/PointBufferParts.h>
#include <RaylibWidgets/PointPicking.h>
#include <RaylibWidgets/ShortcutsTable.h>
#include <RaylibWidgets/WindowFit.h>
Expand Down Expand Up @@ -163,8 +164,8 @@ using trajectory_viewer_shaders::kVS;

struct GpuCloud
{
unsigned int vao = 0, vbo = 0;
int count = 0;
std::vector<raylib_widgets::PointBufferPart> parts;
size_t count = 0;
float maxDist = 50.f;

void upload(const std::vector<float>& data, float mx)
Expand All @@ -173,35 +174,16 @@ struct GpuCloud
if (data.empty())
return;
maxDist = mx;
vao = rlLoadVertexArray();
rlEnableVertexArray(vao);
vbo = rlLoadVertexBuffer(data.data(), (int)(data.size() * sizeof(float)), false);
const int stride = 7 * sizeof(float);
rlSetVertexAttribute(0, 3, RL_FLOAT, false, stride, 0);
rlEnableVertexAttribute(0);
rlSetVertexAttribute(1, 1, RL_FLOAT, false, stride, 3 * sizeof(float));
rlEnableVertexAttribute(1);
rlSetVertexAttribute(2, 1, RL_FLOAT, false, stride, 4 * sizeof(float));
rlEnableVertexAttribute(2);
rlSetVertexAttribute(3, 1, RL_FLOAT, false, stride, 5 * sizeof(float));
rlEnableVertexAttribute(3);
rlSetVertexAttribute(4, 1, RL_FLOAT, false, stride, 6 * sizeof(float));
rlEnableVertexAttribute(4);
rlDisableVertexArray();
count = (int)(data.size() / 7);
count = data.size() / 7;
parts = raylib_widgets::uploadPointBufferParts(data.data(), count, { 3, 1, 1, 1, 1 });
}
void draw() const
{
raylib_widgets::drawPointBufferParts(parts);
}
void unload()
{
if (vao)
{
rlUnloadVertexArray(vao);
vao = 0;
}
if (vbo)
{
rlUnloadVertexBuffer(vbo);
vbo = 0;
}
raylib_widgets::unloadPointBufferParts(parts);
count = 0;
}
};
Expand Down Expand Up @@ -1621,9 +1603,7 @@ static void drawScene(AppState& s)
rlSetUniform(s.locDecim, &s.drawDecim, RL_SHADER_UNIFORM_INT, 1);
int sel = (s.isolateCamera && s.imgViewIdx >= 0 && s.imgViewIdx < (int)s.imageTsNs.size()) ? s.imgViewIdx : -1;
rlSetUniform(s.locSel, &sel, RL_SHADER_UNIFORM_INT, 1);
rlEnableVertexArray(s.cloud.vao);
glDrawArrays(GL_POINTS, 0, s.cloud.count);
rlDisableVertexArray();
s.cloud.draw();
rlDisableShader();
}
}
Expand Down
84 changes: 59 additions & 25 deletions apps/multi_session_registration/multi_session_registration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static const std::vector<ShortcutEntry> appShortcuts = { { "Normal keys", "A", "
{ "", "L", "" },
{ "", "Ctrl+L", "Load sessions" },
{ "", "M", "" },
{ "", "Ctrl+M", "" },
{ "", "Ctrl+M", "Manual loop closure" },
{ "", "N", "" },
{ "", "Ctrl+N", "" },
{ "", "O", "" },
Expand Down Expand Up @@ -404,6 +404,15 @@ void setActiveEdge(int i)

void loop_closure_gui()
{
// Session gizmos are not drawn in this mode and would block the edge gizmo, so drop the selection.
if (index_gizmo != -1)
{
index_gizmo = -1;
old_index_gizmo = -1;
for (auto& s : sessions)
s.is_gizmo = false;
}

if (ImGui::Begin("Manual Pose Graph Loop Closure Mode", &is_loop_closure_gui, ImGuiWindowFlags_AlwaysAutoResize))
{
if (ImGui::Button("Optimize GRAPH"))
Expand Down Expand Up @@ -507,6 +516,7 @@ void loop_closure_gui()
is_session_gizmo |= s.is_gizmo;

ImGui::BeginDisabled(is_session_gizmo);
int delete_edge_index = -1;
for (int i = 0; i < (int)edges.size(); i++)
{
const auto& e = edges[i];
Expand All @@ -527,21 +537,36 @@ void loop_closure_gui()
setActiveEdge(i);
manipulate_active_edge = true;
}
ImGui::SameLine();
snprintf(buttonLabel, sizeof(buttonLabel), "Delete##%d", i);
if (ImGui::Button(buttonLabel))
delete_edge_index = i;
}
ImGui::EndDisabled();

// Deleted after the loop so the list is not modified while it is drawn. The active edge keeps pointing at
// the same edge; deleting the active edge itself leaves manipulate mode, as "remove active edge" does.
if (delete_edge_index != -1)
{
edges.erase(edges.begin() + delete_edge_index);

if (delete_edge_index == index_active_edge)
{
edge_gizmo = false;
manipulate_active_edge = false;
index_active_edge = edges.empty() ? -1 : std::clamp(delete_edge_index - 1, 0, (int)edges.size() - 1);
}
else if (delete_edge_index < index_active_edge)
{
index_active_edge--;
}
}
if (edges.size() > 0)
{
if (ImGui::Checkbox("manipulate_active_edge", &manipulate_active_edge) && manipulate_active_edge)
setActiveEdge(std::clamp(index_active_edge, 0, (int)edges.size() - 1));
if (manipulate_active_edge)
{
int remove_edge_index = -1;
if (ImGui::Button("remove active edge"))
{
edge_gizmo = false;
remove_edge_index = index_active_edge;
}

int prev_index_active_edge = index_active_edge;

if (!edge_gizmo)
Expand Down Expand Up @@ -576,20 +601,6 @@ void loop_closure_gui()
txt = "index_to: " + std::to_string(edges[index_active_edge].index_to);
ImGui::Text(txt.c_str());

if (remove_edge_index != -1)
{
std::vector<Edge> new_edges;
for (size_t i = 0; i < edges.size(); i++)
{
if (remove_edge_index != i)
new_edges.push_back(edges[i]);
}
edges = new_edges;

index_active_edge = edges.empty() ? -1 : std::clamp(remove_edge_index - 1, 0, (int)edges.size() - 1);
manipulate_active_edge = false;
}

const bool prev_gizmo = edge_gizmo;
ImGui::Checkbox("gizmo", &edge_gizmo);

Expand Down Expand Up @@ -1750,14 +1761,22 @@ bool revert_to_initial(std::vector<Session>& sessions)

bool save_results(std::vector<Session>& sessions)
{
std::string failed;
for (auto& session : sessions)
{
if (!session.is_ground_truth)
{
std::cout << "saving result to: " << session.point_clouds_container.poses_file_name << std::endl;
session.point_clouds_container.save_poses(fs::path(session.point_clouds_container.poses_file_name).string(), false);
if (!session.point_clouds_container.save_poses(fs::path(session.point_clouds_container.poses_file_name).string(), false))
failed += "'" + session.point_clouds_container.poses_file_name + "'\n";
}
}

if (!failed.empty())
{
pfd::message("Saving poses failed", "Could not write poses file(s):\n" + failed, pfd::choice::ok, pfd::icon::error);
return false;
}
return true;
}

Expand Down Expand Up @@ -2495,7 +2514,7 @@ void settings_gui()

ImGui::BeginDisabled(!sessions[i].visible);
{
ImGui::BeginDisabled(sessions[i].is_ground_truth);
ImGui::BeginDisabled(sessions[i].is_ground_truth || is_loop_closure_gui);
{
ImGui::SameLine();
if (ImGui::RadioButton(("Gizmo##" + std::to_string(i)).c_str(), &index_gizmo, i))
Expand Down Expand Up @@ -3614,6 +3633,16 @@ pose_tait_bryan_from_affine_matrix(m_src.inverse() * m_g);
io.AddKeyEvent(ImGuiKey_L, false);
io.AddKeyEvent(ImGuiMod_Ctrl, false);
}
// Same enable rule as the "Manual Loop Closure" menu item; closing is always allowed.
if (is_loop_closure_gui || number_visible_sessions == 1 || number_visible_sessions == 2)
if (io.KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_M, false))
{
is_loop_closure_gui = !is_loop_closure_gui;

// workaround
io.AddKeyEvent(ImGuiKey_M, false);
io.AddKeyEvent(ImGuiMod_Ctrl, false);
}
if (io.KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_O, false))
{
openProject();
Expand Down Expand Up @@ -3671,7 +3700,12 @@ pose_tait_bryan_from_affine_matrix(m_src.inverse() * m_g);
loadSessions();

ImGui::Separator();
if (ImGui::MenuItem("Save session poses", nullptr, nullptr, loaded_sessions && !sessions.empty()))
save_results(sessions);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
ImGui::SetTooltip("Overwrite the poses file of every session except ground truth");

ImGui::Separator();
if (ImGui::BeginMenu("Save all marked trajectories", sessions.size() > 0))
{
if (ImGui::MenuItem("Save all as las/laz files"))
Expand Down Expand Up @@ -4197,7 +4231,7 @@ pose_tait_bryan_from_affine_matrix(m_src.inverse() * m_g);

// bool prev_is_loop_closure_gui
ImGui::MenuItem(
"Manual Loop Closure", "Ctrl+L", &is_loop_closure_gui, (number_visible_sessions == 1 || number_visible_sessions == 2));
"Manual Loop Closure", "Ctrl+M", &is_loop_closure_gui, (number_visible_sessions == 1 || number_visible_sessions == 2));
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Manually connect overlapping scan sections");

Expand Down
7 changes: 4 additions & 3 deletions core/include/Core/raylib_render.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

#include "raylib.h"

#include <RaylibWidgets/PointBufferPart.h>

#include <Core/point_clouds.h>
#include <Core/session.h>

Expand Down Expand Up @@ -238,9 +240,8 @@ class ScanRenderer
private:
struct CloudGPU
{
unsigned int vao = 0;
unsigned int vbo = 0;
int count = 0;
std::vector<raylib_widgets::PointBufferPart> parts;
size_t count = 0;
Eigen::Affine3d lastPose = Eigen::Affine3d::Identity();
bool hasPose = false;
bool hasMarkColor = false;
Expand Down
Loading
Loading