这里会用我写的程序来说明怎样用AS3来开发AR程序。这个程序是从FLARManager的example改写的。程序运行效果见http://cankeyyin.blog.163.com/album163/
一、FLARToolKit介绍
FLARToolKit是ARToolKit的AS3版本。ARToolKit是个可以创建增强现实的C程序库,然而兼容于Adobe Flash/Flex/AIR的FLARToolKit并不仅仅只是对之前C版本的移植。FLARToolKit是从Java版本移植过来的,其名称叫做 NyARToolKit(经过nyatla的艰苦努力之后,现在NyARToolKit的执行速度要比原始的C版本快)。
二、使用AS3开发的好处
1。跨系统跨平台
2。程序可嵌入网页运行
三、开发前要准备的。。。
1。摄像头
2。安装AS3的IDE:Flash、Flex或Flashdevelop,任意一个都行
下面的例子是用Flex来做的,建议初学者用Flex
3。下载&安装附件的ARToolkit Marker Generator
这个是AIR程序,需要你的电脑有AIR的Runtime
4。下载附件的FLARManager(里面包含FLARToolkit和3D引擎)
四、调试FLARManager的例程
FLARManager是一个针对FLARToolkit开发的类库,主要用于管理多个识别图形。
开发前,先调试一下已经写好的程序
附件里面的FLARManager_v5,解压后打开Flex,选择File-Import-Flex Project。在Project Folder里面选择解压后的路径,就可以导入这个项目。
项目的marker图像都在\FLARManager_v05\resources\flar\patterns里面,打印pattens01.pdf,装上摄像头后,选择Run-Debug就可以调试这个程序看效果了。如果不想打印,你打开pattens01.pdf,用摄像头对着它也行。
下面再来看一下程序文件是怎样组织的。
FLARToolkit库在src/org/libspark里面
3D引擎在lib里面
示例程序的入口在src/FLARManagerExampleLauncher.as。我们打开这个as文件就可以看到,这里有很多例程给我们调试。这些例程的主文件在src/example里面。对象类在src/example/support里面。
五、开发程序
附件里面的Car.rar是我类库的例程改写的程序。里面的汽车模型是在Flash 3D研究所网站下载的:http://www.flab3d.com/tutorials_05_pv3dloadDAE.php。而且这里绍了怎样导出DAE模型。
程序由类库的例程改写,减少工作量。我们要做的有以下几步:
第一步:画一个Marker,制作pat文件
我们可以用ARToolkit Marker Generator软件制作Marker对应的pat文件,附件里面有这个软件。详细步骤可以看这个网址:http://www.mikkoh.com/blog/?p=182。
第二步:改写flarConfig.xml
这个文件是记录pat文件路径的。
由于我用的Marker是例程中\FLARManager_v05\resources\flar\patterns目录下的pattens01.pdf,所以前两步我就不用做了。
第三步:改写代码
在我的程序里面主要有两个类,一个是对象类Objects_3D,另一个是FLARManager控制对象显示的类FLARManager_PV3D。
Objects_3D类的主要工作:初始化PV3D环境、创建对象、定义操作对象的方法
1。初始化PV3D环境- //初始化PV3D
- private function initPapervisionEnvironment (cameraParams:FLARParam, mirrorDisplay:Boolean, viewportWidth:Number, viewportHeight:Number) :void {
- this.scene3D = new Scene3D();
- this.camera3D = new FLARCamera3D(cameraParams);
- this.viewport3D = new Viewport3D(viewportWidth, viewportHeight);
- if (mirrorDisplay) {
- this.viewport3D.x = viewportWidth;
- this.viewport3D.scaleX = -1;
- }
- this.addChild(this.viewport3D);
- this.renderEngine = new LazyRenderEngine(this.scene3D, this.camera3D, this.viewport3D);
- this.pointLight3D = new PointLight3D();
- this.pointLight3D.x = 1000;
- this.pointLight3D.y = 1000;
- this.pointLight3D.z = -1000;
- this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
- }
复制代码 我们可以根据显示的需要,修改当中的代码。
2。创建对象- private function creatModel():void{
- //正方体模型
- var materialsList:MaterialsList = new MaterialsList({all: new FlatShadeMaterial(this.pointLight3D, 0x19FFAA, 0x007348)});
- cube = new Cube(materialsList, CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
- cube.z = 0.5 * CUBE_SIZE;
- //读入汽车模型
- car = new DAE(true, "car", true);
- car.load("../resources/assets/car.xml");
- car.rotationX = 90;
- car.rotationZ = 90;
- car.scale = 10;
- }
复制代码 3。定义操作对象的方法- public function addMarker (marker:FLARMarker) :void {
- //存放Marker
- var markerList:Vector.<FLARMarker> = this.markersByPatternId[marker.patternId];
- markerList.push(marker);
- //创建一个3D模型的容器
- var containerisplayObject3D = new DisplayObject3D();
- //根据不同的Marker显示不同的对象
- //我打印出来的纸上面有12个Marker,3*4排列,patternId为4和7的就是中间那两个
- if(marker.patternId==4)
- container.addChild(car);
- else if(marker.patternId==7)
- container.addChild(cube);
- this.scene3D.addChild(container);
- this.containersByMarker[marker] = container;
- }
- public function removeMarker (marker:FLARMarker) :void {
- var markerList:Vector.<FLARMarker> = this.markersByPatternId[marker.patternId];
- var markerIndex:uint = markerList.indexOf(marker);
- if (markerIndex != -1) {
- markerList.splice(markerIndex, 1);
- }
- var containerisplayObject3D = this.containersByMarker[marker];
- if (container) {
- this.scene3D.removeChild(container);
- }
- delete this.containersByMarker[marker]
- }
- private function onEnterFrame (evt:Event) :void {
- this.updateObjects();
- this.renderEngine.render();
- }
- private function updateObjects () :void {
- var i:int = this.markersByPatternId.length;
- var markerList:Vector.<FLARMarker>;
- var marker:FLARMarker;
- var containerisplayObject3D;
- var j:int;
- while (i--) {
- markerList = this.markersByPatternId;
- j = markerList.length;
- while (j--) {
- marker = markerList[j];
- container = this.containersByMarker[marker];
- container.transform = FLARPVGeomUtils.convertFLARMatrixToPVMatrix(marker.transformMatrix);
- }
- }
- }
复制代码 FLARManager_PV3D类的主要工作:初始化FLARManager、处理Marker事件
这个类的代码基本上不需要作什么改动。写代码的时候复制过去就可以了。
1。初始化FLARManager- private function init () :void {
- this.flarManager = new FLARManager("../resources/flar/flarConfig.xml");
- this.flarManager.addEventListener(ErrorEvent.ERROR, this.onFlarManagerError);
- this.addChild(Sprite(this.flarManager.flarSource));
- this.flarManager.addEventListener(FLARMarkerEvent.MARKER_ADDED, this.onMarkerAdded);
- this.flarManager.addEventListener(FLARMarkerEvent.MARKER_UPDATED, this.onMarkerUpdated);
- this.flarManager.addEventListener(FLARMarkerEvent.MARKER_REMOVED, this.onMarkerRemoved);
- var framerateDisplay:FramerateDisplay = new FramerateDisplay();
- this.addChild(framerateDisplay);
- this.flarManager.addEventListener(Event.INIT, this.onFlarManagerInited);
- }
- private function onFlarManagerError (evt:ErrorEvent) :void {
- this.flarManager.removeEventListener(ErrorEvent.ERROR, this.onFlarManagerError);
- this.flarManager.removeEventListener(Event.INIT, this.onFlarManagerInited);
- trace(evt.text);
- }
- private function onFlarManagerInited (evt:Event) :void {
- this.flarManager.removeEventListener(ErrorEvent.ERROR, this.onFlarManagerError);
- this.flarManager.removeEventListener(Event.INIT, this.onFlarManagerInited);
- this.myObjects = new Objects_3D(this.flarManager.numLoadedPatterns, this.flarManager.cameraParams,
- this.flarManager.mirrorDisplay, this.stage.stageWidth, this.stage.stageHeight);
- this.addChild(this.myObjects);
- this.myObjects.mouseChildren = false;
- }
复制代码 2。处理Marker事件- //监听事件,然后作出相应处理
- private function onMarkerAdded (evt:FLARMarkerEvent) :void {
- this.myObjects.addMarker(evt.marker);
- }
- private function onMarkerUpdated (evt:FLARMarkerEvent) :void {
- }
- private function onMarkerRemoved (evt:FLARMarkerEvent) :void {
- this.myObjects.removeMarker(evt.marker);
- }
复制代码 (完)
附件:
本帖隐藏的内容需要回复才可以浏览 |