找回密码
 立即注册

QQ登录

只需一步,快速开始

nimotea

超级版主

23

主题

95

帖子

540

积分

超级版主

Rank: 8Rank: 8

积分
540
nimotea
超级版主   /  发表于:2023-12-8 11:09  /   查看:1009  /  回复:0
本帖最后由 nimotea 于 2024-1-11 17:28 编辑

背景

在制作3D可视化看板时候,除了精细的模型结构,炫酷的动画效果也是必不可少的。当然,动画效果有复杂的和简单之分,动画效果,要做到100%的自然平滑,不管是物理引擎的计算能力,还是要对动画效果做数学建模分析,抑或是模型网格复杂程度,都会是极具挑战性的工作。相信除了专业的3D建模从业人员,几乎无法完成这项挑战。但回到实际情况,当我们对动画精细程度的要求没有那么高的情况下,我们还是能借助一些外部工具来实现一些比如巡检,移动,旋转的组合动画。今天介绍的工具就是 BABYLONJS 中提供的 动画曲线编辑器,通过 ui 拖拽点击,就能自定义设计动画效果了。(文末有示例代码可以参考)




动画编辑器.gif125350951.png
robotAnimation (1).gif879331664.png


前置说明
要使用动画曲线编辑器,就得先使用 BABYLON Inspector,后者是 BABYLONJS 提供的一个强大的模型检查工具,不仅可以查看模型网格对象的各种属性,还可以提供 gizmo 工具来让用户手动拖拽缩放平移网格体,实现和3D模型的实时交互,最后还具备像 动画曲线编辑器等强大工具,让用户可以通过 ui 操作就能自定义设计动画效果。那要使用 BABYLON Inspector 又需要哪些操作呢?
①  babylon playground 站点 这个站点提供了一个在线的 babylonjs 代码运行环境,用户可以在这个平台上协同创建3D场景,   缺点: 要引入外部资源(模型,图片),只能通过 web url 方式载入。
babylon sandbox 站点 这个站点提供了一个在线的 模型运行检查环境,用户可以在这个平台上检查自己的 模型文件是否正常运行,参数设定是否如预期,缺点: 不能同时引入多个模型文件(比如,先引入园区模型,再引入人物模型,这在 sandbox 环境是无法实现的。)
代码方式引入 ,因为babylonjs 毕竟是 前端工具, insepector 也提供了对应的前端开发包  
  1. npm install @babylonjs/core
  2. npm install @babylonjs/inspector
复制代码
引入依赖包之后,只需要通过
  1. import { Inspector } from "@babylonjs/inspector";
  2. function createScene(){
  3. // create babylonjs scene
  4. return scene;
  5. }
  6. const scene = createScene();
  7. Inspector.Show(scene);
复制代码
即可对指定的 3D 场景应用 Inspector 查看器了。缺点:需要一定的前端开发基础。

动画须知
在使用动画编辑器之前,首先需要了解,babylonjs 中的动画 其实就是 按顺序执行的一系列帧画面,所以,如果了解了每一帧 模型对象的属性值,就可以制作出对应的动画。


动画编辑器场景
使用动画编辑器有两种场景
  • 选中一个模型对象,选择右侧对象的 Animations 属性,点击 Editor 就可以新增或修改动画

    open_curve_editor1.jpg550016479.png
  • 选中一个模型的 AnimationGroup ,即可编辑 Group 中每个单独动画

    open_curve_editor2.jpg38641356.png


动画编辑器菜单说明
curve_editor_menu.jpg282757567.png


createMenu.jpg851868591.png
  • "+" 按钮即为创建动画按钮,一个动画编辑器中可以对对象创建多个动画
   其中创建菜单中的选项如下
  • Display Name 为动画名称
  • Mode 为 List 即为内置的模型属性,Custom 即为 自定义的模型属性
  • Property 取决于 Mode 的选择模式,一般List 情况下就能够下拉选择到 position rotation 等常用属性
  • Type 即 property 的数据类型,这个也和代码创建动画的参数是一致的


  • 第二个箭头符号 则表示用户可以上传动画内容,和下一个保存按钮中的保存为 json  文件中的格式保持对应
  • 保存按钮, 可以保存到 babylon 的在线服务器也可以保存为 json 文件
  • 编辑按钮,可以编辑现有的动画内容
  • 每秒显示帧数, fps 支持用户自定义修改


接下来是编辑器主题部分顶部的 key 控制面板
keyControls.jpg350886534.png
frameKey.png366385497.png
其中按钮分别是
  • 当前 key 帧数,当用户选中一个 key 时,可以通过这个输入框来修改 当前 key 的帧号 (选中一个key时)
  • 当前 key value 当用户选中一个 key 时,可以通过这个输入框来修改当前 key 的属性具体值 (选中一个key时)
  • 创建关键 key, 这个按钮将会再 整个播放轴上 创建一个 新的 关键 key, 并且将 渲染画布此时 网格对象的对应属性值 作为 新创建 key 的属性值,(换句话说,可以在 inspect 页面通过 gizmo 工具拖动旋转物体到指定位置,点击创建 关键 key 按钮就能创建一个新的关键 key , 并将手动拖动的网格对象的属性值作为 该关键 key 的value 值)
  • 帧画布 ,这个按钮会自适应当前设定的 关键 key, 当在设定的 key value 超出画布时,可以使用该按钮来重置画布。

接下来的 5 个按钮都是用来控制 每个 关键 key 和前后帧 的 value 之间的变化关系,也就是关键 key 的左右切线
  • 平铺切线,会让当前关键 key 的左右切线都变成 水平线,在这种情况下,由于 左右斜率一致,我们可以做出一些更加平滑的曲线效果出来
  • 线性切线,会让当前关键 key 的左右切线都变成 指向 前后关键 key 的 一次线条,一般用来展示一些匀速变化关系
  • 切分左右切线模式,可以单独的控制 关键 key 的左右切线
  • 整合左右切线模型,如上,切分模式的反面
  • 阶梯式切线,在从 当前 key 到 下一个 key 之间的帧,value 值保持不变,在下一个关键 key 到来时,value 瞬间切换到该 key value,可以用来制作一些转身,旋转的瞬时动画

stepTangents.jpg428713683.png


最后是动画播放面板
playControls.jpg498987731.png
按钮分别如下
  • 第一帧和最后一帧

firstLast.jpg792380370.png

  • 前一帧和后一帧

previousNext.jpg433668517.png

  • 前一个和后一个关键 key

prevKeyNextKey.jpg350705260.png

  • 播放和倒放动画

playButtons.jpg601226501.png

  • 播放范围,需要指定动画开始和结束播放帧数


playRange.jpg142692870.png
正常情况下,指定了动画属性值和播放模式之后,就可以点击创建 关键 key 来设定关键动画值,一方面可以在 inspector 中手动拖动网格对象,让新建key来获取指定 value, 另一方面也可以在 动画播放面板反复查看修改动画属性,制作好动画之后,就可以使用保存按钮来将制作好的动画导入了。对于历史动画也可以通过导入按钮来对动画做细节调整。

动画制作(实战)
当动画路线比较复杂,而且对动画速度时机的展示要求比较高得情况下,就需要先提前大概算出来动画得关键参数。这里以绕场一周动画为例,说明下步骤:


首先需要获取到总帧数,以及特定行为(转向移动)的对应帧数。(这一步是动画制作最重要的一步,总体上可以参考物理位移原理  位移 = 速度 * 时间  来合理设计帧数。)
  • 获取到物体运动的路线图,记录下每一个特殊(转向移动)帧 模型对象所在的坐标(这里可以使用Inspector 当中的坐标拾取功能以及 位移 gizmo 工具来快速获取)


pathPosition.png171122740.png

  • 可以给物体运动设置一个固定速度,比如每秒 2.5 个单位,使用坐标算出来 每个坐标到坐标的距离,除以时间便是每个单独路径的耗时。

calculateTime.png341218566.png

  • 然后需要计算累计耗时

Calculate_accumulated_time.png584277343.png

  • 累计耗时乘以 默认 每秒渲染的帧数, 就可以得到最终的 动画帧数据了(切记不要忘了乘每秒帧数,默认每秒60帧)



接下来就要引入 Inspector 模块了,参考文章开始的 playground,sandbox, 或者代码开发
引入 Inspetor, 打开动画编辑器,新建动画
animationCurve.jpg451675109.png
我们在 上一步中计算了总帧数为 20*60 = 1200, 修改动画播放范围
totalFrame.jpg374844970.png
注意到网格对象全程 y 坐标都是 0 ,我们可以先确定 y 轴动画
yAxisValue.jpg117284239.png
然后按照创建 新 key => 设定新key frame value => 播放动画方式来创建新key
createNewKey.png954862670.png
通过切线按钮可以调整动画之间的线性关系
createAnimation.jpg789268493.png

最后就是点击保存按钮,点击导出成 file, 在代码中可以通过这两种方式来导入动画内容

  1. // url 文件方式
  2.     let animation = Animation.ParseFromFileAsync(null,urlPath)
  3.   // json hard-code
  4.     var json = animationJson; // 将动画文件内容写死在代码里
  5.     let animation = [Animation.Parse(animationJson[0])];
  6.    
  7.     // 直接执行动画,或者包装成 animationGroup 来执行,后者封装性更好;
  8.     let robot.animations= animation;
  9.      scene.beginAnimation(robot,0,8871,true);

  10.     // animatioinGroup
  11.       let robotAnimation = new BABYLON.AnimationGroup("robotAnim",scene);
  12.       robotAnimation.addTargetedAnimation(animations[0],robot);
  13.       robotAnimation.addTargetedAnimation(animations[1],robot);
  14.       robotAnimation.from = 0;
  15.       robotAnimation.to = 3120;
  16.       robotAnimation.start(true,1,robotAnimation.from,robotAnimation.to,false);
复制代码
以上,便是使用 动画曲线编辑器来实现一个简易动画的全过程了,最后我也上传一份代码集成 Inspector 模块的示例,感兴趣的小伙伴可以试试。 3D-Inspector.zip (16.81 MB, 下载次数: 76)
您需要登录后才可以回帖 登录 | 立即注册
返回顶部