三维组态部件动画解决方案
三维组态部件动画解决方案
前言
最近做了一个制冷系统的三维组态监控系统。大致的效果如下图所示:
其中涉及到的设备有冷却塔、水泵、螺杆机、离心机 、分水器(集水器)、阀门,以及管路。
其中冷却塔,水泵,螺杆机,离心机都有停机/开机状态,开机状态下要有叶轮转动效果。
因此我们需要给这几种模型,在开机状态下做叶轮转动的动画。
分离模型发方案
我们知道一般模型的动画主要是模型的位置,旋转角度等发生变化。位置旋转角度的变化是比较容易实现的一种动画。直接调用模型的setPosition方法和setRotation方法即可。
因此要做叶轮的旋转动画,一种比较简便的模式就是把叶轮的模型,从主体模型里面分离出来,做成一个独立的模型。然后针对独立模型不断的调用setRotation方法即可。示意代码如下:
function animate(obj){
new mono.Animate({
dur:1000,
from:0,
to:1,
onUpdate(v){
obj.setRotationX(v * Math.PI *2);
}
}).play();
}
分离模型的好处是动画的实现方式比较简单。但是也有缺点,增加了模型的数量。比如一个设备有多少个部件要进行动画,那就得独立出多少个模型。另外一个缺点就是独立的出来的部件的模型,需要和建模人员沟通部件在整个模型中的位置,开发人员需要进行位置的摆放,增加了开发的复杂度。
为了解决上面的缺点,我们的想法是使用整体模型。
整体模型方案
不分离模型,把所有的部件都做到一个设备模型上面,但是对部件进行分组命名。这样我们在导入整个模型之后,可以通过分组命名获取到部件子模型。然后对部件子模型进行动画操作。
但是这个里面有一个问题是此时部件子模型的建模中心点不在子模型本身的中心,而是整体设备的中心。因此我们不能通过简单的setRotation的方法来进行模型的旋转动画。而是首先需要把旋转的中心点移动到子模型真实的中心,然后再进行旋转操作。
那么问题来了如何获取子模型本身的中心点呢?
包围盒(BoundingBox)
首先想到的是通过计算模型的包围盒来计算部件的中心点。但是由于通过OBJ格式导入的模型,它的每一个部件的包围盒都是整个模型的大小。所以我们需要修改包外盒的计算逻辑。之所以部件包围盒的大小和整个模型的大小一样,是因为所有部件的顶点都是共享了一个顶点数组,该顶点数组包括了所有的部件顶点的集合。而计算部件的包围盒的时候,是通过所有顶点来进行计算的。而部件的实际的包围盒应该是只能包括自己本身的顶点,因此我们重新构建一个包围盒的计算方法。代码如下:
mono.Node.prototype.computeRealBoundingBox = function(){
if (this.realBoundingBox == null) {
this.realBoundingBox = new TGL.BoundingBox();
}
const vertices = this.vertices,
faces = this.faces,
realVertices = [];
let indices = [],set = new Set();
for(let i =0; i < faces.length;i ++){
let {a,b,c,d} = faces[i];
set.add(a);
set.add(b);
set.add(c);
if(d != null){
set.add(d);
}
}
indices = [...set];
indices.forEach((i) =>{
realVertices.push(vertices[i]);
});
this.realBoundingBox.setFromPoints(realVertices);
return this.realBoundingBox;
}
通过包围盒得到了部件的实际中心点之后,可以使用先平移再旋转的方法来进行旋转操作。大致代码如下:
function rotate(obj,axisDir){
let bbox = (obj._realBoundingBox = obj._realBoundingBox || obj.computeRealBoundingBox());
let center = bbox .center();
obj.rotateFromAxis(axisDir,center,0.2);
}
首先获取部件真实的包围盒。然后调用对象的rotateFromAxis方法进行旋转,该方法内部的第一个参数指定旋转的轴,第二个参数指定旋转的中心点,第三个参数指定了旋转的角度;该方法内部实际上是先进行平移操作,在进行旋转操作,具体实现上通过矩阵的变换叠加来实现。看看效果:
看起来好像完美,直到遇到这个模型:
感觉不对了,好像没有绕着中心点旋转。 这是因为通过包围盒计算模型中心点的时候,模型需要是一个基于中心点可以任意均分的形状。上面第一个张图和第二张图就是这样的(限于x轴方向),而第三张图中的模型明显不是。
那应该如何计算第三种模型的中心点呢?答案是使用包围球。
包围球(BoundingSphere)
首先,构造一个方法,计算模型的包围球体。
mono.Node.prototype.computeRealBoundingSphere = function() {
if (this.realBoundingSphere == null) {
this.realBoundingSphere = new TGL.BoundingSphere();
}
const vertices = this.vertices,
faces = this.faces,
realVertices = []
let indices = [],set = new Set();
for(let i =0; i < faces.length;i ++){
let {a,b,c,d} = faces[i];
set.add(a);
set.add(b);
set.add(c);
if(d != null){
set.add(d);
}
}
indices = [...set];
indices.forEach((i) =>{
realVertices.push(vertices[i]);
});
var center = new mono.Vec3(),
vertexNum = realVertices.length;
realVertices.forEach((v) =>{
center.x += v.x / vertexNum;
center.y += v.y / vertexNum;
center.z += v.z / vertexNum;
})
this.realBoundingSphere.setFromCenterAndPoints(center, realVertices);
return this.realBoundingSphere;
}
计算出部件的包围球之后,获取中心点,后面就是旋转模型,旋转的方法和前面说的一样。
function rotate(obj,axisDir){
let bSphere = (obj._realBoundingSphere = obj._realBoundingSphere ||obj.computeRealBoundingSphere());
let center = bSphere.center;
obj.rotateFromAxis(axisDir,center,0.2);
}
使用包围球后的效果:
可以看到中心旋转的效果出来了。
整体效果
最后,上一张整体的三维组态运行效果图:
总结
这种整体模型下部件进行动画的技巧,减少了需要建模师的工作量,同时也提高了开发人员的开发效率和开发的整体复杂度。
同时,这种方式有利于我们在三维组态编辑器中进行模型的整体导入和动画配置。 因为如果是分离的模型,我们还需要在编辑器中导入多个模型再进行模型的拼装,位置对齐等难度很大。
关注公号“ITMan彪叔” 可以及时收到更多有价值的文章。如果对可视化感兴趣,可以和我交流,微信541002349。
相关文章
- 赛博打工人会梦见996吗?年轻人的元宇宙入口,只要799
- 苹果发布新款iPad Pro!就换了个「芯」,转换器骚操作笑翻网友
- 斯坦福/谷歌大脑:两次蒸馏,引导扩散模型采样提速256倍!
- 「最牛AI艺术家」Stable Diffusion有多值钱?种子轮融资即晋升独角兽!
- Science与之江实验室联合发布:智能计算领域10个重大科学问题
- 死磕操作系统!谷歌重磅发布开源KataOS,网友:「谷歌坟场」喜+1
- 王者荣耀开源环境上榜!九月AI研究GitHub排行来了,「star多」才叫好论文
- DeepFake从未如此真实!英伟达最新提出的「隐式扭曲」到底有多强?
- 又来?美国酝酿新对华技术禁令,目标直指量子计算和AI软件
- WonderPen for Mac(妙笔写作软件) v2.2.3免激活版
- MIT新任女校长震撼北美高校圈!61岁的她曾是杜克首位女教务长
- 「图像编辑」太卷了!谷歌最新论文发布仅6小时就被自己砸了场子
- 这个让小伙和亡妻对话的AI火了!背后故事令人泪目
- 关于mac硬盘分区、容器、宗卷,这些事情你需要知道
- 新晋独角兽陷纠纷!「AI艺术大师」stable diffusion到底归谁所有?
- 全球割韭菜40亿美元,中国成重灾区!「加密货币女王」人间蒸发已五年
- Mac|ps 2020/2019/2018下载安装教程PS全版本软件下载地址(包括最新的2023)
- 克罗格 Kroger EDI需求分析及注意事项
- Photoshop2023安装及下载教程PS全版本软件下载地址(包括最新的2023)
- PS下载安装教程Win/Mac(含安装包)PS全版本软件下载地址(包括最新的2023)