摘 要: 以GPS、北斗等为主的室外导航系统的研究进行得如火如荼,但是室内导航的研究却进行得不如人意。以Unity3D为引擎,结合3DS MAX建模,开发室内离线3D仿真寻路系统。该系统完全按照室内样貌建造模型,以最真实的虚拟场景还原室内样貌,供导航者更好地完成室内寻路。最后介绍了场景优化的方法,以便在PC、智能手机等平台上使用。
0 引言
虚拟现实(Virtual Reality,VR)[1]是一项综合集成技术,涉及计算机图形学、人机交互技术、传感技术、人工智能等领域,它利用计算机生成逼真的三维视、听、嗅觉等,使人作为参与者通过适当装置,自然地对虚拟世界有更完美的体验和交互作用。虚拟现实具有很好的交互性、沉浸性和想象性,这三个特性合称为虚拟现实铁三角,如图1所示。
其中沉浸性是虚拟现实技术的最主要的特征。体验者在外部硬件的帮助下将表达传递到虚拟现实中,在虚拟现实中产生相应反应,这些刺激能积极调动体验者的感官系统,从而让体验者更易于沉浸虚拟世界,如图2所示。
现如今人们日常活动范围主要还是在室内,且伴随着我国建筑行业的快速发展,结构复杂的巨型建筑如上海世贸大厦等逐渐进入人们的日常生活,室内寻路问题亟需解决。而近年来关于虚拟现实及Unity3D的研究越来越热,通过建模并完成贴图后导入Unity3D,在Unity3D中完成脚本语言的编写,从而实现交互及寻路系统。由于虚拟场景具有较强的真实性,寻路者在极具复杂的室内环境中也能找到目标位置。
1概述
本文讨论的是基于Unity3D[2]的室内导航系统,应用到软件工程思想,从需求入手,设计室内寻路导航系统的各个功能模块。由于室内场景极其复杂,室内导航系统的开发步骤如下:
(1)数据采集:采用CAD图纸和场景图片,应用Photoshop优化场景图片信息;
(2)数据处理:结合3Dsmax建模应用,在Mari中完成模型贴图;
(3)开发应用:将完成贴图的模型导成.FBX格式后导入到Unity3D,在Unity3D中添加相机、灯光、碰撞体、寻路组件等,利用NGUI进行寻路系统交互界面设计等完成场景交互,最终实现室内自动寻路系统。其中包括输入目的地,以最优算法实现最短路途,到达目的地,到达目的地后可以接着实现二次寻路;在寻路过程中遇到门、灯等组件,进行碰撞检测,门、灯等自动打开[3]。其制作流程如图3所示。
2 室内导航系统的设计与实现
2.1 前期工作
由于现代建筑其场景巨大室内场景复杂,在建模前,要搜集完整的数据,否则将会影响后续建模的进展及模型的使用。对要建模的物体进行照片采集并且利用PS处理,拥有一整套的从内到外的照片,此照片不仅用来帮助建模还用来完成模型贴图;将CAD图纸导入AutoCAD软件,删除不需要的部分,并且添加上建模所需要的补测数据,导出.DWG格式。
2.2 建模技术
将.DWG格式的文件导入3DSMAX[4],根据左视图、顶视图等将CAD文件按照其实际位置放好。选择全部的CAD文件,使其冻结,然后根据制作顺序暂时隐藏其他不需要的CAD。建模过程中可以参照采集的图片保证模型的真实性。为了保证打包出的软件运行流畅,在这里可以制作两套模型,一套低模,一套高模,实现高模转低模而低模拥有高模的效果。利用3DS MAX高效的建模技巧将模型建成之后,选择UV展开,将模型展开UV,UV展开的好坏直接决定贴图的效果,按照比例展开。将展好UV的模型导入Mari进行贴图绘制,而一个场景的逼真度往往由贴图所决定,因此,在进行贴图绘制时统一采用1 024×1 024的照片进行,且在Mari中进行绘制时要细心。此时,模型已经建成,物体表面贴图也已完成,导出.FBX文件。
2.3 Unity3D场景搭建技术
在Unity3D中实现寻路系统[5],由于本文讨论的是在离线状况下实现室内导航,而现在的建筑物往往有多个入口,因此需要选择建筑物入口。此时进入交互界面,输入需要导航的目标点,通过Find寻找该点是否存在,如果存在虚拟人物就会根据最优路径自动到达,寻路结束,提醒是否再次寻路。场景制作流程如图4所示。
2.3.1 寻路组件
使用Unity实现室内自动寻路,其有多种方式。第一种比较传统的是使用A*寻路,它是一种比较传统的人工智能算法,在游戏开发中比较常用到。A*的原理并不复杂,不过由于不是Unity3D自带的功能,因此在设定网格和烘焙的过程中难免会出现问题。而NavMesh作为Unity自带的功能,用法与之前的LightMapping烘焙或者遮挡剔除Occlusion Culling有很多相似之处,最主要是它用起来很方便。
将制作好的场景导入Unity3D,选择场景模型,然后将Navigation Static选中,对于与场景无关的模型确定其不被选中。打开Navigation,根据场景需要调整寻路者半径、高度以及寻路者能行走的最大坡度和高度,完成后烘焙场景[6]。
2.3.2 第三人称物体设置
将预先设置好的人物prefab拖入场景,为其添加上Nav Mesh Agent组件,由于寻路者可能需要多次寻路,因此通过编写C#代码在Update函数中实现二次寻路。部分代码如下:
public NavMeshAgent man;
public Transform target;
GameObject go;
void Start(){
man=gameObject.GetComponent<NavMeshAgent>();
go=GameObject.Find(Xinan.rukou);}
target=go.transform;
void Update(){
if(Xunlu. roomNum != null){
go=GameObject.Find(Xunlu.roomNum);
target=go.transform;
man.SetDestination(target.position); }}
由于使用角色为第三人称,角色所处的状态即为等待或行走,通过将事先导入的动画进行设置进而实现。创造两个bool类型数值,分别为idel与walk,实现其与动画过度关联,并通过脚本进行控制。部分脚本如下:
void Start() {
m_ani=this.GetComponent<Animator>();}
void Update(){
AnimatorStateInfo stateInfo=m_ani.GetCurrentAnimatorStateInfo(0);
…..
m_ani.SetBool("idle",true);
…….
m_ani.SetBool("idel",false);
…..
m_ani.SetBool("walk",true);
…….
m_ani.SetBool("walk",false);}}
2.3.3 相机设置
需要将相机设置成伴随角色的移动。通过设置相机相对角色位置并且每帧都去检测相机相对角色位置,即保证相机相对角色为静止状态。部分实现代码如下:
public Transform m_transform;
float m_camHeight=1.4f;
Transform m_camTransform;
CharacterController m_ch;
void Update(){
m_transform=this.transform;
m_camTransform=Camera.main.transform;
Vector3 pos=m_transform.position;
pos.y+=m_camHeight;
m_camTransform.position=pos;
m_camTransform.rotation=m_transform.rotation;
m_camTransform.eulerAngles=m_transform. eulerAngles}
2.3.4 交互界面
对于交互界面[7]的设计,采用了NGUI,大大方便了界面设计,提高了效率。对于交互界面,分为两部分,即建筑物入口选择界面和目标点输入界面。
建筑物入口选择部分交互界面,单独放到一个场景中,将使用说明等与之组合在一起。如果用户点击某一入口,则将值传递给角色,角色切换到相应入口处。实现主要代码如下:
void OnClick()
{Application.LoadLevel(2);
rukou="easterndoor";
M=true;}
场景二中人物添加代码如下:
void Start(){
go=GameObject.Find(Xinan.rukou);
target=go.transform;
man.transform.position=target.position;}
交互界面效果图如图5所示。
通过在寻路代码中添加设置虚拟人物与目标点的距离来判读是否出现输入目标点的交互界面[8]:
float dist=Vector3.Distance(man.transform.position,target.transform.position);
if(dist<=1.0){UI.SetActive(true);}
对于目标点的输入采用获取输入框的值,如果输入的地点不存在,则返回提醒输入正确的目标点;否则,需找目标点,效果如图6所示。
public GameObject errorUI;
public static string classroomNum;
……
classroomNum=GuiInput.value;
在角色代码中添加如下代码:
if(xunlu.flag==1)
{errorUI.SetActive(true);}
else
{errorUI.SetActive(false);}
2.3.5 检测碰撞
当角色经过门时,如果门是关闭的,则此时门应该打开,若灯是关闭的则也需打开,这需要在灯和门上添加刚体碰撞检测[8],虽然实现不是很容易,但增加了交互性[9],场景真实感加强。对于门的检测,需要在脚本代码中分别实现OnTriggerEnter和OnTriggerExit函数,在OnTriggerEnter中播放门打开的动画,在OnTriggerExit中停止门打开的动画。灯的检测直接利用OnTriggerEnter,当角色与灯组件发生碰撞时,灯的组件被唤醒。
3 场景优化
本导航系统基于智能手机开发,虽然现在的智能手机处理器、内存等都有大的提升,但是如果场景较大,模型点面较多,代码优化不合理,在智能机上的运行将会受影响。因此,本文认为应该从以下几个方面进行场景优化[9]:
(1)对于场景内的点面,最好控制在10万以内,看不见的点面将其删除;
(2)尽可能减少角色骨骼数量;
(3)多张贴图共享一张材质球;
(4)保证代码逻辑正确,删除脚本中未使用的Update函数;
(5)尽可能减少像素灯光、反射、阴影等的使用,这些操作会导致模型被多次渲染,加重CPU的负担。
4 结论
本文介绍了虚拟现实技术在室内导航方面应用的关键技术。通过数据采集、模型绘制、Unity3D场景开发,模拟出最真实的虚幻场景,让使用者拥有身临其境的感觉,帮助其更好地完成室内导航。本系统适合各种大中型室内场所导航,如医院场所导航、大型超市货物导航等。当然,由于开发场景的过程过于繁琐,开发所需成本目前还较高,但是随着虚拟现实技术、计算机网络技术、虚拟现实眼镜技术等的发展,在未来成本等问题会得到解决,届时虚拟现实3D仿真导航系统将会取代传统的二维平面导航系统。
参考文献
[1] 冯俊杰.基于UML的三维漫游系统的分析与设计[D].大连:辽宁师范大学,2011.
[2] 朱惠娟.基于Unity3D的虚拟漫游系统[J].计算机系统应用,2012,21(10):36-39,65.
[3] 干建松.基于Unity3d的室内漫游仿真系统[J].淮阴师范学院学报(自然科学版),2011,10(6):515-518.
[4] 祝敏娇.基于Unity3D的虚拟漫游技术的研究[J].硅谷.2012(20):77,102.
[5] 黄健柏,邹峥嵘,朱学红.虚拟校园及其在校园规划管理中的应用[J].教育信息化,2002(6):7-8.
[6] 吴凤娟,刁永锋.虚拟校园漫游系统的设计及实现[J].苏州科技学院学报(工程技术版),2005,18(2):78-80.
[7] 李峻峰.虚拟现实技术与虚拟校园的研究与实践——以潍坊学院虚拟校园建设为例[J].工程图学学报,2011,32(3):62-68.
[8] 金汉均,王晓荣,徐星,等.一种基于DirectX的碰撞检测算法[J].电子技术应用,2006,32(1):56-58.
[9] 雷忠诚,胡文山,邬静阳,等.基于Web的3D智能家居系统设计与实现[J].电子技术应用,2014,40(9):114-117.
[10] 金玺曾.Unity3D手机游戏开发[M].北京:清华大学出版社,2013.