iT邦幫忙

2022 iThome 鐵人賽

DAY 19
0
DevOps

IoT Cloud Computing on robotic vehicle系列 第 19

[虛實整合]前端3D介面讀取的檔案格式與顯示

  • 分享至 

  • xImage
  •  

前端介面的呈現我們使用Vue+three.js。

Vue我們不選用vue-cli來建置專案,而是使用Vite,以求更好的性能。

然後再利用Vue 3D plugins - troisjs(based on Vite),來使用three.js library控制WebGL,呈現Unity的地圖與車子(物件)資料在瀏覽器上。

https://ithelp.ithome.com.tw/upload/images/20221004/20005722PZrf7rvM8d.png
(成大學生念誠提供)

主要從troisjs中使用Camera, Renderer, Scene物件,協助畫面渲染。

import {
  Camera,
  Renderer,
  Scene,
} from 'troisjs';
  <Renderer ref="renderer" antialias orbit-ctrl resize="window">
    <Camera ref="camera" />
    <Scene ref="scene">
    </Scene>
  </Renderer>

左邊的icon是使用FontAwesomeIcon,並在css樣式上我們使用目前比較popular的atomic css - tailwind來協助畫面快速的樣式呈現。

    <div class="w-12 grid grid-cols-1 gap-4 "> 
      <button id="hand" class="bg-pink-600 hover:bg-pink-500 text-white font-bold py-2 px-2 rounded drop-shadow">
        <font-awesome-icon icon="hand" />
      </button>
      <button id="pointer" class="bg-pink-600 hover:bg-pink-500 text-white font-bold py-2 px-2 rounded drop-shadow">
        <font-awesome-icon icon="arrow-pointer" />
      </button>
      <button id="Cube" class="bg-pink-600 hover:bg-pink-500 text-white font-bold py-2 px-2 rounded drop-shadow">
        <font-awesome-icon icon="cube" />
      </button>
      <button id="Sphere"  class="bg-pink-600 hover:bg-pink-500 text-white font-bold py-3 px-2 rounded drop-shadow flex justify-center items-center">
        <svg-icon stroke-width="5px" name="sphere" class="w-fit h-4 icon-color"></svg-icon>
      </button>
      <button id="save"  class="bg-pink-600 hover:bg-pink-500 text-white font-bold py-2 px-2 rounded drop-shadow">
        <font-awesome-icon icon="floppy-disk" />
      </button>
    </div>

其中最後一個save button可以產生glTF(GL Transmission Format)格式的3D資料。

import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';
const exporter = new GLTFExporter();
// scene 是上述透過troisjs所取得的scene object
exporter.parse(
    scene,
    function ( gltf ) {
        const output = JSON.stringify( gltf, null, 2 );
        saveString( output, 'scene.gltf' );
    },
    function ( error ) {
        console.log( 'An error happened' );
    }
);

然後再轉成Unity可使用的.fbx格式,類似像以下格式:

Definitions:  {
	Version: 100
	Count: 4
	ObjectType: "GlobalSettings" {
		Count: 1
	}
	ObjectType: "Model" {
		Count: 1
		PropertyTemplate: "FbxNode" {
			Properties70:  {
				P: "QuaternionInterpolate", "enum", "", "",0
				P: "RotationOffset", "Vector3D", "Vector", "",0,0,0
				P: "RotationPivot", "Vector3D", "Vector", "",0,0,0
				P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0
				P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0
				P: "TranslationActive", "bool", "", "",0
				P: "TranslationMin", "Vector3D", "Vector", "",0,0,0
				P: "TranslationMax", "Vector3D", "Vector", "",0,0,0
				P: "TranslationMinX", "bool", "", "",0
				P: "TranslationMinY", "bool", "", "",0
				P: "TranslationMinZ", "bool", "", "",0
				P: "TranslationMaxX", "bool", "", "",0
				P: "TranslationMaxY", "bool", "", "",0
				P: "TranslationMaxZ", "bool", "", "",0
				P: "RotationOrder", "enum", "", "",0
				P: "RotationSpaceForLimitOnly", "bool", "", "",0
				P: "RotationStiffnessX", "double", "Number", "",0
				P: "RotationStiffnessY", "double", "Number", "",0
				P: "RotationStiffnessZ", "double", "Number", "",0
				P: "AxisLen", "double", "Number", "",10
				P: "PreRotation", "Vector3D", "Vector", "",0,0,0
				P: "PostRotation", "Vector3D", "Vector", "",0,0,0
				P: "RotationActive", "bool", "", "",0
				P: "RotationMin", "Vector3D", "Vector", "",0,0,0
				P: "RotationMax", "Vector3D", "Vector", "",0,0,0
				P: "RotationMinX", "bool", "", "",0
				P: "RotationMinY", "bool", "", "",0
				P: "RotationMinZ", "bool", "", "",0
				P: "RotationMaxX", "bool", "", "",0
				P: "RotationMaxY", "bool", "", "",0
				P: "RotationMaxZ", "bool", "", "",0
				P: "InheritType", "enum", "", "",0
				P: "ScalingActive", "bool", "", "",0
				P: "ScalingMin", "Vector3D", "Vector", "",0,0,0
				P: "ScalingMax", "Vector3D", "Vector", "",1,1,1
				P: "ScalingMinX", "bool", "", "",0
				P: "ScalingMinY", "bool", "", "",0
				P: "ScalingMinZ", "bool", "", "",0
				P: "ScalingMaxX", "bool", "", "",0
				P: "ScalingMaxY", "bool", "", "",0
				P: "ScalingMaxZ", "bool", "", "",0
				P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0
				P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0
				P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1
				P: "MinDampRangeX", "double", "Number", "",0
				P: "MinDampRangeY", "double", "Number", "",0
				P: "MinDampRangeZ", "double", "Number", "",0
				P: "MaxDampRangeX", "double", "Number", "",0
				P: "MaxDampRangeY", "double", "Number", "",0
				P: "MaxDampRangeZ", "double", "Number", "",0
				P: "MinDampStrengthX", "double", "Number", "",0
				P: "MinDampStrengthY", "double", "Number", "",0
				P: "MinDampStrengthZ", "double", "Number", "",0
				P: "MaxDampStrengthX", "double", "Number", "",0
				P: "MaxDampStrengthY", "double", "Number", "",0
				P: "MaxDampStrengthZ", "double", "Number", "",0
				P: "PreferedAngleX", "double", "Number", "",0
				P: "PreferedAngleY", "double", "Number", "",0
				P: "PreferedAngleZ", "double", "Number", "",0
				P: "LookAtProperty", "object", "", ""
				P: "UpVectorProperty", "object", "", ""
				P: "Show", "bool", "", "",1
				P: "NegativePercentShapeSupport", "bool", "", "",1
				P: "DefaultAttributeIndex", "int", "Integer", "",-1
				P: "Freeze", "bool", "", "",0
				P: "LODBox", "bool", "", "",0
				P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0
				P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0
				P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1
				P: "Visibility", "Visibility", "", "A",1
				P: "Visibility Inheritance", "Visibility Inheritance", "", "",1
			}
		}
	}
	ObjectType: "Geometry" {
		Count: 1
		PropertyTemplate: "FbxMesh" {
			Properties70:  {
				P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8
				P: "BBoxMin", "Vector3D", "Vector", "",0,0,0
				P: "BBoxMax", "Vector3D", "Vector", "",0,0,0
				P: "Primary Visibility", "bool", "", "",1
				P: "Casts Shadows", "bool", "", "",1
				P: "Receive Shadows", "bool", "", "",1
			}
		}
	}
	ObjectType: "Material" {
		Count: 1
		PropertyTemplate: "FbxSurfaceLambert" {
			Properties70:  {
				P: "ShadingModel", "KString", "", "", "Lambert"
				P: "MultiLayer", "bool", "", "",0
				P: "EmissiveColor", "Color", "", "A",0,0,0
				P: "EmissiveFactor", "Number", "", "A",1
				P: "AmbientColor", "Color", "", "A",0.2,0.2,0.2
				P: "AmbientFactor", "Number", "", "A",1
				P: "DiffuseColor", "Color", "", "A",0.8,0.8,0.8
				P: "DiffuseFactor", "Number", "", "A",1
				P: "Bump", "Vector3D", "Vector", "",0,0,0
				P: "NormalMap", "Vector3D", "Vector", "",0,0,0
				P: "BumpFactor", "double", "Number", "",1
				P: "TransparentColor", "Color", "", "A",0,0,0
				P: "TransparencyFactor", "Number", "", "A",0
				P: "DisplacementColor", "ColorRGB", "Color", "",0,0,0
				P: "DisplacementFactor", "double", "Number", "",1
				P: "VectorDisplacementColor", "ColorRGB", "Color", "",0,0,0
				P: "VectorDisplacementFactor", "double", "Number", "",1
			}
		}
	}
}

這個.fbx檔案我們可以透過後端的api,將資料使用byte string insert進去dynamodb資料庫中。

API我們使用python的fastapi框架,並搭配uvicorn作為啟動的server。

from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
from uuid import UUID
from datetime import datetime

class Item(BaseModel):
    _id: UUID
    topic: str
    timestamp: datetime
    payload: bytes

app = FastAPI()

@app.post("/fbx/")
async def create_fbxItem(item: Item):
    return item
uvicorn main:app --reload

如之前所說,insert data到dynamodb在python的code中使用boto3。

data = {
    "_id": "xxxx-xxxx-xxxx-xxxx",
    "topic": "fbx",
    "timestamp": int(round(time.time() * 1000)),
    "payload": pickle.dump(fbxObject)
}
table.put_item(Item=item)

之後讀取資料使用

response = table.get_item(
    Key={
        '_id': "xxxx-xxxx-xxxx-xxxx",
    }
)
item = response['Item']["payload"]
pickle.loads(bytes(item))

因此整個讀取檔案格式與顯示的架構改成如下:

https://ithelp.ithome.com.tw/upload/images/20221004/20005722LTKZpLbroF.png


上一篇
[虛實整合]Unity裡FRC虛擬車產出格式與溝通
下一篇
[虛實整合]Unity+ML雲端運算的設計與AWS support
系列文
IoT Cloud Computing on robotic vehicle30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言