三維場景中常用的路徑動畫


三維場景中常用的路徑動畫

前言

在三維場景中,除了用逼近真實的模型代表現實中的設備、標識物外,通常還會使用一些動畫來表示模型在現實中一些行為和作用。常見的動畫比如路徑動畫、旋轉動畫、發光動畫、流動動畫等。本文將為大家介紹幾種常用的路徑動畫。首先,最簡單的自然是直線路徑動畫。

直線路徑動畫

比如以下場景,地鐵需要從上一站A駛入當前站B,在此過程中,我們將AB組合成一條路徑(假設路徑為直線),使用動畫,不停的設置地鐵(模型)的在路徑上的位置,就可以實現地鐵從A站-B站的動畫過程。

const points = [A, B];
// 創建路徑
let path = new mono.Path();
points.forEach((point, i) => {
  const { x, y, z } = point;
  if (i == 0) {
    path.moveTo(x, y, z);
  } else {
    path.lineTo(x, y, z);
  }
});
// 動畫
const instance = new mono.Animate({
    form: 0,
    to:1,
    dur:3000,
    delay,
    reverse:false,
    repeat: 1,
    easing,
    onPlay,
    onUpdate: (val) => {
      // 獲取路徑上的點
      const point = path.getPointAt(val);
      // 設置實體位置
      entity.setPosition(point);
    },
    onDone,
});
instance.play();

動畫效果:

至此,直線路徑動畫就實現了。那么現在想想,現實場景中不可能只有直線運動這種場景,比如小車巡檢,就屬於一個折線場景,那么我們就需要使用折線動畫來完成。

折線路徑動畫

小車在房間內不間斷的通過巡檢監控,記錄設備狀態及檢測相關數據。模擬小車巡檢動畫,我們需要采集巡檢小車核心點位:A、B、C、D。同樣的將ABCD組合成路徑,不停的設置小車(模型)位置

const points = [A, B, C, D];
// 創建路徑
let path = new mono.Path();
points.forEach(...);
// 動畫
const instance = new mono.Animate({
    ...
    onUpdate: (val) => {
      // 獲取路徑上的點
      const point = path.getPointAt(val);
      // 設置實體位置
      entity.setPosition(point);
    },
    onDone,
});
instance.play();

動畫效果:折線路徑

當然,巡檢過程可能是一個循環的閉合路徑,所以可以滿足使用四個點創建閉環路徑,行形成閉環路徑動畫

折線路徑閉環動畫

const points = [A, B, C, D];
// 創建路徑
let path = new mono.Path();
points.forEach(...);
// 閉環路徑
path.closePath()
// 動畫
const instance = new mono.Animate({
    ...
});
instance.play();

動畫效果:閉環路徑

上面的折線動畫是完成了,但是轉彎的時候似乎略顯生硬,接下來我們再嘗試如何讓轉彎更自然。

圓潤的折線路徑動畫

其實很簡單,在已有的折線動畫基礎上,對路徑先進行一步拐角處理,讓路徑整體顯得很趨於自然。

const points = [A, B, C, D];
// 創建路徑
let path = new mono.Path();
points.forEach(...);
// 閉環路徑
path.closePath()
// 獲取平滑路徑, 讓轉彎更自然
path = mono.PathNode.prototype.adjustPath(path, 20, 1);
// 動畫
const instance = new mono.Animate({
    ...
});
instance.play();

動畫效果:轉彎更加的自然
自然彎道.gif
實現了圓潤的折線路徑動畫后,貌似看起來已經完工了。其實再仔細觀察下,可以發現,在轉彎的時候,模型沒有同步轉向,那么我們需要如何處理呢。

模型與路徑動畫同步旋轉

在折線動畫中,將模型繞對應的旋轉旋轉方向即可

const points = [A, B, C, D];
// 創建路徑
let path = new mono.Path();
points.forEach(...);
// 閉環路徑 獲取平滑路徑, 讓轉彎更自然
...
// 旋轉向量
const rotate = new mono.Vec3();
// 動畫
const instance = new mono.Animate({
    onUpdate: (val) => {
      // 位置
      ...
      // 模型同步旋轉
      const tangent = path.getTangentAt(val);
      var normal = new mono.Vec3(0, 0, -1);
      rotate.rotationTowards(normal, tangent);
      entity.setRotation(rotate);
    }
});
instance.play();

動畫效果:可以看到小車上的攝像頭是一直朝向設備

同步.gif
那么,直線路徑動畫和折線路徑動畫介紹完了。從上面動畫截圖中可以看出,我們是在一個固定的位置查看動畫,那么,能讓鏡頭沿着路徑一起移動么

鏡頭沿路徑動畫一起移動

顯然,鏡頭是可以沿着路徑同時移動的。通常用於巡航(自動巡檢)中.主要是在折線動畫的基礎上,同步設置鏡頭動畫的位置和朝向點。

const points = [....];
// 創建路徑
let path = new mono.Path();
points.forEach(...);
// 閉環路徑 獲取平滑路徑, 讓轉彎更自然
...
// 鏡頭初始位置
  const pos = camera.p(),
    target = camera.t();
  const length = pos.clone().sub(target).length();
// 動畫
const instance = new mono.Animate({
    onUpdate: (val) => {
      // 模型
      ...
      // 鏡頭沿路徑動畫
      const tangent = path.getTangentAt(value);
      point = path.getPointAt(value);
      ntarget = point.clone().add(tangent.multiplyScalar(length));
      camera.p(point);
      camera.lookAt(ntarget);
    }
});
instance.play();

動畫效果:

既然能讓鏡頭沿着路徑同步移動,那么是否能讓鏡頭與路徑保持平行移動呢

鏡頭與路徑保持平行一起移動

保持平行移動,其實是在點位的基礎上,將鏡頭位置設置到對應距離點位置。以下是基於動畫鏈完成的某流水線作業動畫,需要路徑動畫同時,鏡頭同步移動。對動畫鏈有興趣的可參考前文《基於路徑集合的三維動畫鏈

const points = [....];
// 創建路徑
let path = new mono.Path();
points.forEach(...);
// 閉環路徑 獲取平滑路徑, 讓轉彎更自然
...
// 鏡頭相對於目標動畫模型的距離
const dis = 550
// 動畫
const instance = new mono.Animate({
    onUpdate: (val) => {
      // 模型
      ...
      // 鏡頭平行X軸動畫
      point = path.getPointAt(value);
      camera.setPosition(point.clone().add(new mono.Vec3(0, dis, dis)));
      camera.lookAt(point);
    }
});
instance.play();

動畫效果:

案例說明

上面舉例說明動畫的示意圖,來自兩個案例,一個是地鐵站三維可視化,可以認為是一個軌道交通方面的;另外一個是實驗室車間 流水線可視化,主要用於流水線,設備監控等三維可視化呈現。

結語

至此,路徑動畫已經介紹的差不多了。利用常用的動畫能夠讓整個三維場景更豐滿,寫實。希望在項目中可以多多利用起來。

關注公眾號“ITMan彪叔” 可以及時收到更多有價值的文章。另外如果對可視化感興趣,可以和我交流,微信541002349.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM