Scene papervision

Cet article portera sur la création d’une Scène Papervision 3D, l’ajout dans cette scène d’une camera , d’une sphère et des différents mouvements apportés à ces objets.
Tout d’abord il convient d’importer les principales classe de Papervision

import org.papervision3d.cameras.Camera3D;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.BitmapFileMaterial;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;

puis on declarera : une vue (Viewport3D) , une camera (Camera3D) , un renderer (BasicRenderEngine), une sphere et un bitmapFileMaterial qui nous servira a texture la sphere.

public var scene:Scene3D;
public var vue:Viewport3D;
public var camera:Camera3D;
public var rendu:BasicRenderEngine;

private var s:Sphere;

private var Bmat1:BitmapFileMaterial;

Dans la scene , nous allons ajouter notre vue qui prend comme parametre la largeur et la hauteur de la vue , les deux autres parametres étant autoScaleToStage (la vue est redimensionnée pour être de la taille de la scène) et si elle est interactive

vue = new Viewport3D(900, 700,true, true);
addChild(vue);
vue.buttonMode = true;

scene = new Scene3D();
camera = new Camera3D();
rendu = new BasicRenderEngine();

ensuite nous allons créer la sphere et la texturer


// bitmap material
Bmat1 = new BitmapFileMaterial("terre-mars.jpg");
Bmat1.doubleSided = true;
Bmat1.interactive = true;

s = new Sphere(Bmat1,500,30,30);
scene.addChild(s);

s.x = 0;

// ici la camera est centrée sur la sphere
camera.lookAt(s);

camera.zoom = 1;
camera.focus = 10;

addEventListener(MouseEvent.MOUSE_WHEEL,onZoom,false,0,true);
s.addEventListener(InteractiveScene3DEvent.OBJECT_OVER,move1,false,0,true);

Enfin, nous devons initialiser le rendu final de la scene :

rendu.renderScene(scene, camera, vue);

puis dans un enter frame , nous pourrons faire tourner la sphere , et la camera zoomera sur la sphère

protected function renduScene():void
{

s.yaw(1);

if(camera.zoom <= 25)
{
camera.zoom = camera.zoom+0.1;

}
else
{

}

c.yaw(10);

}





Réalitée augmentée en utilisant une webcam et Flash

Avant de coder dans un projet Flash CS4, nous avons besoin de préparer les librairies et les assets .

Pour démarrer :

1/ créer un nouveau projet dans Flash CS4, pour cela aller dans Fichiers -> nouveau…-> fichier flash (AS3.0) et sauver le fichier en
tant que  AugmentedReality.fla dans le répertoire du projet

2/ créer un document en choisissant Fichiers -> nouveau … -> Fichier ActionScript et le sauver en tant que AugmentedReality.as
le sauver dans le répertoire du projet

3/ définir ce fichier comme le fichier par défaut , fenêtre -> propriétés -> classe

4/ Créer un répertoire de librairie dans le projet et rajouter rajouter les librairies suivantes (Flex SDK code Library, Flash augmented Reality Code Library, Papervision3D code Library)  en allant dans Fichiers > Paramètres de publication > Flash > ActionScript 3.0 > répertoire librairie

5/ Créer un répertoire asset et rajouter le modèle 3D Collada et les deux fichiers de données AR.

Les différents rôles des librairies :

Flex SDK Code library : Permet d’importer les données de fichiers FLAR.
Spark Project’s Flash Augmented Reality code library (FLARToolkit): Détection graphique.
Papervision3D code library (PV3D): Permet l’import , le positionnement et le rendu du modèle 3D.

La Bibliothèque de Réalité augmentée Flash Toolkit (FLARToolkit) est importante pour cette application. Il analyse l’image fournie par la webcam et définit l’espace occupée pour cartographier le modèle 3D. Le fichier FLARCameraParams.dat Il corrige la distorsion de la webcam et détecte le pattern. L’image du pattern est définie dans le fichier FLARPattern.pat. Pour utiliser un autre graphique, créer une image JPEG , et utilisez le FLAR Marker Generator (AIR, 322K) pour générer un nouveau fichier de signatures.

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 AugmentedReality 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 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;

[Embed(source="./assets/FLAR/FLARPattern.pat", mimeType="application/octet-stream")]
private var Pattern : 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;

//   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 = 30;  //Set 5 to 30. Higher values = smoother video
private var DETECTION_THRESHOLD : uint  = 80;  //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.1 to 5. Set higher to enlarge model

// Fun, Editable Properties: Load a Different Model
private var COLLADA_3D_MODEL : String = "./assets/models/licensed/hummer/models/hummer.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 AugmentedReality()
{
//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);
flarCode.loadARPatt(new Pattern());

//   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

//  Add the 3D model into the
//  FLAR container and add the
//  3D cameras view to the screen
//  so the user can view the result
flarBaseNode.addChild(collada3DModel);
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) {}
}
}
}

constructeur de la classe

À partir de la ligne 93, les méthodes de préparation sont appelés pour chacun des éléments suivants: la webcam, la détection du pattern et Papervision3D. En plus des méthodes de configuration, la fonction loopToDetectMarkerAndUpdate3D est configuré pour exécuter encore et encore. En écoutant l’événement ENTER_FRAME construit en Flash, cette boucle sera appelé à plusieurs reprises tant que la demande est en cours d’exécution.

Initialiser la webcam

Comme l’exécution de l’application et d’une caméra est détectée, Flash Player invitera automatiquement l’utilisateur a activer sa webcam (ligne 96) .

Initialiser FLAR

La partie la plus importante du projet est la détection du pattern (marqueur graphique). Comme le marqueur graphique est détectée via la webcam, sa position, la rotation et l’échelle dans l’espace sont calculés. Ce calcul sera utilisée dans les prochaines étapes. À commencer par la ligne 97, FLAR va rechercher encore chaque trame d’images webcam pour le marqueur graphique prédéfinie (objet Pattern). Le schéma de détection utilise un objet ActionScript BitmapData, qui ne contient que la dernière trame de vidéo à un moment donné (la fonction BitmapData Draw).

Papervision 3D

Pour l’essentiel, la configuration 3D à la ligne 98 est typique de tout projet Papervision3D. Un objet BasicRenderEngine va gérer l’essentiel des mathématiques vecteur, transformant la géométrie 3D à la 2D graphiques pour les afficher sur l’écran. Le modèle 3D Collada est chargé et inséré dans la scène 3D, et la vue dans cet objet (scène ViewPort) est ajouté à la scène.

routine de mise à jour de la détection
En utilisant l’ENTER_FRAME, la fonction loopToDetectMarkerAndUpdate3D à la ligne 102 sera appelé 30 fois par seconde. Chaque fois, l’objet BitmapData va copier dans la dernière trame de la séquence webcam. FLAR exécute la détection sur l’image fixe. Si le marqueur est détecté, FLAR retourne à jour la position, la rotation et données à grande échelle (objet TransformMatrix). Le conteneur (objet FLARBaseNode) détenant le modèle 3D est mis à jour.

Tutoriel reprenant l’article http://www.adobe.com/devnet/flash/articles/augmented_reality.html




Réalitée augmentée en Flash avec FLARToolKit

Le tutoriel présenté ici sera une mise en application de FLARToolKit, libraire Flash de réalité augmentée. il s’agira de la coupler avec papervision pour interagir avec une scène en 3D.
Cette libraire japonaise Open Source” est de plus en plus utilisée dans les campagnes marketing.
Tout d’abord , nous allons déclarer deux sources externes , la première sont les paramètres de la capture vidéo utilise par FLARToolKit
le deuxième est le pattern en lui même

A noter qu’un éditeur de pattern existe en ligne :

http://flash.tarotaro.org/blog/2008/12/14/artoolkit-marker-generator-online-released/

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

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

Nous devons d’abord initialiser la vidéo .
nous créons un objet video que rattachons avec la méthode getCamera()
puis nous rajoutons le flux video sur la scene

/**
*  initWebCam
*
**/
private function initWebCam():void
{
_video  = new Video(VIDEO_WIDTH, VIDEO_HEIGHT);
_webcam = Camera.getCamera();

if(_webcam != null)
{
_webcam.setMode(WEB_CAMERA_WIDTH, WEB_CAMERA_HEIGHT, VIDEO_FRAME_RATE);
//_webcam.addEventListener(ActivityEvent.ACTIVITY,activityHandler);
_video.attachCamera(_webcam);
addChild(_video);
}
else
{

}

}

pour la détection , c’est la que la librairie FLARtoolkit entre en jeu
1/ chargement des paramètres inclut dans le fichier externe
2/ pour que le pattern soit bien detecte , les valeurs passées dans le FLARCode doivent etre le segment et la tailler que nous avons definit dans le pattern
3/ le detcteur a besoin d’un bitmadata pour localsier le pâttern sur une frame de celui ci , c’est pour cela que nous avons FLARRgbRaster_BitmapData
4/ nous passons dans le constructeur de FLARSingleMarkerDetector, les paramètres , la largeur du marqueur et le flar code.

/**
* initDetection
*/
private function initDetection():void
{
/*   Le fichier parametre corrige les imperfections de l'image de la webcam
Le fichier pattern determine le graphique pour la detection
par l'outil FLAR */
_flarParam = new FLARParam();
_flarParam.loadARParam(new Params() as ByteArray);

_flarCode = new FLARCode(FLAR_CODE_SIZE, FLAR_CODE_SIZE);
_flarCode.loadARPatt(new Pattern());

_bitmapData = new BitmapData(VIDEO_WIDTH, VIDEO_HEIGHT);
_bitmapData.draw(_video);
_flarRgbRaster_BitmapData = new FLARRgbRaster_BitmapData(_bitmapData);
_flarSingleMarkerDetector = new FLARSingleMarkerDetector(_flarParam, _flarCode, MARKER_WIDTH);
}

Papervision : le méthode suivante cree une scene Papervision 3D avec un plan ou une sphère auquel on associe un bitmapFileMaterial afin de les texturer.
le BasicRenderEngine sert de moteur de rendu à la scène.

/**
* initGraph
*/
private function initGraph():void
{
_basicRenderEngine     = new BasicRenderEngine();
_flarTransMatResult     = new FLARTransMatResult();
_viewport3D         = new Viewport3D();
_flarCamera3D        = new FLARCamera3D(_flarParam);
_flarBaseNode        = new FLARBaseNode();
_scene3D           = new Scene3D();
_scene3D.addChild(_flarBaseNode);

// graph
// bitmap material
_pMat = new BitmapFileMaterial("../assets/img/logo004.png");
_pMat.doubleSided = true;
_pMat.interactive = true;

// bitmap material
_sMat = new BitmapFileMaterial("../assets/img/terre-mars.jpg");
_sMat.doubleSided = true;00
_sMat.interactive = true;

_s = new Sphere(_sMat,100,100,30);
_p = new Plane(_pMat,100,100,10,10);

_flarCamera3D.lookAt(_s);
_flarCamera3D.zoom = 1;
_flarCamera3D.focus = 10;

addEventListener(MouseEvent.MOUSE_WHEEL,onZoom,false,0,true);

_flarBaseNode.addChild(_p);
addChild(_viewport3D);
}

pendant le rendu de la scene , la sphere tournera.
le rendu étant une terre effectuant une rotation sur son axe

/**
* rendu scene
*/
protected function renduScene():void
{
_s.yaw(30);

if(_flarCamera3D.zoom <= 25)
{
_flarCamera3D.zoom = _flarCamera3D.zoom+0.1;

}
else
{

}

}

La routine de detection : la fonction la plus importante
elle est appelle dans un enterFrame et grace au bitmap data recherche le pattern dans celui ci
les constantes DETECTION_THRESHOLD (valeur comprise en tre 50 et 100) et DETECTION_CONFIDENCE (valeur comprise entre 0.1 et 1) permettent un réglage plus ou moins précis de la détection du pattern.

si le pattern est détecte , nous effectuons un rendu de la scène papervision.


/**
* loopToDetectMarkerAndUpdate
*/
private function loopToDetectMarkerAndUpdate(e:Event):void
{
/* Copie la derniere still-frame de la video de la webcam
dans l'objet bitmapdata pour la detection */
_bitmapData.draw(_video);
renduScene();

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)
{
}
}