尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Rerun C++ SDK 入门实战:用 Points3D 与 LineStrips3D 绘制 3D DNA 螺旋动画

Rerun C++ SDK 入门实战:用 Points3D 与 LineStrips3D 绘制 3D DNA 螺旋动画 Rerun C SDK 入门实战用 Points3D 与 LineStrips3D 绘制 3D DNA 螺旋动画【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun本篇技术指南以仓库中的 examples/cpp/dna/README.md 为核心文档深入解析 Rerun C SDK 的入门示例——用点Points3D与线LineStrips3D两种基础图元primitive archetypes绘制一条旋转的 3D DNA 双螺旋。读完本文你将掌握如何构建并运行该示例、如何理解 Rerun 的实体路径entity path体系、如何区分静态数据log_static与时序数据log、如何使用时间轴驱动动画以及如何组合Transform3D实现整体旋转。该示例是理解 Rerun 数据模型与 C SDK 调用方式的友好起点。示例概览什么是 dna 示例Rerun 是一个用于可视化、查询与流式处理多模态机器人数据的开源工具。dna示例也叫 Helix是 Rerun C SDK 中最简单的示例之一它仅仅通过日志记录logging点与线两类 3D 图元就绘制出一条完整的 DNA 双螺旋结构并让珠子beads沿螺旋骨架上下弹跳、整个结构绕 Z 轴缓慢旋转。从功能上讲该示例覆盖了 Rerun 开发的四个核心概念实体路径entity path用类似dna/structure/left的层级字符串组织场景树基础图元 archetypePoints3D、LineStrips3D、Transform3D静态数据 vs 时序数据结构体用log_static记录一次动画帧用log按时间轴逐帧记录时间轴timeline通过set_time_duration推进动画时钟。完整源码位于 examples/cpp/dna/main.cpp仅约 80 行非常适合作为 Rerun C SDK 的第一课。构建与运行在仓库根目录需要已具备 Rust 工具链因为 C SDK 由 Rust 核心构建下按 README 给出的方式构建并运行cmake . cmake --build . --target example_dna ./examples/cpp/dna/example_dna程序运行后会通过rec.spawn()自动拉起一个 Rerun Viewer 窗口并实时推送动画数据。CMake 构建配置解析示例的构建逻辑在 examples/cpp/dna/CMakeLists.txt 中它支持两种使用场景在 Rerun 仓库内部构建当定义了RERUN_REPOSITORY变量时直接复用仓库内已有的rerun_sdk目标并通过rerun_strict_warning_settings(example_dna)启用严格的编译警告设置独立于仓库使用否则通过 CMake 的FetchContent从RERUN_CPP_URL默认为 rerun_cpp_sdk 的发布压缩包 URL自动下载预编译的 SDK再链接include(FetchContent) FetchContent_Declare(rerun_sdk URL ${RERUN_CPP_URL}) FetchContent_MakeAvailable(rerun_sdk) target_link_libraries(example_dna PRIVATE rerun_sdk)如果你要脱离仓库、仅凭示例代码构建可以在cmake时通过-DRERUN_CPP_URLpath to rerun_sdk_cpp zip指定 SDK 压缩包位置。源码逐段解读从创建流到第一帧1. 创建 RecordingStream 并启动 Viewerconst auto rec rerun::RecordingStream(rerun_example_dna_abacus); rec.spawn().exit_on_failure();第一行创建一个名为rerun_example_dna_abacus的RecordingStream日志记录流它是 C SDK 中一切日志操作的门面对象。第二行spawn()会启动一个 Rerun Viewer 进程并将数据流连接到它.exit_on_failure()表示若启动失败则直接终止程序SDK 中Error的便捷处理方法。spawn还支持传入SpawnOptions与可选的 flush 超时参数详见 recording_stream.hpp。2. 用 color_spiral 生成两条螺旋链static constexpr size_t NUM_POINTS 100; std::vectorrerun::Position3D points1, points2; std::vectorrerun::Color colors1, colors2; color_spiral(NUM_POINTS, 2.0f, 0.02f, 0.0f, 0.1f, points1, colors1); color_spiral(NUM_POINTS, 2.0f, 0.02f, TAU * 0.5f, 0.1f, points2, colors2);color_spiral是 SDK 为示例提供的演示工具函数声明与实现在 demo_utils.hpp 与 demo_utils.cpp其核心算法为for (size_t i 0; i num_points; i) { float angle static_castfloat(i) * angular_step * TAU angular_offset; out_points.push_back({ cosf(angle) * radius, sinf(angle) * radius, static_castfloat(i) * z_step, }); out_colors.push_back(colormap_turbo_srgb(static_castfloat(i) / static_castfloat(num_points))); }参数含义num_points螺旋上的点数此处为 100radius螺旋半径2.0angular_step每步绕圆周的角度增量系数0.02即每步转过0.02 * TAU弧度angular_offset起始角度偏移第一条链为 0第二条链为TAU * 0.5f即恰好错开半圈——这正是双螺旋两条链的相位关系z_step沿 Z 轴的步进增量0.1使螺旋在高度方向上延展。每个点的颜色取自 Turbo 色彩映射colormap_turbo_srgb实现见 demo_utils.cpp使用 sRGB 多项式近似沿螺旋长度从蓝渐变到红。3. 记录静态结构两条链 横档rec.log_static( dna/structure/left, rerun::Points3D(points1).with_colors(colors1).with_radii({0.08f}) ); rec.log_static( dna/structure/right, rerun::Points3D(points2).with_colors(colors2).with_radii({0.08f}) ); std::vectorrerun::LineStrip3D lines; for (size_t i 0; i points1.size(); i) { lines.emplace_back(rerun::LineStrip3D({points1[i].xyz, points2[i].xyz})); } rec.log_static( dna/structure/scaffolding, rerun::LineStrips3D(lines).with_colors(rerun::Color(128, 128, 128)) );这里有三层信息值得注意Points3Darchetype 的构建器风格 APIPoints3D(points1)传入位置.with_colors(...)设置颜色.with_radii({0.08f})设置点半径链式调用一气呵成LineStrips3D由一组LineStrip3D组成每个LineStrip3D是一条折线这里每条折线只有两个端点——即左右两条螺旋对应点之间的连线充当 DNA 的横档scaffolding。所有横档共享灰色Color(128, 128, 128)log_static的语义静态数据不关联任何时间在所有时间轴上始终存在并且会无条件覆盖同类型的时序数据。因此骨架结构只需记录一次动画帧只更新珠子与整体旋转即可。log_static的完整语义说明见 recording_stream.hpp。4. 动画主循环珠子弹跳 结构旋转std::default_random_engine gen; std::uniform_real_distributionfloat dist(0.0f, 1.0f); std::vectorfloat offsets(NUM_POINTS); std::generate(offsets.begin(), offsets.end(), [] { return dist(gen); }); for (int t 0; t 400; t) { auto time std::chrono::durationfloat(t) * 0.01f; rec.set_time_duration(stable_time, time); for (size_t i 0; i lines.size(); i) { float time_offset time.count() offsets[i]; auto c static_castuint8_t(bounce_lerp(80.0f, 230.0f, time_offset * 2.0f)); beads_positions[i] rerun::Position3D( bounce_lerp(lines[i].points[0].x(), lines[i].points[1].x(), time_offset), bounce_lerp(lines[i].points[0].y(), lines[i].points[1].y(), time_offset), bounce_lerp(lines[i].points[0].z(), lines[i].points[1].z(), time_offset) ); beads_colors[i] rerun::Color(c, c, c); } rec.log( dna/structure/scaffolding/beads, rerun::Points3D(beads_positions).with_colors(beads_colors).with_radii({0.06f}) ); rec.log( dna/structure, rerun::archetypes::Transform3D(rerun::RotationAxisAngle( {0.0f, 0.0f, 1.0f}, rerun::Angle::radians(time.count() / 4.0f * TAU) )) ); }动画循环共 400 帧每帧推进0.01s并做了三件事推进时间轴rec.set_time_duration(stable_time, time)在当前线程上设置名为stable_time的时间轴值单位为秒此后该线程上所有log都会被盖上这个时间戳。时间设置方法族还包括set_time_sequence整型序号时间轴与便捷的set_time_duration_secs/set_time_duration_nanos见 recording_stream.hpp计算珠子位置与颜色每个珠子沿着对应横档的两端点之间弹跳。bounce_lerp(a, b, t)是一个会往复的线性插值函数定义见 demo_utils.hpp当t的整数部分为偶数时正向插值为奇数时反向插值从而在a、b之间来回摆动。offsets[i]是每颗珠子独立的随机相位偏移[0,1)避免所有珠子同步运动颜色则随相位在灰度 80230 之间弹跳形成明暗交替的流动感记录珠子并旋转整体珠子记录在层级更深的实体路径dna/structure/scaffolding/beads下因此自动继承父级变换随后在dna/structure上记录一个Transform3D——绕 Z 轴{0.0f, 0.0f, 1.0f}按角度time / 4 * TAU匀速旋转整个 DNA 结构包括其子树中的所有实体随之转动。注意Points3D在每帧都通过rec.log非 static写入同一实体路径dna/structure/scaffolding/beads这正是时序数据的典型用法同一实体在不同时间戳上可以有不同的取值Viewer 沿时间轴播放时即可看到珠子运动。核心概念深挖实体路径用层级字符串组织场景Rerun 用形如dna/structure/left的实体路径entity path标识场景中的每个实体/分隔的每一段构成场景树的一层。本示例的实体树如下dna └── structure ├── left (Points3D, 静态) ├── right (Points3D, 静态) └── scaffolding ├── (LineStrips3D, 静态) └── beads (Points3D, 时序动画)这种组织方式让对structure应用变换子树全部跟着动成为自然结果——Transform3D记录在dna/structure上其下所有实体包括珠子和骨架都在同一空间变换下。SDK 文档强调以__开头的路径段为 Rerun 保留用途用户数据不应使用见 recording_stream.hpp。archetype 与构建器声明式描述场景本示例用到了三种 archetype均位于rerun_cpp/src/rerun/archetypes/下Archetype文件用途本例使用的构建器Points3Dpoints3d.hpp一批 3D 点with_colors、with_radiiLineStrips3Dline_strips3d.hpp多条 3D 折线with_colorsTransform3Dtransform3d.hpp空间变换配合RotationAxisAngle其中RotationAxisAngle描述绕某轴的旋转轴向量 角度rerun::Angle::radians(...)以弧度构造角度。log方法可灵活接收任意数量的 archetype 或 component batch并合并到同一实体上文档示例见 recording_stream.hpp。静态 vs 时序Rerun 数据模型的两类数据这是理解 Rerun 的关键概念本示例恰好同时演示了二者静态数据staticlog_static记录无时间关联存在于所有时间轴且无条件遮蔽shadow同类型的所有时序数据。适合记录不随时间变化的结构——本例中的螺旋骨架时序数据temporallog记录自动带上log_time等时间戳并包含当前线程上通过set_time_*设置的所有额外时间轴。适合记录随时间演化的状态——本例中每帧更新的珠子和旋转角。二者最终都通过try_log_with_static(entity_path, static_, ...)进入统一的日志管线见 recording_stream.hpp只是static_标志不同。运行效果与观察要点运行示例后Viewer 中可以看到两条彩色螺旋链Turbo 色映射蓝→红渐变与灰色横档构成 DNA 骨架白色珠子沿横档往复弹跳明暗交替形成波动效果整个结构绕 Z 轴匀速旋转拖动时间轴stable_time即可逐帧回放动画——因为所有动画数据都带时间戳回放、scrubbing 与查询都由 Rerun 的时间索引机制原生支持。如果想自行调整效果可以尝试修改main.cpp中的参数增大/减小NUM_POINTS改变密度修改color_spiral的radius、angular_step、z_step改变螺旋形态或调整循环次数400与步长0.01f改变动画时长与速度。更进一步查看示例的构建入口 examples/cpp/dna/CMakeLists.txt 与完整源码 examples/cpp/dna/main.cpp尝试改写演示工具函数螺旋生成、弹跳插值、Turbo 色映射位于 rerun_cpp/src/rerun/demo_utils.hpp 与 rerun_cpp/src/rerun/demo_utils.cpp可供其他示例复用RecordingStream的完整 APIspawn、save、to_stdout、时间轴控制、日志记录等见 rerun_cpp/src/rerun/recording_stream.hpp例如rec.save(out.rrd)可将数据流保存为.rrd文件离线回放仓库中还有其他 C 示例如examples/cpp/clock、examples/cpp/minimal、examples/cpp/log_file等可对照学习不同 archetype 的用法。dna示例虽小却完整演示了 Rerun 的核心心智模型用实体路径组织场景、用 archetype 描述图元、用静态/时序区分数据的生命周期、用时间轴驱动动画。掌握了这四点你就已经拿到了使用 Rerun C SDK 进行 3D 可视化开发的第一把钥匙。【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表