/* * PROJECT: FLARManager * http://transmote.com/flar * Copyright 2009, Eric Socolofsky * -------------------------------------------------------------------------------- * This work complements FLARToolkit, developed by Saqoosha as part of the Libspark project. * http://www.libspark.org/wiki/saqoosha/FLARToolKit * FLARToolkit is Copyright (C)2008 Saqoosha, * and is ported from NYARToolkit, which is ported from ARToolkit. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this framework; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For further information please contact: * * http://transmote.com/flar * */ package com.transmote.flar.marker { import __AS3__.vec.Vector; import com.transmote.flar.source.IFLARSource; import com.transmote.flar.utils.FLARGeomUtils; import com.transmote.flar.utils.IFLARMatrixSmoother; import flash.geom.Point; import flash.geom.Vector3D; import org.libspark.flartoolkit.core.FLARSquare; import org.libspark.flartoolkit.core.types.FLARDoublePoint2d; import org.libspark.flartoolkit.core.types.FLARIntPoint; import org.libspark.flartoolkit.core.types.FLARLinear; import org.libspark.flartoolkit.core.types.matrix.FLARDoubleMatrix34; import org.libspark.flartoolkit.detector.FLARMultiMarkerDetectorResult; /** *

* Container for information about a detected marker, including:
*

*

* * @author Eric Socolofsky * @url http://transmote.com/flar * @see com.transmote.flar.marker.FLARMarkerEvent */ public class FLARMarker { private static var sessionIdCounter:uint = 0; internal var _sessionId:int = -1; internal var _patternId:int; internal var _direction:int; internal var _flarSquare:FLARSquare; internal var _confidence:Number; internal var _transformMatrix:FLARDoubleMatrix34; internal var _flarSource:IFLARSource; private var matrixHistory:Vector.; private var screenCenter:Point; internal var _centerpoint2D:Point = null; internal var _centerpoint3D:Point = null; internal var _vector3D:Vector3D = null; internal var _rotationX:Number = NaN; internal var _rotationY:Number = NaN; internal var _rotationZ:Number = NaN; private var rotations:Vector3D; private var _corners:Vector.; internal var _deprecatedOutline:FLARMarkerOutline; /** * constructor. */ public function FLARMarker (detectorResult:FLARMultiMarkerDetectorResult, transformMatrix:FLARDoubleMatrix34, flarSource:IFLARSource, deprecatedOutline:FLARMarkerOutline) { this._patternId = detectorResult.codeId; this._direction = detectorResult.direction; this._flarSquare = detectorResult.square; this._confidence = detectorResult.confidence; this._transformMatrix = transformMatrix; this._flarSource = flarSource; this._deprecatedOutline = deprecatedOutline; if (this._flarSource.mirrored) { this.mirror(); } this.screenCenter = new Point(0.5*this._flarSource.sourceSize.width, 0.5*this._flarSource.sourceSize.height); this.calcCorners(); } /** * copy the properties of a FLARMarker into this FLARMarker. */ public function copy (otherMarker:FLARMarker) :void { this._patternId = otherMarker._patternId; this._direction = otherMarker._direction; this._flarSquare = otherMarker._flarSquare; this._confidence = otherMarker._confidence; this._transformMatrix = otherMarker._transformMatrix; this._flarSource = otherMarker._flarSource; this._deprecatedOutline = otherMarker._deprecatedOutline; this.resetAllCalculations(); } /** * ID unique to this marker in this session. * no two markers in a session share the same sessionId. */ public function get sessionId () :uint { return this._sessionId; } /** * called only by FLARManager, when a new FLARMarker is detected. * this method should not be called by developers. * (poor OOP, i know....sorry.) */ public function setSessionId () :void { if (this._sessionId == -1) { this._sessionId = FLARMarker.sessionIdCounter++; } } /** * ID of this marker's pattern. * pattern IDs are zero-indexed, and are * assigned to patterns in the order they were initially loaded. */ public function get patternId () :int { return this._patternId; } /** * closest orthographic orientation of detected marker. * value between 0 and 3, inclusive: * 0: up * 1: left * 2: down * 3: right */ public function get direction () :int { return this._direction; } /** * 'confidence' is a value assigned by FLARToolkit to each detected marker, * that describes the algorithm's perceived accuracy of the pattern match. */ public function get confidence () :Number { return this._confidence; } /** * FLARDoubleMatrix34 matrix that describes transformation of marker relative to the camera. * apply to FLARBaseNodes that should appear 'tethered' to the marker. */ public function get transformMatrix () :FLARDoubleMatrix34 { return this._transformMatrix; } /** * FLARSquare instance used to create this FLARMarkerOutline instance. * can be accessed if direct access to FLARToolkit output is desired; * no downsampling correction is applied. */ public function get flarSquare () :FLARSquare { return this._flarSquare; } public function get corners () :Vector. { return this._corners; } /** * centerpoint of marker outline in the 2D space of the screen, * calculated as the average of the outline's four corner points. * to access the centerpoint reported by FLARToolkit in three dimensions, * use FLARMarker.centerpoint. */ public function get centerpoint () :Point { if (!this._centerpoint2D) { this._centerpoint2D = this.calcCenterpoint2D(); } return this._centerpoint2D; } /** * centerpoint of marker outline extracted from FLARToolkit transformation matrix. * this centerpoint is determined based on the 3D location of the detected marker, * and is used by FLARManager in 3D calculations. * to avoid having to correct for Z location, use centerpoint2D. */ public function get centerpoint3D () :Point { if (!this._centerpoint3D) { this._centerpoint3D = this.calcCenterpoint3D(this._transformMatrix); } return this._centerpoint3D; } /** * returns centerpoint at location toward which this FLARMarker is moving * (target location at end of smoothing animation). */ public function get targetCenterpoint3D () :Point { if (!this.matrixHistory) { return this.centerpoint3D; } // find most recent stored transformation matrix var i:int = this.matrixHistory.length - 1; while (this.matrixHistory[i] == null) { i--; if (i == -1) { return this.centerpoint3D; } } return this.calcCenterpoint3D(this.matrixHistory[i]); } /** * Vector3D instance that describes x, y, and z coordinates, * as well as rotationZ (stored as vector3D.w). */ public function get vector3D () :Vector3D { if (!this._vector3D) { if (this._transformMatrix) { this._vector3D = new Vector3D( this._transformMatrix.m03 / this._flarSource.resultsToDisplayRatio, this._transformMatrix.m13 / this._flarSource.resultsToDisplayRatio, this._transformMatrix.m23, this.rotationZ); } else { // no transformMatrix when using FLARProxy this._vector3D = new Vector3D(this.centerpoint.x, this.centerpoint.y, 0, 0); } } return this._vector3D; } /** * rotation of marker along X axis. */ public function get rotationX () :Number { if (!this.rotations) { this.calcRotations(); } return this.rotations.x; } /** * rotation of marker along Y axis. */ public function get rotationY () :Number { if (!this.rotations) { this.calcRotations(); } return this.rotations.y; } /** * rotation of marker along Z axis. */ public function get rotationZ () :Number { if (!this.rotations) { this.calcRotations(); } return this.rotations.z; } /** * apply smoothing algorithm over a number of frames. * called by FLARManager as part of marker tracking/maintenance process. */ public function applySmoothing (smoother:IFLARMatrixSmoother, numFrames:int) :void { if (!this.matrixHistory) { this.matrixHistory = new Vector.(numFrames, false); } else if (this.matrixHistory.length != numFrames) { this.matrixHistory.length = numFrames; } for (var i:int=0; i(4); var i:int = 4; var flarCorner:FLARDoublePoint2d; while (i--) { flarCorner = FLARDoublePoint2d(this.flarSquare.sqvertex[i]); this._corners[i] = new Point(flarCorner.x / this._flarSource.resultsToDisplayRatio, flarCorner.y / this._flarSource.resultsToDisplayRatio); } } private function calcRotations () :void { this.rotations = FLARGeomUtils.calcFLARMatrixRotations(this._transformMatrix); } private function resetAllCalculations () :void { this._centerpoint2D = null; this._centerpoint3D = null; this._vector3D = null; this.rotations = null; this.calcCorners(); } } }