足不出户,一探古今,打造线上3D数字博物馆!

随着3D技术的不断革新,为了让更多的用户领略历史之美,愈来愈多的博物馆开始举办线上展览。经过模拟不一样的环境、灯光投影、360°无死角放大缩小展品,观众能够享受到身临其境的沉浸体验。不只如此,给展品加上BGM或者语音解说,帮助观众更加了解展品的详细背景,让演示场景更有代入感。android

效果示意

看完如此逼真的效果展现,是否是想知道到底是怎么实现的呢?app

经过Android Studio的Kotlin工程实现 3D场景构建、物品展现以及声音播放功能,就能够作到。maven

1、准备3D模型

华为移动服务最新开放的3D物体建模服务(3D Modeling Kit),助力轻松建模。咱们只需使用手机相机,经过拍摄物体的不一样角度图像,即可实现物体的3D几何模型和纹理的自动化生成,为应用提供3D模型构建、预览等能力。具体操做指导可参考《5分钟给商品创建3D模型,我是如何作到的?ide

2、制做3D物体视图

接下来咱们将准备好的展品3D模型,经过华为图形引擎服务建立一个可交互的3D物体视图,如图所示:
gradle

↓↓↓ui

↓↓↓this

集成华为图形引擎服务

软件要求:JDK1.7及以上版本编码

• minSdkVersion :设置为19或以上url

• targetSdkVersion:设置为19或以上.net

• 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物体建模服务演示DEMO

华为图形引擎服务官网演示DEMO

华为音频服务官网 演示DEMO

华为HMS Core官方论坛

解决集成问题请到Stack Overflow

点击关注,第一时间了解HMS Core最新技术~

相关文章
相关标签/搜索