隨着3D技術的不斷革新,爲了讓更多的用戶領略歷史之美,愈來愈多的博物館開始舉辦線上展覽。經過模擬不一樣的環境、燈光投影、360°無死角放大縮小展品,觀衆能夠享受到身臨其境的沉浸體驗。不只如此,給展品加上BGM或者語音解說,幫助觀衆更加了解展品的詳細背景,讓演示場景更有代入感。android
效果示意
看完如此逼真的效果展現,是否是想知道到底是怎麼實現的呢?git
經過Android Studio的Kotlin工程實現 3D場景構建、物品展現以及聲音播放功能,就能夠作到。app
1、準備3D模型
華爲移動服務最新開放的3D物體建模服務(3D Modeling Kit),助力輕鬆建模。咱們只需使用手機相機,經過拍攝物體的不一樣角度圖像,即可實現物體的3D幾何模型和紋理的自動化生成,爲應用提供3D模型構建、預覽等能力。具體操做指導可參考《5分鐘給商品創建3D模型,我是如何作到的?》maven
2、製做3D物體視圖
接下來咱們將準備好的展品3D模型,經過華爲圖形引擎服務建立一個可交互的3D物體視圖,如圖所示: ide
↓↓↓gradle
↓↓↓ui
集成華爲圖形引擎服務
軟件要求:JDK1.7及以上版本this
• minSdkVersion :設置爲19或以上編碼
• targetSdkVersion:設置爲19或以上url
• compileSdkVersion:設置爲19或以上
• Gradle 3.5及以上版本
在build.gradle文件中配置如下內容:
buildscript { repositories { ... maven { url 'https://developer.huawei.com/repo/' } } ... } allprojects { repositories { ... maven { url 'https://developer.huawei.com/repo/' } } }
在應用級build.gradle文件中配置如下內容:
dependencies { ... implementation 'com.huawei.scenekit:full-sdk:5.1.0.300' } 示例工程使用了Kotlin的viewBinding功能從而略過了視圖初始化樣板代碼。可在應用級build.gradle文件里加入以下代碼來啓用viewBinding功能: android { ... buildFeatures { viewBinding true } ... }
build.gradle文件同步完成後,就能在工程中使用圖形引擎服務了。
本文中,咱們僅須要使用該服務便可展現物品的3D圖像,而且與之進行交互。若是還須要使用其餘功能,能夠參閱華爲圖形引擎服務官方文檔。
建立3D視圖
建立自定義視圖的目的很簡單,確保視圖初始化完成後,第一個模型能自動加載到視圖裏。經過默認的SceneView手動實現模型加載,以下所示:
import android.content.Context import android.util.AttributeSet import android.view.SurfaceHolder import com.huawei.hms.scene.sdk.SceneView class CustomSceneView : SceneView { constructor(context: Context?) : super(context) constructor( context: Context?, attributeSet: AttributeSet? ) : super(context, attributeSet) override fun surfaceCreated(holder: SurfaceHolder) { super.surfaceCreated(holder) loadScene("qinghuaci/scene.gltf") loadSpecularEnvTexture("qinghuaci/specularEnvTexture.dds") loadDiffuseEnvTexture("qinghuaci/diffuseEnvTexture.dds") } }
展現物品需添加相關模型文件,打開工程文件夾,在「src/main」路徑下建立「assets」文件夾,將3D模型文件保存,好比:
surfaceCreated中的loadScene()、loadSpecularEnvTexture()和loadDiffuseEnvTexture()方法用於加載物品。建立surface後,第一個物品將加載到surface中。 接下來,打開用於展現3D模型視圖的XML文件,本工程中爲activity_main.xml。在該文件中,建立剛纔構造的CustomSceneView。下方代碼使用了箭頭圖片用以在不一樣的物品模型間切換。
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.example.sceneaudiodemo.CustomSceneView android:id="@+id/csv_main" android:layout_width="match_parent" android:layout_height="match_parent"/> <ImageView android:id="@+id/iv_rightArrow" android:layout_width="32dp" android:layout_height="32dp" android:layout_margin="12dp" android:src="@drawable/ic_arrow" android:tint="@color/white" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/iv_leftArrow" android:layout_width="32dp" android:layout_height="32dp" android:layout_margin="12dp" android:rotation="180" android:src="@drawable/ic_arrow" android:tint="@color/white" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
一切準備就緒,應用打開以後就能看到第一個展品:青花瓷花瓶了。
增長切換功能
如今,咱們經過切換功能來查看多個展品3D模型。 在MainActivity中,配置以下信息:
private lateinit var binding: ActivityMainBinding private var selectedId = 0 private val modelSceneList = arrayListOf( "qinghuaci/scene.gltf", "tangyong/scene.gltf", ) private val modelSpecularList = arrayListOf( "qinghuaci/specularEnvTexture.dds", "tangyong/specularEnvTexture.dds", ) private val modelDiffList = arrayListOf( "qinghuaci/diffuseEnvTexture.dds", "tangyong/diffuseEnvTexture.dds", ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) val view = binding.root setContentView(view) binding.ivRightArrow.setOnClickListener { if (modelSceneList.size == 0) return@setOnClickListener selectedId = (selectedId + 1) % modelSceneList.size // 確保ID處於模型列表的範圍內。 loadImage() } binding.ivLeftArrow.setOnClickListener { if (modelSceneList.size == 0) return@setOnClickListener if (selectedId == 0) selectedId = modelSceneList.size - 1 // 確保ID處於模型列表的範圍內。 else selectedId -= 1 loadImage() } } private fun loadImage() { binding.csvMain.loadScene(modelSceneList[selectedId]) binding.csvMain.loadSpecularEnvTexture(modelSpecularList[selectedId]) binding.csvMain.loadDiffuseEnvTexture(modelDiffList[selectedId]) }
在onCreate()中,建立了一個簡單的邏輯,查看下一個/上一個模型。物品文件路徑以字符串的形式保存於各個硬編碼列表中。能夠自行修改這個邏輯,使模型呈現更富動態。其中selectedId表示正在展現的物品模型ID。 這樣,就實現了利用SceneView來展現3D模型,效果以下:
3、爲展品增長講解詞
在加載不一樣的3D模型時,咱們能夠經過華爲音頻服務播放該展品對應的講解詞,爲用戶提供展品詳細介紹。 集成華爲音頻服務
軟件要求:
• JDK版本1.8.211及以上版本
• minSdkVersion:設置爲21
• targetSdkVersion:設置爲29
• compileSdkVersion:設置爲29
• Gradle 4.6及以上版本
能夠看到,音頻服務相較於圖形引擎服務軟件要求更高,因此咱們須要確保知足音頻服務的使用要求。
首先,打開應用級build.gradle文件,添加音頻服務的相關配置。
dependencies { ... implementation 'com.huawei.hms:audiokit-player:1.1.0.300' ... }
以前在配置圖形引擎服務時,已經添加了必要的庫,因此項目級build.gradle不須要改動。 在activity_main.xml文件中,添加一個簡單的播放按鈕。
<Button android:id="@+id/btn_playSound" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Play" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" />
這個按鈕能夠用來爲展現中的物品播放聲音。 而後,在MainActivity中添加如下配置:
private var mHwAudioManager: HwAudioManager? = null private var mHwAudioPlayerManager: HwAudioPlayerManager? = null override fun onCreate(savedInstanceState: Bundle?) { ... initPlayer(this) binding.btnPlaySound.setOnClickListener { mHwAudioPlayerManager?.play(selectedId) //建立播放列表實例。selectedId:播放曲目的參數。 } ... } private fun initPlayer(context: Context) { val hwAudioPlayerConfig = HwAudioPlayerConfig(context) HwAudioManagerFactory.createHwAudioManager(hwAudioPlayerConfig, object : HwAudioConfigCallBack { override fun onSuccess(hwAudioManager: HwAudioManager?) { try { mHwAudioManager = hwAudioManager mHwAudioPlayerManager = hwAudioManager?.playerManager mHwAudioPlayerManager?.playList(getPlaylist(), 0, 0) } catch (ex: Exception) { ex.printStackTrace() } } override fun onError(p0: Int) { Log.e("init:onError: ","$p0") } }) } fun getPlaylist(): List<HwAudioPlayItem>? { val playItemList: MutableList<HwAudioPlayItem> = ArrayList() val audioPlayItem1 = HwAudioPlayItem() val sound = Uri.parse("android.resource://yourpackagename/raw/soundfilename").toString() // soundfilename不包含文件擴展名。 audioPlayItem1.audioId = "1000" audioPlayItem1.singer = "Taoge" audioPlayItem1.onlinePath = "https://lfmusicservice.hwcloudtest.cn:18084/HMS/audio/Taoge-chengshilvren.mp3" //此處Demo使用歌曲示意 audioPlayItem1.setOnline(1) audioPlayItem1.audioTitle = "chengshilvren" playItemList.add(audioPlayItem1) val audioPlayItem2 = HwAudioPlayItem() audioPlayItem2.audioId = "1001" audioPlayItem2.singer = "Taoge" audioPlayItem2.onlinePath = "https://lfmusicservice.hwcloudtest.cn:18084/HMS/audio/Taoge-dayu.mp3"//此處Demo使用歌曲示意 audioPlayItem2.setOnline(1) audioPlayItem2.audioTitle = "dayu" playItemList.add(audioPlayItem2) return playItemList }
上述配置添加完成後,就能爲展品播放講解詞了。本工程使用的聲音音頻爲線上資源。若是須要播放本地音頻,能夠參考官網指導。這樣,就能導入音頻文件,爲物品播放聲音了。
至此,咱們就能夠建立一個360°可旋轉、放大縮小、帶有音效的展覽場景了。
最後,除了3D文物展現等應用場景,咱們還能夠把這些能力應用到不少相關行業,好比:
線上社交領域中的臉萌、視頻表情包、視頻虛擬背景; 電商購物領域的3D商品展現、家裝場景渲染、AR試穿; 影音領域的3D解鎖屏保/手機主題、3D特效渲染、直播表情包; 教育領域的3D教學、3D書籍、VR遠程教學。
欲瞭解更多詳情,請參閱:
>>華爲3D建模服務官網 、 開源倉庫
>>華爲圖形引擎服務官網 、 開源倉庫
>>華爲音頻服務官網 、 開源倉庫
>>華爲HMS Core官方論壇
>>解決集成問題請到Stack Overflow
點擊關注,第一時間瞭解HMS Core最新技術~