ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Webots Web 动画导出:将 3D 仿真录制为可交互的 HTML5 动画页面

Webots Web 动画导出:将 3D 仿真录制为可交互的 HTML5 动画页面 科研自动驾驶物理引擎【免费下载链接】webotsWebots Robot Simulator项目地址https://gitcode.com/gh_mirrors/web/webots点击查看免费下载导读Web Animation 是 Webots 内建的一项导出功能它可以把正在运行的 3D 仿真实时录制为一个可交互的电影——一个独立的HTML5页面页面自带播放/暂停等播放控件同时还允许观众在任意时刻自由旋转、缩放、平移视角。与单纯的 Web Scene 导出静态 3D 场景快照不同Web 动画额外导出一个包含运动物体轨迹的JSON动画文件完整重现仿真过程中物体的位移、旋转与外观变化。阅读完本文你将掌握 Web 动画的录制与导出流程、webots-viewWeb 组件WebotsView.js 包的属性与方法 API、动画文件记录的字段范围与底层实现原理并了解如何在自有网站中嵌入动画、如何规避浏览器本地文件安全限制。什么是 Web 动画Webots 可以将一段仿真录制为交互式 3DHTML页面效果类似带播放控制条的电影但观看者可以在播放过程中随时改变视角用鼠标或触摸屏导航操作方式与 Webots 内 3D 窗口一致。其机制与 Web Scene 导出 基本一致导出时先生成一个包含世界图形信息的W3D文件Webots 自定义的、基于 XML 的 3D 图形格式再生成HTML5页面和CSS样式文件。Web 动画与 Web Scene 的唯一区别在于Web 动画额外导出一个JSON动画文件其中记录了运动物体的位置序列页面加载后由播放器按时间轴回放这些更新。下图为 Webots 生成的一个动画页面示例原文档中的示例动画页面由 Cyberbotics 官方托管说明在项目仓库的 docs/guide/web-animation.md 中可查看本文对应的官方文档原文关于导出过程中的静态场景W3D、CSS文件与浏览器兼容性细节请同时参考 docs/guide/web-scene.md。如何导出 Web 动画导出过程全部在 Webots 图形界面中完成无需编写任何代码打开一个正在或准备运行的仿真世界在主菜单中选择Share...在弹出的共享对话框中选择是上传到 webots.cloud还是保存到本地点击Record and export animation按钮开始录制在仿真中执行你想要展示的动作录制完成后点击Stop HTML5 animation按钮结束录制并保存动画Webots 会询问是否用操作系统默认浏览器播放生成的文件。导出产物录制结束后目标HTML文件所在目录会同时生成以下文件文件作用*.html包含 Webots 播放器web component的 HTML5 页面*.css页面样式仅作为样式参考可以修改或删除*.w3d3D 场景图形文件*.json动画序列文件运动物体位置、颜色等更新的时间序列所需纹理图片场景引用的贴图资源注意由于默认浏览器对本地file协议的限制详见下文浏览器兼容性与安全限制一节播放选项可能无法正常工作此时请改用本地 HTTP 服务器方式预览。用 Supervisor 控制器控制录制除了 GUI 按钮一个 Supervisor 控制器同样可以启动或停止动画录制这让批量生成动画、或让仿真在特定条件满足时自动开始录制成为可能。对应 API 声明位于 include/controller/c/webots/supervisor.hbool wb_supervisor_animation_start_recording(const char *filename); bool wb_supervisor_animation_stop_recording();在 Webots 内部WbSupervisorUtilities会将 Supervisor 发出的录制请求与WbAnimationRecorder的状态信号animationStartStatusChanged/animationStopStatusChanged关联起来见 src/webots/nodes/utils/WbSupervisorUtilities.cpp。如何在网站中嵌入 Web 动画嵌入方式与 Web Scene 完全一致请参考 docs/guide/web-scene.md#how-to-embed-a-web-scene-in-your-website 中的说明导出的HTML页面本身即为最简单的集成参照外站可以直接引用导出的CSS文件可以在集成过程中替换。若追求更省事的方案可以用一个指向生成页面的iframe标签嵌入。无论哪种方式播放器所需的CSS、JavaScript等资源都可以长期复用 Cyberbotics 官网托管的资源。编程接口webots-viewWeb 组件Web 动画页面由 WebotsView.js 包中的webots-viewWeb 组件负责播放。组件通过自定义属性接收配置通过公开方法实现更复杂的交互。组件属性Attributes属性说明data-thumbnail缩略图.jpg文件名不设置时加载期间显示默认缩略图data-scene包含 3D 场景的.w3d文件名data-animation包含动画序列的.json文件名data-autoplay布尔值是否自动播放动画默认为truedata-isMobileDevice布尔值指定应用是否运行在移动设备上showCustomWindow布尔值是否在工具栏显示自定义窗口按钮默认隐藏且必须在加载动画之前设置关键行为webots-view的属性只在页面加载时求值一次。如果data-scene与data-animation均已设置组件会自动尝试加载动画。典型用法示例将动画文件与页面放在同一目录时webots-view >script const view document.querySelector(webots-view); view.loadAnimation(scene.w3d, animation.json, true, false, scene.jpg, false); /script自定义信息窗口你可以将一个空窗口个性化为动画的辅助信息面板如显示图表、动画说明等。要启用它必须在加载动画之前将webots-view元素的showCustomWindow属性设为true之后工具栏右侧会出现一个打开该窗口的图标。可用以下函数个性化窗口内容函数说明setCustomWindowTitle(title)设置窗口标题title为新标题setCustomWindowTooltip(tooltip)设置窗口按钮的提示文字tooltip为新的提示setCustomWindowContent(content)设置窗口内容替换已有内容content为新内容注意这些函数必须在onReady()被调用之后调用以确保窗口已经创建完成。动画文件格式与底层实现JSON 文件结构动画JSON文件不是对每一帧做完整快照而是只记录发生变化的部分。从 src/webots/engine/WbAnimationRecorder.cpp 的computeUpdateData()可以看出每一帧的结构为{ time: 12.34, updates: [ { id: 42, translation: 0.1 0.2 0.3, rotation: 0 1 0 1.5708 } ] }文件头部还包含两个关键元数据见 WbAnimationRecorder.cppbasicTimeStep由WorldInfo.basicTimeStep与WorldInfo.fps共同推导公式为basicTimeStep * ceil((1000.0 / fps) / basicTimeStep)是播放时每个动画帧对应的仿真时间间隔labelsIds动画中涉及的 Supervisor 文本标签labelid 列表用;分隔。录制停止时WbAnimationRecorder::stopRecording()会把初始状态帧时间time: 0写在所有更新帧之前初始状态只包含那些在动画期间实际发生过变化的节点通过WbAnimationCommand::isChangedFromStart()判断。如果整个仿真期间没有任何节点发生变化Webots 会给出明确提示无动画内容可导出此时应改用 Web Scene 导出。录制器的核心流程Web 动画录制在 Webots 内部由单例WbAnimationRecordersrc/webots/engine/WbAnimationRecorder.hpp实现其工作流程为start()先把世界导出为 HTML/W3D 场景world-exportAsHtml(fileName, true)再把目标文件名由.html替换为.json并开始录制WbAnimationRecorder.cpppopulateCommands()遍历世界中所有子节点对每个实现了fieldsToSynchronizeWithW3d()的节点创建一个WbAnimationCommand监听其相关字段的valueChanged等信号USE节点被跳过——DEF/USE 机制由前端webots.min.js处理WbAnimationRecorder.cppupdate()在每个物理步结束physicsStepEnded信号时检查是否满足当前时间 - 上次更新时间 1000.0 / fps满足则把这一时刻的脏字段dirty fields序列化写入JSON文件WbAnimationRecorder.cpp——这就是下文刷新率一节中WorldInfo.fps起作用的代码依据stop()断开信号、写入头部与初始帧、收尾关闭文件并询问用户是否在浏览器中打开WbAnimationRecorder.cpp。另外WbAnimationCommand在序列化translation与rotation时做了数值舍入ROUND(x, 0.0001)写入文件、ROUND(x, 0.001)做变化检测既能压缩数据量又避免每帧都因浮点噪声写出无意义更新WbAnimationRecorder.cpp。节点删除与标签Labels当某个节点在录制过程中被删除updateCommandsAfterNodeDeletion()会移除对应的录制命令避免写入失效节点数据WbAnimationRecorder.cppSupervisor 在仿真中添加的文本标签wb_supervisor_set_label也会被同步记录为动画的labels数组可随动画一起回放。动画记录字段的范围Limitations动画文件只记录以下字段的变化节点字段说明LED.colorLED 颜色变化Material.diffuseColor漫反射颜色变化Material.emissiveColor自发光颜色变化TextureTransform.translation纹理坐标平移仅针对 Track 节点用于表现传送带等履带纹理运动Pose.rotation姿态旋转Pose.translation姿态平移Light.color光源颜色变化Light.on光源开关变化其余字段均不会被记录节点的插入与删除也不会被记录。其他限制请参考 docs/guide/web-scene.md#limitations如Skin节点不支持、Pen设备不支持、同一页面只能存在一个webots-view元素等。从源码角度看记录哪些字段由各节点实现的fieldsToSynchronizeWithW3d()方法决定录制器只同步这些字段。例如src/webots/nodes/WbPose.cppPose同步translation、rotationsrc/webots/nodes/WbLight.cppLight同步color、on、intensity、ambientIntensity、castShadowssrc/webots/nodes/WbMaterial.cppMaterial同步ambientIntensity、shininess、specularColor、transparency、emissiveColor等src/webots/nodes/WbTextureTransform.cppTextureTransform同步center、rotation、scale、translation。一个值得注意的实现细节LED.color本身并没有独立的序列化逻辑——在 src/webots/nodes/WbLed.cpp 中LED 节点会递归查找其子结构中的Material、PBRAppearance与Light节点并把颜色写入这些节点setMaterialsAndLightsColor()。因此 LED 颜色动画在JSON文件中实际表现为Material.diffuseColor/Material.emissiveColor/Light.color等字段的更新这也解释了为什么LED.color出现在可记录字段列表中。场景刷新率Scene Refresh Rate动画的渲染节奏由浏览器标准的window.requestAnimationFrame()驱动其回调次数通常为每秒 60 次多数浏览器中会与显示器刷新率保持一致参见 MDN 关于requestAnimationFrame的文档。但刷新率还受WorldInfo.basicTimeStep影响因为动画更新只在仿真步进physics step时才会发出。实际刷新率可用下图公式估算即实际帧率受以下三者共同制约浏览器requestAnimationFrame提供的显示刷新率通常约 60 Hz仿真步长WorldInfo.basicTimeStep更新只在每个仿真步发送WorldInfo.fps录制器按1000 / fps毫秒间隔采样见上文WbAnimationRecorder::update()源码。实际刷新率约为min(1 / basicTimeStep, 显示刷新率)附近并受WorldInfo.fps的采样上限约束。注意不建议在录制动画过程中修改WorldInfo.FPS或WorldInfo.basicTimeStep字段否则会导致动画时间轴与采样节奏错乱。浏览器兼容性与安全限制Web 动画播放器内部基于WRENJS库Webots 渲染引擎 WREN 编译为 WebAssembly 的版本底层依赖WebGL 2。相关限制与应对方法与 Web Scene 一致详见 docs/guide/web-scene.md#remarks-on-the-used-technologies-and-their-limitations核心要点如下WebGL 2 支持新版 Firefox、Chrome、Edge 均已支持Safari 尚未支持遇到渲染异常请先确认浏览器设置中 WebGL 2 已启用。本地文件file协议限制Chrome、Firefox 68 等浏览器默认禁止通过file协议打开本地W3D与纹理文件而播放器需要读取这些文件。解决方式有两种在导出文件所在目录启动本地 HTTP 服务器然后通过服务器访问HTML文件# Python 3 python3 -m http.server # Python 2 python -m SimpleHTTPServer # Node.js需先全局安装 http-server sudo npm install -g http-server http-server临时关闭浏览器安全标志Chrome以--allow-file-access-from-files或--disable-web-security --user-data-dir.chrome启动Firefox在地址栏输入about:config搜索privacy.file_unique_origin或security.fileuri.strict_origin_policy双击将其从true改为false。总结Web Animation 把 Webots 仿真与 Web 发布无缝衔接通过 GUI 一键录制或 Supervisor API 程序化控制即可产出一套HTML W3D JSON CSS的交互式动画页面再由webots-viewWeb 组件在任意支持 WebGL 2 的浏览器中回放。录制过程以只记录变化字段 时间序列的方式生成紧凑的 JSON 动画字段范围受各节点fieldsToSynchronizeWithW3d()约束播放节奏则由WorldInfo.basicTimeStep、WorldInfo.fps与浏览器刷新率共同决定。掌握了本文的导出流程、组件 API 与底层机制你便可以在自己的网站中快速发布可交互、可自由观察视角的机器人仿真动画。赞分享科研自动驾驶物理引擎【免费下载链接】webotsWebots Robot Simulator项目地址https://gitcode.com/gh_mirrors/web/webots点击查看免费下载相关推荐Webots 网页接口Web Interface完整指南Web 场景导出、动画录制与 Streaming 流式传输Webots 网页接口Web Interface完整指南Web 场景导出、动画录制与 Streaming 流式传输 Webots 提供了一整套仿真上 W科研自动驾驶物理引擎OpenNHP 架构图动画录制指南用 Puppeteer 与 ffmpeg 将交互式 SVG 架构图导出为 GIF/MP4OpenNHP 架构图动画录制指南用 Puppeteer 与 ffmpeg 将交互式 SVG 架构图导出为 GIF/MP4 导读 OpenNHPZero T网络安全零信任密码学身份认证网络Carbon Components React数据可视化图表、仪表盘和数据表格的高级应用Carbon Components React数据可视化图表、仪表盘和数据表格的高级应用 Carbon Components React是IBM开发的基于Ca上一篇百度网盘密码智能获取工具完全操作指南下一篇Neovim LSP配置终极指南快速搭建300语言开发环境的完整方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进