如何用AR Engine環境Mesh能力實現虛實遮擋

在AR應用中,用戶最不希望看到不真實的穿模現象發生,如虛擬形象部分身體陷入墻壁之中,或者未碰到墻壁卻已無法移動,這種不真實的交互十分影響用戶體驗 。那如何才能讓避免虛擬物體的穿模問題呢?使用AR Engine的環境Mesh能力就能幫助開發者解決這個問題 。
效果展示實現方法AR Engine提供實時計算并輸出畫面環境Mesh數據的能力 。通過環境Mesh能力虛擬角色可以準確識別當前所處三維空間的情況,讓虛擬物體不僅僅能放置在水平面和垂直面上,還可以放置在任意可重建的曲面上 。開發者可利用重建的環境Mesh實現虛實遮擋和碰撞檢測,可以讓虛擬物體藏在真實物品后,避免現實物體和虛擬物體融合現象的發生,從而實現沉浸式AR體驗 。
集成步驟開發環境要求:JDK 1.8.211及以上 。
安裝Android Studio 3.0及以上:
minSdkVersion 26及以上
targetSdkVersion 29(推薦)
compileSdkVersion 29(推薦)
Gradle 6.1.1及以上(推薦)
在華為終端設備上的應用市場下載AR Engine服務端APK(需在華為應用市場 , 搜索“華為AR Engine”)并安裝到終端設備 。
測試應用的設備:參見AREngine特性軟硬件依賴表中環境Mesh支持設備列表 。如果同時使用多個HMS Core的服務,則需要使用各個Kit對應的最大值 。
開發準備

  1. 在開發應用前需要在華為開發者聯盟網站上注冊成為開發者并完成實名認證,具體方法請參見帳號注冊認證 。
  2. 華為提供了Maven倉集成方式的AR Engine SDK包 , 在開始開發前,需要將AR Engine SDK集成到您的開發環境中 。
  3. Android Studio的代碼庫配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同 。請根據您當前的Gradle插件版本,選擇對應的配置過程 。
  4. 以7.0為例:
打開Android Studio項目級“build.gradle”文件,添加Maven代碼庫 。
在“buildscript > repositories”中配置HMS Core SDK的Maven倉地址 。
buildscript {     repositories {         google()         jcenter()         maven {url "https://developer.huawei.com/repo/" }     }}打開項目級“settings.gradle”文件,配置HMS Core SDK的Maven倉地址
dependencyResolutionManagement {    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)    repositories {        repositories {             google()            jcenter()            maven {url "https://developer.huawei.com/repo/" }        }    }}
  1. 添加依賴 在“dependencies”中添加如下編譯依賴:
dependencies {    implementation 'com.huawei.hms:arenginesdk:{version}}開發步驟
  1. 創建HitResultDisplay類,這個類根據指定的參數來繪制虛擬對象
Public class HitResultDisplay implements SceneMeshComponenDisplay{ //初始化VirtualObjectData VirtualObjectData mVirtualObject = new VirtualObjectData(); //在init方法中給mVirtualObject傳入上下文 Public void init(Context context){mVirtualObject.init(context);//傳入材質屬性mVirtualObject.setMaterialProperties(); } //在onDrawFrame方法中傳入ARFrame,用來獲取光照估計 Public void onDrawFrame(ARFrame arframe){//獲取光照估計ARLightEstimate le = arframe.getLightEstimate();//獲取當前相機視野的像素強度lightIntensity = le.getPixelIntensity();//獲取好之后,需要給mVirtualObject中一些方法傳入數據mVirtualObject.draw(…,…,lightIntensity,…);//創建handleTap方法傳入ARFrame對象來獲取坐標信息handleTap(arframe); }     //實現handleTap方法     Private void handleTap(ARFrame frame){        //用ARFrame對象調用hitTest        List<ARHitResult> hitTestResults = frame.hitTest(tap);        //檢測平面是否被擊中,是否在平面多邊形中被擊中        For(int i = 0;i<hitTestResults.size();i++){            ARHitResult hitResultTemp = hitTestResults.get(i);            Trackable = hitResultTemp.getTrackable();            If(trackable instanceof ARPoint && ((ARPoint) trackable).getOrientationMode() == ARPoint.OrientationMode.ESTIMATED_SURFACE_NORMAL){                isHasHitFlag = true;                hitResult = hitResultTemp;            }        }     }}

推薦閱讀