共计 7096 个字符,预计需要花费 18 分钟才能阅读完成。
随着 3D 技术的一直变革,为了让更多的用户领略历史之美,越来越多的博物馆开始举办线上展览。通过模仿不同的环境、灯光投影、360°无死角放大放大展品,观众能够享受到身临其境的沉迷体验。不仅如此,给展品加上 BGM 或者语音讲解,帮忙观众更加理解展品的具体背景,让演示场景更有代入感。
成果示意
看完如此真切的成果展现,是不是想晓得到底是怎么实现的呢?
通过 Android Studio 的 Kotlin 工程实现 3D 场景构建、物品展现以及声音播放性能,就能够做到。
一、筹备 3D 模型
华为挪动服务最新凋谢的 3D 物体建模服务(3D Modeling Kit),助力轻松建模。咱们只需应用手机相机,通过拍摄物体的不同角度图像,便可实现物体的 3D 几何模型和纹理的自动化生成,为利用提供 3D 模型构建、预览等能力。具体操作领导可参考《5 分钟给商品建设 3D 模型,我是如何做到的?》
二、制作 3D 物体视图
接下来咱们将筹备好的展品 3D 模型,通过华为图形引擎服务创立一个可交互的 3D 物体视图,如图所示:
↓↓↓
↓↓↓
集成华为图形引擎服务
软件要求 :JDK1.7 及以上版本
• minSdkVersion:设置为 19 或以上
• targetSdkVersion:设置为 19 或以上
• 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 模型,成果如下:
三、为展品减少解说词
在加载不同的 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 最新技术~