iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
Build on Google AI

AI 策展人:用 Google ADK 打造會思考、會介紹的 3D 展示平台系列 第 11 篇

Day 11|自己蓋展示櫃(一):載入、轉台、復位,全由一份說明書決定

  • 分享至 

  • xImage
  •  

Day 10 對照過兩種檢視器,今天開始拆解自己寫的那個:viewer-core。這一篇處理最基本的三件事:載入 GLB、轉動它、轉亂了能復位。

用什麼寫的

viewer-core 用 three.js(最普及的網頁 3D 函式庫)實作。它的入口是一個函式 createViewer:你給它一個網頁上的容器,加上一份「場景說明書」(scene.json),它就在容器裡蓋好整個展示櫃。

基本功能,各對應一個零件

功能 怎麼做到的
載入 GLB 用 three.js 的 GLTFLoader 讀取。Day 09 壓縮過的檔案,由 DRACOLoader 負責解壓縮(解壓縮器預設走網路,離線播放包要指向本機)
載入進度條 GLTFLoader 回報進度;如果不知道總大小,就顯示一個不定長度的動畫;成功或失敗都會把進度條收起來
拖曳旋轉、縮放 OrbitControls(軌道控制器):鏡頭永遠繞著一個「目標點」轉,可拉近拉遠。開了「阻尼」,放手後帶點慣性,慢慢停下來
自動轉台 沒人碰時,鏡頭自己繞著展品轉;有人操作就停,閒置一段時間後又轉起來
復位 右下角按鈕,一按鏡頭回到說明書寫的初始位置;也可以設定「閒置太久自動復位」
打光 一盞半球環境光、一盞主燈、一盞補光,加上地面陰影

說明書:櫃子完全不知道自己在展什麼

viewer-core 不寫死任何展品。以下全部來自說明書 scene.json:

  • 鏡頭初始位置(camera.initial):看向哪裡、離多遠、水平與垂直角度、視野
  • 鏡頭限制(camera.limits):最近/最遠能拉到哪、最高/最低能看幾度
  • 自動轉台(camera.auto_rotate):開不開、每秒轉幾度、閒置多久(例如 20 秒)才重新開始轉
  • 互動(interaction):要不要復位按鈕、閒置多久(例如 60 秒)自動復位
  • 環境(environment):背景色、有沒有地面陰影

這就是 Day 03 講的「模型」(asset)與「怎麼展示」(scene)分開存:同一個櫃子換一份說明書,就是不同的展示。

單位陷阱:全黑的畫面

說明書的座標仍是 Day 03 約定的 Z 軸朝上、公釐;而 Day 09 的成品 GLB 已經是 Y 軸朝上、公尺。所以 viewer 拿說明書的數字去定位鏡頭之前,必須換算。這個換算集中在一個函式 convertPoint:先把公釐換成公尺(×0.001),再把軸向轉過去。整個套件只有這一個地方知道怎麼換算。

這個設計是被兩次意外教出來的:

  1. 展品躺著。 第一次為了不等其他工班,直接用 Day 07 的半成品 raw.glb(Z-up)。viewer 照契約假設拿到的已經是 Y-up,所以整台機器躺著。這是預期中的,不該為了遷就半成品去猜它有沒有轉過。
  2. 畫面全黑。 換上 Day 09 真正的成品後,畫面反而全黑。因為當時 convertPoint 只轉了軸向、沒換算單位:鏡頭以為展品在幾百公尺外,實際展品只有零點幾公尺大,小到不到一個像素;連鏡頭的「近裁切面」都是以公尺思考,展品直接被裁掉。修法:convertPoint 同時管軸向與單位,並且把鏡頭距離限制、近遠裁切面一併換算成公尺。

第一個問題在捷徑階段就看到,第二個問題只有換上真成品才炸出來,這正是「先用捷徑看到東西、再拿真正的輸出驗證」的價值。

還沒做的

Raycast 點選零件(Day 12)、導覽標記點(Day 13)。


上一篇
Day 10|【里程碑】終於看得到了:同一顆 GLB,兩種展示櫃
下一篇
Day 12|自己蓋展示櫃(二):點得到零件——Raycast、高亮、零件列表
系列文
AI 策展人:用 Google ADK 打造會思考、會介紹的 3D 展示平台 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言