diff --git a/.github/workflows/pip_publish.yml b/.github/workflows/pip_publish.yml
index 7104183f..e136e4ca 100644
--- a/.github/workflows/pip_publish.yml
+++ b/.github/workflows/pip_publish.yml
@@ -1,6 +1,7 @@
-name: Upload Python Package to PyPI when a Release is Created
+name: Build Python Wheels
on:
+ pull_request:
release:
types: [created]
@@ -13,16 +14,6 @@ jobs:
with:
submodules: recursive
- - name: Copy stuff
- run: |
- rm -rf python_bindings/vendored_deps
- rm -rf python_bindings/slamd_src
- rm -rf python_bindings/README.md
-
- cp -r vendored_deps python_bindings/vendored_deps
- cp -r slamd python_bindings/slamd_src
- cp README.md python_bindings/README.md
-
- name: Set up Python
uses: actions/setup-python@v4
with:
@@ -49,15 +40,13 @@ jobs:
libxkbcommon-devel \
mesa-libEGL-devel \
mesa-libGLES-devel
- run: |
- cd python_bindings
- cibuildwheel --output-dir dist
+ run: cibuildwheel --output-dir dist
- name: Upload Linux artifact
uses: actions/upload-artifact@v4
with:
name: dist-linux
- path: python_bindings/dist
+ path: dist
build-macos:
name: Build wheels on macOS
@@ -67,16 +56,6 @@ jobs:
with:
submodules: recursive
- - name: Copy stuff
- run: |
- rm -rf python_bindings/vendored_deps
- rm -rf python_bindings/slamd_src
- rm -rf python_bindings/README.md
-
- cp -r vendored_deps python_bindings/vendored_deps
- cp -r slamd python_bindings/slamd_src
- cp README.md python_bindings/README.md
-
- name: Set up Python
uses: actions/setup-python@v4
with:
@@ -88,20 +67,19 @@ jobs:
pip install cibuildwheel
- name: Build wheels with cibuildwheel
- run: |
- cd python_bindings
- cibuildwheel --output-dir dist
+ run: cibuildwheel --output-dir dist
- name: Upload macOS artifact
uses: actions/upload-artifact@v4
with:
name: dist-macos
- path: python_bindings/dist
+ path: dist
publish:
name: Publish to PyPI
+ if: github.event_name == 'release'
runs-on: ubuntu-latest
- needs: [build-linux, build-macos] # 🔥 waits for both builds
+ needs: [build-linux, build-macos]
environment:
name: pypi
permissions:
diff --git a/.github/workflows/test_python_build.yml b/.github/workflows/test_python_build.yml
deleted file mode 100644
index a75f638f..00000000
--- a/.github/workflows/test_python_build.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-name: Build python wheels
-
-on: [pull_request]
-
-jobs:
- build-wheels:
- name: Build wheels on ${{ matrix.os }}
- runs-on: ${{ matrix.os }}
- strategy:
- matrix:
- os: [ubuntu-latest, macos-latest]
-
- steps:
- - uses: actions/checkout@v4
- with:
- submodules: recursive
-
- - name: Copy stuff
- run: |
- rm -rf python_bindings/vendored_deps
- rm -rf python_bindings/slamd_src
- rm -rf python_bindings/README.md
-
- cp -r vendored_deps python_bindings/vendored_deps
- cp -r slamd python_bindings/slamd_src
- cp README.md python_bindings/README.md
-
- - name: Set up Python
- uses: actions/setup-python@v4
- with:
- python-version: '3.11'
-
- - name: Install build deps
- run: |
- python -m pip install --upgrade pip
- pip install cibuildwheel
-
- - name: Build wheels with cibuildwheel
- env:
- CIBW_ARCHS_LINUX: 'x86_64'
- CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
- CIBW_BEFORE_ALL_LINUX: |
- yum install -y epel-release && \
- yum install -y \
- glfw-devel \
- libX11-devel \
- libXcursor-devel \
- libXrandr-devel \
- libXinerama-devel \
- libXi-devel \
- wayland-devel \
- mesa-libEGL-devel \
- mesa-libGLES-devel \
- SDL2-devel \
- qt5-qtbase-devel \
- gtk3-devel
- run: |
- cd python_bindings
- cibuildwheel --output-dir dist
diff --git a/.gitignore b/.gitignore
index 27bec269..59ff82a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,8 @@ build/
**/*.so
**/*__pycache__
.cache/
-.testvenv/
\ No newline at end of file
+.testvenv/
+dist/
+*.egg-info/
+_skbuild/
+src/slamd/slamd_window
diff --git a/.vscode/settings.json b/.vscode/settings.json
index bb965869..d3dd6bf1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,7 +1,6 @@
{
"clangd.arguments": [
- "--compile-commands-dir=python_bindings/build",
- // "--compile-commands-dir=examples/build",
+ "--compile-commands-dir=build/cp312-cp312-linux_x86_64",
"--function-arg-placeholders=false",
"--tweaks=-Wall",
"--tweaks=-Wextra",
@@ -119,8 +118,8 @@
"C_Cpp.inlayHints.autoDeclarationTypes.showOnLeft": false,
"C_Cpp.inlayHints.parameterNames.enabled": true,
"C_Cpp.inlayHints.referenceOperator.enabled": true,
- "python.analysis.extraPaths": ["python_bindings/src/"],
- "cmake.sourceDirectory": "/home/robert/projects/slam_dunk/examples",
+ "python.analysis.extraPaths": ["src/"],
+ "cmake.sourceDirectory": "${workspaceFolder}",
"python.analysis.exclude": [
"**/build/",
"**/.venv/",
diff --git a/python_bindings/CMakeLists.txt b/CMakeLists.txt
similarity index 95%
rename from python_bindings/CMakeLists.txt
rename to CMakeLists.txt
index d0cd6038..969a65c8 100644
--- a/python_bindings/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.14)
-project(myviz_bindings LANGUAGES CXX)
+project(slamd LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
-set(LIB_DIR vendored_deps)
+set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendored_deps)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(BUILD_SHARED_LIBS OFF)
@@ -36,7 +36,7 @@ add_compile_definitions(SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_OFF)
# EXCLUDE_FROM_ALL prevents vendored deps from installing their own
# files (static archives, examples, tools) into the wheel.
-add_subdirectory(slamd_src EXCLUDE_FROM_ALL)
+add_subdirectory(slamd EXCLUDE_FROM_ALL)
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module REQUIRED)
@@ -82,7 +82,7 @@ target_link_libraries(bindings
fmt::fmt
)
-# slamd_window is excluded from ALL due to EXCLUDE_FROM_ALL on slamd_src,
+# slamd_window is excluded from ALL due to EXCLUDE_FROM_ALL on slamd,
# so we need to make bindings depend on it to ensure it gets built.
add_dependencies(bindings slamd_window)
diff --git a/README.md b/README.md
index 3e5e56c8..a094ccf2 100644
--- a/README.md
+++ b/README.md
@@ -1,125 +1,97 @@
-
+
---
-SlamDunk is a powerful and user-friendly Python library for making 3D and 2D visualizations for prototyping, data exploration, and algorithm development.
+
-It is lightweight, built using OpenGL and ImGui.
+
-# Examples
+`slamd` is a 3D visualization library for Python. `pip install`, write a few lines, and you have a GPU-accelerated interactive 3D viewer. No event loops, no boilerplate — just set geometry and it shows up.
-## Hello world
-
-Here is a simple "hello world" program for a SlamDunk visualization.
-
-```python
-import slamd
-
-if __name__ == "__main__":
- vis = slamd.Visualizer("Hello world")
-
- scene = vis.scene("scene")
-
- scene.set_object("/origin", slamd.geom.Triad())
-
- vis.hang_forever()
+```bash
+pip install slamd
```
-Running this program results in the following interactive visualization:
-
-
-This example highlights the main components of SlamDunk.
-
-The `Visualizer` object maintains the state of the visualization, and starts a TCP server that the visualization window connects to.
+## Why slamd?
-By default, it spawns a window process that reads from it and displays the visualizations. You can opt out of this with the `spawn` argument, and control the port with the `port` argument.
-In this case, you can start a window with the `slamd-window` executable:
+Most 3D visualization in Python is either painfully slow (matplotlib's 3D mode), or requires you to learn a massive framework. `slamd` is neither.
-```
-slamd-window --port [port] --ip [ip]
-```
+- **Dead simple** — create a visualizer, set geometry, done. The viewer window spawns automatically in a separate process. No event loop, no main thread hijacking, no callbacks.
+- **Real 3D rendering** — GPU-accelerated OpenGL. Handles millions of points, animated meshes, and real geometry at interactive framerates. This is not a plot library pretending to do 3D.
+- **Pose tree** — objects live in a transform tree (like ROS TF or a scene graph). Set a parent transform and everything underneath moves. Makes articulated and hierarchical scenes trivial.
+- **The right primitives** — point clouds, meshes, camera frustums, triads, arrows, polylines, spheres, planes. The stuff you actually need when working with 3D data, robotics, or SLAM.
-This client-server architecture allows launching a visualizer a remote server, and connecting to it on your local machine.
+## How is this different from Rerun?
-A `Scene` object represents and contains a tree of 3D objects, accessed by paths like `/comp1/comp2/comp3`. 3D poses and `Geometry` objects can be assigned with the `set_transform` and `set_object` methods.
+`slamd` is a **stateful viewer**, not a logging database. There's no append-only log, no timeline, no timestamps forced onto your data. You have a tree of geometry — you set objects, move them, delete them, and what you see is what's there right now.
-`Geometry` objects represent the objects that are displayed in the scene.
+Rerun is powerful, but it's a big tool with a lot of concepts. `slamd` does one thing: show your geometry, right now, with minimal API surface. If you want a data recording platform with time-series scrubbing, use Rerun. If you want to throw some geometry on screen and look at it, use `slamd`.
-## Multiple scenes
-
-SlamDunk uses ImGui to allow multiple sub-windows with floating and docking support inside the SlamDunk viewer. The following example illustrates creating two windows, each showing its own scene.
+## Quick Start
```python
import slamd
-import numpy as np
-
-if __name__ == "__main__":
- vis = slamd.Visualizer("two windows")
-
- scene1 = vis.scene("scene 1")
- scene2 = vis.scene("scene 2")
-
- scene1.set_object("/box", slamd.geom.Box())
-
- scene2.set_object("/origin", slamd.geom.Triad())
-
- scene2.set_object("/ball", slamd.geom.Sphere(2.0))
-
- sphere_transform = np.identity(4, dtype=np.float32)
- sphere_transform[:, 3] = np.array([5.0, 1.0, 2.0, 1.0])
-
- scene2.set_transform("/ball", sphere_transform)
-
- vis.hang_forever()
+vis = slamd.Visualizer("Hello world")
+scene = vis.scene("scene")
+scene.set_object("/origin", slamd.geom.Triad())
```
-The resulting window looks like this:
-
-
+
-The windows are fully controllable - you can drag them around, make tabs, use them in floating mode, or dock them to the sides like you see in the screenshot. All of this is supported by [ImGui](https://github.com/ocornut/imgui).
+That's it. A window opens with an interactive 3D view.
-Here is a slightly more elaborate example of something you can do with SlamDunk:
+Objects live in a transform tree — move a parent and children follow:
-
-
-Or this one:
+```python
+scene.set_object("/robot/camera/frustum", slamd.geom.CameraFrustum(K, w, h, scale=0.2))
+scene.set_object("/robot/lidar/cloud", slamd.geom.PointCloud(pts, colors, point_size))
-
+# Move the whole robot — camera and lidar come with it
+scene.set_transform("/robot", pose)
+```
-## Supported geometry primitives
+## Multiple Windows
-### 3D
+Create multiple scenes — each gets its own sub-window with ImGui docking. Drag, tab, float, or dock them however you like:
-- Camera Frustums (with optional image) (`slamd.geom.CameraFrustum`)
-- Arrows/Vectors (`slamd.geom.Arrows`)
-- Arbitrary meshes (`slamd.geom.Mesh`)
-- Planes (`slamd.geom.Plane`)
-- Point Clouds (`slamd.geom.PointCloud`)
-- Piecewise linear curves (`slamd.geom.PolyLine`)
-- Spheres (`slamd.geom.Sphere`)
-- Triads/reference frames (`slamd.geom.Triad`)
+```python
+vis = slamd.Visualizer("multi-view")
+scene1 = vis.scene("RGB camera")
+scene2 = vis.scene("point cloud")
-## 2D
+scene1.set_object("/frustum", slamd.geom.CameraFrustum(K, w, h, img, 1.0))
+scene2.set_object("/cloud", slamd.geom.PointCloud(pts, colors, 0.3, 0.5))
+```
-- Images (`slamd.geom2d.Image`)
-- Points (`slamd.geom2d.Points`)
-- Piecewise linear curves (`slamd.geom2d.PolyLine`)
-- Circles (`slamd.geom2d.Circles`)
+
-## Further reading
+## Geometry
-The examples in `python_examples` showcase some more features of SlamDunk. Some examples are canvases for 2D visualizations and lots of additional geometry primitives such as point clouds, meshes, camera frustums, etc.
+- Point clouds — `slamd.geom.PointCloud`
+- Meshes — `slamd.geom.Mesh`
+- Camera frustums (with image) — `slamd.geom.CameraFrustum`
+- Arrows — `slamd.geom.Arrows`
+- Polylines — `slamd.geom.PolyLine`
+- Spheres — `slamd.geom.Sphere` / `slamd.geom.Spheres`
+- Triads — `slamd.geom.Triad`
+- Planes — `slamd.geom.Plane`
+- Boxes — `slamd.geom.Box`
-# Installation
+## Installation
-Wheels are available on [PyPi](https://pypi.org/project/slamd/), so you can simply
+Wheels on [PyPI](https://pypi.org/project/slamd/) for Linux and macOS (Python >= 3.11):
```bash
pip install slamd
```
-# Contributions
+Only runtime dependency is `numpy >= 1.23`.
+
+## Examples
+
+See [examples/](./examples) for the full set.
+
+## License
-All contributions and feedback are welcome and appreciated!
+Apache 2.0 — see [LICENSE](./LICENSE).
diff --git a/examples/attractor_swarm.py b/examples/attractor_swarm.py
new file mode 100644
index 00000000..8599e5f7
--- /dev/null
+++ b/examples/attractor_swarm.py
@@ -0,0 +1,86 @@
+"""
+Aizawa attractor — thousands of particles swirling through a strange attractor.
+
+The Aizawa attractor produces a beautiful mushroom/tornado shape with particles
+spiraling around a central axis, periodically collapsing inward and exploding
+outward. With a swarm of particles you see the attractor's structure come alive.
+"""
+
+import slamd
+import time
+import numpy as np
+
+
+def aizawa_deriv(states, a=0.95, b=0.7, c=0.6, d=3.5, e=0.25, f=0.1):
+ """Vectorized Aizawa attractor derivatives for N particles."""
+ x, y, z = states[:, 0], states[:, 1], states[:, 2]
+ x2 = x * x
+ y2 = y * y
+ z2 = z * z
+ z3 = z2 * z
+
+ dx = (z - b) * x - d * y
+ dy = d * x + (z - b) * y
+ dz = c + a * z - z3 / 3.0 - (x2 + y2) * (1.0 + e * z) + f * z * x2 * x
+
+ return np.column_stack([dx, dy, dz])
+
+
+def rk4_step(states, dt):
+ k1 = aizawa_deriv(states)
+ k2 = aizawa_deriv(states + 0.5 * dt * k1)
+ k3 = aizawa_deriv(states + 0.5 * dt * k2)
+ k4 = aizawa_deriv(states + dt * k3)
+ return states + (dt / 6.0) * (k1 + 2 * k2 + 2 * k3 + k4)
+
+
+def main():
+ vis = slamd.Visualizer("Aizawa Attractor", spawn=True, port=6002)
+ scene = vis.scene("scene")
+
+ n = 50000
+ rng = np.random.default_rng(42)
+
+ # Seed all particles near the attractor with small random offsets
+ base = np.array([0.1, 0.0, 0.0])
+ states = base + rng.normal(0, 0.05, (n, 3))
+
+ # Warm up — let particles settle onto the attractor
+ dt = 0.005
+ for _ in range(200):
+ states = rk4_step(states, dt)
+
+ spheres = None
+ scale = 3.0
+
+ while True:
+ for _ in range(3):
+ states = rk4_step(states, dt)
+
+ positions = (states * scale).astype(np.float32)
+
+ # Color by angle around z-axis + height
+ angle = np.arctan2(states[:, 1], states[:, 0])
+ angle_norm = (angle + np.pi) / (2 * np.pi)
+ z_norm = np.clip((states[:, 2] + 1.5) / 3.0, 0, 1)
+
+ colors = np.column_stack([
+ 0.9 * (0.5 + 0.5 * np.sin(angle_norm * 6.28 + 0.0)),
+ 0.3 + 0.6 * z_norm,
+ 0.9 * (0.5 + 0.5 * np.sin(angle_norm * 6.28 + 2.5)),
+ ]).astype(np.float32)
+
+ radii = np.full(n, 0.025, dtype=np.float32)
+
+ if spheres is None:
+ spheres = slamd.geom.Spheres(positions, colors, radii, 0.15)
+ scene.set_object("/swarm", spheres)
+ else:
+ spheres.update_positions(positions)
+ spheres.update_colors(colors)
+
+ time.sleep(0.01)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python_examples/bunch_of_triads.py b/examples/bunch_of_triads.py
similarity index 100%
rename from python_examples/bunch_of_triads.py
rename to examples/bunch_of_triads.py
diff --git a/examples/double_pendulum.py b/examples/double_pendulum.py
new file mode 100644
index 00000000..5271903e
--- /dev/null
+++ b/examples/double_pendulum.py
@@ -0,0 +1,92 @@
+"""
+Double pendulum — chaotic motion with a fading trail.
+"""
+
+import slamd
+import numpy as np
+import time
+
+G = 9.81
+L1, L2 = 1.5, 1.5
+M1, M2 = 1.0, 1.0
+
+
+def derivs(state):
+ t1, w1, t2, w2 = state
+ delta = t1 - t2
+ sd, cd = np.sin(delta), np.cos(delta)
+ den = 2 * M1 + M2 - M2 * np.cos(2 * delta)
+
+ a1 = (-G * (2 * M1 + M2) * np.sin(t1)
+ - M2 * G * np.sin(t1 - 2 * t2)
+ - 2 * sd * M2 * (w2**2 * L2 + w1**2 * L1 * cd)) / (L1 * den)
+
+ a2 = (2 * sd * (w1**2 * L1 * (M1 + M2)
+ + G * (M1 + M2) * np.cos(t1)
+ + w2**2 * L2 * M2 * cd)) / (L2 * den)
+
+ return np.array([w1, a1, w2, a2])
+
+
+def rk4(state, dt):
+ k1 = derivs(state)
+ k2 = derivs(state + 0.5 * dt * k1)
+ k3 = derivs(state + 0.5 * dt * k2)
+ k4 = derivs(state + dt * k3)
+ return state + (dt / 6.0) * (k1 + 2 * k2 + 2 * k3 + k4)
+
+
+def angles_to_xy(t1, t2):
+ x1 = L1 * np.sin(t1)
+ y1 = -L1 * np.cos(t1)
+ x2 = x1 + L2 * np.sin(t2)
+ y2 = y1 - L2 * np.cos(t2)
+ return (x1, y1), (x2, y2)
+
+
+def main():
+ vis = slamd.Visualizer("Double Pendulum", spawn=True, port=6001)
+ scene = vis.scene("scene")
+
+ state = np.array([2.8, 0.0, 3.0, 0.0]) # high angles -> chaos
+ dt = 0.002
+ trail = []
+ max_trail = 500
+
+ spheres = None
+ arm_line = None
+ trail_line = None
+
+ while True:
+ for _ in range(10):
+ state = rk4(state, dt)
+
+ p1, p2 = angles_to_xy(state[0], state[2])
+ trail.append([p2[0], 0.0, p2[1]])
+ if len(trail) > max_trail:
+ trail = trail[-max_trail:]
+
+ positions = np.array([[p1[0], 0, p1[1]], [p2[0], 0, p2[1]]], dtype=np.float32)
+ colors = np.array([[1.0, 0.2, 0.1], [0.2, 0.6, 1.0]], dtype=np.float32)
+ radii = np.array([0.12, 0.12], dtype=np.float32)
+
+ if spheres is None:
+ spheres = slamd.geom.Spheres(positions, colors, radii, 0.3)
+ scene.set_object("/masses", spheres)
+ else:
+ spheres.update_positions(positions)
+
+ arm_pts = np.array([[0, 0, 0], [p1[0], 0, p1[1]], [p2[0], 0, p2[1]]], dtype=np.float32)
+ arm = slamd.geom.PolyLine(arm_pts, 0.04, np.array([0.9, 0.9, 0.9], dtype=np.float32), 0.5)
+ scene.set_object("/arm", arm)
+
+ if len(trail) > 2:
+ pts = np.array(trail, dtype=np.float32)
+ trail_obj = slamd.geom.PolyLine(pts, 0.02, np.array([1.0, 0.7, 0.1], dtype=np.float32), 0.3)
+ scene.set_object("/trail", trail_obj)
+
+ time.sleep(0.01)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python_examples/frustum_with_images.py b/examples/frustum_with_images.py
similarity index 96%
rename from python_examples/frustum_with_images.py
rename to examples/frustum_with_images.py
index cda1cbce..2900a513 100644
--- a/python_examples/frustum_with_images.py
+++ b/examples/frustum_with_images.py
@@ -48,7 +48,7 @@ def get_camera_intrinsics_and_image():
frustum = slamd.geom.CameraFrustum(K, width, height, img, 1.0)
- scene.set_object("/rot1/tr/rot2/cam/triad", slamd.geom.Triad(0.5))
+ scene.set_object("/rot1/tr/rot2/cam/triad", slamd.geom.Triad(scale=0.5))
scene.set_object("/rot1/tr/rot2/cam/frustum", frustum)
rot2 = np.eye(4)
@@ -61,10 +61,10 @@ def get_camera_intrinsics_and_image():
scene.set_transform("/rot1/tr", tr)
- t = 0.0
+ t0 = time.monotonic()
while True:
+ t = time.monotonic() - t0
rot1 = np.eye(4)
rot1[:3, :3] = Rotation.from_euler("z", t).as_matrix()
scene.set_transform("/rot1", rot1)
- t += 0.01
time.sleep(10 / 1000)
diff --git a/examples/galaxy.py b/examples/galaxy.py
new file mode 100644
index 00000000..bb35b361
--- /dev/null
+++ b/examples/galaxy.py
@@ -0,0 +1,78 @@
+"""
+Spiral galaxy — 150k stars in a rotating galaxy with arms, bulge, and dust.
+"""
+
+import slamd
+import numpy as np
+
+
+def make_galaxy(n: int, rng: np.random.Generator) -> tuple[np.ndarray, np.ndarray]:
+ n_bulge = n // 5
+ n_disk = n - n_bulge
+
+ # Spiral disk
+ r = rng.exponential(3.0, n_disk)
+ theta = rng.uniform(0, 2 * np.pi, n_disk)
+ # Add spiral arm structure — stars cluster around 3 arms
+ n_arms = 3
+ arm = rng.integers(0, n_arms, n_disk)
+ arm_offset = arm * (2 * np.pi / n_arms)
+ spiral_angle = arm_offset + r * 0.6 + rng.normal(0, 0.3 / (1 + r * 0.1), n_disk)
+
+ x = r * np.cos(spiral_angle)
+ y = r * np.sin(spiral_angle)
+ z = rng.normal(0, 0.1 + 0.02 * r, n_disk)
+
+ disk_pos = np.column_stack([x, y, z])
+
+ # Hot blue-white in arms, redder further out
+ arm_phase = np.cos(spiral_angle * n_arms - r * 0.6 * n_arms)
+ brightness = np.clip(0.5 + 0.5 * arm_phase, 0.2, 1.0)
+ temp = np.clip(1.0 - r / 15.0, 0.0, 1.0)
+
+ disk_colors = np.column_stack([
+ 0.9 * brightness + 0.1,
+ 0.7 * brightness * temp + 0.3 * brightness,
+ 0.9 * brightness * temp,
+ ])
+
+ # Central bulge
+ br = rng.exponential(0.8, n_bulge)
+ btheta = rng.uniform(0, 2 * np.pi, n_bulge)
+ bphi = rng.normal(0, 0.5, n_bulge)
+
+ bx = br * np.cos(btheta) * np.cos(bphi)
+ by = br * np.sin(btheta) * np.cos(bphi)
+ bz = br * np.sin(bphi) * 0.4
+
+ bulge_pos = np.column_stack([bx, by, bz])
+
+ bulge_brightness = np.clip(1.0 - br / 3.0, 0.3, 1.0)
+ bulge_colors = np.column_stack([
+ bulge_brightness,
+ bulge_brightness * 0.85,
+ bulge_brightness * 0.5,
+ ])
+
+ positions = np.concatenate([disk_pos, bulge_pos]).astype(np.float32)
+ colors = np.concatenate([disk_colors, bulge_colors]).astype(np.float32)
+
+ return positions, colors
+
+
+def main():
+ vis = slamd.Visualizer("Galaxy")
+ scene = vis.scene("scene")
+
+ n = 1_000_000
+ rng = np.random.default_rng(42)
+ positions, colors = make_galaxy(n, rng)
+
+ cloud = slamd.geom.PointCloud(positions, colors, 0.08, 0.7)
+ scene.set_object("/galaxy", cloud)
+
+ vis.hang_forever()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python_examples/hello_world.py b/examples/hello_world.py
similarity index 87%
rename from python_examples/hello_world.py
rename to examples/hello_world.py
index 2df6726a..b16f2b09 100644
--- a/python_examples/hello_world.py
+++ b/examples/hello_world.py
@@ -6,5 +6,3 @@
scene = vis.scene("scene")
scene.set_object("/origin", slamd.geom.Triad())
-
- vis.hang_forever()
diff --git a/examples/large_scale_stress_test.py b/examples/large_scale_stress_test.py
new file mode 100644
index 00000000..f564a865
--- /dev/null
+++ b/examples/large_scale_stress_test.py
@@ -0,0 +1,39 @@
+import slamd
+import numpy as np
+
+
+def main():
+ vis = slamd.Visualizer("large scale stress test")
+ scene = vis.scene("scene")
+
+ # Objects at scales of hundreds of thousands to millions
+ # Simulates e.g. millimeter-unit coordinate systems
+ scale = 500_000.0
+ triad_size = scale * 0.1
+
+ # Place triads in a grid pattern at large scale
+ for i, x in enumerate(np.linspace(-scale, scale, 5)):
+ for j, y in enumerate(np.linspace(-scale, scale, 5)):
+ pose = np.eye(4)
+ pose[0, 3] = x
+ pose[1, 3] = y
+ scene.set_object(
+ f"/triad_{i}_{j}",
+ slamd.geom.Triad(pose, triad_size),
+ )
+
+ # A big point cloud spread across the large space
+ n_points = 1000
+ points = np.random.uniform(-scale, scale, size=(n_points, 3))
+ points[:, 2] = np.abs(points[:, 2]) * 0.1 # flatten Z a bit
+ colors = np.random.uniform(0.2, 1.0, size=(n_points, 3))
+ scene.set_object(
+ "/point_cloud",
+ slamd.geom.PointCloud(points, colors, triad_size * 0.2),
+ )
+
+ vis.hang_forever()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/lorenz_attractor.py b/examples/lorenz_attractor.py
new file mode 100644
index 00000000..afeca10d
--- /dev/null
+++ b/examples/lorenz_attractor.py
@@ -0,0 +1,77 @@
+"""
+Lorenz attractor — multiple trails tracing the strange attractor with color gradients.
+
+This is a fun math demo, not representative of typical slamd usage.
+See the other examples for more practical use cases.
+"""
+
+import slamd
+import numpy as np
+import time
+
+
+def lorenz_deriv(state, sigma=10.0, rho=28.0, beta=8 / 3):
+ x, y, z = state[0], state[1], state[2]
+ return np.array([sigma * (y - x), x * (rho - z) - y, x * y - beta * z])
+
+
+def rk4_step(state, dt, sigma=10.0, rho=28.0, beta=8 / 3):
+ k1 = lorenz_deriv(state, sigma, rho, beta)
+ k2 = lorenz_deriv(state + 0.5 * dt * k1, sigma, rho, beta)
+ k3 = lorenz_deriv(state + 0.5 * dt * k2, sigma, rho, beta)
+ k4 = lorenz_deriv(state + dt * k3, sigma, rho, beta)
+ return state + (dt / 6) * (k1 + 2 * k2 + 2 * k3 + k4)
+
+
+TRAIL_COLORS = [
+ (1.0, 0.3, 0.1), # red-orange
+ (0.2, 0.7, 1.0), # sky blue
+ (1.0, 0.85, 0.1), # gold
+ (0.4, 1.0, 0.5), # mint green
+ (1.0, 0.4, 0.7), # pink
+ (0.6, 0.4, 1.0), # purple
+]
+
+
+def main():
+ vis = slamd.Visualizer("Lorenz Attractor")
+ scene = vis.scene("scene")
+
+ n_trails = 6
+ dt = 0.01
+
+ # Known point on the attractor — no pre-run needed
+ base = np.array([-6.2, -8.3, 22.0])
+ states = [base + np.array([i * 0.05, 0, 0]) for i in range(n_trails)]
+
+ max_len = 600
+ trails: list[list[np.ndarray]] = [[] for _ in range(n_trails)]
+
+ frame = 0
+ while True:
+ for _ in range(3):
+ for i in range(n_trails):
+ states[i] = rk4_step(states[i], dt)
+ trails[i].append(states[i].astype(np.float32))
+ if len(trails[i]) > max_len:
+ trails[i] = trails[i][-max_len:]
+
+ frame += 1
+ if frame % 2 != 0:
+ time.sleep(0.01)
+ continue
+
+ for i in range(n_trails):
+ if len(trails[i]) < 10:
+ continue
+ points = np.array(trails[i], dtype=np.float32)
+ r, g, b = TRAIL_COLORS[i % len(TRAIL_COLORS)]
+ color = np.array([r, g, b], dtype=np.float32)
+ polyline = slamd.geom.PolyLine(points, 0.2, color, 0.5)
+ scene.set_object(f"/trail_{i}", polyline)
+
+ time.sleep(0.01)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python_examples/lots_of_paths.py b/examples/lots_of_paths.py
similarity index 100%
rename from python_examples/lots_of_paths.py
rename to examples/lots_of_paths.py
diff --git a/python_examples/moving_mesh.py b/examples/moving_mesh.py
similarity index 97%
rename from python_examples/moving_mesh.py
rename to examples/moving_mesh.py
index 1f80728b..6db23de2 100644
--- a/python_examples/moving_mesh.py
+++ b/examples/moving_mesh.py
@@ -53,9 +53,10 @@ def main():
mesh = None
- t = 0
+ t0 = time.monotonic()
while True:
time.sleep(0.01)
+ t = time.monotonic() - t0
z = f(coords, t)
points = np.concatenate((coords, z[:, None]), axis=1)
@@ -76,7 +77,6 @@ def main():
mesh.update_positions(points)
mesh.update_colors(colors)
- t += 0.02
if __name__ == "__main__":
diff --git a/python_examples/moving_pointcloud.py b/examples/moving_pointcloud.py
similarity index 92%
rename from python_examples/moving_pointcloud.py
rename to examples/moving_pointcloud.py
index 79bfbb13..7e48789a 100644
--- a/python_examples/moving_pointcloud.py
+++ b/examples/moving_pointcloud.py
@@ -29,7 +29,7 @@ def uniform_grid_points(n: int, a: float) -> np.ndarray:
def main():
- vis = slamd.Visualizer("hello python", spawn=True, port=6000)
+ vis = slamd.Visualizer("hello python", spawn=True, port=6001)
# coords = uniform_grid_points(100000, 10.0)
coords = uniform_grid_points(100000, 30.0)
@@ -39,9 +39,10 @@ def main():
point_cloud = None
- t = 0
+ t0 = time.monotonic()
while True:
time.sleep(0.01)
+ t = time.monotonic() - t0
z = f(coords, t)
points = np.concatenate((coords, z[:, None]), axis=1)
@@ -62,8 +63,6 @@ def main():
point_cloud.update_positions(points)
point_cloud.update_colors(colors)
- t += 0.02
-
if __name__ == "__main__":
main()
diff --git a/examples/moving_spheres.py b/examples/moving_spheres.py
new file mode 100644
index 00000000..4a78641e
--- /dev/null
+++ b/examples/moving_spheres.py
@@ -0,0 +1,56 @@
+import slamd
+import time
+import numpy as np
+
+
+def uniform_grid_points(n: int, a: float) -> np.ndarray:
+ side = int(np.sqrt(n))
+ x = np.linspace(-a, a, side)
+ y = np.linspace(-a, a, side)
+ xv, yv = np.meshgrid(x, y)
+ grid = np.stack([xv.ravel(), yv.ravel()], axis=1)
+ return grid[:n]
+
+
+def main():
+ vis = slamd.Visualizer("moving spheres", spawn=True, port=6001)
+ scene = vis.scene("scene")
+
+ coords = uniform_grid_points(100000, 30.0)
+ dist = np.sqrt(coords[:, 0] ** 2 + coords[:, 1] ** 2)
+ spheres = None
+
+ t0 = time.monotonic()
+ while True:
+ time.sleep(0.01)
+ t = time.monotonic() - t0
+
+ # Calm concentric ripple
+ z = 2.0 * np.sin(dist * 0.4 - t * 1.5) * np.exp(-dist * 0.03)
+
+ points = np.column_stack(
+ [coords[:, 0], coords[:, 1], z]
+ ).astype(np.float32)
+
+ # Smooth gradient: deep blue in troughs, warm orange on peaks
+ h = (z - z.min()) / (z.max() - z.min() + 1e-8)
+ colors = np.column_stack([
+ h * 1.0,
+ h * 0.4 + 0.1,
+ (1.0 - h) * 0.8 + 0.2,
+ ]).astype(np.float32)
+
+ # Radii: gentle swell that follows the ripple outward
+ radii = (0.15 + 0.08 * np.sin(dist * 0.4 - t * 1.5)).astype(np.float32)
+
+ if spheres is None:
+ spheres = slamd.geom.Spheres(points, colors, radii, 0.3)
+ scene.set_object("/spheres", spheres)
+ else:
+ spheres.update_positions(points)
+ spheres.update_colors(colors)
+ spheres.update_radii(radii)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/noisy_sphere.py b/examples/noisy_sphere.py
new file mode 100644
index 00000000..f4a71f29
--- /dev/null
+++ b/examples/noisy_sphere.py
@@ -0,0 +1,123 @@
+import slamd
+import time
+import numpy as np
+
+
+def uv_sphere(subdivisions: int = 5) -> tuple[np.ndarray, list[int]]:
+ n_lat = 2 ** (subdivisions + 1)
+ n_lon = 2 * n_lat
+
+ vertices = []
+ indices = []
+
+ for i in range(n_lat + 1):
+ theta = np.pi * i / n_lat
+ for j in range(n_lon + 1):
+ phi = 2.0 * np.pi * j / n_lon
+ x = np.sin(theta) * np.cos(phi)
+ y = np.sin(theta) * np.sin(phi)
+ z = np.cos(theta)
+ vertices.append([x, y, z])
+
+ for i in range(n_lat):
+ for j in range(n_lon):
+ p0 = i * (n_lon + 1) + j
+ p1 = p0 + 1
+ p2 = p0 + (n_lon + 1)
+ p3 = p2 + 1
+ indices.extend([p0, p2, p1])
+ indices.extend([p1, p2, p3])
+
+ return np.array(vertices, dtype=np.float32), indices
+
+
+def snoise(positions: np.ndarray, t: float, freq: float, speed: float, phase: float = 0.0) -> np.ndarray:
+ x, y, z = positions[:, 0], positions[:, 1], positions[:, 2]
+ return (
+ np.sin(freq * x + speed * t + phase)
+ * np.sin(freq * y - 0.7 * speed * t + phase * 1.3)
+ * np.cos(freq * z + 0.3 * speed * t + phase * 0.7)
+ )
+
+
+def main():
+ vis = slamd.Visualizer("noisy sphere", port=6000)
+
+ scene = slamd.Scene()
+ vis.add_scene("scene", scene)
+
+ base_verts, indices = uv_sphere(subdivisions=5)
+ radius = 5.0
+ normals = base_verts.copy()
+
+ # Precompute spherical coords for color effects
+ theta = np.arccos(np.clip(base_verts[:, 2], -1, 1))
+ phi = np.arctan2(base_verts[:, 1], base_verts[:, 0])
+
+ mesh = None
+ t0 = time.monotonic()
+
+ while True:
+ time.sleep(0.01)
+ t = time.monotonic() - t0
+
+ # Breathing base radius
+ breath = 1.0 + 0.15 * np.sin(0.5 * t)
+
+ # Displacement: many octaves with drifting phases for chaotic feel
+ d = (
+ 0.50 * snoise(base_verts, t, freq=2.0, speed=0.8)
+ + 0.30 * snoise(base_verts, t, freq=4.0, speed=1.3, phase=np.sin(0.2 * t))
+ + 0.20 * snoise(base_verts, t, freq=7.0, speed=1.9, phase=np.cos(0.3 * t))
+ + 0.10 * snoise(base_verts, t, freq=13.0, speed=2.7, phase=t * 0.1)
+ + 0.05 * snoise(base_verts, t, freq=23.0, speed=3.5)
+ )
+
+ # Warp: let displacement feed back into itself for gnarly topology
+ warp = 0.4 * np.sin(3.0 * d + 1.5 * t)
+ d_final = d + warp
+
+ points = (radius * breath + d_final[:, None]) * normals
+
+ # --- Psychedelic color ---
+ nd = d_final / (np.abs(d_final).max() + 1e-8)
+
+ # Rotating hue based on spherical position + time
+ hue_shift = phi + 0.8 * t + 2.0 * nd
+ saturation_wave = theta * 2.0 + 0.5 * t
+
+ # HSV-ish via sine waves = trippy rainbow
+ r = 0.5 + 0.5 * np.sin(hue_shift)
+ g = 0.5 + 0.5 * np.sin(hue_shift + 2.094) # +120 deg
+ b = 0.5 + 0.5 * np.sin(hue_shift + 4.189) # +240 deg
+
+ # Iridescent shimmer tied to displacement peaks
+ shimmer = 0.4 * np.sin(10.0 * nd + 3.0 * t) * np.sin(saturation_wave)
+ r += shimmer
+ g += shimmer * 0.6
+ b -= shimmer * 0.3
+
+ # Deep glow in the valleys, hot highlights on peaks
+ glow = np.exp(-2.0 * (nd + 0.5) ** 2) # gaussian centered on valleys
+ r += 0.3 * glow * np.sin(t * 1.1)
+ g += 0.1 * glow
+ b += 0.5 * glow * np.cos(t * 0.7)
+
+ # Pulsing veins along latitude lines
+ veins = 0.3 * (np.sin(12.0 * theta + 4.0 * d + 1.5 * t) ** 8)
+ g += veins
+ r += veins * 0.3
+
+ colors = np.stack([r, g, b], axis=1).astype(np.float32)
+ np.clip(colors, 0.0, 1.0, out=colors)
+
+ if mesh is None:
+ mesh = slamd.geom.Mesh(points, colors, indices)
+ scene.set_object("/sphere", mesh)
+ else:
+ mesh.update_positions(points)
+ mesh.update_colors(colors)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python_examples/planes.py b/examples/planes.py
similarity index 100%
rename from python_examples/planes.py
rename to examples/planes.py
diff --git a/examples/spheres.py b/examples/spheres.py
new file mode 100644
index 00000000..ff8b706d
--- /dev/null
+++ b/examples/spheres.py
@@ -0,0 +1,47 @@
+import slamd
+import numpy as np
+
+
+def main():
+ vis = slamd.Visualizer("spheres example", spawn=True, port=6006)
+ scene = vis.scene("scene")
+
+ n = 500
+ rng = np.random.default_rng(42)
+
+ # Random positions on a sphere surface
+ phi = rng.uniform(0, 2 * np.pi, n)
+ cos_theta = rng.uniform(-1, 1, n)
+ theta = np.arccos(cos_theta)
+ r = 5.0
+
+ positions = np.column_stack(
+ [
+ r * np.sin(theta) * np.cos(phi),
+ r * np.sin(theta) * np.sin(phi),
+ r * np.cos(theta),
+ ]
+ ).astype(np.float32)
+
+ # Color by height
+ height_norm = (positions[:, 2] - positions[:, 2].min()) / (
+ positions[:, 2].max() - positions[:, 2].min()
+ )
+ colors = np.column_stack(
+ [
+ height_norm,
+ 0.3 * np.ones(n),
+ 1.0 - height_norm,
+ ]
+ ).astype(np.float32)
+
+ radii = rng.uniform(0.1, 0.4, n).astype(np.float32)
+
+ spheres = slamd.geom.Spheres(positions, colors, radii, 0.3)
+ scene.set_object("/spheres", spheres)
+
+ input("Press Enter to exit...")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python_examples/three_d_spiral.py b/examples/three_d_spiral.py
similarity index 92%
rename from python_examples/three_d_spiral.py
rename to examples/three_d_spiral.py
index a59ea076..7a05a70b 100644
--- a/python_examples/three_d_spiral.py
+++ b/examples/three_d_spiral.py
@@ -22,8 +22,9 @@ def cool_spiral(n: int, t: float) -> np.ndarray:
pink = np.array([212, 13, 125]) / 255
- t = 0.0
+ t0 = time.monotonic()
while True:
+ t = time.monotonic() - t0
# make spiral
coords = cool_spiral(1000, t)
max_z = coords[:, 2].max()
@@ -33,4 +34,3 @@ def cool_spiral(n: int, t: float) -> np.ndarray:
scene.set_object("/poly_line", poly_line)
time.sleep(10 / 1000)
- t += 0.05
diff --git a/examples/tree_stress_test.py b/examples/tree_stress_test.py
new file mode 100644
index 00000000..0915735b
--- /dev/null
+++ b/examples/tree_stress_test.py
@@ -0,0 +1,89 @@
+"""Stress test for the tree overlay: multiple views, deep/wide trees, long names."""
+
+import slamd
+import numpy as np
+
+
+def make_transform(x: float, y: float, z: float) -> np.ndarray:
+ T = np.eye(4, dtype=np.float32)
+ T[0, 3] = x
+ T[1, 3] = y
+ T[2, 3] = z
+ return T
+
+
+def populate_scene_deep(scene: slamd.Scene):
+ """Deep tree with varied name lengths."""
+ # A deeply nested chain
+ for depth in range(8):
+ prefix = "/deep_hierarchy"
+ for d in range(depth + 1):
+ if d % 2 == 0:
+ prefix += f"/level_{d}"
+ else:
+ prefix += f"/this_is_a_deliberately_long_name_at_level_{d}"
+
+ scene.set_object(
+ prefix + "/triad",
+ slamd.geom.Triad(make_transform(depth * 3.0, 0, 0)),
+ )
+
+ # Wide tree at one level
+ for i in range(30):
+ if i % 3 == 0:
+ name = f"/objects/short_{i}"
+ elif i % 3 == 1:
+ name = f"/objects/medium_length_object_number_{i}"
+ else:
+ name = f"/objects/this_is_object_with_a_really_long_descriptive_name_{i}"
+
+ scene.set_object(name, slamd.geom.Sphere(0.5))
+ scene.set_transform(name, make_transform(i * 2.0, 5.0, 0))
+
+ # Several mid-depth branches
+ categories = ["sensors", "actuators", "reference_frames", "debug_vis"]
+ for cat in categories:
+ for j in range(5):
+ path = f"/{cat}/unit_{j}/geometry"
+ scene.set_object(path, slamd.geom.Box())
+ scene.set_transform(
+ path,
+ make_transform(j * 2.0, -5.0 - categories.index(cat) * 3.0, 0),
+ )
+
+
+def populate_scene_wide(scene: slamd.Scene):
+ """Very wide tree with many siblings."""
+ # Flat list of many objects
+ for i in range(50):
+ scene.set_object(
+ f"/item_{i:03d}",
+ slamd.geom.Triad(make_transform(
+ (i % 10) * 3.0,
+ (i // 10) * 3.0,
+ 0,
+ )),
+ )
+
+ # A few nested groups
+ for g in range(5):
+ for sub in range(10):
+ path = f"/group_{g}/subgroup_with_longer_name_{sub}/sphere"
+ scene.set_object(path, slamd.geom.Sphere(0.3))
+ scene.set_transform(path, make_transform(g * 5.0, sub * 2.0, 5.0))
+
+
+def main():
+ vis = slamd.Visualizer("tree overlay stress test")
+
+ scene1 = vis.scene("deep tree")
+ scene2 = vis.scene("wide tree")
+
+ populate_scene_deep(scene1)
+ populate_scene_wide(scene2)
+
+ vis.hang_forever()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/two_windows.py b/examples/two_windows.py
new file mode 100644
index 00000000..68844603
--- /dev/null
+++ b/examples/two_windows.py
@@ -0,0 +1,42 @@
+"""Multiple windows — two scenes side by side."""
+
+import slamd
+import numpy as np
+
+vis = slamd.Visualizer("Two Windows")
+
+scene1 = vis.scene("camera view")
+scene2 = vis.scene("point cloud")
+
+# Scene 1: camera frustum with an image
+K = np.array([[500, 0, 320], [0, 500, 240], [0, 0, 1]], dtype=np.float64)
+w, h = 640, 480
+img = np.zeros((h, w, 3), dtype=np.uint8)
+img[:h // 2] = [140, 180, 230] # sky
+img[h // 2:] = [80, 130, 60] # ground
+
+scene1.set_object("/origin", slamd.geom.Triad())
+scene1.set_object("/cam/frustum", slamd.geom.CameraFrustum(K, w, h, img, 0.8))
+scene1.set_object("/cam/triad", slamd.geom.Triad(scale=0.3))
+
+cam_tf = np.eye(4)
+cam_tf[0, 3] = 2.0
+cam_tf[2, 3] = 1.0
+scene1.set_transform("/cam", cam_tf)
+
+# Scene 2: point cloud
+n = 50000
+rng = np.random.default_rng(42)
+theta = rng.uniform(0, 2 * np.pi, n)
+r = rng.exponential(2.0, n)
+z = rng.normal(0, 0.5, n)
+positions = np.column_stack([r * np.cos(theta), r * np.sin(theta), z]).astype(np.float32)
+
+dist = np.sqrt(positions[:, 0]**2 + positions[:, 1]**2)
+d = dist / dist.max()
+colors = np.column_stack([0.9 * d, 0.3 + 0.5 * (1 - d), 0.8 * (1 - d)]).astype(np.float32)
+
+scene2.set_object("/cloud", slamd.geom.PointCloud(positions, colors, 0.08, 0.6))
+scene2.set_object("/origin", slamd.geom.Triad())
+
+vis.hang_forever()
diff --git a/flatbuffers/geometry.fbs b/flatbuffers/geometry.fbs
index 6339faf4..fb863b4e 100644
--- a/flatbuffers/geometry.fbs
+++ b/flatbuffers/geometry.fbs
@@ -8,13 +8,6 @@ table Triad {
pose: Mat4;
}
-table Circles2D {
- positions: [Vec2];
- colors: [Vec3];
- radii: [float];
- thickness: float;
-}
-
table CameraFrustum {
intrinsics: Mat3;
image_width: uint32;
@@ -35,12 +28,6 @@ table Image {
normalized: bool;
}
-table Points2D {
- positions: [Vec2];
- colors: [Vec3];
- radii: [float];
-}
-
table Box {}
table Sphere {
@@ -62,17 +49,18 @@ table PolyLine {
min_brightness: float;
}
-table PolyLine2D {
- points: [Vec2];
- color: Vec3;
- thickness: float;
-}
-
table Mesh {
data: MeshData;
min_brightness: float;
}
+table Spheres {
+ positions: [Vec3];
+ colors: [Vec3];
+ radii: [float];
+ min_brightness: float;
+}
+
table Plane {
normal: Vec3;
point: Vec3;
@@ -83,18 +71,16 @@ table Plane {
union GeometryUnion {
triad: Triad,
- circles_2d: Circles2D,
camera_frustum: CameraFrustum,
point_cloud: PointCloud,
image: Image,
- points_2d: Points2D,
box: Box,
sphere: Sphere,
arrows: Arrows,
poly_line: PolyLine,
- poly_line_2d: PolyLine2D,
mesh: Mesh,
- plane: Plane
+ plane: Plane,
+ spheres: Spheres
}
table Geometry {
diff --git a/flatbuffers/messages.fbs b/flatbuffers/messages.fbs
index f916e0e1..8f742461 100644
--- a/flatbuffers/messages.fbs
+++ b/flatbuffers/messages.fbs
@@ -24,18 +24,18 @@ table UpdateMeshNormals {
}
-// circles2d
-table UpdateCircles2DPositions {
+// spheres
+table UpdateSpheresPositions {
object_id: ulong;
- positions: [Vec2];
+ positions: [Vec3];
}
-table UpdateCircles2DColors {
+table UpdateSpheresColors {
object_id: ulong;
colors: [Vec3];
}
-table UpdateCircles2DRadii {
+table UpdateSpheresRadii {
object_id: ulong;
radii: [float];
}
@@ -120,15 +120,15 @@ union MessageUnion {
update_mesh_colors: UpdateMeshColors,
update_mesh_normals: UpdateMeshNormals,
- // circles 2d
- update_circles2d_positions: UpdateCircles2DPositions,
- update_circles2d_colors: UpdateCircles2DColors,
- update_circles2d_radii: UpdateCircles2DRadii,
-
// point cloud
update_point_cloud_positions: UpdatePointCloudPositions,
update_point_cloud_colors: UpdatePointCloudColors,
- update_point_cloud_radii: UpdatePointCloudRadii
+ update_point_cloud_radii: UpdatePointCloudRadii,
+
+ // spheres
+ update_spheres_positions: UpdateSpheresPositions,
+ update_spheres_colors: UpdateSpheresColors,
+ update_spheres_radii: UpdateSpheresRadii
}
table Message {
diff --git a/flatbuffers/visualizer.fbs b/flatbuffers/visualizer.fbs
index 51ede966..b3243b63 100644
--- a/flatbuffers/visualizer.fbs
+++ b/flatbuffers/visualizer.fbs
@@ -20,16 +20,9 @@ table Tree {
root: Node;
}
-enum ViewType: byte {
- NONE = 0,
- CANVAS = 1,
- SCENE = 2
-}
-
table View {
name: string;
tree_id: ulong;
- view_type: ViewType;
}
table InitialState {
diff --git a/images/double_pendulum.gif b/images/double_pendulum.gif
new file mode 100644
index 00000000..8da794ed
Binary files /dev/null and b/images/double_pendulum.gif differ
diff --git a/images/moving_mesh.webm b/images/galaxy.gif
similarity index 61%
rename from images/moving_mesh.webm
rename to images/galaxy.gif
index 144d5f02..54461221 100644
Binary files a/images/moving_mesh.webm and b/images/galaxy.gif differ
diff --git a/images/spiral.gif b/images/hello_world.gif
similarity index 52%
rename from images/spiral.gif
rename to images/hello_world.gif
index 40e43f93..4fca4a38 100644
Binary files a/images/spiral.gif and b/images/hello_world.gif differ
diff --git a/images/hello_world.png b/images/hello_world.png
deleted file mode 100644
index 2a90ed27..00000000
Binary files a/images/hello_world.png and /dev/null differ
diff --git a/images/logo.png b/images/logo.png
index 3eb89c20..4688b518 100644
Binary files a/images/logo.png and b/images/logo.png differ
diff --git a/images/lorenz_attractor.gif b/images/lorenz_attractor.gif
new file mode 100644
index 00000000..054a881e
Binary files /dev/null and b/images/lorenz_attractor.gif differ
diff --git a/images/moving_mesh.gif b/images/moving_mesh.gif
deleted file mode 100644
index 398f8174..00000000
Binary files a/images/moving_mesh.gif and /dev/null differ
diff --git a/images/moving_spheres.gif b/images/moving_spheres.gif
new file mode 100644
index 00000000..3e475b29
Binary files /dev/null and b/images/moving_spheres.gif differ
diff --git a/images/palette.png b/images/palette.png
deleted file mode 100644
index 1ae2b71f..00000000
Binary files a/images/palette.png and /dev/null differ
diff --git a/images/two_scenes.png b/images/two_scenes.png
deleted file mode 100644
index 78a8a7fb..00000000
Binary files a/images/two_scenes.png and /dev/null differ
diff --git a/images/two_windows.gif b/images/two_windows.gif
new file mode 100644
index 00000000..957c7796
Binary files /dev/null and b/images/two_windows.gif differ
diff --git a/ports/slamd/portfile.cmake b/ports/slamd/portfile.cmake
deleted file mode 100644
index 44bcda12..00000000
--- a/ports/slamd/portfile.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-vcpkg_from_github(
- OUT_SOURCE_PATH REPO_ROOT
- REPO Robertleoj/slam_dunk
- REF v0.1.0
- SHA512 0
-)
-
-# for local usage
-# set(REPO_ROOT "${CMAKE_CURRENT_LIST_DIR}/../..")
-
-set(SOURCE_DIR "${REPO_ROOT}/slamd")
-
-vcpkg_cmake_configure(
- SOURCE_PATH "${SOURCE_DIR}"
-)
-
-vcpkg_cmake_install()
-
-vcpkg_cmake_config_fixup(PACKAGE_NAME "slamd")
-
-file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
-
-file(INSTALL "${REPO_ROOT}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
-
-configure_file("${SOURCE_DIR}/usage" "${CURRENT_PACKAGES_DIR}/share/${PORT}/usage" COPYONLY)
diff --git a/ports/slamd/vcpkg.json b/ports/slamd/vcpkg.json
deleted file mode 100644
index 73ae99c0..00000000
--- a/ports/slamd/vcpkg.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "slamd",
- "version-string": "0.1.0",
- "homepage": "https://github.com/Robertleoj/slam_dunk",
- "description": "3D visualization library targeted at SLAM applications",
- "license": "Apache-2.0",
- "dependencies": [
- "spdlog",
- "glbinding",
- "glfw3",
- "glm",
- {
- "name": "imgui",
- "features": [
- "glfw-binding",
- "opengl3-binding",
- "docking-experimental"
- ]
- },
- {
- "name": "vcpkg-cmake",
- "host": true
- },
- {
- "name": "vcpkg-cmake-config",
- "host": true
- }
- ]
-}
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index eae0e409..c536a306 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,14 +1,36 @@
+[build-system]
+requires = ["scikit-build-core>=0.10", "pybind11", "numpy>=1.23"]
+build-backend = "scikit_build_core.build"
+
[project]
-name = "slamd_dev_env"
-version = "0.1.0"
+name = "slamd"
+version = "3.0.0"
+description = "A 3D visualiztion library"
+authors = [{ name = "Robert Leo", email = "robert.leo.jonsson@gmail.com" }]
readme = "README.md"
requires-python = ">=3.11"
-dependencies = [
+dependencies = ["numpy>=1.23"]
+
+[project.scripts]
+slamd-window = "slamd:_window_cli"
+
+[dependency-groups]
+dev = [
"fire>=0.7.0",
"imageio>=2.37.0",
"jinja2>=3.1.6",
- "numpy>=2.2.4",
+ "numpy>=1.23",
+ "pillow>=10.0",
"pybind11>=2.13.6",
"pybind11-stubgen>=2.5.3",
+ "scikit-build-core>=0.10",
"scipy>=1.15.2",
]
+
+[tool.scikit-build]
+minimum-version = "build-system.requires"
+cmake.build-type = "MinSizeRel"
+build-dir = "build/{wheel_tag}"
+
+[tool.cibuildwheel]
+skip = ["*musllinux*", "*win*", "pp*"]
diff --git a/python_bindings/README.md b/python_bindings/README.md
deleted file mode 120000
index 32d46ee8..00000000
--- a/python_bindings/README.md
+++ /dev/null
@@ -1 +0,0 @@
-../README.md
\ No newline at end of file
diff --git a/python_bindings/pyproject.toml b/python_bindings/pyproject.toml
deleted file mode 100644
index f02323c1..00000000
--- a/python_bindings/pyproject.toml
+++ /dev/null
@@ -1,22 +0,0 @@
-[build-system]
-requires = ["scikit-build-core>=0.10", "pybind11", "numpy>=1.23"]
-build-backend = "scikit_build_core.build"
-
-[project]
-name = "slamd"
-version = "2.2.0"
-description = "Python bindings for SlamDunk"
-authors = [{ name = "Robert Leo", email = "robert.leo.jonsson@gmail.com" }]
-readme = "README.md"
-requires-python = ">=3.11"
-dependencies = ["numpy>=1.23"]
-
-[project.scripts]
-slamd-window = "slamd:_window_cli"
-
-[tool.scikit-build]
-minimum-version = "build-system.requires"
-cmake.build-type = "MinSizeRel"
-
-[tool.cibuildwheel]
-skip = ["*musllinux*", "*win*", "pp*"]
diff --git a/python_bindings/slamd_src b/python_bindings/slamd_src
deleted file mode 120000
index 605e7696..00000000
--- a/python_bindings/slamd_src
+++ /dev/null
@@ -1 +0,0 @@
-../slamd
\ No newline at end of file
diff --git a/python_bindings/src/slamd/bindings/geom2d.pyi b/python_bindings/src/slamd/bindings/geom2d.pyi
deleted file mode 100644
index 74efc652..00000000
--- a/python_bindings/src/slamd/bindings/geom2d.pyi
+++ /dev/null
@@ -1,21 +0,0 @@
-from __future__ import annotations
-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 | typing.SupportsIndex = 0.1) -> bindings._geom.Circles2D:
- """
- Create a set of circles
- """
-def Image(image: numpy.ndarray) -> bindings._geom.Image:
- """
- Create an Image geometry from a NumPy uint8 array (H, W, C)
- """
-def Points(positions: numpy.ndarray, colors: numpy.ndarray, radii: list[float] | numpy.ndarray) -> bindings._geom.Points2D:
- """
- Create 2D points with per-point color and radius
- """
-def PolyLine(points: numpy.ndarray, color: numpy.ndarray, thickness: typing.SupportsFloat | typing.SupportsIndex) -> bindings._geom.PolyLine2D:
- """
- Create a 2D poly line
- """
diff --git a/python_bindings/src/slamd/geom2d/__init__.py b/python_bindings/src/slamd/geom2d/__init__.py
deleted file mode 100644
index 2158809d..00000000
--- a/python_bindings/src/slamd/geom2d/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from ..bindings.geom2d import Image
-from .overrides import Points, PolyLine, Circles
-
-
-__all__ = ["Points", "Image", "PolyLine", "Circles"]
diff --git a/python_bindings/src/slamd/geom2d/overrides.py b/python_bindings/src/slamd/geom2d/overrides.py
deleted file mode 100644
index 61e54bb9..00000000
--- a/python_bindings/src/slamd/geom2d/overrides.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import numpy as np
-
-from .._utils.colors import Color
-from ..bindings.geom2d import (
- Points as Points_internal,
- PolyLine as PolyLine_internal,
- Circles as Circles_internal,
-)
-
-from .._utils.handle_input import process_color, process_radii, process_single_color
-
-
-def Points(
- positions: np.ndarray,
- colors: np.ndarray | tuple[int, int, int] = Color.black,
- radii: np.ndarray | float = 1.0,
-):
- """A set of 2D points.
-
- Args:
- positions: a N x 2 array of the 2D point centers.
- colors: The color of the points. Can be one of
- - array of shape N x 3 of RGB colors in (0, 1)
- - array of shape 3 with a single RGB color in (0, 1)
- - tuple an RGB value, 0-255
- radii: The radius of each point. Can be one of
- - array of shape N with a radius for each point
- - a single float specifying the radius of all the points.
- """
- n = positions.shape[0]
- colors_np = process_color(colors, n)
- radii_np = process_radii(radii, n)
-
- return Points_internal(positions, colors_np, radii_np)
-
-
-def PolyLine(
- points: np.ndarray,
- color: np.ndarray | tuple[int, int, int] = Color.pink,
- thickness: float = 1.0,
-):
- """A piecewise-linear line.
-
- Args:
- points: The points which the piecewise-linear line goes through.
- color: Either a numpy array with values in (0, 1), or an RGB tuple (0-255)
- thickness: The thickness of the line.
- """
- return PolyLine_internal(points, process_single_color(color), thickness)
-
-
-def Circles(
- positions: np.ndarray,
- colors: np.ndarray | tuple[int, int, int] = Color.dark_blue,
- radii: np.ndarray | float = 1.0,
- thickness: float = 0.1,
-):
- """A set of hollow circles.
-
- Args:
- positions: a N x 2 array of the 2D point centers.
- colors: The color of the points. Can be one of
- - array of shape N x 3 of RGB colors in (0, 1)
- - array of shape 3 with a single RGB color in (0, 1)
- - tuple an RGB value, 0-255
- radii: The radius of each point. Can be one of
- - array of shape N with a radius for each point
- - a single float specifying the radius of all the points.
- thickness: Thickness of the circle as a proportion of the radius.
- """
- n = positions.shape[0]
-
- return Circles_internal(
- positions, process_color(colors, n), process_radii(radii, n), thickness
- )
diff --git a/python_bindings/vendored_deps b/python_bindings/vendored_deps
deleted file mode 120000
index bd8758d7..00000000
--- a/python_bindings/vendored_deps
+++ /dev/null
@@ -1 +0,0 @@
-../vendored_deps
\ No newline at end of file
diff --git a/python_examples/circles.py b/python_examples/circles.py
deleted file mode 100644
index e7407df1..00000000
--- a/python_examples/circles.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import slamd
-import numpy as np
-import time
-
-
-def main():
- vis = slamd.Visualizer("🌀 Slamd Circle Rave — Juiced Edition 🌀")
- canvas = slamd.Canvas()
- vis.add_canvas("canvas", canvas)
-
- # Fewer, beefier circles
- n = 500
- positions = np.random.uniform(-500.0, 500.0, (n, 2))
- velocities = np.random.uniform(-50.0, 50.0, (n, 2))
- colors = np.zeros((n, 3))
- radii = np.random.uniform(20.0, 40.0, n) # more thicc
- base_radii = radii.copy()
- thickness = 0.1
-
- circles = slamd.geom2d.Circles(positions, colors, radii, thickness)
- canvas.set_object("/circles", circles)
-
- t = 0.0
- center = np.array([0.0, 0.0])
-
- while True:
- t += 0.016
-
- # Orbit swirl
- direction_to_center = center - positions
- distance = np.linalg.norm(direction_to_center, axis=1, keepdims=True) + 1e-6
- normalized = direction_to_center / distance
- perp = np.stack([-normalized[:, 1], normalized[:, 0]], axis=1)
- velocities += 0.5 * perp
- velocities *= 0.99
- positions += velocities * 0.016
-
- # RGB cyclone
- colors = 0.5 + 0.5 * np.stack(
- [
- np.sin(0.001 * positions[:, 0] + t),
- np.sin(0.001 * positions[:, 1] + t + 2.1),
- np.sin(0.001 * (positions[:, 0] + positions[:, 1]) + t + 4.2),
- ],
- axis=1,
- )
-
- # Pulse bigger bois
- radii = base_radii * (1.0 + 0.4 * np.sin(t * 2 + positions[:, 0] * 0.01))
-
- circles.update_positions(positions)
- circles.update_colors(colors)
- circles.update_radii(radii)
-
- time.sleep(0.016)
-
-
-if __name__ == "__main__":
- main()
diff --git a/python_examples/drawing_2d.py b/python_examples/drawing_2d.py
deleted file mode 100644
index 4e6b75b3..00000000
--- a/python_examples/drawing_2d.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import slamd
-import numpy as np
-import time
-
-
-def cool_spiral(n: int, t: float) -> np.ndarray:
- t_arr = np.linspace(0, 10 * np.pi, n) + t
- r = np.linspace(0, 1, n)
- x = r * np.cos(t_arr)
- y = r * np.sin(t_arr)
- return np.stack((x, y), axis=1)
-
-
-if __name__ == "__main__":
- vis = slamd.Visualizer("drawing_2d")
-
- canvas = slamd.Canvas()
-
- vis.add_canvas("canvas", canvas)
-
- t = 0.0
- while True:
- line_points = cool_spiral(10000, t)
-
- poly_line = slamd.geom2d.PolyLine(
- line_points,
- np.array([0.5, 0.5, 0.0]),
- 0.1,
- )
-
- canvas.set_object("/line", poly_line)
-
- time.sleep(10 / 1000)
- t += 0.05
diff --git a/python_examples/image.py b/python_examples/image.py
deleted file mode 100644
index 1a2822cb..00000000
--- a/python_examples/image.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import slamd
-import imageio.v3 as iio
-from pathlib import Path
-
-
-def main():
- vis = slamd.Visualizer("image")
-
- canvas = slamd.Canvas()
-
- image_path = Path(__file__).parent.parent / "images" / "logo.png"
-
- image = iio.imread(image_path)
-
- canvas.set_object("/image", slamd.geom2d.Image(image))
-
- vis.add_canvas("canvas", canvas)
-
- vis.hang_forever()
-
-
-if __name__ == "__main__":
- main()
diff --git a/python_examples/slamd b/python_examples/slamd
deleted file mode 120000
index a131dac0..00000000
--- a/python_examples/slamd
+++ /dev/null
@@ -1 +0,0 @@
-../python_bindings/src/slamd/
\ No newline at end of file
diff --git a/python_examples/two_windows.py b/python_examples/two_windows.py
deleted file mode 100644
index 95e1288d..00000000
--- a/python_examples/two_windows.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import slamd
-import numpy as np
-
-if __name__ == "__main__":
- vis = slamd.Visualizer("two windows")
-
- scene1 = slamd.Scene()
- scene2 = slamd.Scene()
-
- vis.add_scene("scene 1", scene1)
- scene1.set_object("/box", slamd.geom.Box())
-
- vis.add_scene("scene 2", scene2)
- scene2.set_object("/origin", slamd.geom.Triad())
-
- scene2.set_object("/ball", slamd.geom.Sphere(2.0))
-
- sphere_transform = np.identity(4, dtype=np.float32)
- sphere_transform[:, 3] = np.array([5.0, 1.0, 2.0, 1.0])
-
- scene2.set_transform("/ball", sphere_transform)
-
- vis.hang_forever()
diff --git a/scripts/record_example.sh b/scripts/record_example.sh
new file mode 100755
index 00000000..fcca70f3
--- /dev/null
+++ b/scripts/record_example.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+#
+# Record a slamd window to GIF.
+#
+# Usage: ./scripts/record_example.sh [duration_seconds] [wait_seconds]
+#
+# Example: ./scripts/record_example.sh examples/galaxy.py images/galaxy.gif 5 10
+
+set -euo pipefail
+
+EXAMPLE="${1:?Usage: record_example.sh [duration] [wait]}"
+OUTPUT="${2:?Usage: record_example.sh [duration] [wait]}"
+DURATION="${3:-5}"
+SETTLE_TIME="${4:-3}"
+FPS=30
+GIF_WIDTH=800
+
+# Start the example in background
+python3 "$EXAMPLE" &
+PY_PID=$!
+trap "kill $PY_PID 2>/dev/null" EXIT
+
+# Wait for any new window to appear, then let the scene settle
+echo "Waiting for window..."
+sleep "$SETTLE_TIME"
+
+# Find the most recently mapped window (last in the list)
+WID=$(xdotool search --onlyvisible --name "." 2>/dev/null | tail -1)
+
+if [ -z "$WID" ]; then
+ echo "ERROR: Could not find window to record"
+ exit 1
+fi
+
+echo "Found window: $(xdotool getwindowname "$WID")"
+
+# Get window geometry
+eval $(xdotool getwindowgeometry --shell "$WID")
+
+echo "Recording ${WIDTH}x${HEIGHT} at ($X,$Y) for ${DURATION}s..."
+
+# Record raw video first
+TMP_VID="/tmp/_slamd_rec.mp4"
+ffmpeg -y -loglevel warning \
+ -video_size "${WIDTH}x${HEIGHT}" -framerate "$FPS" \
+ -f x11grab -i "${DISPLAY}+${X},${Y}" \
+ -t "$DURATION" \
+ -c:v libx264 -crf 18 -preset ultrafast \
+ "$TMP_VID"
+
+kill $PY_PID 2>/dev/null || true
+
+# Generate palette
+TMP_PAL="/tmp/_slamd_palette.png"
+ffmpeg -y -loglevel warning -i "$TMP_VID" \
+ -vf "fps=$FPS,scale=$GIF_WIDTH:-1:flags=lanczos,palettegen=max_colors=128:stats_mode=diff" \
+ "$TMP_PAL"
+
+# Convert to GIF using palette
+ffmpeg -y -loglevel warning -i "$TMP_VID" -i "$TMP_PAL" \
+ -lavfi "fps=$FPS,scale=$GIF_WIDTH:-1:flags=lanczos[x];[x][1:v]paletteuse=dither=bayer:bayer_scale=3" \
+ "$OUTPUT"
+
+rm -f "$TMP_VID" "$TMP_PAL"
+echo "Saved to $OUTPUT"
diff --git a/slamd/CMakeLists.txt b/slamd/CMakeLists.txt
index 6f32bade..5a89d7d8 100644
--- a/slamd/CMakeLists.txt
+++ b/slamd/CMakeLists.txt
@@ -9,30 +9,37 @@ project(slam_dunk VERSION 0.1.0)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-set(LIB_DIR vendored_deps)
+if(NOT DEFINED LIB_DIR)
+ set(LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendored_deps)
+endif()
if(NOT TARGET glbinding::glbinding-aux)
- add_subdirectory(${LIB_DIR}/glbinding)
+ add_subdirectory(${LIB_DIR}/glbinding ${CMAKE_CURRENT_BINARY_DIR}/_deps/glbinding)
endif()
if(NOT TARGET glfw)
- add_subdirectory(${LIB_DIR}/glfw)
+ add_subdirectory(${LIB_DIR}/glfw ${CMAKE_CURRENT_BINARY_DIR}/_deps/glfw)
endif()
if(NOT TARGET spdlog::spdlog)
- add_subdirectory(${LIB_DIR}/spdlog)
+ add_subdirectory(${LIB_DIR}/spdlog ${CMAKE_CURRENT_BINARY_DIR}/_deps/spdlog)
endif()
if(NOT TARGET imgui::imgui)
- add_subdirectory(${LIB_DIR}/imgui_wrapper)
+ add_subdirectory(${LIB_DIR}/imgui_wrapper ${CMAKE_CURRENT_BINARY_DIR}/_deps/imgui_wrapper)
endif()
if(NOT TARGET fmt::fmt)
- add_subdirectory(${LIB_DIR}/fmt)
+ add_subdirectory(${LIB_DIR}/fmt ${CMAKE_CURRENT_BINARY_DIR}/_deps/fmt)
+endif()
+
+if(NOT TARGET glm::glm)
+ add_subdirectory(${LIB_DIR}/glm ${CMAKE_CURRENT_BINARY_DIR}/_deps/glm)
endif()
-add_subdirectory(${LIB_DIR}/glm)
-add_subdirectory(${LIB_DIR}/cxxopts)
+if(NOT TARGET cxxopts)
+ add_subdirectory(${LIB_DIR}/cxxopts ${CMAKE_CURRENT_BINARY_DIR}/_deps/cxxopts)
+endif()
add_subdirectory(flatb)
@@ -51,7 +58,6 @@ target_sources(
src/common/utils/mesh.cpp
src/common/gmath/aabb.cpp
- src/common/gmath/rect2d.cpp
src/common/gmath/angle.cpp
src/common/gmath/transforms.cpp
src/common/gmath/serialization.cpp
@@ -92,7 +98,6 @@ target_sources(
PRIVATE
src/window/main.cpp
- src/window/camera_2d.cpp
src/window/image_texture.cpp
src/window/glfw.cpp
src/window/frame_buffer.cpp
@@ -101,6 +106,7 @@ target_sources(
src/window/arcball.cpp
src/window/frame_timer.cpp
src/window/run_window.cpp
+ src/window/tree_overlay.cpp
src/window/state_manager.cpp
src/window/connection.cpp
src/window/message.cpp
@@ -109,11 +115,8 @@ target_sources(
src/window/tree/node.cpp
src/window/tree/tree_path.cpp
- src/window/view/view.cpp
src/window/view/scene_view.cpp
- src/window/view/canvas_view.cpp
- src/window/geom/points_2d.cpp
src/window/geom/geometry.cpp
src/window/geom/deserialize.cpp
src/window/geom/box.cpp
@@ -127,9 +130,8 @@ target_sources(
src/window/geom/image.cpp
src/window/geom/point_cloud.cpp
src/window/geom/camera_frustum.cpp
- src/window/geom/poly_line_2d.cpp
src/window/geom/mono_instanced.cpp
- src/window/geom/circles_2d.cpp
+ src/window/geom/spheres.cpp
src/window/geom/plane.cpp
)
@@ -138,8 +140,8 @@ target_include_directories(
PUBLIC
$
- $
- $
+ $
+ $
)
target_link_libraries(
@@ -185,7 +187,6 @@ target_sources(
src/slamd/tree/tree.cpp
src/slamd/tree/tree_path.cpp
- src/slamd/geom/points_2d.cpp
src/slamd/geom/geometry.cpp
src/slamd/geom/box.cpp
src/slamd/geom/mesh.cpp
@@ -197,9 +198,8 @@ target_sources(
src/slamd/geom/image.cpp
src/slamd/geom/point_cloud.cpp
src/slamd/geom/camera_frustum.cpp
- src/slamd/geom/poly_line_2d.cpp
src/slamd/geom/mono_instanced.cpp
- src/slamd/geom/circles_2d.cpp
+ src/slamd/geom/spheres.cpp
)
target_include_directories(
@@ -207,8 +207,8 @@ target_include_directories(
PUBLIC
$
- $
- $
+ $
+ $
)
target_link_libraries(
diff --git a/slamd/flatb/CMakeLists.txt b/slamd/flatb/CMakeLists.txt
index 0c1f7133..e703f450 100644
--- a/slamd/flatb/CMakeLists.txt
+++ b/slamd/flatb/CMakeLists.txt
@@ -3,7 +3,7 @@ add_compile_options(-Wno-stringop-overflow)
if (NOT TARGET flatbuffers)
set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(FLATBUFFERS_BUILD_FLATC OFF CACHE BOOL "" FORCE)
- add_subdirectory(../vendored_deps/flatbuffers ${CMAKE_CURRENT_BINARY_DIR}/_deps/flatbuffers)
+ add_subdirectory(${LIB_DIR}/flatbuffers ${CMAKE_CURRENT_BINARY_DIR}/_deps/flatbuffers)
endif()
# Grab all .cpp and .h/.hpp files in current dir
diff --git a/slamd/flatb/flatb/geometry_generated.h b/slamd/flatb/flatb/geometry_generated.h
index 3f63ca65..c27f34b9 100644
--- a/slamd/flatb/flatb/geometry_generated.h
+++ b/slamd/flatb/flatb/geometry_generated.h
@@ -21,9 +21,6 @@ namespace flatb {
struct Triad;
struct TriadBuilder;
-struct Circles2D;
-struct Circles2DBuilder;
-
struct CameraFrustum;
struct CameraFrustumBuilder;
@@ -33,9 +30,6 @@ struct PointCloudBuilder;
struct Image;
struct ImageBuilder;
-struct Points2D;
-struct Points2DBuilder;
-
struct Box;
struct BoxBuilder;
@@ -48,12 +42,12 @@ struct ArrowsBuilder;
struct PolyLine;
struct PolyLineBuilder;
-struct PolyLine2D;
-struct PolyLine2DBuilder;
-
struct Mesh;
struct MeshBuilder;
+struct Spheres;
+struct SpheresBuilder;
+
struct Plane;
struct PlaneBuilder;
@@ -63,65 +57,59 @@ struct GeometryBuilder;
enum GeometryUnion : uint8_t {
GeometryUnion_NONE = 0,
GeometryUnion_triad = 1,
- GeometryUnion_circles_2d = 2,
- GeometryUnion_camera_frustum = 3,
- GeometryUnion_point_cloud = 4,
- GeometryUnion_image = 5,
- GeometryUnion_points_2d = 6,
- GeometryUnion_box = 7,
- GeometryUnion_sphere = 8,
- GeometryUnion_arrows = 9,
- GeometryUnion_poly_line = 10,
- GeometryUnion_poly_line_2d = 11,
- GeometryUnion_mesh = 12,
- GeometryUnion_plane = 13,
+ GeometryUnion_camera_frustum = 2,
+ GeometryUnion_point_cloud = 3,
+ GeometryUnion_image = 4,
+ GeometryUnion_box = 5,
+ GeometryUnion_sphere = 6,
+ GeometryUnion_arrows = 7,
+ GeometryUnion_poly_line = 8,
+ GeometryUnion_mesh = 9,
+ GeometryUnion_plane = 10,
+ GeometryUnion_spheres = 11,
GeometryUnion_MIN = GeometryUnion_NONE,
- GeometryUnion_MAX = GeometryUnion_plane
+ GeometryUnion_MAX = GeometryUnion_spheres
};
-inline const GeometryUnion (&EnumValuesGeometryUnion())[14] {
+inline const GeometryUnion (&EnumValuesGeometryUnion())[12] {
static const GeometryUnion values[] = {
GeometryUnion_NONE,
GeometryUnion_triad,
- GeometryUnion_circles_2d,
GeometryUnion_camera_frustum,
GeometryUnion_point_cloud,
GeometryUnion_image,
- GeometryUnion_points_2d,
GeometryUnion_box,
GeometryUnion_sphere,
GeometryUnion_arrows,
GeometryUnion_poly_line,
- GeometryUnion_poly_line_2d,
GeometryUnion_mesh,
- GeometryUnion_plane
+ GeometryUnion_plane,
+ GeometryUnion_spheres
};
return values;
}
inline const char * const *EnumNamesGeometryUnion() {
- static const char * const names[15] = {
+ static const char * const names[13] = {
"NONE",
"triad",
- "circles_2d",
"camera_frustum",
"point_cloud",
"image",
- "points_2d",
"box",
"sphere",
"arrows",
"poly_line",
- "poly_line_2d",
"mesh",
"plane",
+ "spheres",
nullptr
};
return names;
}
inline const char *EnumNameGeometryUnion(GeometryUnion e) {
- if (::flatbuffers::IsOutRange(e, GeometryUnion_NONE, GeometryUnion_plane)) return "";
+ if (::flatbuffers::IsOutRange(e, GeometryUnion_NONE, GeometryUnion_spheres)) return "";
const size_t index = static_cast(e);
return EnumNamesGeometryUnion()[index];
}
@@ -134,10 +122,6 @@ template<> struct GeometryUnionTraits {
static const GeometryUnion enum_value = GeometryUnion_triad;
};
-template<> struct GeometryUnionTraits {
- static const GeometryUnion enum_value = GeometryUnion_circles_2d;
-};
-
template<> struct GeometryUnionTraits {
static const GeometryUnion enum_value = GeometryUnion_camera_frustum;
};
@@ -150,10 +134,6 @@ template<> struct GeometryUnionTraits {
static const GeometryUnion enum_value = GeometryUnion_image;
};
-template<> struct GeometryUnionTraits {
- static const GeometryUnion enum_value = GeometryUnion_points_2d;
-};
-
template<> struct GeometryUnionTraits {
static const GeometryUnion enum_value = GeometryUnion_box;
};
@@ -170,10 +150,6 @@ template<> struct GeometryUnionTraits {
static const GeometryUnion enum_value = GeometryUnion_poly_line;
};
-template<> struct GeometryUnionTraits {
- static const GeometryUnion enum_value = GeometryUnion_poly_line_2d;
-};
-
template<> struct GeometryUnionTraits {
static const GeometryUnion enum_value = GeometryUnion_mesh;
};
@@ -182,6 +158,10 @@ template<> struct GeometryUnionTraits {
static const GeometryUnion enum_value = GeometryUnion_plane;
};
+template<> struct GeometryUnionTraits {
+ static const GeometryUnion enum_value = GeometryUnion_spheres;
+};
+
bool VerifyGeometryUnion(::flatbuffers::Verifier &verifier, const void *obj, GeometryUnion type);
bool VerifyGeometryUnionVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types);
@@ -246,97 +226,6 @@ inline ::flatbuffers::Offset CreateTriad(
return builder_.Finish();
}
-struct Circles2D FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
- typedef Circles2DBuilder Builder;
- enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
- VT_POSITIONS = 4,
- VT_COLORS = 6,
- VT_RADII = 8,
- VT_THICKNESS = 10
- };
- const ::flatbuffers::Vector *positions() const {
- return GetPointer *>(VT_POSITIONS);
- }
- const ::flatbuffers::Vector *colors() const {
- return GetPointer *>(VT_COLORS);
- }
- const ::flatbuffers::Vector *radii() const {
- return GetPointer *>(VT_RADII);
- }
- float thickness() const {
- return GetField(VT_THICKNESS, 0.0f);
- }
- bool Verify(::flatbuffers::Verifier &verifier) const {
- return VerifyTableStart(verifier) &&
- VerifyOffset(verifier, VT_POSITIONS) &&
- verifier.VerifyVector(positions()) &&
- VerifyOffset(verifier, VT_COLORS) &&
- verifier.VerifyVector(colors()) &&
- VerifyOffset(verifier, VT_RADII) &&
- verifier.VerifyVector(radii()) &&
- VerifyField(verifier, VT_THICKNESS, 4) &&
- verifier.EndTable();
- }
-};
-
-struct Circles2DBuilder {
- typedef Circles2D Table;
- ::flatbuffers::FlatBufferBuilder &fbb_;
- ::flatbuffers::uoffset_t start_;
- void add_positions(::flatbuffers::Offset<::flatbuffers::Vector> positions) {
- fbb_.AddOffset(Circles2D::VT_POSITIONS, positions);
- }
- void add_colors(::flatbuffers::Offset<::flatbuffers::Vector> colors) {
- fbb_.AddOffset(Circles2D::VT_COLORS, colors);
- }
- void add_radii(::flatbuffers::Offset<::flatbuffers::Vector> radii) {
- fbb_.AddOffset(Circles2D::VT_RADII, radii);
- }
- void add_thickness(float thickness) {
- fbb_.AddElement(Circles2D::VT_THICKNESS, thickness, 0.0f);
- }
- explicit Circles2DBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
- : fbb_(_fbb) {
- start_ = fbb_.StartTable();
- }
- ::flatbuffers::Offset Finish() {
- const auto end = fbb_.EndTable(start_);
- auto o = ::flatbuffers::Offset(end);
- return o;
- }
-};
-
-inline ::flatbuffers::Offset CreateCircles2D(
- ::flatbuffers::FlatBufferBuilder &_fbb,
- ::flatbuffers::Offset<::flatbuffers::Vector> positions = 0,
- ::flatbuffers::Offset<::flatbuffers::Vector> colors = 0,
- ::flatbuffers::Offset<::flatbuffers::Vector> radii = 0,
- float thickness = 0.0f) {
- Circles2DBuilder builder_(_fbb);
- builder_.add_thickness(thickness);
- builder_.add_radii(radii);
- builder_.add_colors(colors);
- builder_.add_positions(positions);
- return builder_.Finish();
-}
-
-inline ::flatbuffers::Offset CreateCircles2DDirect(
- ::flatbuffers::FlatBufferBuilder &_fbb,
- const std::vector *positions = nullptr,
- const std::vector *colors = nullptr,
- const std::vector *radii = nullptr,
- float thickness = 0.0f) {
- auto positions__ = positions ? _fbb.CreateVectorOfStructs(*positions) : 0;
- auto colors__ = colors ? _fbb.CreateVectorOfStructs(*colors) : 0;
- auto radii__ = radii ? _fbb.CreateVector(*radii) : 0;
- return slamd::flatb::CreateCircles2D(
- _fbb,
- positions__,
- colors__,
- radii__,
- thickness);
-}
-
struct CameraFrustum FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef CameraFrustumBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
@@ -562,85 +451,6 @@ inline ::flatbuffers::Offset CreateImage(
return builder_.Finish();
}
-struct Points2D FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
- typedef Points2DBuilder Builder;
- enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
- VT_POSITIONS = 4,
- VT_COLORS = 6,
- VT_RADII = 8
- };
- const ::flatbuffers::Vector *positions() const {
- return GetPointer *>(VT_POSITIONS);
- }
- const ::flatbuffers::Vector *colors() const {
- return GetPointer *>(VT_COLORS);
- }
- const ::flatbuffers::Vector *radii() const {
- return GetPointer *>(VT_RADII);
- }
- bool Verify(::flatbuffers::Verifier &verifier) const {
- return VerifyTableStart(verifier) &&
- VerifyOffset(verifier, VT_POSITIONS) &&
- verifier.VerifyVector(positions()) &&
- VerifyOffset(verifier, VT_COLORS) &&
- verifier.VerifyVector(colors()) &&
- VerifyOffset(verifier, VT_RADII) &&
- verifier.VerifyVector(radii()) &&
- verifier.EndTable();
- }
-};
-
-struct Points2DBuilder {
- typedef Points2D Table;
- ::flatbuffers::FlatBufferBuilder &fbb_;
- ::flatbuffers::uoffset_t start_;
- void add_positions(::flatbuffers::Offset<::flatbuffers::Vector> positions) {
- fbb_.AddOffset(Points2D::VT_POSITIONS, positions);
- }
- void add_colors(::flatbuffers::Offset<::flatbuffers::Vector> colors) {
- fbb_.AddOffset(Points2D::VT_COLORS, colors);
- }
- void add_radii(::flatbuffers::Offset<::flatbuffers::Vector> radii) {
- fbb_.AddOffset(Points2D::VT_RADII, radii);
- }
- explicit Points2DBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
- : fbb_(_fbb) {
- start_ = fbb_.StartTable();
- }
- ::flatbuffers::Offset Finish() {
- const auto end = fbb_.EndTable(start_);
- auto o = ::flatbuffers::Offset(end);
- return o;
- }
-};
-
-inline ::flatbuffers::Offset CreatePoints2D(
- ::flatbuffers::FlatBufferBuilder &_fbb,
- ::flatbuffers::Offset<::flatbuffers::Vector> positions = 0,
- ::flatbuffers::Offset<::flatbuffers::Vector> colors = 0,
- ::flatbuffers::Offset<::flatbuffers::Vector> radii = 0) {
- Points2DBuilder builder_(_fbb);
- builder_.add_radii(radii);
- builder_.add_colors(colors);
- builder_.add_positions(positions);
- return builder_.Finish();
-}
-
-inline ::flatbuffers::Offset CreatePoints2DDirect(
- ::flatbuffers::FlatBufferBuilder &_fbb,
- const std::vector *positions = nullptr,
- const std::vector *colors = nullptr,
- const std::vector *radii = nullptr) {
- auto positions__ = positions ? _fbb.CreateVectorOfStructs(*positions) : 0;
- auto colors__ = colors ? _fbb.CreateVectorOfStructs(*colors) : 0;
- auto radii__ = radii ? _fbb.CreateVector(*radii) : 0;
- return slamd::flatb::CreatePoints2D(
- _fbb,
- positions__,
- colors__,
- radii__);
-}
-
struct Box FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef BoxBuilder Builder;
bool Verify(::flatbuffers::Verifier &verifier) const {
@@ -899,133 +709,149 @@ inline ::flatbuffers::Offset CreatePolyLineDirect(
min_brightness);
}
-struct PolyLine2D FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
- typedef PolyLine2DBuilder Builder;
+struct Mesh FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+ typedef MeshBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
- VT_POINTS = 4,
- VT_COLOR = 6,
- VT_THICKNESS = 8
+ VT_DATA = 4,
+ VT_MIN_BRIGHTNESS = 6
};
- const ::flatbuffers::Vector *points() const {
- return GetPointer *>(VT_POINTS);
- }
- const slamd::flatb::Vec3 *color() const {
- return GetStruct(VT_COLOR);
+ const slamd::flatb::MeshData *data() const {
+ return GetPointer(VT_DATA);
}
- float thickness() const {
- return GetField(VT_THICKNESS, 0.0f);
+ float min_brightness() const {
+ return GetField(VT_MIN_BRIGHTNESS, 0.0f);
}
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
- VerifyOffset(verifier, VT_POINTS) &&
- verifier.VerifyVector(points()) &&
- VerifyField(verifier, VT_COLOR, 4) &&
- VerifyField(verifier, VT_THICKNESS, 4) &&
+ VerifyOffset(verifier, VT_DATA) &&
+ verifier.VerifyTable(data()) &&
+ VerifyField(verifier, VT_MIN_BRIGHTNESS, 4) &&
verifier.EndTable();
}
};
-struct PolyLine2DBuilder {
- typedef PolyLine2D Table;
+struct MeshBuilder {
+ typedef Mesh Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
- void add_points(::flatbuffers::Offset<::flatbuffers::Vector> points) {
- fbb_.AddOffset(PolyLine2D::VT_POINTS, points);
- }
- void add_color(const slamd::flatb::Vec3 *color) {
- fbb_.AddStruct(PolyLine2D::VT_COLOR, color);
+ void add_data(::flatbuffers::Offset data) {
+ fbb_.AddOffset(Mesh::VT_DATA, data);
}
- void add_thickness(float thickness) {
- fbb_.AddElement(PolyLine2D::VT_THICKNESS, thickness, 0.0f);
+ void add_min_brightness(float min_brightness) {
+ fbb_.AddElement(Mesh::VT_MIN_BRIGHTNESS, min_brightness, 0.0f);
}
- explicit PolyLine2DBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
+ explicit MeshBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
- ::flatbuffers::Offset Finish() {
+ ::flatbuffers::Offset Finish() {
const auto end = fbb_.EndTable(start_);
- auto o = ::flatbuffers::Offset(end);
+ auto o = ::flatbuffers::Offset(end);
return o;
}
};
-inline ::flatbuffers::Offset CreatePolyLine2D(
+inline ::flatbuffers::Offset CreateMesh(
::flatbuffers::FlatBufferBuilder &_fbb,
- ::flatbuffers::Offset<::flatbuffers::Vector> points = 0,
- const slamd::flatb::Vec3 *color = nullptr,
- float thickness = 0.0f) {
- PolyLine2DBuilder builder_(_fbb);
- builder_.add_thickness(thickness);
- builder_.add_color(color);
- builder_.add_points(points);
+ ::flatbuffers::Offset data = 0,
+ float min_brightness = 0.0f) {
+ MeshBuilder builder_(_fbb);
+ builder_.add_min_brightness(min_brightness);
+ builder_.add_data(data);
return builder_.Finish();
}
-inline ::flatbuffers::Offset CreatePolyLine2DDirect(
- ::flatbuffers::FlatBufferBuilder &_fbb,
- const std::vector *points = nullptr,
- const slamd::flatb::Vec3 *color = nullptr,
- float thickness = 0.0f) {
- auto points__ = points ? _fbb.CreateVectorOfStructs(*points) : 0;
- return slamd::flatb::CreatePolyLine2D(
- _fbb,
- points__,
- color,
- thickness);
-}
-
-struct Mesh FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
- typedef MeshBuilder Builder;
+struct Spheres FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+ typedef SpheresBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
- VT_DATA = 4,
- VT_MIN_BRIGHTNESS = 6
+ VT_POSITIONS = 4,
+ VT_COLORS = 6,
+ VT_RADII = 8,
+ VT_MIN_BRIGHTNESS = 10
};
- const slamd::flatb::MeshData *data() const {
- return GetPointer(VT_DATA);
+ const ::flatbuffers::Vector *positions() const {
+ return GetPointer *>(VT_POSITIONS);
+ }
+ const ::flatbuffers::Vector *colors() const {
+ return GetPointer *>(VT_COLORS);
+ }
+ const ::flatbuffers::Vector *radii() const {
+ return GetPointer *>(VT_RADII);
}
float min_brightness() const {
return GetField(VT_MIN_BRIGHTNESS, 0.0f);
}
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
- VerifyOffset(verifier, VT_DATA) &&
- verifier.VerifyTable(data()) &&
+ VerifyOffset(verifier, VT_POSITIONS) &&
+ verifier.VerifyVector(positions()) &&
+ VerifyOffset(verifier, VT_COLORS) &&
+ verifier.VerifyVector(colors()) &&
+ VerifyOffset(verifier, VT_RADII) &&
+ verifier.VerifyVector(radii()) &&
VerifyField(verifier, VT_MIN_BRIGHTNESS, 4) &&
verifier.EndTable();
}
};
-struct MeshBuilder {
- typedef Mesh Table;
+struct SpheresBuilder {
+ typedef Spheres Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
- void add_data(::flatbuffers::Offset data) {
- fbb_.AddOffset(Mesh::VT_DATA, data);
+ void add_positions(::flatbuffers::Offset<::flatbuffers::Vector> positions) {
+ fbb_.AddOffset(Spheres::VT_POSITIONS, positions);
+ }
+ void add_colors(::flatbuffers::Offset<::flatbuffers::Vector> colors) {
+ fbb_.AddOffset(Spheres::VT_COLORS, colors);
+ }
+ void add_radii(::flatbuffers::Offset<::flatbuffers::Vector> radii) {
+ fbb_.AddOffset(Spheres::VT_RADII, radii);
}
void add_min_brightness(float min_brightness) {
- fbb_.AddElement(Mesh::VT_MIN_BRIGHTNESS, min_brightness, 0.0f);
+ fbb_.AddElement(Spheres::VT_MIN_BRIGHTNESS, min_brightness, 0.0f);
}
- explicit MeshBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
+ explicit SpheresBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
- ::flatbuffers::Offset Finish() {
+ ::flatbuffers::Offset Finish() {
const auto end = fbb_.EndTable(start_);
- auto o = ::flatbuffers::Offset(end);
+ auto o = ::flatbuffers::Offset(end);
return o;
}
};
-inline ::flatbuffers::Offset CreateMesh(
+inline ::flatbuffers::Offset CreateSpheres(
::flatbuffers::FlatBufferBuilder &_fbb,
- ::flatbuffers::Offset data = 0,
+ ::flatbuffers::Offset<::flatbuffers::Vector> positions = 0,
+ ::flatbuffers::Offset<::flatbuffers::Vector> colors = 0,
+ ::flatbuffers::Offset<::flatbuffers::Vector> radii = 0,
float min_brightness = 0.0f) {
- MeshBuilder builder_(_fbb);
+ SpheresBuilder builder_(_fbb);
builder_.add_min_brightness(min_brightness);
- builder_.add_data(data);
+ builder_.add_radii(radii);
+ builder_.add_colors(colors);
+ builder_.add_positions(positions);
return builder_.Finish();
}
+inline ::flatbuffers::Offset CreateSpheresDirect(
+ ::flatbuffers::FlatBufferBuilder &_fbb,
+ const std::vector *positions = nullptr,
+ const std::vector *colors = nullptr,
+ const std::vector *radii = nullptr,
+ float min_brightness = 0.0f) {
+ auto positions__ = positions ? _fbb.CreateVectorOfStructs(*positions) : 0;
+ auto colors__ = colors ? _fbb.CreateVectorOfStructs(*colors) : 0;
+ auto radii__ = radii ? _fbb.CreateVector(*radii) : 0;
+ return slamd::flatb::CreateSpheres(
+ _fbb,
+ positions__,
+ colors__,
+ radii__,
+ min_brightness);
+}
+
struct Plane FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef PlaneBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
@@ -1127,9 +953,6 @@ struct Geometry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
const slamd::flatb::Triad *geometry_as_triad() const {
return geometry_type() == slamd::flatb::GeometryUnion_triad ? static_cast(geometry()) : nullptr;
}
- const slamd::flatb::Circles2D *geometry_as_circles_2d() const {
- return geometry_type() == slamd::flatb::GeometryUnion_circles_2d ? static_cast(geometry()) : nullptr;
- }
const slamd::flatb::CameraFrustum *geometry_as_camera_frustum() const {
return geometry_type() == slamd::flatb::GeometryUnion_camera_frustum ? static_cast(geometry()) : nullptr;
}
@@ -1139,9 +962,6 @@ struct Geometry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
const slamd::flatb::Image *geometry_as_image() const {
return geometry_type() == slamd::flatb::GeometryUnion_image ? static_cast(geometry()) : nullptr;
}
- const slamd::flatb::Points2D *geometry_as_points_2d() const {
- return geometry_type() == slamd::flatb::GeometryUnion_points_2d ? static_cast(geometry()) : nullptr;
- }
const slamd::flatb::Box *geometry_as_box() const {
return geometry_type() == slamd::flatb::GeometryUnion_box ? static_cast(geometry()) : nullptr;
}
@@ -1154,15 +974,15 @@ struct Geometry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
const slamd::flatb::PolyLine *geometry_as_poly_line() const {
return geometry_type() == slamd::flatb::GeometryUnion_poly_line ? static_cast(geometry()) : nullptr;
}
- const slamd::flatb::PolyLine2D *geometry_as_poly_line_2d() const {
- return geometry_type() == slamd::flatb::GeometryUnion_poly_line_2d ? static_cast(geometry()) : nullptr;
- }
const slamd::flatb::Mesh *geometry_as_mesh() const {
return geometry_type() == slamd::flatb::GeometryUnion_mesh ? static_cast(geometry()) : nullptr;
}
const slamd::flatb::Plane *geometry_as_plane() const {
return geometry_type() == slamd::flatb::GeometryUnion_plane ? static_cast(geometry()) : nullptr;
}
+ const slamd::flatb::Spheres *geometry_as_spheres() const {
+ return geometry_type() == slamd::flatb::GeometryUnion_spheres ? static_cast(geometry()) : nullptr;
+ }
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField(verifier, VT_GEOMETRY_ID, 8) &&
@@ -1177,10 +997,6 @@ template<> inline const slamd::flatb::Triad *Geometry::geometry_as inline const slamd::flatb::Circles2D *Geometry::geometry_as() const {
- return geometry_as_circles_2d();
-}
-
template<> inline const slamd::flatb::CameraFrustum *Geometry::geometry_as() const {
return geometry_as_camera_frustum();
}
@@ -1193,10 +1009,6 @@ template<> inline const slamd::flatb::Image *Geometry::geometry_as inline const slamd::flatb::Points2D *Geometry::geometry_as() const {
- return geometry_as_points_2d();
-}
-
template<> inline const slamd::flatb::Box *Geometry::geometry_as() const {
return geometry_as_box();
}
@@ -1213,10 +1025,6 @@ template<> inline const slamd::flatb::PolyLine *Geometry::geometry_as inline const slamd::flatb::PolyLine2D *Geometry::geometry_as() const {
- return geometry_as_poly_line_2d();
-}
-
template<> inline const slamd::flatb::Mesh *Geometry::geometry_as() const {
return geometry_as_mesh();
}
@@ -1225,6 +1033,10 @@ template<> inline const slamd::flatb::Plane *Geometry::geometry_as inline const slamd::flatb::Spheres *Geometry::geometry_as() const {
+ return geometry_as_spheres();
+}
+
struct GeometryBuilder {
typedef Geometry Table;
::flatbuffers::FlatBufferBuilder &fbb_;
@@ -1270,10 +1082,6 @@ inline bool VerifyGeometryUnion(::flatbuffers::Verifier &verifier, const void *o
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
}
- case GeometryUnion_circles_2d: {
- auto ptr = reinterpret_cast(obj);
- return verifier.VerifyTable(ptr);
- }
case GeometryUnion_camera_frustum: {
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
@@ -1286,10 +1094,6 @@ inline bool VerifyGeometryUnion(::flatbuffers::Verifier &verifier, const void *o
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
}
- case GeometryUnion_points_2d: {
- auto ptr = reinterpret_cast(obj);
- return verifier.VerifyTable(ptr);
- }
case GeometryUnion_box: {
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
@@ -1306,10 +1110,6 @@ inline bool VerifyGeometryUnion(::flatbuffers::Verifier &verifier, const void *o
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
}
- case GeometryUnion_poly_line_2d: {
- auto ptr = reinterpret_cast(obj);
- return verifier.VerifyTable(ptr);
- }
case GeometryUnion_mesh: {
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
@@ -1318,6 +1118,10 @@ inline bool VerifyGeometryUnion(::flatbuffers::Verifier &verifier, const void *o
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
}
+ case GeometryUnion_spheres: {
+ auto ptr = reinterpret_cast(obj);
+ return verifier.VerifyTable(ptr);
+ }
default: return true;
}
}
diff --git a/slamd/flatb/flatb/messages_generated.h b/slamd/flatb/flatb/messages_generated.h
index a3532ead..bdb0917a 100644
--- a/slamd/flatb/flatb/messages_generated.h
+++ b/slamd/flatb/flatb/messages_generated.h
@@ -29,14 +29,14 @@ struct UpdateMeshColorsBuilder;
struct UpdateMeshNormals;
struct UpdateMeshNormalsBuilder;
-struct UpdateCircles2DPositions;
-struct UpdateCircles2DPositionsBuilder;
+struct UpdateSpheresPositions;
+struct UpdateSpheresPositionsBuilder;
-struct UpdateCircles2DColors;
-struct UpdateCircles2DColorsBuilder;
+struct UpdateSpheresColors;
+struct UpdateSpheresColorsBuilder;
-struct UpdateCircles2DRadii;
-struct UpdateCircles2DRadiiBuilder;
+struct UpdateSpheresRadii;
+struct UpdateSpheresRadiiBuilder;
struct UpdatePointCloudPositions;
struct UpdatePointCloudPositionsBuilder;
@@ -92,14 +92,14 @@ enum MessageUnion : uint8_t {
MessageUnion_update_mesh_positions = 11,
MessageUnion_update_mesh_colors = 12,
MessageUnion_update_mesh_normals = 13,
- MessageUnion_update_circles2d_positions = 14,
- MessageUnion_update_circles2d_colors = 15,
- MessageUnion_update_circles2d_radii = 16,
- MessageUnion_update_point_cloud_positions = 17,
- MessageUnion_update_point_cloud_colors = 18,
- MessageUnion_update_point_cloud_radii = 19,
+ MessageUnion_update_point_cloud_positions = 14,
+ MessageUnion_update_point_cloud_colors = 15,
+ MessageUnion_update_point_cloud_radii = 16,
+ MessageUnion_update_spheres_positions = 17,
+ MessageUnion_update_spheres_colors = 18,
+ MessageUnion_update_spheres_radii = 19,
MessageUnion_MIN = MessageUnion_NONE,
- MessageUnion_MAX = MessageUnion_update_point_cloud_radii
+ MessageUnion_MAX = MessageUnion_update_spheres_radii
};
inline const MessageUnion (&EnumValuesMessageUnion())[20] {
@@ -118,12 +118,12 @@ inline const MessageUnion (&EnumValuesMessageUnion())[20] {
MessageUnion_update_mesh_positions,
MessageUnion_update_mesh_colors,
MessageUnion_update_mesh_normals,
- MessageUnion_update_circles2d_positions,
- MessageUnion_update_circles2d_colors,
- MessageUnion_update_circles2d_radii,
MessageUnion_update_point_cloud_positions,
MessageUnion_update_point_cloud_colors,
- MessageUnion_update_point_cloud_radii
+ MessageUnion_update_point_cloud_radii,
+ MessageUnion_update_spheres_positions,
+ MessageUnion_update_spheres_colors,
+ MessageUnion_update_spheres_radii
};
return values;
}
@@ -144,19 +144,19 @@ inline const char * const *EnumNamesMessageUnion() {
"update_mesh_positions",
"update_mesh_colors",
"update_mesh_normals",
- "update_circles2d_positions",
- "update_circles2d_colors",
- "update_circles2d_radii",
"update_point_cloud_positions",
"update_point_cloud_colors",
"update_point_cloud_radii",
+ "update_spheres_positions",
+ "update_spheres_colors",
+ "update_spheres_radii",
nullptr
};
return names;
}
inline const char *EnumNameMessageUnion(MessageUnion e) {
- if (::flatbuffers::IsOutRange(e, MessageUnion_NONE, MessageUnion_update_point_cloud_radii)) return "";
+ if (::flatbuffers::IsOutRange(e, MessageUnion_NONE, MessageUnion_update_spheres_radii)) return "";
const size_t index = static_cast(e);
return EnumNamesMessageUnion()[index];
}
@@ -217,18 +217,6 @@ template<> struct MessageUnionTraits {
static const MessageUnion enum_value = MessageUnion_update_mesh_normals;
};
-template<> struct MessageUnionTraits {
- static const MessageUnion enum_value = MessageUnion_update_circles2d_positions;
-};
-
-template<> struct MessageUnionTraits {
- static const MessageUnion enum_value = MessageUnion_update_circles2d_colors;
-};
-
-template<> struct MessageUnionTraits {
- static const MessageUnion enum_value = MessageUnion_update_circles2d_radii;
-};
-
template<> struct MessageUnionTraits {
static const MessageUnion enum_value = MessageUnion_update_point_cloud_positions;
};
@@ -241,6 +229,18 @@ template<> struct MessageUnionTraits {
static const MessageUnion enum_value = MessageUnion_update_point_cloud_radii;
};
+template<> struct MessageUnionTraits {
+ static const MessageUnion enum_value = MessageUnion_update_spheres_positions;
+};
+
+template<> struct MessageUnionTraits {
+ static const MessageUnion enum_value = MessageUnion_update_spheres_colors;
+};
+
+template<> struct MessageUnionTraits {
+ static const MessageUnion enum_value = MessageUnion_update_spheres_radii;
+};
+
bool VerifyMessageUnion(::flatbuffers::Verifier &verifier, const void *obj, MessageUnion type);
bool VerifyMessageUnionVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types);
@@ -433,8 +433,8 @@ inline ::flatbuffers::Offset CreateUpdateMeshNormalsDirect(
normals__);
}
-struct UpdateCircles2DPositions FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
- typedef UpdateCircles2DPositionsBuilder Builder;
+struct UpdateSpheresPositions FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+ typedef UpdateSpheresPositionsBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_OBJECT_ID = 4,
VT_POSITIONS = 6
@@ -442,8 +442,8 @@ struct UpdateCircles2DPositions FLATBUFFERS_FINAL_CLASS : private ::flatbuffers:
uint64_t object_id() const {
return GetField(VT_OBJECT_ID, 0);
}
- const ::flatbuffers::Vector *positions() const {
- return GetPointer *>(VT_POSITIONS);
+ const ::flatbuffers::Vector *positions() const {
+ return GetPointer *>(VT_POSITIONS);
}
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
@@ -454,50 +454,50 @@ struct UpdateCircles2DPositions FLATBUFFERS_FINAL_CLASS : private ::flatbuffers:
}
};
-struct UpdateCircles2DPositionsBuilder {
- typedef UpdateCircles2DPositions Table;
+struct UpdateSpheresPositionsBuilder {
+ typedef UpdateSpheresPositions Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_object_id(uint64_t object_id) {
- fbb_.AddElement(UpdateCircles2DPositions::VT_OBJECT_ID, object_id, 0);
+ fbb_.AddElement(UpdateSpheresPositions::VT_OBJECT_ID, object_id, 0);
}
- void add_positions(::flatbuffers::Offset<::flatbuffers::Vector> positions) {
- fbb_.AddOffset(UpdateCircles2DPositions::VT_POSITIONS, positions);
+ void add_positions(::flatbuffers::Offset<::flatbuffers::Vector> positions) {
+ fbb_.AddOffset(UpdateSpheresPositions::VT_POSITIONS, positions);
}
- explicit UpdateCircles2DPositionsBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
+ explicit UpdateSpheresPositionsBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
- ::flatbuffers::Offset Finish() {
+ ::flatbuffers::Offset Finish() {
const auto end = fbb_.EndTable(start_);
- auto o = ::flatbuffers::Offset(end);
+ auto o = ::flatbuffers::Offset(end);
return o;
}
};
-inline ::flatbuffers::Offset CreateUpdateCircles2DPositions(
+inline ::flatbuffers::Offset CreateUpdateSpheresPositions(
::flatbuffers::FlatBufferBuilder &_fbb,
uint64_t object_id = 0,
- ::flatbuffers::Offset<::flatbuffers::Vector> positions = 0) {
- UpdateCircles2DPositionsBuilder builder_(_fbb);
+ ::flatbuffers::Offset<::flatbuffers::Vector> positions = 0) {
+ UpdateSpheresPositionsBuilder builder_(_fbb);
builder_.add_object_id(object_id);
builder_.add_positions(positions);
return builder_.Finish();
}
-inline ::flatbuffers::Offset CreateUpdateCircles2DPositionsDirect(
+inline ::flatbuffers::Offset CreateUpdateSpheresPositionsDirect(
::flatbuffers::FlatBufferBuilder &_fbb,
uint64_t object_id = 0,
- const std::vector *positions = nullptr) {
- auto positions__ = positions ? _fbb.CreateVectorOfStructs(*positions) : 0;
- return slamd::flatb::CreateUpdateCircles2DPositions(
+ const std::vector *positions = nullptr) {
+ auto positions__ = positions ? _fbb.CreateVectorOfStructs(*positions) : 0;
+ return slamd::flatb::CreateUpdateSpheresPositions(
_fbb,
object_id,
positions__);
}
-struct UpdateCircles2DColors FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
- typedef UpdateCircles2DColorsBuilder Builder;
+struct UpdateSpheresColors FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+ typedef UpdateSpheresColorsBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_OBJECT_ID = 4,
VT_COLORS = 6
@@ -517,50 +517,50 @@ struct UpdateCircles2DColors FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Ta
}
};
-struct UpdateCircles2DColorsBuilder {
- typedef UpdateCircles2DColors Table;
+struct UpdateSpheresColorsBuilder {
+ typedef UpdateSpheresColors Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_object_id(uint64_t object_id) {
- fbb_.AddElement(UpdateCircles2DColors::VT_OBJECT_ID, object_id, 0);
+ fbb_.AddElement(UpdateSpheresColors::VT_OBJECT_ID, object_id, 0);
}
void add_colors(::flatbuffers::Offset<::flatbuffers::Vector> colors) {
- fbb_.AddOffset(UpdateCircles2DColors::VT_COLORS, colors);
+ fbb_.AddOffset(UpdateSpheresColors::VT_COLORS, colors);
}
- explicit UpdateCircles2DColorsBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
+ explicit UpdateSpheresColorsBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
- ::flatbuffers::Offset Finish() {
+ ::flatbuffers::Offset Finish() {
const auto end = fbb_.EndTable(start_);
- auto o = ::flatbuffers::Offset(end);
+ auto o = ::flatbuffers::Offset(end);
return o;
}
};
-inline ::flatbuffers::Offset CreateUpdateCircles2DColors(
+inline ::flatbuffers::Offset CreateUpdateSpheresColors(
::flatbuffers::FlatBufferBuilder &_fbb,
uint64_t object_id = 0,
::flatbuffers::Offset<::flatbuffers::Vector> colors = 0) {
- UpdateCircles2DColorsBuilder builder_(_fbb);
+ UpdateSpheresColorsBuilder builder_(_fbb);
builder_.add_object_id(object_id);
builder_.add_colors(colors);
return builder_.Finish();
}
-inline ::flatbuffers::Offset CreateUpdateCircles2DColorsDirect(
+inline ::flatbuffers::Offset CreateUpdateSpheresColorsDirect(
::flatbuffers::FlatBufferBuilder &_fbb,
uint64_t object_id = 0,
const std::vector *colors = nullptr) {
auto colors__ = colors ? _fbb.CreateVectorOfStructs(*colors) : 0;
- return slamd::flatb::CreateUpdateCircles2DColors(
+ return slamd::flatb::CreateUpdateSpheresColors(
_fbb,
object_id,
colors__);
}
-struct UpdateCircles2DRadii FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
- typedef UpdateCircles2DRadiiBuilder Builder;
+struct UpdateSpheresRadii FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
+ typedef UpdateSpheresRadiiBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_OBJECT_ID = 4,
VT_RADII = 6
@@ -580,43 +580,43 @@ struct UpdateCircles2DRadii FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tab
}
};
-struct UpdateCircles2DRadiiBuilder {
- typedef UpdateCircles2DRadii Table;
+struct UpdateSpheresRadiiBuilder {
+ typedef UpdateSpheresRadii Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_object_id(uint64_t object_id) {
- fbb_.AddElement(UpdateCircles2DRadii::VT_OBJECT_ID, object_id, 0);
+ fbb_.AddElement(UpdateSpheresRadii::VT_OBJECT_ID, object_id, 0);
}
void add_radii(::flatbuffers::Offset<::flatbuffers::Vector> radii) {
- fbb_.AddOffset(UpdateCircles2DRadii::VT_RADII, radii);
+ fbb_.AddOffset(UpdateSpheresRadii::VT_RADII, radii);
}
- explicit UpdateCircles2DRadiiBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
+ explicit UpdateSpheresRadiiBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
- ::flatbuffers::Offset Finish() {
+ ::flatbuffers::Offset Finish() {
const auto end = fbb_.EndTable(start_);
- auto o = ::flatbuffers::Offset(end);
+ auto o = ::flatbuffers::Offset(end);
return o;
}
};
-inline ::flatbuffers::Offset CreateUpdateCircles2DRadii(
+inline ::flatbuffers::Offset CreateUpdateSpheresRadii(
::flatbuffers::FlatBufferBuilder &_fbb,
uint64_t object_id = 0,
::flatbuffers::Offset<::flatbuffers::Vector> radii = 0) {
- UpdateCircles2DRadiiBuilder builder_(_fbb);
+ UpdateSpheresRadiiBuilder builder_(_fbb);
builder_.add_object_id(object_id);
builder_.add_radii(radii);
return builder_.Finish();
}
-inline ::flatbuffers::Offset CreateUpdateCircles2DRadiiDirect(
+inline ::flatbuffers::Offset CreateUpdateSpheresRadiiDirect(
::flatbuffers::FlatBufferBuilder &_fbb,
uint64_t object_id = 0,
const std::vector *radii = nullptr) {
auto radii__ = radii ? _fbb.CreateVector(*radii) : 0;
- return slamd::flatb::CreateUpdateCircles2DRadii(
+ return slamd::flatb::CreateUpdateSpheresRadii(
_fbb,
object_id,
radii__);
@@ -1335,15 +1335,6 @@ struct Message FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
const slamd::flatb::UpdateMeshNormals *message_as_update_mesh_normals() const {
return message_type() == slamd::flatb::MessageUnion_update_mesh_normals ? static_cast(message()) : nullptr;
}
- const slamd::flatb::UpdateCircles2DPositions *message_as_update_circles2d_positions() const {
- return message_type() == slamd::flatb::MessageUnion_update_circles2d_positions ? static_cast(message()) : nullptr;
- }
- const slamd::flatb::UpdateCircles2DColors *message_as_update_circles2d_colors() const {
- return message_type() == slamd::flatb::MessageUnion_update_circles2d_colors ? static_cast(message()) : nullptr;
- }
- const slamd::flatb::UpdateCircles2DRadii *message_as_update_circles2d_radii() const {
- return message_type() == slamd::flatb::MessageUnion_update_circles2d_radii ? static_cast(message()) : nullptr;
- }
const slamd::flatb::UpdatePointCloudPositions *message_as_update_point_cloud_positions() const {
return message_type() == slamd::flatb::MessageUnion_update_point_cloud_positions ? static_cast(message()) : nullptr;
}
@@ -1353,6 +1344,15 @@ struct Message FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
const slamd::flatb::UpdatePointCloudRadii *message_as_update_point_cloud_radii() const {
return message_type() == slamd::flatb::MessageUnion_update_point_cloud_radii ? static_cast(message()) : nullptr;
}
+ const slamd::flatb::UpdateSpheresPositions *message_as_update_spheres_positions() const {
+ return message_type() == slamd::flatb::MessageUnion_update_spheres_positions ? static_cast(message()) : nullptr;
+ }
+ const slamd::flatb::UpdateSpheresColors *message_as_update_spheres_colors() const {
+ return message_type() == slamd::flatb::MessageUnion_update_spheres_colors ? static_cast(message()) : nullptr;
+ }
+ const slamd::flatb::UpdateSpheresRadii *message_as_update_spheres_radii() const {
+ return message_type() == slamd::flatb::MessageUnion_update_spheres_radii ? static_cast(message()) : nullptr;
+ }
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField(verifier, VT_MESSAGE_TYPE, 1) &&
@@ -1414,18 +1414,6 @@ template<> inline const slamd::flatb::UpdateMeshNormals *Message::message_as inline const slamd::flatb::UpdateCircles2DPositions *Message::message_as() const {
- return message_as_update_circles2d_positions();
-}
-
-template<> inline const slamd::flatb::UpdateCircles2DColors *Message::message_as() const {
- return message_as_update_circles2d_colors();
-}
-
-template<> inline const slamd::flatb::UpdateCircles2DRadii *Message::message_as() const {
- return message_as_update_circles2d_radii();
-}
-
template<> inline const slamd::flatb::UpdatePointCloudPositions *Message::message_as() const {
return message_as_update_point_cloud_positions();
}
@@ -1438,6 +1426,18 @@ template<> inline const slamd::flatb::UpdatePointCloudRadii *Message::message_as
return message_as_update_point_cloud_radii();
}
+template<> inline const slamd::flatb::UpdateSpheresPositions *Message::message_as() const {
+ return message_as_update_spheres_positions();
+}
+
+template<> inline const slamd::flatb::UpdateSpheresColors *Message::message_as() const {
+ return message_as_update_spheres_colors();
+}
+
+template<> inline const slamd::flatb::UpdateSpheresRadii *Message::message_as() const {
+ return message_as_update_spheres_radii();
+}
+
struct MessageBuilder {
typedef Message Table;
::flatbuffers::FlatBufferBuilder &fbb_;
@@ -1526,18 +1526,6 @@ inline bool VerifyMessageUnion(::flatbuffers::Verifier &verifier, const void *ob
auto ptr = reinterpret_cast(obj);
return verifier.VerifyTable(ptr);
}
- case MessageUnion_update_circles2d_positions: {
- auto ptr = reinterpret_cast(obj);
- return verifier.VerifyTable(ptr);
- }
- case MessageUnion_update_circles2d_colors: {
- auto ptr = reinterpret_cast