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
6 changes: 3 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"clangd.arguments": [
// "--compile-commands-dir=python_examples/build",
"--compile-commands-dir=examples/build",
"--compile-commands-dir=python_bindings/build",
// "--compile-commands-dir=examples/build",
"--function-arg-placeholders=false",
"--tweaks=-Wall",
"--tweaks=-Wextra",
Expand Down Expand Up @@ -120,7 +120,7 @@
"C_Cpp.inlayHints.parameterNames.enabled": true,
"C_Cpp.inlayHints.referenceOperator.enabled": true,
"python.analysis.extraPaths": ["python_bindings/src/"],
"cmake.sourceDirectory": "/home/robert/learning/slam_dunk/examples",
"cmake.sourceDirectory": "/home/robert/projects/slam_dunk/examples",
"python.analysis.exclude": [
"**/build/",
"**/.venv/",
Expand Down
4 changes: 2 additions & 2 deletions python_bindings/src/slamd/bindings/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Scene:
def set_transform(self, path: str, transform: numpy.ndarray) -> None:
...
class Visualizer:
def __init__(self, name: str, port: typing.SupportsInt = 5555) -> None:
def __init__(self, name: str, port: typing.SupportsInt | typing.SupportsIndex = 5555) -> None:
...
def add_canvas(self, name: str, canvas: Canvas) -> None:
...
Expand All @@ -41,5 +41,5 @@ class Visualizer:
...
def scene(self, name: str) -> Scene:
...
def spawn_window(port: typing.SupportsInt = 5555, executable_path: str | None = None) -> None:
def spawn_window(port: typing.SupportsInt | typing.SupportsIndex = 5555, executable_path: str | None = None) -> None:
...
18 changes: 9 additions & 9 deletions python_bindings/src/slamd/bindings/geom.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,45 @@ import collections.abc
import numpy
import typing
__all__ = ['Arrows', 'Box', 'CameraFrustum', 'Mesh', 'Plane', 'PointCloud', 'PolyLine', 'Sphere', 'Triad']
def Arrows(starts: numpy.ndarray, ends: numpy.ndarray, colors: numpy.ndarray, thickness: typing.SupportsFloat) -> bindings._geom.Arrows:
def Arrows(starts: numpy.ndarray, ends: numpy.ndarray, colors: numpy.ndarray, thickness: typing.SupportsFloat | typing.SupportsIndex) -> bindings._geom.Arrows:
"""
Create an Arrows geometry
"""
def Box() -> bindings._geom.Box:
"""
Create a Box geometry
"""
def CameraFrustum(intrinsics_matrix: numpy.ndarray, image_width: typing.SupportsInt, image_height: typing.SupportsInt, image: numpy.ndarray | None = None, scale: typing.SupportsFloat = 1.0) -> bindings._geom.CameraFrustum:
def CameraFrustum(intrinsics_matrix: numpy.ndarray, image_width: typing.SupportsInt | typing.SupportsIndex, image_height: typing.SupportsInt | typing.SupportsIndex, image: numpy.ndarray | None = None, scale: typing.SupportsFloat | typing.SupportsIndex = 1.0) -> bindings._geom.CameraFrustum:
"""
Create a CameraFrustum geometry
"""
@typing.overload
def Mesh(vertices: numpy.ndarray, vertex_colors: numpy.ndarray, triangle_indices: collections.abc.Sequence[typing.SupportsInt]) -> bindings._geom.Mesh:
def Mesh(vertices: numpy.ndarray, vertex_colors: numpy.ndarray, triangle_indices: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex]) -> bindings._geom.Mesh:
"""
Create a SimpleMesh geometry from raw data
"""
@typing.overload
def Mesh(vertices: numpy.ndarray, vertex_colors: numpy.ndarray, triangle_indices: collections.abc.Sequence[typing.SupportsInt], vertex_normals: numpy.ndarray) -> bindings._geom.Mesh:
def Mesh(vertices: numpy.ndarray, vertex_colors: numpy.ndarray, triangle_indices: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex], vertex_normals: numpy.ndarray) -> bindings._geom.Mesh:
"""
Create a SimpleMesh geometry from raw data
"""
def Plane(normal: numpy.ndarray, point: numpy.ndarray, color: numpy.ndarray, radius: typing.SupportsFloat, alpha: typing.SupportsFloat) -> bindings._geom.Plane:
def Plane(normal: numpy.ndarray, point: numpy.ndarray, color: numpy.ndarray, radius: typing.SupportsFloat | typing.SupportsIndex, alpha: typing.SupportsFloat | typing.SupportsIndex) -> bindings._geom.Plane:
"""
Create a Plane geometry
"""
def PointCloud(positions: numpy.ndarray, colors: numpy.ndarray, radii: list[float] | numpy.ndarray, min_brightness: typing.SupportsFloat = 1.0) -> bindings._geom.PointCloud:
def PointCloud(positions: numpy.ndarray, colors: numpy.ndarray, radii: list[float] | numpy.ndarray, min_brightness: typing.SupportsFloat | typing.SupportsIndex = 1.0) -> bindings._geom.PointCloud:
"""
Create a PointCloud with per-point color and radius
"""
def PolyLine(points: numpy.ndarray, thickness: typing.SupportsFloat, color: numpy.ndarray, min_brightness: typing.SupportsFloat) -> bindings._geom.PolyLine:
def PolyLine(points: numpy.ndarray, thickness: typing.SupportsFloat | typing.SupportsIndex, color: numpy.ndarray, min_brightness: typing.SupportsFloat | typing.SupportsIndex) -> bindings._geom.PolyLine:
"""
Create a PolyLine geometry
"""
def Sphere(radius: typing.SupportsFloat = 1.0, color: numpy.ndarray = ...) -> bindings._geom.Sphere:
def Sphere(radius: typing.SupportsFloat | typing.SupportsIndex = 1.0, color: numpy.ndarray = ...) -> bindings._geom.Sphere:
"""
Create a Sphere geometry
"""
def Triad(pose: numpy.ndarray[float32[4][4]] | None = None, scale: typing.SupportsFloat = 1.0, thickness: typing.SupportsFloat = 0.10000000149011612) -> bindings._geom.Triad:
def Triad(pose: numpy.ndarray[float32[4][4]] | None = None, scale: typing.SupportsFloat | typing.SupportsIndex = 1.0, thickness: typing.SupportsFloat | typing.SupportsIndex = 0.10000000149011612) -> bindings._geom.Triad:
"""
Create a Triad geometry
"""
4 changes: 2 additions & 2 deletions python_bindings/src/slamd/bindings/geom2d.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import bindings._geom
import numpy
import typing
__all__ = ['Circles', 'Image', 'Points', 'PolyLine']
def Circles(positions: numpy.ndarray, colors: numpy.ndarray, radii: list[float] | numpy.ndarray, thickness: typing.SupportsFloat = 0.1) -> bindings._geom.Circles2D:
def Circles(positions: numpy.ndarray, colors: numpy.ndarray, radii: list[float] | numpy.ndarray, thickness: typing.SupportsFloat | typing.SupportsIndex = 0.1) -> bindings._geom.Circles2D:
"""
Create a set of circles
"""
Expand All @@ -15,7 +15,7 @@ def Points(positions: numpy.ndarray, colors: numpy.ndarray, radii: list[float] |
"""
Create 2D points with per-point color and radius
"""
def PolyLine(points: numpy.ndarray, color: numpy.ndarray, thickness: typing.SupportsFloat) -> bindings._geom.PolyLine2D:
def PolyLine(points: numpy.ndarray, color: numpy.ndarray, thickness: typing.SupportsFloat | typing.SupportsIndex) -> bindings._geom.PolyLine2D:
"""
Create a 2D poly line
"""
2 changes: 1 addition & 1 deletion python_examples/bunch_of_triads.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def random_poses(n: int, t_scale: float = 10.0) -> np.ndarray:


def main():
vis = slamd.Visualizer("poses")
vis = slamd.Visualizer("poses", port=4399)
scene = vis.scene("poses")

for i, pose_mat in enumerate(random_poses(100, 10)):
Expand Down
2 changes: 1 addition & 1 deletion slamd/include/slamd_window/frame_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class FrameBuffer {
~FrameBuffer();

uint32_t frame_texture(); // Resolved texture ID
void rescale(size_t width, size_t height);
bool rescale(size_t width, size_t height);
void bind(); // Bind MSAA FBO for rendering
void unbind(); // Unbind
void resolve(); // Blit MSAA → resolved texture
Expand Down
1 change: 1 addition & 0 deletions slamd/include/slamd_window/geom/arcball_indicator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ArcballIndicator : public Geometry {

void set_arcball_zoom(float zoom);
void interact();
bool is_animating() const;

private:
static glm::mat4 get_scale_mat(float scale);
Expand Down
2 changes: 1 addition & 1 deletion slamd/include/slamd_window/state_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class StateManager {

void try_connect(std::string ip = "127.0.0.1", ushort port = 5555);

void apply_updates();
bool apply_updates();

private:
void handle_initial_state(const slamd::flatb::InitialState* initial_state);
Expand Down
3 changes: 3 additions & 0 deletions slamd/include/slamd_window/view/view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ class View {
static std::unique_ptr<View>
deserialize(const flatb::View* view, std::shared_ptr<Tree> tree);

void mark_dirty();

public:
bool _dirty = true;
std::shared_ptr<Tree> tree;
std::unordered_map<Node*, bool> tree_open;
std::optional<std::string> visualize_glob = std::nullopt;
Expand Down
5 changes: 3 additions & 2 deletions slamd/src/window/frame_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,12 @@ void FrameBuffer::resolve() {
gl::glBindFramebuffer(gl::GL_FRAMEBUFFER, 0);
}

void FrameBuffer::rescale(
bool FrameBuffer::rescale(
size_t width,
size_t height
) {
if (width == current_width && height == current_height) {
return;
return false;
}

current_width = width;
Expand Down Expand Up @@ -211,6 +211,7 @@ void FrameBuffer::rescale(
width,
height
);
return true;
}

double FrameBuffer::aspect() const {
Expand Down
9 changes: 9 additions & 0 deletions slamd/src/window/geom/arcball_indicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ void ArcballIndicator::render(
gl::glBindVertexArray(0);
};

bool ArcballIndicator::is_animating() const {
if (!this->last_interacted.has_value()) {
return false;
}
auto now = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> secs = now - last_interacted.value();
return secs.count() < 0.4f;
}

void ArcballIndicator::set_arcball_zoom(
float zoom
) {
Expand Down
1 change: 1 addition & 0 deletions slamd/src/window/glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ GLFWwindow* make_window(
SPDLOG_INFO("GLFW window created");

glfwMakeContextCurrent(window);
glfwSwapInterval(1);

glbinding::initialize(glfwGetProcAddress);

Expand Down
36 changes: 16 additions & 20 deletions slamd/src/window/run_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <spdlog/spdlog.h>
#include <slamd_window/frame_timer.hpp>
#include <slamd_window/glfw.hpp>
#include <slamd_window/run_window.hpp>

Expand Down Expand Up @@ -109,11 +108,13 @@ inline void tree_menu(
);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
}
ImGui::InputText(
"##filter",
view->filter_buf,
IM_ARRAYSIZE(view->filter_buf)
);
if (ImGui::InputText(
"##filter",
view->filter_buf,
IM_ARRAYSIZE(view->filter_buf)
)) {
view->mark_dirty();
}
if (filter_error_text.has_value()) {
ImGui::PopStyleVar();
ImGui::PopStyleColor(4);
Expand Down Expand Up @@ -173,7 +174,9 @@ inline void tree_menu(
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, base_alpha * 0.45f);
}

ImGui::Checkbox("##visible", &n->checked);
if (ImGui::Checkbox("##visible", &n->checked)) {
view->mark_dirty();
}
ImGui::SameLine(0.0f, 4.0f);

bool open = false;
Expand Down Expand Up @@ -370,13 +373,16 @@ void run_window(

ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
FrameTimer frame_timer;
constexpr double target_frame_time = 1.0 / 120.0; // ~0.00833 seconds
bool loaded_layout = false;
bool checked_layout = false;

while (!glfwWindowShouldClose(window)) {
state_manager.apply_updates();
bool had_updates = state_manager.apply_updates();
if (had_updates) {
for (auto& [name, view] : state_manager.views) {
view->mark_dirty();
}
}

ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
Expand Down Expand Up @@ -444,16 +450,6 @@ void run_window(

glfwSwapBuffers(window);
glfwPollEvents();

frame_timer.log_frame();
float frame_time = frame_timer.timedelta();

if (frame_time < target_frame_time) {
float sleep_duration = target_frame_time - frame_time;
std::this_thread::sleep_for(
std::chrono::duration<float>(sleep_duration)
);
}
}

SPDLOG_INFO("Window closed!");
Expand Down
8 changes: 5 additions & 3 deletions slamd/src/window/state_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,19 +247,21 @@ void StateManager::handle_update_point_cloud_radii(
geom->update_radii(data);
}

void StateManager::apply_updates() {
bool StateManager::apply_updates() {
if (!this->connection.has_value()) {
return;
return false;
}

auto& connection = this->connection.value();
auto& message_queue = connection.messages;
bool had_updates = false;

while (true) {
auto maybe_message = message_queue.try_pop();
if (!maybe_message.has_value()) {
return;
return had_updates;
}
had_updates = true;
auto message = std::move(maybe_message.value());

auto message_fb = message->msg();
Expand Down
14 changes: 12 additions & 2 deletions slamd/src/window/view/canvas_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@ void CanvasView::render_to_imgui() {

int width = static_cast<int>(image_size.x);
int height = static_cast<int>(image_size.y);
this->frame_buffer.rescale(width, height);
bool resized = this->frame_buffer.rescale(width, height);

if (!this->manually_moved) {
this->set_default_pos();
} else {
this->fix_view_aspect();
}

this->render_to_frame_buffer();
bool need_render = this->_dirty || resized;

if (need_render) {
this->render_to_frame_buffer();
this->_dirty = false;
}

ImGui::Image(
(ImTextureID)this->frame_buffer.frame_texture(),
Expand Down Expand Up @@ -99,6 +104,7 @@ void CanvasView::handle_input() {
if (ImGui::IsKeyPressed(ImGuiKey_Period, false)) {
this->set_default_pos();
this->manually_moved = false;
this->mark_dirty();
}
}
}
Expand Down Expand Up @@ -127,6 +133,7 @@ void CanvasView::handle_mouse_input() {
{-mouse_drag_delta_x, -mouse_drag_delta_y}
);
this->manually_moved = true;
this->mark_dirty();
}

if (io.MouseWheel != 0.0f) {
Expand All @@ -140,6 +147,7 @@ void CanvasView::handle_mouse_input() {
);

this->manually_moved = true;
this->mark_dirty();
}
}
}
Expand Down Expand Up @@ -194,11 +202,13 @@ void CanvasView::handle_translation_input() {
if (glm::length(translation) > 1e-6f) {
this->manually_moved = true;
this->camera.translate_relative(translation);
this->mark_dirty();
}

if (glm::abs(zoom) > 1e-6f) {
this->manually_moved = true;
this->camera.zoom_relative(zoom);
this->mark_dirty();
}
}

Expand Down
Loading
Loading