您的位置:首页 > 移动开发 > Unity3D

ARToolKit for Unity Scripting and Low-Level API

2016-04-03 16:53 513 查看

ARToolKit for Unity 代码编写以及底层 API

Unity 的上层代码编写环境

  Unity 为开发互动应用提供了一个丰富的编程接口。脚本可以使用C#或是Javascript语言编写并且可以调用大量的函数库。基本来说,任何可以手动添加到Unity editor 中的物体都可以被编程。这些脚本也十分紧密的结合到编辑器中。举例来说,脚本中的public 数据会在编辑器的UI上自动地表示为一个输入框,方便调整数值和配置。

  

  Unity 的C#使用Mono 框架支持,它提供了微软.Net 框架的跨平台实现。C#是一个流行的面向对象语言,由于它的流行度,网络上有很多学习C#语言的教程。Mono 的框架没有提供.Net 在Windows 平台上的所有特性,但是所有的核心特性全都拥有。

  

  另外一个Mono 运行环境的特点是对原生代码的支持,也就是那些针对指定CPU编译的,直接与该平台操作系统编程接口(API)通讯的代码。Mono 管理的C# 运行环境中的代码通过平台调用服务(P/Invoke)与原生的代码进行数据通讯。这允许Unity 中的一个C# 脚本可以调用使用C/C++代码实现的函数。这就是ARToolKit for Unity 以及其他插件实现的原理。ARToolKit 与操作系统通讯获取摄像头捕获的图像,执行大量的计算并进行marker 跟踪,甚至将捕获图像处理为原生贴图,全都是使用原生代码实现的。然后,一个简化的用来配置,运行,终止的函数集以库的形式展示出来。这些函数可以使用DllImport的方式映射到C#脚本中,并直接在Unity中直接调用。

  

  在Windows,OS X,和Android系统上libARWrapper 作为动态链接库出现(分别打包为.dll文件、.dylib文件和.so文件)。由于iOS系统不支持动态链接库,libARWrapper 将作为静态库(.a文件)连接到最终应用中。

  

  下面的图展示了组成ARToolKit for Unity 的不同部件间的关系:

  


  如果想获得ARToolKit 在Unity平台上的总体信息,请查看Getting Started with ARToolKit for Unity这篇文章。

控制ARToolKit的主要操作

  你可以通过将ARController 脚本附加到场景中的一个GameObject 上来将ARToolKit 添加到你的项目中。这个GameObject在场景的任何位置都没关系,在ARToolKit 给出的样例中,ARController 都是附加在一个独立无父物体的GameObject上的。

  

  这里十分推荐使用Unity Editor将ARController 添加到场景中,因为使用程序进行ARController 的配置十分复杂。如果你不想听从建议,我们鼓励你去检查一下ARController 的Public 属性以及它们在Unity Editor的脚本中的配置方式。

  

  默认情况下,ARController 实现了Start(),Stop(),和Update() 这些MonoBehaviour,并且分别调用下面这些函数:StartAR()——开始识别跟踪已经配置好的AR场景。UpdateAR()——执行识别跟踪以及各种常务处理。StopAR()——停止识别跟踪。

  

  默认情况下,StartAR()在Start()函数执行过程中被调用。如果你不希望它自动开始工作,可以设置AutoStartAR 这个Public 属性

   GameObject myARObject;

ARController myARController = myARObject.GetComponent《ARMarker》();

myARController.AutoStartAR = false;

然后你就可以在需要的时候手动调用StartAR()和StopAR()函数了。

Marker的添加,移除,寻找和查询

  ARMarker 脚本是在Unity 中使用的marker 的抽象表示。

添加一个新的marker

  为了动态地加载一个要跟踪的marker,你应该在场景中实例化一个GameObject 并给它附加一个ARMarker 脚本。通常来说,所有的ARMarker 实例都要和ARController 脚本附加到同一个GameObject 上:

   GameObject myARObject;

myMarker = myARObject.AddComponent("ARMarker") as ARMarker;

// 配置

myMarker. myMarker.Tag = "myMarker1";

myMarker.MarkerType = MarkerType.SquareBarcode;

myMarker.BarcodeID = 0;

myMarker.PatternWidth = 0.08f;

// 以米为单位,如0.08 = 8cm

myMarker.Load();

  你可以查看ARMarker 的源码来找到更多的选项。

  

  这里有一些在通过代码添加ARMarker时需要注意的事情:

  

除非ARController.StartAR()函数已经被调用,实际上将marker 载入到ARToolKit 中的操作要推迟到StartAR()执行后,而且像丢失数据(missing data)这种错误只有那时候才会显示出来。

If you are using pattern-based square markers, you must supply the contents of the pattern file yourself (for an ARMarker added in the Unity Editor, this is done by the ARMarkerEditor script which runs in the Unity Editor.)如果你在使用基于图案的Square Marker,你必须自己手动提供这个图案文件(?有待实践考察)(对于在Unity Editor 中添加的ARMarker来说,这件事已经被ARMarkerEditor 这个运行在Unity Editor中的脚本完成了)。

如果你在使用NFT marker 或是 multi-marker 集,你必须确保这些marker 的数据文件在应用的文件系统中是可以获取的,通常都放在你项目中的”StreamingAssets”文件夹下。

获取所有Marker 的列表

// 注意,FindObjectsOfType函数十分的占用资源,不要每一帧都调用它

ARMarker[] markers = FindObjectsOfType(typeof(ARMarker)) as ARMarker[];

移除一个Marker

// 如果你要获取这个marker
GameObject myARObject;
ARMarker myMarker = myARObject.GetComponent《ARMarker》();
// 现在销毁它
Destroy(GetComponent(myMarker));
// 或者禁用它
myMarker.enabled = false;


查询一个Marker 的可见性和位置

ARMarker myMarker;

if (myMarker.Visible) Debug.Log("Marker is visible.");

// Pose 是一个在左手坐标系中的4x4齐次坐标变换(transform)

// Pose 表示了marker 相对于观察摄像头的变换。

// 想获得观察摄像头关于marker 的相对变换,可以使用pose.inverse方法;

Matrix4x4 pose = myMarker.TransformationMatrix;

Vec3 position = ARUtilityFunctions.PositionFromMatrix(pose);

Quaternion orientation = ARUtilityFunctions.QuaternionFromMatrix(pose);

将Marker 与场景连接起来

使用ARTrackedObject 和ARCamera

  连接ARMarker(这个marker可以是一个图案,一个二维码,一个Multi-Marker集或是一个NFT marker)与Unity 场景的一个简单方式是使用ARCamera 脚本。这个脚本必须附加到拥有AROrigin 脚本的GameObject 的子物体上。

  

  ARTrackedObject 与ARMarker 通过将各自的Tag 设置为相同值来构建联系。当ARMarker 出现并被跟踪时,附加了ARCamera 的Unity Camera 将显示出真正摄像机相对真正marker 位置上看到的画面,当ARMarker 消失时,这个摄像机的所有虚拟画面将隐藏。

  

  通过将GameObject 放到指定Layer中并设置Camera 仅仅显示那些需要的物体所在的Layer 可以让这些内容很容易的根据marker 决定显示和隐藏。通常来说,所有的marker 和它们对应的AR内容都放在被我们称为foreground 的Layer 中。

   // 通常情况下,你应该使用一个tag或是其他方法来将你要修改的camera 标记出来。

Camera[] Cameras = FindObjectsOfType(typeof(Camera)) as Camera[];

myCamera = Cameras[0];

// 为这个camera 设置culling mask 参数来分辨那些要显示或隐藏的Layer。切记,这些一定要在添加ARCamera脚本前完成。

myARForegroundLayer = 9;

// 0 是起始编号,所以9代表user layer 2。

myCamera.cullingMask = 1<< myARForegroundLayer;

myCamera.AddComponent("ARCamera") as ARCamera;

  配置ARTrackedObject:

myARTrackedObject = arToolKitRoot.GetComponent();

myARTrackedObject.MarkerTag = "myMarker1";

// 就像前面的例子里设置的一样


  为了让对GameObject 的控制不被它们的是否可见而影响,你可以将GameObject 连接到ARTrackedObject 脚本的eventReceiver 属性上。当marker 出现,被跟踪或是消失时,这些函数就会对应的被Unity 的BroadcastMessage 系统调用。

  
// 所有的消息函数。

  OnMarkerFound(ARMarker marker);

OnMarkerTracked(ARMarker marker);

OnMarkerLost(ARMarker marker);


  ARCamera 的projection 和viewport 属性都会在AR脚本启动自动设置。目前你还不能在StartAR()函数被调用之后添加ARCamera,除非去修改ARController。

使用插件的底层接口

  最后,所有的关于AR功能的函数都会调用原生插件,也就是libARWrapper中的API。当然,你也可以完全自由地使用这些API。

  

  我们的网站上有基于C语言的libARWrapper的完整的API文档。官方网站
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AR ARToolKit Unity