uniApp開發XR-Frame微信小程序 | 動態加載與刪除模型

在使用xr-frame開發3D小程序時,我們經常需要根據需求去動態加載模型或刪除模型,在官方的說明中,提到了相關方法,但并不太明確,也沒有確切的實例。

我們先來看一下官方給出的說明。

一. Shadow元素

我們需要用代碼動態創建元素之后添加到場景中,這個需求和wxml寫標簽這種靜態的模板編譯方式是沖突的,為了保證DOM樹不混亂,我們提供了類似于HTML中的ShadowRoot的XRShadow元素,對應于xml中的xr-shadow標簽,來解決這個問題。

<xr-shadow id="shadow" position="0 1 0" />

也就是說,我們要動態添加模型,就需要在這個xr-shadow元素下操作。

我們先來看一下實例

實例中,我們通過點擊下一個按鈕,將xr-frame框架中的模型卸載后再重新加載一個新的模型。

二.代碼實現

下面我們從源碼角度來講解如何實現。

(1)index.wxml?中的部分代碼

<xr-scene render-system="alpha:true" bind:ready="handleReady"><xr-light type="ambient" color="1 1 1" intensity="1" /><xr-light type="directional" rotation="40 150 0" color="1 1 1" intensity="3" cast-shadow /><xr-node node-id="target" anim-keyframe="anim" anim-autoplay="clip:cube"><xr-shadow id="shadow" position="0 0 0" /></xr-node><xr-env env-data="xr-frame-team-workspace-day" sky-map="weakme"/><xr-camera id="camera" clear-color="0 0 0 0" position="0 0.5 1.5" target="target" camera-orbit-control background="skybox"/>
</xr-scene>

上面的代碼中,我們主要看

<xr-shadow id="shadow" position="0 0 0" />

這段源碼就是shadow元素,我們要添加和刪除模型,都是在這個元素里操作的。

我們給shadow元素設置了id,就是用于在 index.js 文件中查找這個元素,然后通過xr-frame框架下的API操作在這個元素下添加新的節點。

(2)獲取場景中的shadow節點

?index.js?中的源碼中

handleReady({detail}) {this.xrFrameSystem = wx.getXrFrameSystem()this.scene = detail.valuethis.control.isLockZoom = truethis.shadow = this.scene.getElementById('shadow')// 給父組件發送通知this.triggerEvent('sceneReady',"ready")},

handleReady() 這個函數表示場景加載完成后執行的回調函數。

在這個函數中,我們通過?this.scene = detail.value?獲取到了場景的根節點信息,這一步是基礎,獲取到場景的根節點后,才能獲取更多的子節點。

隨后,我們通過?this.shadow =this.scene.getElementById('shadow')?獲取到了?shadow?元素的節點,下一步,我們就要實現在?shadow?元素下添加子節點的操作了。

(3)使用api動態創建gltf節點到shadow中。

async addGltf() {//1 創建xr-gltf元素const el = this.scene.createElement(this.xrFrameSystem.XRGLTF)//2 獲取shadow節點this.shadow = this.scene.getElementById('shadow')//3 將xr-gltf節點加入到shaodow節點中this.shadow.addChild(el)//4 讀取對應的模型文件const { value: model} = await this.scene.assets.loadAsset({type: 'gltf',assetId: 'gltfmodel',src: modelsrc})// 5 獲取gltf組件this.gltfComp = el.getComponent('gltf') // 6 給gltf組件設置模型數據this.gltfComp.setData({model: model})// 7 給元素設置一個ID,用于后續方便removeel.setId(name)
}

注意:這個函數前面加了 async ,是一個異步函數。

因為在函數中我們需要做加載模型文件的操作,這個操作可能會很耗時,需要視網絡情況和模型大小而定。

下面我們一步步解析:

..1 源碼中,我們先創建了一個xr-gltf元素

const el = this.scene.createElement(this.xrFrameSystem.XRGLTF)
????????這里通過框架的API createElement()我們創建了一個元素

..2?然后將該元素作為子元素添加到shadow元素中

//2 獲取shadow節點
this.shadow = this.scene.getElementById('shadow')
//3 將xr-gltf節點加入到shaodow節點中
this.shadow.addChild(el)
? ? ? ? 這里我們先通過 getElementById() 方法找到shadow節點。
? ? ? ? 然后,通過?addChild() 方法將創建的XRGLTF元素添加到節點下。

..3?通過?scene.assets.loadAsset()?方法加載一個模型資源

const { value: model} = await this.scene.assets.loadAsset({type: 'gltf',assetId: 'gltfmodel',src: modelsrc})
這個方法中有幾個屬性:
type?表示要加載的資源類型,這里設置為gltf。
assetId?表示設置的資源ID,這個可以用于后期清理資源。
src?表示資源的網絡地址。
這里需要注意的一點,scene.assets.loadAsset()?這個方法要加載資源,有時耗費時間會比較長,所以這里采用async/await?的語法來進行異步操作。

..4?獲取到xr-gltf元素中的 gltf 組件

this.gltfComp = el.getComponent('gltf') 
這一部,我們獲取到了元素XRGLTF元素中的gltf組件

..5 給組件設置屬性

// 6 給gltf組件設置模型數據
this.gltfComp.setData({model: model})
// 7 給元素設置一個ID,用于后續方便remove
el.setId(name)
這一步我們給組件中的model屬性設置了變量名為?model?的對象
這個 model 就是我們第3步加載的模型對象
最后我們給元素 el 設置了一個id。用于后期清理資源使用。

(4)清理資源

在官方說明中,通過動態加載的資源需要自己手動釋放,不然如果加載越來越多,會對程序造成卡頓。

release(name) {//1 刪除節點this.shadow.removeChild(this.scene.getElementById(name))//2 釋放資源this.scene.assets.releaseAsset('gltf', name)
},

上面代碼中,我們首先調用了 shadow.removeChild() 方法,移除了shadow下的子節點。

然后通過 scene.assets.releaseAsset()方法,釋放了加載的gltf資源。

函數中的參數 name 就是我們給上一步創建的 el 設置的 id

函數中的這兩個方法都是xr-frame官方api中的方法,詳細的解釋可以看一下官方文件。

關于釋放資源的時機,可以根據自己的場景需求進行合理的設計。

三.附件說明

附件中的代碼就是本篇文章用到的動態加載模型的xr-frame組件中的代碼。

代碼中我做了一些優化,由于gltf文件有時會過大,所以我采用模型和貼圖分開加載的方法,加載完成后再給模型設置上貼圖。

大家可以參考學習,如果不會配置需要查看一下這篇文章,xr-frame基礎環境搭建。

四.示例小程序

附件中的小程序碼,是我根據官方指南做的一個簡易的示例程序,其中運用了場景的搭建,材質動態修改,模型動態添加與刪除,粒子特效等功能,可以作為本片文章的參考。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:
http://www.pswp.cn/web/97894.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/97894.shtml
英文地址,請注明出處:http://en.pswp.cn/web/97894.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

把多個 PPT 合并在一起,三步告別復制粘貼

制作部門匯報分冊、項目階段文件等工作需要將多個零散的PPT合并為一份完整文檔。手動復制粘貼不僅效率低下&#xff0c;還容易導致格式錯亂、動畫丟失。本文介紹一種高效方法&#xff0c;三步操作即可將多個PPT文件快速合并為單一文檔。無論是整合匯報材料&#xff0c;還是準備…

安卓旋轉屏幕后如何防止數據丟失-ViewModel入門

Android ViewModel 入門教程 在日常開發中&#xff0c;當 Activity 因為旋轉屏幕或內存回收被銷毀重建時&#xff0c;UI 中的數據也會丟失。 這時候&#xff0c;Android Jetpack 提供的 ViewModel 就能幫我們解決這個問題。 1. 什么是 ViewModel ViewModel 是一種架構組件。它專…

Linux 下的 Vim 使用與網絡安全配置詳解

目錄 引言 一、Vim 編輯器的使用 1. Vim 的模式 2. 常用操作命令 3. 保存與退出 4. 多窗口與 Shell 切換 二、Linux 網絡基礎 1. 網絡分類 2. IP 地址與分類 三、網絡配置與工具 1. ifconfig 2. netstat 3. wget 4. 主機名與 IP 映射 四、Linux 防火墻與安全設置…

Docker 容器傳輸文件的常用方法

Docker 容器傳輸文件的常用方法 在 Docker 日常使用中&#xff0c;經常需要在主機與容器之間傳輸文件&#xff08;如配置文件、代碼包、日志等&#xff09;。以下是四種最常用的實現方式&#xff0c;覆蓋臨時傳輸、持久共享、構建集成等不同場景。 1. 使用 docker cp 命令&…

視頻轉音頻在線工具大比拼,哪家體驗更勝一籌?

最近工作上遇到了個挺有意思的需求&#xff0c;需要從幾個教學視頻里提取出音頻內容&#xff0c;方便做成播客形式&#xff0c;讓學員能隨時隨地學習。一開始&#xff0c;我以為這活兒挺簡單的&#xff0c;不就是把視頻里的聲音單獨弄出來嘛&#xff0c;結果一上手才發現&#…

KafKa02:Kafka配置文件server.properties介紹

一、配置文件位置二、配置文件介紹默認下&#xff1a;9092 是處理消息隊列核心業務&#xff08;客戶端與 broker 交互&#xff09;的端口9093 是集群內部控制器通信的端口# 指定節點角色&#xff0c;這里同時作為 broker&#xff08;消息代理&#xff09;和 controller&#xf…

哈爾濱云前沿服務器租用托管

黑龍江前沿數據&#xff0c;始建于2005年&#xff0c;多年的歷史&#xff0c;專業從事域名注冊&#xff0c;虛擬主機&#xff0c;服務器租用&#xff0c;云主機&#xff0c;網站建設等互聯網服務。電信/聯通/雙線/機房/眾多機房供您選擇&#xff0c;總有一個適合您的服務器&…

Qt開發經驗 --- Qt 修改控件樣式的方式(16)

文章目錄[toc]1 概述2 Qt Style Sheets (QSS)3 使用 QStyle 和 QProxyStyle4 設置 Palette (調色板)5 使用預定義的 QStyle6 直接設置控件屬性7 自定義控件繪制更多精彩內容&#x1f449;內容導航 &#x1f448;&#x1f449;Qt開發經驗 &#x1f448;1 概述 Qt 提供了多種修改…

Vue3》》Svg圖標 封裝和使用

SVG 安裝插件 npm i vite-plugin-svg-icons // vite.config.ts import { defineConfig } from vite import vue from vitejs/plugin-vue import { createSvgIconsPlugin } from vite-plugin-svg-icons import { resolve } from path export default defineConfig({//配置路徑別…

【04】AI輔助編程完整的安卓二次商業實戰-尋找修改替換新UI首頁圖標-菜單圖標-消息列表圖標-優雅草伊凡

【04】AI輔助編程完整的安卓二次商業實戰-尋找修改替換新UI首頁圖標-菜單圖標-消息列表圖標-優雅草伊凡引言本次二開布局沒有變&#xff0c;但是下一次整體布局會有變&#xff0c;不過本次開發發現朋友圈跳轉功能的流程步驟也做了一定的變化。原生項目復雜就復雜于就算一個顏色…

龍蜥8.10中spark各種集群及單機模式的搭建spark3.5.6(基于hadoop3.3.6集群)

先說最終的訪問端口&#xff0c;如我這里ip為172.20.94.37、172.20.94.38、172.20.94.39&#xff0c;主機名分別為&#xff1a;hadoop37、hadoop38、hadoop39. 最終訪問&#xff08;默認端口&#xff09;&#xff1a; hadoop webui 172.20.94.37:9870 hdfs 端口 8020 yarn 172.…

關于我重新學習 react 的第一遍

今天是25年9月11號&#xff0c;很久很久沒有學習前端知識了&#xff0c;坦誠來說還清楚記得在大學里因為前端技術第一次獲獎的心情&#xff0c;也清晰記得寫完第一篇博客后的心情&#xff0c;工作和運動給我最大程度的成就感。 打破自己 重新開始 完全地 版本一 25.9.11 文章目…

第2課:Agent系統架構與設計模式

第2課&#xff1a;Agent系統架構與設計模式 課程目標 理解Agent的基本概念和特性掌握多Agent系統的設計模式學習Agent通信協議和消息傳遞實踐創建簡單的Agent框架 課程內容 2.1 Agent基礎概念 什么是Agent&#xff1f; Agent是一個具有自主性、反應性、社會性和主動性的計…

Day42 51單片機中斷系統與8×8 LED點陣掃描顯示

day42 51單片機中斷系統與88 LED點陣掃描顯示一、51單片機引腳位操作 —— sbit 關鍵字 作用 sbit 是專用于 51 單片機架構的 C 語言擴展關鍵字&#xff0c;用于定義特殊功能寄存器&#xff08;SFR&#xff09;中的某一位&#xff0c;從而實現對單個 I/O 引腳的直接位操作。 示…

差分: 模板+題目

題目&#xff1a;【模板】差分 應用場景&#xff1a;快速解決將某一個區間所有元素加上 “一個數” 的操作。 第一步&#xff0c;預處理差分數組。 f[i] 表示&#xff1a;當前元素與前一個元素的差值 a[i] - a[i-1]; 但在題目中&#xff0c;我們其實可以不用到a[]這個數組…

GD32 Timer+ADC多通道+DMA+PWM調試記錄

本例記錄使用GD32307C開發板&#xff0c;實現以內部Timer1 CH1為觸發源&#xff0c;觸發ADC0的兩個通道&#xff0c;進行并行非連續采樣&#xff0c;病通過DMA傳輸采樣結果。同時輸出PWM&#xff0c;用來檢測Timer1 CH1的觸發周期。下面介紹具體實現過程&#xff1a;1. gpio初始…

阻塞 IO為什么叫BIO,非阻塞IO為什么叫NIO,異步IO為什么叫AIO

IOIO的核心就是數據傳輸&#xff0c;也就是程序與外部設備之間進行傳輸&#xff0c;通過IO的核心可以分為&#xff0c;文件IO和網絡IO文件IO交互的對象就是本地存儲設備&#xff0c;比方說讀寫本地文件。網絡IO交互的對象就是網絡設備&#xff0c;核心的應用場景就是網絡通信。…

10分鐘了解什么是多模態大模型

10分鐘了解什么是多模態大模型&#xff08;MM-LLMs&#xff09; 1. 什么是多模態 Multimodality 多模態&#xff08;Multimodality&#xff09;是指集成和處理兩種或兩種以上不同類型的信息或數據的方法和技術。在機器學習和人工智能領域&#xff0c;多模態涉及的數據類型通常…

通過DSL生成Jenkins流水線

代碼化管理 Jenkins 流水線&#xff08;Infrastructure as Code&#xff09; 版本控制&#xff1a;DSL 腳本可以像代碼一樣存入 Git、GitLab 等版本控制系統&#xff0c;所有任務配置的變更都有提交記錄&#xff0c;便于追溯歷史、回滾錯誤。協作效率&#xff1a;團隊成員可以通…

信號量主要API及綜合應用

1.信號量概述信號量是一個底層核心模塊【int】類型變量&#xff0c;記錄當前信號量數據。信號量 P 操作 (sem_wait)線程檢測對應信號量底層 int 數據數值&#xff0c;如果大于 0&#xff0c;當前線程獲得 CPU 執行權&#xff0c;同時將信號量底層 int 數據-1 操作。如果底層數據…