FLAR Pattern Emulator(模型仿真)
在我们被构建摄像机和FLARToolKit搞疯之前,我们需要创建一个测试的环境。这个有很多好处: 1、我们构建一个预测的环境是我们的创意原型显示。 2、通过创建一个测试环境我们可以非常容易地协调我们的程序而不用任何的从属关系。 3、有一个可靠地debug模式可以辅助验证我们代码的稳定性,并在做实时测试时排除了表面错误。 4、用摄像头测试是个痛苦的过程。每次你重新编译你的工程拟不得不接收使用摄像头的许可。用debug模式你可以建立出任何事物,当你知道所有都正常的时候你可以进行最后的摄像头测试。 所以仿真器将做什么?像我们前面讨论的一样,我们需要一个标记去解析。这个仿真器将会用我们的测试标记创建一个简单的3d plane。我们也会使用鼠标在3d空间内来旋转我们的虚拟卡片来模仿用户通过摄像头将做的交互。所以让我们来创建一个叫做CardEmulator的类。
- /**
- * Original Author: Jesse Freeman
- * Class File: CardEmulator.as
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * Revisions
- * 1.0 Initial version April 29, 2009
- *
- */
- package com.insideria.flar
- {
- import flash.display.Sprite;
-
- import org.papervision3d.cameras.Camera3D;
- import org.papervision3d.materials.BitmapFileMaterial;
- import org.papervision3d.objects.primitives.Plane;
- import org.papervision3d.render.BasicRenderEngine;
- import org.papervision3d.scenes.Scene3D;
- import org.papervision3d.view.BitmapViewport3D;
- /**
- * The CardEmulator represent a simple system for testing an AR Marker with
- * needing to use a webcam as a source. This class creates an instance of a
- * Papervision 3D renderer, viewport and scene with a simple 3d plane skinned
- * with a texture of your marker. When render is called the mouse is tracked
- * and the plane is adjusted to test your pattern at different angles.
- *
- * This since this class requires a reference to stage for the mouse
- * calculations you must attach it to the stage or another display object.
- * In cases when you don't want to see the viewport you can optionally toggle
- * addViewportToDisplay in the constructor.
- *
- * @author Jesse Freeman
- *
- */
- public class CardEmulator extends Sprite
- {
-
- protected var _width:Number = 0;
- protected var _height:Number = 0;
- protected var testMarkerURL:String;
- protected var emulatorViewport:BitmapViewport3D;
- protected var emulatorRenderer:BasicRenderEngine;
- protected var emulatorScene:Scene3D;
- protected var emulatorCamera:Camera3D;
- protected var testCard:Plane;
- protected var addViewportToDisplay:Boolean = false;
-
- /**
- * Returns an instance of the viewport as a BitmapViewport3d object.
- *
- * @return BitmapViewport3D and can be used to sample BitmapData from.
- *
- */
- public function get viewport():BitmapViewport3D
- {
- return emulatorViewport;
- }
-
- /**
- * Constructs the emulator environment. We need a url to the test
- * marker, a width and a height.
- *
- * @param testMarkerURL loads in a sample test marker image.
- * @param w width of the emulators display - default 320.
- * @param h height of the emulators display - default 240.
- * @param addViewportToDisplay tells the emulator if it should attach
- * the viewport to the display or not. In most cases you would not want
- * to set this to true unless you are testing that the Emulator is
- * actually displaying and working.
- *
- */
- public function CardEmulator(testMarkerURL:String, w:Number = 320, h:Number = 240, addViewportToDisplay:Boolean = false)
- {
- this.testMarkerURL = testMarkerURL;
- _width = w;
- _height = h;
- this.addViewportToDisplay = addViewportToDisplay;
- init();
- }
-
- /**
- * @private
- *
- * On init we create the emulators viewport, render scene and camera.
- * We also attach a testCard (plane) to the scene to act as our sample
- * pattern.
- *
- */
- protected function init():void
- {
- // Setup PV3D
- emulatorViewport = new BitmapViewport3D(_width, _height);
- emulatorRenderer = new BasicRenderEngine();
- emulatorScene = new Scene3D();
- emulatorCamera = new Camera3D();
-
- // Create test pattern plane
- var bmpMaterial:BitmapFileMaterial = new BitmapFileMaterial(testMarkerURL, true);
- bmpMaterial.doubleSided = true;
-
- testCard = new Plane(bmpMaterial, 300, 300, 4, 4);
-
- // Make the camera face the testCard
- emulatorCamera.target = testCard;
- emulatorScene.addChild( testCard );
-
- // Make sure we should add this to the display
- if(addViewportToDisplay)
- addChild(emulatorViewport);
- }
-
- /**
- *
- * Here we take the mouse's movement and rotate the camera
- * accordingly. This assumes that the CardEmulator instance has a
- * reference to the stage.
- *
- */
- protected function calculateMouseMovement():void
- {
- if(stage)
- {
- var rotY: Number = (mouseY-(stage.stageHeight/2))/(stage.height/2)*(2200);
- var rotX: Number = (mouseX-(stage.stageWidth/2))/(stage.width/2)*(-2200);
- emulatorCamera.x = emulatorCamera.x + (rotX - emulatorCamera.x) / 2;
- emulatorCamera.y = emulatorCamera.y + (rotY - emulatorCamera.y) / 2;
- }
- }
-
- /**
- *
- * When a render is called we calculate the mouseMovement then render
- * out the scene.
- *
- */
- public function render():void
- {
- calculateMouseMovement();
- emulatorRenderer.renderScene(emulatorScene, emulatorCamera, emulatorViewport);
- }
- }
- }
复制代码这个类和我们构建的文件类一样简单,值得注意的是我们使用一个BitmapViewport3D,使得我们今后可以很轻松地通过它加载BitmapData。同时,我们创建了一个Plane并添加了BitmapFileMaterial纹理。我们要做的最后一件事是render方法和calculateMouseMovement方法。注意到这两个方法为什么没有EnterFrame监听器来运行渲染?因为这个方法将要被FLARVision外部调用,而FLARVision有自己的render方法。通过这种方法我们保证渲染循环最简化。这种方法尤其适用于同时有两个papervision的实例的情况。 现在我们来在FLARVision文件类中构建,在create3dObjects方法后添加下列方法
- /**
- * Creates the emulator card to use in debug mode.
- *
- */
- protected function createEmulatorCard():void
- {
- cardEmulator = new CardEmulator("images/flarlogo.gif", 320, 240, true);
- addChild(cardEmulator);
复制代码同时添加变量和导入类包:
protected var cardEmulator:CardEmulator;import com.insideria.flar.CardEmulator; 在我们测试我们的仿真器工作之前,让我们改变我们的init方法:
- protected function init():void {
- createEmulatorCard();
- setupPapervision();
- addEventListener(Event.ENTER_FRAME, renderViewport);
- }
复制代码 同时改变我们的renderViewport来调用CardEmulator的render方法:- public function renderViewport(event:Event = null):void
- {
- cardEmulator.render();
- renderer.renderScene(scene, camera, viewport);
- }
复制代码在你编译之前需要注意到你应该拷贝一份data和images文件夹到FLARVision的html-template文件夹或者你存放你编译的swfs文件的地方。你可以从工程中获得资源包。一旦你这样做了,你可能需要清理你的工程(Project -> clean ...)的bin目录。 如果你编译成功你将会在屏幕的左上角看到我们的测试仿真模拟器当移动出表的时候,这个测试仿真会跟随着旋转。
(这里有可能会遇到一个安全沙箱错误,不过我们都知道flex的debug模式不用理会沙箱问题,当你部署到服务器上才会遇到,我还没去做部署,所以先不翻译,有兴趣可看原文。)
需要注意的是我们仅仅使测试仿真达到320*240的分辨率。当我们更深入教程的时候我们会注意到当运行FLARToolKit的时候性能会降低。AR对与Flash来说仍然是新生的,不成熟的代码决定了仿真的大小需要受到限制。与之相对应的,我们经常以320*240的分辨率从video源取样。这将会提高性能并且得到可能最佳的结果。接下来我们会向未伸缩的源图片添加些代码,但是让我们先来看看如何构建FLARToolKit.
|