FLARToolKit Multiple Markers and Objects

2.3k views Asked by At

I'm trying to get the Augmented Reality code to work with multiple objects. How do I do this? I've tried everything but it just doesn't work. The following code is for a single augmented reality marker, but it displays every object.

package {

    //--------------------------------------
    //  Imports
    //--------------------------------------
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.utils.ByteArray;

    import org.libspark.flartoolkit.core.FLARCode;
    import org.libspark.flartoolkit.core.param.FLARParam;
    import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
    import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;
    import org.libspark.flartoolkit.detector.FLARSingleMarkerDetector;
    import org.libspark.flartoolkit.pv3d.FLARBaseNode;
    import org.libspark.flartoolkit.pv3d.FLARCamera3D;

    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.parsers.DAE;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;


    //--------------------------------------
    //  Class Definition
    //--------------------------------------
    public class AugmentedRealityMulti extends Sprite
    {

        //--------------------------------------
        //  Class Properties
        //--------------------------------------

        //  1. WebCam
        private var video   : Video;
        private var webcam  : Camera;

        //  2. FLAR Marker Detection
        private var flarBaseNode                : FLARBaseNode;
        private var flarParam                   : FLARParam;
        private var flarCode                    : FLARCode;
        private var flarCodePark                : FLARCode;
        private var flarCodeTNT                 : FLARCode;
        private var flarCodeMushroom            : FLARCode;
        private var flarCodeTrafficLight        : FLARCode;
        private var flarRgbRaster_BitmapData    : FLARRgbRaster_BitmapData;
        private var flarSingleMarkerDetector    : FLARSingleMarkerDetector;
        private var flarCamera3D                : FLARCamera3D;
        private var flarTransMatResult          : FLARTransMatResult;
        private var bitmapData                  : BitmapData;
        private var FLAR_CODE_SIZE              : uint      = 16;
        private var MARKER_WIDTH                : uint      = 80;
        private var markerId: int;


        [Embed(source = "./assets/FLAR/marker2.pat", mimeType = "application/octet-stream")]
        private var Pattern : Class;

        [Embed(source = "./assets/FLAR/marker2.pat", mimeType = "application/octet-stream")]
        private var PatternPark : Class;

        [Embed(source = "./assets/FLAR/marker2.pat", mimeType = "application/octet-stream")]
        private var PatternMushroom : Class;

        [Embed(source = "./assets/FLAR/marker2.pat", mimeType = "application/octet-stream")]
        private var PatternTNT  : Class;

        [Embed(source = "./assets/FLAR/marker2.pat", mimeType = "application/octet-stream")]
        private var PatternTrafficLight : Class;

        [Embed(source = "./assets/FLAR/FLARCameraParameters.dat", mimeType = "application/octet-stream")]
        private var Params : Class;

        //  3. PaperVision3D
        private var basicRenderEngine   : BasicRenderEngine;
        private var viewport3D          : Viewport3D;
        private var scene3D             : Scene3D;
        private var collada3DModel      : DAE;
        private var collada3DModelPark  : DAE;
        private var collada3DModelTrafficLight: DAE;
        private var collada3DModelMushroom  : DAE;
        private var collada3DModelTNT   : DAE;

        //  Fun, Editable Properties
        private var VIDEO_WIDTH             : Number = 640;             //Set 100 to 1000 to set width of screen
        private var VIDEO_HEIGHT            : Number = 480;             //Set 100 to 1000 to set height of screen
        private var WEB_CAMERA_WIDTH        : Number = VIDEO_WIDTH / 2; //Smaller than video runs faster
        private var WEB_CAMERA_HEIGHT       : Number = VIDEO_HEIGHT / 2;    //Smaller than video runs faster
        private var VIDEO_FRAME_RATE        : Number = 60;              //Set 5 to 30.  Higher values = smoother video
        private var DETECTION_THRESHOLD     : uint   = 100;             //Set 50 to 100. Set to detect marker more accurately.
        private var DETECTION_CONFIDENCE    : Number = 0.5;             //Set 0.1 to 1. Set to detect marker more accurately.
        private var MODEL_SCALE             : Number = 0.8;             //Set 0.01 to 5. Set higher to enlarge model
        private var MODEL_SCALE_PARK        : Number = 0.1;

        //  Fun, Editable Properties: Load a Different Model
        private var COLLADA_3D_MODEL        : String = "./assets/banana/models/banana2.dae";
        private var COLLADA_3D_MODEL_PARK   : String = "./assets/park/models/Park 01.dae";
        private var COLLADA_3D_MODEL_TNT    : String = "./assets/tnt/models/spootnak.dae";
        private var COLLADA_3D_MODEL_MUSHROOM: String = "./assets/mushroom/models/mushroom.dae";
        private var COLLADA_3D_MODEL_TRAFFIC: String = "./assets/trafficlight/models/Untitled.dae";


        //--------------------------------------
        // Constructor
        //--------------------------------------

        /**
        * The constructor is the ideal place
        * for project setup since it only runs once.
        * Prepare A,B, & C before repeatedly running D.
        **/
        public function AugmentedRealityMulti()
        {
            //Prepare
            prepareWebCam();  //Step A
            prepareMarkerDetection();  //Step B
            preparePaperVision3D();  //Step C

            //  Repeatedly call the loop method
            //  to detect and adjust the 3D model.
            addEventListener(Event.ENTER_FRAME, loopToDetectMarkerAndUpdate3D); //Step D
        }


        //--------------------------------------
        // Methods
        //--------------------------------------

        /**
        * A. Access the user's webcam, wire it
        *    to a video object, and display the
        *    video onscreen.
        **/
        private function prepareWebCam() : void
        {
            video  = new Video(VIDEO_WIDTH, VIDEO_HEIGHT);
            webcam = Camera.getCamera();
            webcam.setMode(WEB_CAMERA_WIDTH, WEB_CAMERA_HEIGHT, VIDEO_FRAME_RATE);
            video.attachCamera(webcam);
            addChild(video);
        }


        /**
        * B. Prepare the FLAR tools to detect with
        *    parameters, the marker pattern, and
        *    a BitmapData object to hold the information
        *    of the most recent webcam still-frame.
        **/
        private function prepareMarkerDetection() : void
        {
            //   The parameters file corrects imperfections
            //   In the webcam's image. The pattern file
            //   defines the marker graphic for detection
            //   by the FLAR tools.
            flarParam = new FLARParam();
            flarParam.loadARParam(new Params() as ByteArray);

            flarCode = new FLARCode(FLAR_CODE_SIZE, FLAR_CODE_SIZE);
            flarCodePark = new FLARCode(FLAR_CODE_SIZE, FLAR_CODE_SIZE);
            flarCodeMushroom = new FLARCode(FLAR_CODE_SIZE, FLAR_CODE_SIZE);
            flarCodeTNT = new FLARCode(FLAR_CODE_SIZE, FLAR_CODE_SIZE);
            flarCodeTrafficLight = new FLARCode(FLAR_CODE_SIZE, FLAR_CODE_SIZE);

            flarCode.loadARPatt(new Pattern());
            flarCodePark.loadARPatt(new PatternPark());
            flarCodeMushroom.loadARPatt(new PatternMushroom());
            flarCodeTNT.loadARPatt(new PatternTNT());
            flarCodeTrafficLight.loadARPatt(new PatternTrafficLight());

            //   A BitmapData is Flash's version of a JPG image in memory.
            //   FLAR studies this image every frame with its
            //   marker-detection code.
            bitmapData = new BitmapData(VIDEO_WIDTH, VIDEO_HEIGHT);
            bitmapData.draw(video);
            flarRgbRaster_BitmapData = new FLARRgbRaster_BitmapData(bitmapData);

            flarSingleMarkerDetector = new FLARSingleMarkerDetector(flarParam, flarCode, MARKER_WIDTH);
        }


        /**
        * C. Create PaperVision3D's 3D tools including
        *    a scene, a base node container to hold the
        *    3D Model, and the loaded 3D model itself.
        **/
        private function preparePaperVision3D() : void
        {
            //  Basics of the empty 3D scene fit for
            //  FLAR detection inside a 3D render engine.
            basicRenderEngine   = new BasicRenderEngine();
            flarTransMatResult  = new FLARTransMatResult();
            viewport3D          = new Viewport3D();
            flarCamera3D        = new FLARCamera3D(flarParam);
            flarBaseNode        = new FLARBaseNode();
            scene3D           = new Scene3D();
            scene3D.addChild(flarBaseNode);

            //  Load, scale, and position the model
            //  The position and rotation will be
            //  adjusted later in method D below.

            collada3DModel = new DAE();
            collada3DModel.load(COLLADA_3D_MODEL);
            collada3DModel.scaleX = collada3DModel.scaleY = collada3DModel.scaleZ = MODEL_SCALE;
            collada3DModel.z = 5;       //Moves Model 'Up' a Line Perpendicular to Marker
            collada3DModel.rotationX = -90; //Rotates Model Around 2D X-Axis of Marker
            collada3DModel.rotationY = 180; //Rotates Model Around 2D Y-Axis of Marker
            collada3DModel.rotationZ = 90;  //Rotates Model Around a Line Perpendicular to Marker

            flarBaseNode.addChild(collada3DModel);

            collada3DModelPark = new DAE();
            collada3DModelPark.load(COLLADA_3D_MODEL_PARK);
            collada3DModelPark.scaleX = collada3DModelPark.scaleY = collada3DModelPark.scaleZ = MODEL_SCALE_PARK;
            collada3DModelPark.z = 5;
            collada3DModelPark.rotationX = -90;
            collada3DModelPark.rotationY = 180;
            collada3DModelPark.rotationZ = 90;

            flarBaseNode.addChild(collada3DModelPark);

            collada3DModelTNT = new DAE();
            collada3DModelTNT.load(COLLADA_3D_MODEL_TNT);
            collada3DModelTNT.scaleX = collada3DModelTNT.scaleY = collada3DModelTNT.scaleZ = MODEL_SCALE;
            collada3DModelTNT.z = 5;
            collada3DModelTNT.rotationX = -90;
            collada3DModelTNT.rotationY = 180;
            collada3DModelTNT.rotationZ = 90;

            flarBaseNode.addChild(collada3DModelTNT);

            collada3DModelMushroom = new DAE();
            collada3DModelMushroom.load(COLLADA_3D_MODEL_MUSHROOM);
            collada3DModelMushroom.scaleX = collada3DModelMushroom.scaleY = collada3DModelMushroom.scaleZ = MODEL_SCALE;
            collada3DModelMushroom.z = 5;
            collada3DModelMushroom.rotationX = -90;
            collada3DModelMushroom.rotationY = 180;
            collada3DModelMushroom.rotationZ = 90;

            flarBaseNode.addChild(collada3DModelMushroom);

            collada3DModelTrafficLight = new DAE();
            collada3DModelTrafficLight.load(COLLADA_3D_MODEL_TRAFFIC);
            collada3DModelTrafficLight.scaleX = collada3DModelTrafficLight.scaleY = collada3DModelTrafficLight.scaleZ = MODEL_SCALE;
            collada3DModelTrafficLight.z = 5;
            collada3DModelTrafficLight.rotationX = -90;
            collada3DModelTrafficLight.rotationY = 180;
            collada3DModelTrafficLight.rotationZ = 90;

            flarBaseNode.addChild(collada3DModelTrafficLight);

            //  Add the 3D model into the
            //  FLAR container and add the
            //  3D cameras view to the screen
            //  so the user can view the result
            addChild(viewport3D);
        }


        /**
        * D. Detect the marker in the webcamera.
        *    If found: move, scale, and rotate the
        *    3D model to composite it over the marker
        *    in the user's physical space.
        **/
        private function loopToDetectMarkerAndUpdate3D(aEvent : Event) : void
        {

            //  Copy the latest still-frame of the webcam video
            //  into the BitmapData object for detection
            bitmapData.draw(video);

            try {

                //  Detect *IF* the marker is found in the latest still-frame
                if(flarSingleMarkerDetector.detectMarkerLite(flarRgbRaster_BitmapData, DETECTION_THRESHOLD) &&
                flarSingleMarkerDetector.getConfidence() > DETECTION_CONFIDENCE) {

                    //  Repeatedly Loop and Adjust 3D Model to Match Marker
                    flarSingleMarkerDetector.getTransformMatrix(flarTransMatResult);
                    flarBaseNode.setTransformMatrix(flarTransMatResult);
                    basicRenderEngine.renderScene(scene3D, flarCamera3D, viewport3D);
                }
            } catch(error : Error) {}
        }
    }
}

I've also tried to mix it with the thesven augmented reality code for multiple markers, but it worked once, and now it doesn't work. I also don't know how to link the marker with the object.

package {

    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.Cube;
    import org.libspark.flartoolkit.core.transmat.FLARTransMatResult;

    import org.libspark.flartoolkit.core.FLARCode;
    import org.libspark.flartoolkit.core.param.FLARParam;
    import org.libspark.flartoolkit.core.raster.rgb.FLARRgbRaster_BitmapData;
    import org.libspark.flartoolkit.detector.FLARMultiMarkerDetector;
    import org.libspark.flartoolkit.pv3d.FLARBaseNode;
    import org.libspark.flartoolkit.pv3d.FLARCamera3D;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.objects.parsers.DAE;

    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.utils.ByteArray;

    [SWF(width = "640", height = "480", frameRate = "30", backgroundColor = "#FFFFFF")]

    public class FLARMultiMarker extends Sprite {

        //flar specific variables
        [Embed(source = "marker2.pat", mimeType = "application/octet-stream")]
        private  var   pattern: Class;
        [Embed(source = "marker2.pat", mimeType = "application/octet-stream")]
        private  var   pattern2: Class;
        [Embed(source = "marker2.pat", mimeType = "application/octet-stream")]
        private  var   pattern3: Class;
        [Embed(source = "marker2.pat", mimeType = "application/octet-stream")]
        private  var   pattern4: Class;
        [Embed(source = "marker2.pat", mimeType = "application/octet-stream")]
        private  var   pattern5: Class;

        [Embed(source = "/camera_para.dat", mimeType = "application/octet-stream")]
        private  var   params: Class;

        private  var   fparams: FLARParam;
        private  var   fpattern: FLARCode;
        private  var   fpattern2: FLARCode;
        private  var   fpattern3: FLARCode;
        private  var   fpattern4: FLARCode;
        private  var   fpattern5: FLARCode;
        private  var   patternArray: Array;
        private  var   vid: Video;
        private  var   cam: Camera;
        private  var   bmd: BitmapData;
        private  var   raster: FLARRgbRaster_BitmapData;
        private  var   detector: FLARMultiMarkerDetector;
        private  var   transMats: Array;
        private  var   baseNodes: Array;
        private var collada3DModel      : DAE;
        private var collada3DModelPark  : DAE;
        private var collada3DModelTrafficLight: DAE;
        private var collada3DModelMushroom  : DAE;
        private var collada3DModelTNT   : DAE;

        //  Fun, Editable Properties
        private var VIDEO_WIDTH             : Number = 640;             //Set 100 to 1000 to set width of screen
        private var VIDEO_HEIGHT            : Number = 480;             //Set 100 to 1000 to set height of screen
        private var WEB_CAMERA_WIDTH        : Number = VIDEO_WIDTH / 2; //Smaller than video runs faster
        private var WEB_CAMERA_HEIGHT       : Number = VIDEO_HEIGHT / 2;    //Smaller than video runs faster
        private var VIDEO_FRAME_RATE        : Number = 60;              //Set 5 to 30.  Higher values = smoother video
        private var DETECTION_THRESHOLD     : uint   = 100;             //Set 50 to 100. Set to detect marker more accurately.
        private var DETECTION_CONFIDENCE    : Number = 0.5;             //Set 0.1 to 1. Set to detect marker more accurately.
        private var MODEL_SCALE             : Number = 0.8;             //Set 0.01 to 5. Set higher to enlarge model
        private var MODEL_SCALE_PARK        : Number = 0.1;

        //  Fun, Editable Properties: Load a Different Model
        private var COLLADA_3D_MODEL        : String = "banaan/models/banana2.dae";
        private var COLLADA_3D_MODEL_PARK   : String = "park/models/Park 01.dae";
        private var COLLADA_3D_MODEL_TNT    : String = "tnt/models/spootnak.dae";
        private var COLLADA_3D_MODEL_MUSHROOM: String = "mushroom/models/mushroom.dae";
        private var COLLADA_3D_MODEL_TRAFFIC: String = "trafficlight/models/Untitled.dae";

        //papervision variables
        private  var   v: Viewport3D;
        private  var   s: Scene3D;
        private  var   c: FLARCamera3D;
        private  var   r: BasicRenderEngine;
        private  var   pl: PointLight3D;

        public function FLARMultiMarker() {

            addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);

        }

        private function init(e: Event): void{

            setupFLAR();
            setupWebCamera();
            setupBitmap();
            setupPapervision();

            stage.addEventListener(Event.ENTER_FRAME, loop, false, 0, true);

        }

        private function setupFLAR(): void{

            fparams = new FLARParam();
            fparams.loadARParam(new params as ByteArray);

            fpattern = new FLARCode(16, 16);
            fpattern.loadARPatt(new pattern());

            fpattern2 = new FLARCode(16, 16);
            fpattern2.loadARPatt(new pattern2());

            fpattern3 = new FLARCode(16, 16);
            fpattern3.loadARPatt(new pattern3());

            fpattern4 = new FLARCode(16, 16);
            fpattern4.loadARPatt(new pattern4());

            fpattern5 = new FLARCode(16, 16);
            fpattern5.loadARPatt(new pattern5());

            patternArray = [fpattern, fpattern2, fpattern3, fpattern4, fpattern5];
        }

        private function setupWebCamera(): void{

            vid = new Video(640, 480);
            cam = Camera.getCamera();
            cam.setMode(640, 480, 30);
            vid.attachCamera(cam);
            addChild(vid);

        }

        private function setupBitmap(): void{

            bmd = new BitmapData(640, 480);
            bmd.draw(vid);

            raster = new FLARRgbRaster_BitmapData(bmd);

            //parameters, pattern, pattern size, number of markers to pick up
            detector = new FLARMultiMarkerDetector(fparams, patternArray, [80, 80], patternArray.length);
        }

        private function setupPapervision(): void{

            //basic setup
            v = new Viewport3D(640, 480, true, true);
            addChild(v);

            s = new Scene3D();
            c = new FLARCamera3D(fparams);
            r = new BasicRenderEngine();

            pl = new PointLight3D();
            pl.x = 1000;
            pl.y = 1000;
            pl.z = -1000;


            baseNodes = [];
            for(var j: Number = 0; j <= patternArray.length; j++) {
                baseNodes[j] = new FLARBaseNode();
                s.addChild(baseNodes[j]);
            }

            transMats = [];
            for(var i: Number = 0; i < patternArray.length; i++) {
                transMats[i] = new FLARTransMatResult();
            }

            //object setup
            for(var k: Number = 0; k < patternArray.length; k++) {

                collada3DModel = new DAE();
                collada3DModel.load(COLLADA_3D_MODEL_PARK);
                collada3DModel.scaleX = collada3DModel.scaleY = collada3DModel.scaleZ = MODEL_SCALE_PARK;
                collada3DModel.z = 5;       //Moves Model 'Up' a Line Perpendicular to Marker
                collada3DModel.rotationX = -90; //Rotates Model Around 2D X-Axis of Marker
                collada3DModel.rotationY = 180; //Rotates Model Around 2D Y-Axis of Marker
                collada3DModel.rotationZ = 90;  //Rotates Model Around a Line Perpendicular to Marker
                baseNodes[k].addChild(collada3DModel);
            }

        }

        private function loop(e: Event): void{

            try{

                bmd.draw(vid);

                var numDetectedMarkers: int = detector.detectMarkerLite(raster, 80);
                var markerId: int;
                for(var i: int = 0; i < numDetectedMarkers; i++) {

                    //ignore markers with a low confidence
                    if(detector.getConfidence(i) > 0.4) {
                        //figure out which marker we're looking at
                        markerId = detector.getARCodeIndex(i);
                        detector.getTransmationMatrix(i, transMats[markerId]);
                    }

                }

                //apply the transform matricies to the basenodes
                for(var j: Number = 0; j < baseNodes.length; j++) {
                    baseNodes[j].setTransformMatrix(transMats[j]);
                    r.renderScene(s, c, v);
                    trace('set trans mat for ...', baseNodes[j]);
                }

            }
            catch(e: Error) {}

        }

    }
}

Thanks in advanced!

1

There are 1 answers

0
Sruit A.Suk On

because you have put every objects into your FLARBaseNode

here:

        flarBaseNode.addChild(collada3DModelPark);

        flarBaseNode.addChild(collada3DModelMushroom);

        flarBaseNode.addChild(collada3DModelTrafficLight);

you need to make multiple flarBaseNode to display each object per each pattern