AR引擎技术选型和使用实现方案(转载)

avatar
avatar
kktoo
45
文章
12
评论
2023年2月10日16:17:32 评论 1,697 11022字阅读36分44秒
本文为非商业性转载,如有侵权,请联系,立刻删除
原文链接:AR引擎技术选型和使用实现方案
原文出处:腾讯课堂

导读

本篇约6000字阅读需要20分钟,内容有:

  • 开发者对AR的基础认知
  • 主流AR引擎的选型大纲
  • Vuforia引擎的评估和实现方案
  • EasyAR引擎的评估和实现方案
  • ARFoundation引擎的评估和实现方案
  • 自研发AR引擎的评估和实现方案
  • 多引擎融合使用方案
  • AR引擎选型和实现总结

EEA是探娱互动研究院(Explore Entertainment Academy),我们会定期分享我们对游戏研究的文章,希望通过解决一个又一个的命题帮助大家以及我们自己将游戏设计的理论系统化,最终提高生产力。

 

一、研究环境

研究目的:实现AR引擎,提供运动追踪SLAM,平面识别、图像识别、人物遮挡、光照估计、阴影等功能支持。

开发工具:Unity 2020.1.4f1c1。

开发言语:C#

 

二、开发者对AR的基础认知

AR全称Augmented Reality,即为增强现实技术。由现实场景和虚拟场景两部分叠加显示,为用户提供更丰富的感官体验和更立体的信息传达。

 

开发场景中必定有两个“摄像机”分别拍摄现实场景虚拟场景,渲染叠加显示即为AR场景。

现实场景摄像机-手机摄像头硬件:程序获取手机摄像头拍摄的现实画面,并渲染到画布上(需要获取手机摄像头权限)。

虚拟场景摄像机-即Unity的Camera:拍摄3D场景渲染。

 

AR的最大应用价值是基于AI扩展功能,通过图像识别、动作识别、人脸识别等方式,智能分析认知现实场景,在虚拟场景做对应的显示,达到增强现实效果。

 

扩展阅读资料:

从AR到ZR:关于现实的26个概念!

 

三、主流AR引擎的选型大纲

本人能力时间有限,无法对每个引擎都研究透彻,若有错误的地方欢迎大家指出。

大多数AR引擎都是基于ARCore和ARKit,分别用于支持Android设备和IOS设备,并在基础上再次封装扩展开发。少部分AR引擎有自行研发核心功能,用于适配更多手机型号或增强功能。

 

1.ARCore

描述:谷歌推出的AR开发平台,可用于开发Android平台上的AR应用。

设备支持:支持Android,不支持IOS设备。有相当一部分Android设备不支持,与是否有安装Google ARCore的有关,与手机价格和新旧程度无关。

功能:运动追踪、平面追踪、点云图、云锚点、光照估计、环境探针、人脸追踪、2D图片追踪、人物遮挡、射线测试

 

2.ARKit

描述:苹果推出的AR开发平台,可用于开发iPhone和iPad平台上的AR应用。

设备支持:支持IOS设备,不支持Android

功能:运动追踪、平面追踪、点云图、云锚点、光照估计、环境探针、人脸追踪、动作捕捉,2D图片追踪、3D物体追踪、人物遮挡、射线测试

 

3.Vurforia

描述:又称高通AR,与高通公司合作开发产品。支持Unity

依赖引擎:ARCore、ARKit

设备支持:支持Android和IOS设备

识别数据:平台云端存储

 

4.EasyAR

描述:视辰信息科技研发的AR引擎,自研发了一套SLAM,可适配更多机型。支持Unity

依赖引擎:ARCore、ARKit

设备支持:支持Android和IOS设备

识别数据:平台云端存储

功能:最新一些功能,如人物遮挡、光照估计是否有接口实现,待确定暂时未找到。

 

5.ARFoundation

描述:Unity将ARKit和ARFoundation封装,未再实现新功能,便于统一接口和多平台使用。支持Unity

依赖引擎:ARCore、ARKit

设备支持:支持Android和IOS设备

识别数据:自行存储

 

6.SenseAR

描述:商汤科技研发的AR引擎。没做进一步研究评估。支持Unity

设备支持:设备需要预装或手动安装SenseAR,版本间不兼容。

功能:运动最终、光照估计、手饰识别、图像识别和跟踪、人脸跟踪与重建、云锚点、三维物体识别与跟踪、实时三维重建

 

7.百度AR

描述:百度研发的AR引擎。主要是在AI图像识别,人脸识别功能。支持Unity

 

8.阿里AR

描述:阿里研发的AR引擎。主要是在2D图像识别,3D物体追踪功能。商业联系后才能获取SDK开发。

 

9.腾讯AR

描述:腾讯研发的AR引擎。官网资料很简单,没做进一步研究评估。支持Unity

 

10.华为AR

描述:华为研发的AR引擎。对华为设备做了额外的支持,能适配更多的华为手机。支持Unity

依赖引擎:ARFoundation

 

11.网易AR

描述:网易研发的AR引擎。通过商务合作,提供需求由网易完成交付。

 

12.LandMarkAR:

描述:抖音研发的AR引擎。未找到官网和可使用的SDK。

 

13.VoidAR

描述:成都米有研发的AR引擎。客服说是全自主研发,不依赖ARCore、ARKit,设备适配性很强。SLAM功能测试效果非常飘,无法用于实际应用。支持Unity

 

四、Vuforia引擎的评估和实现方案

1.研究环境:

Vurforia版本:add-vuforia-package-9-3-3

Unity版本:Unity 2020.1.2f1c1

 

2.配置SDK并创建AR项目:

2.1 登陆vuforia官网,点击Register注册开发者账号:

2.2 在开发者平台中,点击Develop,在License Manager中,创建AR App的license Key;

2.3 登陆官网下载SDK,将下载好的unitypackage文件导入到Unity项目;

2.4 Unity项目删除原来的Main Camera,点击GameObject-Vuforia Engine-AR Camera添加AR Camera;

2.5 选中AR Camera点击Open Vuforia Configuration,将申请的license Key复制到App License Key输入框中,AR场景必要设置已完成了;

如果我们想进一步创建一个图像识别的AR项目,我们继续做:

2.6 在开发者平台,点击Develop,在TargetManager中点击Add Database,添加对象数据库;

2.6.1 数据库类型有三种:Device(设备识别),Cloud(云端识别),VuMark(条形码)

2.7 点击进入数据库后,点击Add Target将需要识别的图片传入,并填入相应的信息点击Add;

2.7.1 Type:根据需求选择,这里选择Single Image(单个图片)

2.7.2 File:在本地选择识别图上传

2.7.3 Width:识别图片的宽度。用于建立Unity场景中的单位长度,场景中所有其他物体的大小是以这个值为参照建立的。Vuforia中的单位长度是以米来计算。这个值可以是任意的,但是最好比Camera的Near Clip值要大,不然在镜头靠近时你可能会看不到相关内容。这里可输入为1;

2.7.4 Name:识别图片名字。名字唯一,用于识别各个识别图。

2.7.5 Status:Active表示可用。(创建完成后可查看)

2.7.6 Augmentable:可识别度评级,最少需要3颗星才能保证高质量的识别,最高5颗星。(创建完成后可查看)

2.8 将Vuforia - Prefabs中的ImageTarget预制体拖入场景中,并将识别后要显示的模型作为子对象挂在ImageTarget下面;

2.9 在ImageTarget的ImageTargetBehaviour中,Type选择From Database,在Database和ImageTarget选项分别选择之前设置的数据库和图片对象;

2.10 至此AR图像识别已完成,可运行,用摄像头拍摄识别图,对应的模型就会显示出来。

 

数据库DeviceCloud类型的对比

AR引擎技术选型和使用实现方案(转载)

 

3.关键类解析:

VuforiaBehaviour:开启Vurforia引擎的启动类

VuforiaManager:管理可追踪对象的更新,它们在相机中的状态和位置

VuforiaARController:VuforiaBehaviour类处理跟踪并触发本地视频。背景渲染。 该类将更新场景中的所有Trackable。

WebCamARController:MonoBehaviour管理Windows或Mac中“播放模式”网络摄像头的使用。

 

4.评估:

4.1 全球最流行AR引擎之一,图像识别准确性和灵活性都优化得不错;

4.2 测试效果总体不错,但Android设备支持限于ARCore,适配性一般;

4.3 开发需要在国外找资料,国内资料零散不全

 

扩展阅读资料:

Vuforia中文社区

 

五、EasyAR引擎的评估和实现方案

1.研究环境:

EasyAR版本:EasyARSenseUnityPlugin_4.1.0.811

Unity版本:2020.1.4f1c1(官方建议长期支持版本 Unity 2019.4、Unity 2018.4、Unity 2017.4。测试反馈:2020版本是暂没发现影响因素)

 

EasyAR Sense Unity建立在EasyAR Sense C# API之上的非常薄的封装,用于在Unity中暴露EasyAR Sense的功能。建议阅读 EasyAR Sense 文档 来理解EasyAR Sense是如何工作的。

 

2.配置SDK并创建AR项目(官网文档有详细的教程):

2.1 登陆EasyAR官网,注册账号;

2.2 进入开发者中心,申请Sense许可证密钥License Key;

2.3 登陆官网下载SDK,将下载好的unitypackage文件导入到Unity项目;

2.4 从Unity菜单中选择<EasyAR -> Change License Key>并在Inspector面板中输入准备工作中创建的License Key;

如果迫不及待想看AR场景运行效果

2.5 可登陆官网下载实例文件夹,将下载好的unitypackage文件导入到Unity项目;

2.6 项目中Project - Samples - Scenes文件夹中,打开任意场景运行即可体验对应的AR场景(场景说明看英文名或官网教程);

如果想自由学习引擎的运行使用

2.7 打开项目摄像机Main Camera,修改Camera属性设置:

2.7.1 Tag: 设置Camera Tag为 MainCamera 。如果不做这个设置,则需要在场景中 EasyAR 节点的配置中选择 Assemble Mode 为 Manual 并手动配置Camera。

2.7.2 Clear Flags: 需要选择为 Solid Color 以确保Camera图像可以正常渲染。如果选择为 Skybox ,Camera图像将无法显示。

2.7.3 Background: 这个非必需配置,考虑到使用体验,建议将背景颜色设为黑色以便在Camera设备打开前和切换时以黑色显示。

2.7.4 Clipping Planes: 根据识别物体实际的物理距离设置。这里设置Near为0.1(米)以避免相机离物体较近时无法显示。

2.8 在Project - EasyAR - Prefabs文件夹中:

Composites:该文件夹下的预制体是引擎预先配好的AR组件,拖入场景中即可使用对应的AR功能(适合新手);

Primitives:该文件夹下的预制体是单个功能的引擎,可自由组合使用自己想要的AR功能

 

3.关键类解析:

ARSession:在场景中控制AR会话的MonoBehaviour。一个会话包含一组组装成ARAssembly的组件,并控制整个生命周期的数据流。这个类是AR的入口,如果要实现完全不同的AR工作流可以创建一个新的会话类并在场景中替换这个类。

EasyARController:最先运行。在场景中控制EasyAR Sense初始化以及一些全局设置的MonoBehaviour。

RenderCameraController:在场景中控制Camera的MonoBehaviour,Camera投影矩阵会反映现实世界中的CameraDevice或其它光学设备。

CameraImageRenderer:在场景中控制camera图像渲染的MonoBehaviour,这个类目前不支持Unity universal render pipeline (URP) ,但你可以自行扩展这个类的实现来支持URP。

VIOCameraDeviceUnion:运动追踪相关类。在场景中控制VIO相机设备(MotionTrackerCameraDevice、ARKitCameraDevice、ARCoreCameraDevice)的MonoBehaviour,在Unity环境下提供功能扩展。如有需要可以直接使用Device。MotionTracker是EasyAR自己实现的一套运动追踪。

ARAssembly:实现了一种对所有EasyAR Sense组件的典型的组装策略,同时在ARSession控制数据流。可获取ARCamera。

 

检测手机是否支持EasyAR可用以下函数实现:

AR引擎技术选型和使用实现方案(转载)

 

4.注意事项/项目配置:

4.1 Android项目,Android API Level需大于等于17;

4.2 不支持Universal Render Pipeline,即URP项目不支持的。

手机摄像头渲染与URP渲染相互有影响,强制使用URP项目手机摄像头运行不了;

可以通过扩展EasyARSenseUnityPlugin的脚本来支持URP和HDRP;

所有的渲染API调用都组织在CameraImageRenderer脚本组件中。可以扩展这个脚本并修改一些shader来支持URP和HDRP。

4.3 Unity使用mono脚本后台不支持Android arm64-v8a。如果需要使用应开启IL2CPP;

4.4 对于运动追踪功能,各大AR引擎主要通过图像识别、陀螺仪、加速传感器等传感器结合实现。经测试,在手机摄像头朝向上方的时候,都有一定几率会追踪失败,ARCore会重定位恢复显示,EasyAR的MotionTracker会直接卡死。

 

5.评估:

5.1 国内最好的AR引擎之一,资料齐全,接口友好;

5.2 MotionTracker可以适配更多的手机型号,但对比ARCore,还是有差距,一些BUG还待需优化;

5.3 稠密矩阵对现实物体的贴合度体验有差距,还待续优化;

5.4 总之来说EasyAR自研发的功能个人感觉有些鸡肋,但总体效果还是不错。

 

扩展阅读资料:

EasyAR社区教程

 

六、ARFoundation引擎的评估和实现方案

1.研究环境:

ARFoundation版本:Version 4.1.0-preview.12 - November 03, 2020

Unity版本:2020.1.4f1c1

 

2.配置SDK并创建AR项目:

如果迫不及待想看AR场景运行效果

2.1 在Github上下载ARFoundation的示例代码,里面所有功能都有对应的示例场景;

2.2 在示例项目中,Project - Scenes文件夹下,打开任意场景运行即可体验对应的AR场景;

如果想自由学习引擎的运行使用

2.3 在Unity项目中,打开Window - Package Manager安装引擎包,AR Foundation、AR Subsystems、ARCore XR Plugin、ARKit Face Tracking、ARKit XR Plugin,有些包会跟着其他包一起自动安装,注意版本一定要一致:

2.4 在Hierarchy中创建一个空对象A,添加组件ARSession和ARInputManager;

2.5 在Hierarchy中创建一个空对象B,添加组件ARSessionOrigin;

2.6 打开项目摄像机Main Camera,修改Camera属性设置Clear Flags需要选择为 Solid Color,添加组件ARCameraManager,ARCameraBackground,ARPoseDirver;

2.7 再将Main Camera移动对象B下面,作为子对象。AR场景已完成完毕可以运行查看效果了。

 

3.关键类解析:

ARSession:AR会话通过在目标平台上启用或禁用AR来控制AR体验的生命周期

ARSessionOrigin:将可跟踪特征(例如平面和特征点)转换为Unity场景中其最终位置

ARPoseDriver:根据设备的跟踪信息,驱动父GameObject的本地位置和方向

ARCameraManager:AR相机的启用功能,包括对设备相机纹理的管理以及设置光估计模式的属性。

ARCameraBackground:运行时将来自设备相机的视频馈送显示为场景的渲染背景

ARTrackedImageManager:用于图像识别和追踪的类,需要挂在对象B下即可生效;

ARPlaneManager:用于平面检测的类,需要挂载对象B下即可生效;

AROcclusionManager:用于人物遮挡的类,需要挂在Main Camera下即可生效;

 

4.注意事项/项目配置:

4.1 Player Setting设置,Android项目,Android API Level需大于等于24;

4.2 Player Setting设置,XR Plug-in Management勾选ARCore和ARKit

4.3 Player Setting设置,删除 vulkan,Android不支持Vulkan;

4.4 还有一些Player Setting设置因版本不一样,根据实际情况自己选择设置,非必须;

4.4.1 不勾选 Multithreaded Rendering;

4.4.2 不勾选 Auto Graphics API;

4.4.3 不勾选 ARCore Supported;

4.5 ARSession.state可获取引擎的运行状态,可用于检测ARFoundation是否支持设备,各功能可通过subsystem???.descriptor???.supports???的方式查看是否支持。注意引擎和子系统必须要先运行才能知道是否支持;

 

5.评估:

5.1 ARFoundation对接口封装不错,使用简单,ARCore和ARKit发布的最新功能及时更上提供,版本在不停的优化;

5.2 ARFoundation版本和Unity版本有匹配要求,在Unity2019打包最新版本会失败;

5.3 ARFoundation配置出错后,没有社群可以问答,只能对比示例场景一点一点找问题;

5.4 如果环境太暗,则设备运动追踪可能会“丢失跟踪”,因为基于图像识别,所有SLAM都会出现此情况;

 

扩展阅读资料:

Unity AR + GPS Location支持ARFoundation和Vuforia

 

七、自研发AR引擎的评估和实现方案

1.研发目的:

目标一:实现AR场景,现实场景和虚拟场景叠加显示

目标二:虚拟场景摄像机Camera能同手机摄像头一起旋转、移动

目标三:最大程度上适配更多的手机、解决ARCore和ARKit对大量手机不适配情况

 

2.开发思路:

基于对AR场景的基本认知,基于大部分手机均有的硬件设备,完成最基本的AR功能

2.1 获取手机摄像头,并获取摄像头拍摄的画面渲染出来;

2.2 通过手机传感器(陀螺仪、加速传感器、指南针等)识别手机的方向和移动,实现控制摄像机Camera旋转移动;

 

3.实现方案:

3.1 WebCamTexture可获取手机摄像头拍摄的画面并转化成显示材质,核心代码如下(变量类型和变量名相同):

3.1.1 判断是否支持手机摄像头,并设置摄像头渲染显示

AR引擎技术选型和使用实现方案(转载)

3.1.2 每帧更新Update调用,动态检测摄像头显示宽高和手机旋转方向修改

AR引擎技术选型和使用实现方案(转载)

3.2 Input.gyro可获取陀螺仪,用来获取手机空间朝向,进而控制空间摄像机同步旋转

3.2.1 打开项目摄像机Main Camera,修改Camera属性设置Clear Flags需要选择为 Solid Color

3.2.2 在Hierarchy中创建一个空对象A,将Main Camera拖入对象A下,作为子对象;

3.2.3 将对象APosition设置为(0,0,0),Rotaion设置为 Quaternion.Euler(90f, 180f, 0f);

3.2.4 在帧循环Update中,写camera.localRotation = gyro.attitude * new Quaternion(0f, 0f, 1f, 0f); 摄像机即可随着手机旋转而旋转;

3.3 gyro.userAcceleration可获取空间移动加速度,Input.acceleration可获取加速传感器的线性加速度,预想根据加速度计算空间位置从而控制摄像机移动,但实际效果误差太大,移动效果尝试失败ε=(´ο`*)))唉。

3.4 Input.compass.trueHeading可获取设备指南针方向,gyro.attitude.eulerAngles.z陀螺仪的方向角也可以获取,但两者获取值有一点差异,但问题不大,可通过算法优化。通过方向值调整空间锚点方向,从而达到虚拟世界的朝向同现实世界一致;

 

4.评估:

自研发AR引擎能实现现实AR场景,并且控制摄像机旋转。可作为一个原地不动的AR场景使用,运动追踪SLAM功能只基于手机硬件,不使用AI算法暂没法实现,所以主流AR引擎SLAM功能都是基于图像识别定空间锚点等组合方式实现的。

自研发AR引擎对手机的设备适配性达到MAX,只要有陀螺仪的手机都能使用,一些简单AR应用完全能满足要求。

 

扩展阅读资料:

支持ARCore的手机型号查询

 

八、多引擎融合使用方案

1.几款主流的AR引擎介绍完了,先做下对比:

 

基础功能支持:Vurfora ~ EasyAR > ARFoundation >> 自研发AR

Vurfora和EasyAR对ARCore和ARKit基础功能想图像识别定位做了一定的AI优化处理,效果理论下更好

 

高级功能支持:ARFoundation > Vurfora ~ EasyAR >> 自研发AR

ARFoundation只对ARCore和ARKit进行封装,对最新的高级功能支持最好

Vurfora和EasyAR底层封装,ARCore和ARKit的最新高级功能反而不能及时支持

 

URP项目支持:

支持:ARFoundation、Vurfora、自研发AR

不支持:EasyAR

 

设备适配性:自研发AR >> EasyAR > Vurfora ~ ARFoundation

EasyAR自研发了一些系统,能支持更多的设备

Vurfora和ARFoundation限于ARCore和ARKit支持限制

(PS:华为AR对华为手机有更多的适配支持)

 

Unity友好性:自研发AR > ARFoundation > Vurfora > EasyAR

ARFoundation本来就是Unity封装的,包可以直接下载使用,随时更新最新的

Vurfora也是Unity嵌入支持的

 

开发友好性:自研发AR >> EasyAR > ARFoundation > Vurfora

EasyAR官网提供完整的使用说明文和示例项目,并且可在社区随时询问开发问题,很友好

ARFoundation在Github上提供完整的示例项目,加上接口封装的不错,使用上还是比较友好

 

2.各引擎都有自己的优劣,尝试组合使用方案如下

2.1 但由于各引擎对摄像机的控制都是封装到底层,不能再次修改,因此多引擎同时使用方案排除

2.2 根据手机情况,智能选择最合适的引擎使用,但由于主流AR引擎均基于ARCore和ARKit,并且支持的版本不一样,同时在项目中,会因为ARCore和ARKit版本不统一,但只能存在一个版本的,导致使用失败,方案排除;

2.3 主流AR引擎+自研发AR引擎方案,优先使用主流AR引擎,如判断主流AR引擎不支持,就切换使用自研发AR引擎,可行;

 

3.扩展功能实现方案:

AR阴影实现思路

因为AR场景中,背景是现实场景,虚拟场景没有地面存在,3D对象需要显示阴影,就需要在3D对象下方一个透明的平面,然后将阴影渲染到平面上显示,要注意平面大小,如果过小,阴影会显示不全。提供一个阴影shader。

Shader "AR/ARShadowSurface"
{
    Properties
    {
        _Color("Main Color", Color) = (1,1,1,1)
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Cutoff("Cutout", Range(0,1)) = 0.5
    }
    SubShader
    {
        Pass
        {
            Alphatest Greater[_Cutoff]
            SetTexture[_MainTex]
        }

        Pass
        {
            Blend DstColor Zero Tags
            {
                "LightMode" = "ForwardBase"
            }

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase
            #include "AutoLight.cginc" 

            struct v2f
            {
                float4 vertex : SV_POSITION;
                LIGHTING_COORDS(0,1)
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                TRANSFER_VERTEX_TO_FRAGMENT(o);
                return o;
            }

            fixed4 frag (v2f i) : COLOR
            {
		        float attenuation = LIGHT_ATTENULATION(i);
                return attenuation;
            }

            ENDCG
        }
    }

    Fallback "Transparent/Cutout/VertexLit"
}

GPS定位实现思路

方案一:Input.location是Unity提供的获取GPS定位的接口,自行编写换算算法后,便可使用;

SystemInfo.supportsLocationService 可检测手机是否支持GPS

Input.location.isEnabledByUser 可检测用户是否许可开启GPS

方案二:前文提到的Unity AR + GPS Location是有封装好的定位类,算法完整,可直接使用;

方案三:可从地图SDK(如百度地图、高德地图)获取定位信息,传到unity使用,相比Unity的GPS定位,添加了wifi定位和基站定位,更稳定精准;

 

九、AR引擎选型和实现总结

这次AR引擎选型研究遇到最大问题就是设备适配性,特别是Android设备,主流AR引擎依赖ARCore,ARCore依赖手机要有Google ARCore,现在相当一部分手机不支持Google ARCore,最新的高级手机都有不支持的,最终导致基于主流AR引擎开发的AR应用无法使用。

这点抖音做的很好,LandMarkAR实际使用情况大部分手机都支持,适配性不错,可惜未开放SDK,无法基于LandMarkAR开发。

国内第三方AR开发商很多,但很多都是商业合作方式代开发AR应用,面向开发者的第三方SDK提供商不多。

最终AR引擎选型为ARFoundation+自研发AR方案,AR高级功能由ARFoundation实现,适配性由自研发AR保底。

avatar
  • 文本由 发表于 2023年2月10日16:17:32
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
XR常见FAQ(长期持续更新) VR/AR

XR常见FAQ(长期持续更新)

Vuforia免费版会限制功能吗? 2019年5月之前,Vuforia的价格是一次买断。 2022年1月之前,Vuforia的价格是每年订阅付费。 2022年1月之后,Vuforia提供免费版本。 关...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: