Création de hotspots dans un panorama
Cet article a été mis à jour le 14 mars 2009 afin d'être compatible avec la dernière version en date de Papervision
Les hotspots représentent des zones d'interactivité dans un panorama. Ils peuvent avoir pour but le déplacement de pièces en pièces, l'affichage d'informations, le lancement d'une vidéo, etc...
Pour démarrer en douceur , nous allons commencer par ajouter des hotspots sur une des visionneuses du post précédent.
Ceux-ci afficheront un simple texte lorsque l'on clique dessus.
I> Création des hotspots
Pour réaliser nos hotspots, nous allons ajouter un simple plan transparent devant chaque élément qui nous intéresse dans le panorama.
Cet exemple se base sur la visionneuse qui projete les 6 images (512*512) d'une pièce sur un cube (cf exemple ici).
Les images se trouvent ici, et le code source là.
Commençons par décider quels seront nos objets interactifs. Par exemple, j'ai choisi le radiateur qui est sur l'image de la
face droite :

et l'armoire de la face gauche:

Les dimensions de ces zones sont respectivement de 221*124 et 332*329. Elles nous serviront un peu plus tard.
Pour ajouter nos plans qui serviront de zone sensible, rien de plus facile. Cette méthode a d'ailleurs été vue dans un précédent billet : On crée un plan grâce à l'objet 'Plane' en lui spécifiant une texture, une taille, ainsi que son nombre de faces. On l'ajoute ensuite à la scène.
Comme texture, on peut utiliser une simple texture couleur, puisque le plan sera transparent par la suite.
Pour calculer la taille du plan, il suffit de faire une règle de trois. Les images de 512*512 sont appliquées sur des plans
de 1000*1000 donc notre zone interactive qui fait 221*124 sur l'image sera représenté par un plan de 431*242 pour le radiateur et de 648*642 pour l'armoire. Pour les coordonnées x,y ont fait pareil.
Etant donnée que cette solution est assez lourde , un des prochains billets expliquera comment mettre en place un éditeur de hotspots.
Il ne reste plus qu'à ajouter les plans sur la scène. Vous devriez obtenir quelque chose comme ceci pour le moment.
On peut remarquer par certains moments, selon l'orientation de la caméra, certains artefacts sur ces nouveaux plans. Cela est du à
l'algorithme de tri des faces de Papervision. Lorsque 2 objets sont très
rapprochés , il peut arriver que certaines faces passent derrière d'autres alors qu'il ne le faudrait pas.(Plus d'infos
sur cette démo)
Alors que dans les versions précédentes de Papervision, il fallait passer par quelques hacks pour résoudrent ces problèmes, on peut maintenant utiliser des ViewportLayer pour indiquer au moteur de quelle manière trier les éléments de la scène.
II> Ajout des événements souris
L'activation des évenements souris nécessitent 3 étapes :
- Mettre la propriété interactive du viewport à true.
- Mettre la propriété interactive du materiel des objets interactifs à true.
- Ajouter un écouteur sur un évenement de type InteractiveScene3DEvent aux objets.
-
...
-
public function VisionneuseCubeHotspots()
-
{
-
super( 800, 512, true, true, CameraType.FREE );
-
...
-
var colorMaterial:ColorMaterial = new ColorMaterial();
-
colorMaterial.interactive = true;
-
var plane:Plane = new Plane( colorMaterial, 431, 242, 1, 1 );
-
...
-
plane.addEventListener( InteractiveScene3DEvent.OBJECT_PRESS, onMouseDown);
-
plane.addEventListener( InteractiveScene3DEvent.OBJECT_RELEASE, onMouseUp);
Il ne reste plus qu'à définir les finctions onMouseDown et onMouseUp et de rendre nos plans transparent
La version finale avec le code source. A venir, l'éditeur de hotspots.
-
package {
-
import flash.events.Event;
-
import flash.text.TextField;
-
import flash.text.TextFieldAutoSize;
-
import flash.text.TextFormat;
-
-
import org.papervision3d.cameras.CameraType;
-
import org.papervision3d.events.InteractiveScene3DEvent;
-
import org.papervision3d.materials.BitmapFileMaterial;
-
import org.papervision3d.materials.BitmapMaterial;
-
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.view.BasicView;
-
import org.papervision3d.view.layer.ViewportLayer;
-
-
[SWF( width='800', height='512', backgroundColor='0x000000', frameRate='30' )]
-
public class VisionneuseCubeHotspots extends BasicView
-
{
-
private static const IMG_BASE_URL:String = "assets/rendu_cubique_";
-
private static var MAX_X_ROTATION:int = 50;
-
-
private var cube:Cube;
-
private var label:TextField;
-
-
public function VisionneuseCubeHotspots()
-
{
-
super( 800, 512, true, true, CameraType.FREE );
-
-
createTextfield();
-
createCube();
-
createHotspots();
-
-
camera.z = 0;
-
startRendering();
-
}
-
-
private function createCube():void
-
{
-
var frontMat:BitmapMaterial = new BitmapFileMaterial( IMG_BASE_URL+"FR.jpg" );
-
var backMat:BitmapFileMaterial = new BitmapFileMaterial( IMG_BASE_URL+"BK.jpg" );
-
var leftMat:BitmapFileMaterial = new BitmapFileMaterial( IMG_BASE_URL+"LF.jpg" );
-
var rightMat:BitmapFileMaterial = new BitmapFileMaterial( IMG_BASE_URL+"RT.jpg" );
-
var upMat:BitmapFileMaterial = new BitmapFileMaterial( IMG_BASE_URL+"UP.jpg" );
-
var downMat:BitmapFileMaterial = new BitmapFileMaterial( IMG_BASE_URL+"DN.jpg" );
-
-
frontMat.doubleSided = true;
-
backMat.doubleSided = true;
-
leftMat.doubleSided = true;
-
rightMat.doubleSided = true;
-
upMat.doubleSided = true;
-
downMat.doubleSided = true;
-
-
-
var imgMaterialList:MaterialsList = new MaterialsList(
-
{
-
front: frontMat,
-
back: backMat,
-
left: leftMat,
-
right: rightMat,
-
top: upMat,
-
bottom: downMat
-
});
-
-
cube = new Cube( imgMaterialList, 1000, 1000, 1000, 16, 16, 16 );
-
scene.addChild( cube );
-
}
-
-
private function createHotspots():void
-
{
-
var colorMaterial:ColorMaterial = new ColorMaterial();
-
colorMaterial.doubleSided = true;
-
colorMaterial.interactive = true;
-
-
//radiateur
-
var plane:Plane = new Plane( colorMaterial, 431, 242, 1, 1 );
-
plane.name = "radiateur";
-
plane.y = -70;
-
plane.z = -200;
-
plane.x = 500;
-
plane.rotationY = -90;
-
plane.addEventListener( InteractiveScene3DEvent.OBJECT_PRESS, onMouseDown);
-
plane.addEventListener( InteractiveScene3DEvent.OBJECT_RELEASE, onMouseUp);
-
scene.addChild( plane );
-
-
//armoire
-
var plane2:Plane = new Plane( colorMaterial, 648, 642, 1, 1 );
-
plane2.name = "armoire";
-
plane2.y = 10;
-
plane2.z = -120;
-
plane2.x = -500;
-
plane2.rotationY = -90;
-
plane2.addEventListener( InteractiveScene3DEvent.OBJECT_PRESS, onMouseDown);
-
plane2.addEventListener( InteractiveScene3DEvent.OBJECT_RELEASE, onMouseUp);
-
scene.addChild( plane2 );
-
-
//force l'affichage des hotspots
-
var vp:ViewportLayer = viewport.getChildLayer(plane, true);
-
vp.addDisplayObject3D( plane2 );
-
vp.layerIndex = 1;
-
vp.alpha = 0;
-
-
}
-
-
private function createTextfield():void
-
{
-
label = new TextField();
-
label.autoSize = TextFieldAutoSize.LEFT;
-
label.background = true;
-
label.border = true;
-
-
var format:TextFormat = new TextFormat();
-
format.font = "Verdana";
-
format.color = 0xFF0000;
-
format.size = 16;
-
format.underline = true;
-
-
label.defaultTextFormat = format;
-
}
-
-
private function onMouseDown( e:InteractiveScene3DEvent ):void
-
{
-
label.text = "clic sur "+ e.displayObject3D.name
-
addChild(label);
-
}
-
-
private function onMouseUp(event:Event):void
-
{
-
removeChild(label);
-
}
-
-
-
override protected function onRenderTick(event:Event=null):void
-
{
-
camera.rotationY += ( mouseX - ( stage.width/2 ) ) / MAX_X_ROTATION;
-
camera.rotationX += ( mouseY - ( stage.height/2 ) ) / MAX_X_ROTATION;
-
-
//on limite la rotation verticale
-
if( camera.rotationX> MAX_X_ROTATION )
-
{
-
camera.rotationX = MAX_X_ROTATION;
-
}
-
if( camera.rotationX <- MAX_X_ROTATION )
-
{
-
camera.rotationX = - MAX_X_ROTATION;
-
}
-
super.onRenderTick( event );
-
}
-
}
-
}
Tags: hotspots, Panorama, Panoramique
Articles relatifs :

26. juin 2007 at 19:02
Merci beaucoup, je commence jsute à manipuler papervision, et tes tutos sont supers ! Bien expliquer, ca marche bien… un grand merci !
26. juin 2007 at 20:09
Merci beaucoup pour ton commentaire, ça fait plaisir
Sympa ton blog aussi
7. août 2007 at 14:40
Juste une petite question, est-il possible de récupérer la référence de l’objet qui a été cliqué.
Sinon super boulot!!
8. août 2007 at 13:31
Dans les précédentes versions de P3D, il fallait passer par un tableau associatif ou une classe personnalisée pour récupérer la référence.
Avec la version 1.5, tu peux y accèder directement depuis la propriété ‘displayObject3D’de l’événement ‘InteractiveScene3DEvent’ dispatché.
Je vais regarder pour mettre les sources à jour à l’occase.
9. août 2007 at 15:49
Effectivement, je ne savais pas qu’il y avait cette notion d’InteractiveScene. J’ai testé avec mon appli ça marche bien.
Merci!!
1. octobre 2007 at 16:22
Super, je n’ai pas encore essayé mais ca à l’air très interessant. Un grand merci!
3. octobre 2007 at 14:53
Excellent example of hotspotting in a panoramic cube! I’ve been searching for this for quite some time now. Merci Beaucoup!
10. octobre 2008 at 03:00
Un grand merci pour ce tuto mais je débute en AS3 et j’ai du mal à récupérer l’evenement de l’objet cliqué. Pourrait-on publier la partie de code svp.
10. octobre 2008 at 10:08
Salut,
L’intégralité du code est là mais c’est une version qui a plus d’un an. Entre temps, l’API de papervision a évolué et le code n’est plus à jour. Je travaille actuellement sur la refonte de ces articles qui seront bientôt publiés.
14. mars 2009 at 20:20
[...] Réaliser une visionneuse de panorama VR en AS3 Création de hotspots dans un panorama [...]
15. mai 2009 at 22:21
Avez-vous l’éditeur hotspot tutorial … merci.
11. mars 2010 at 13:18
Vraiment un grand merci je cherche depuis 3 semaine un tuto. comme le tien un grand merci.
juste un petit truc…j’ai changé camera.z = 0; en camera.z = 90;
Comme ca à l’affichage la caméra est aligné face au mur et non pas au plafond!
Pourrais tu m’aider pour la gestion de la cam comment faire pour pouvoir bouger avec dans le volume?
Merci d’avance et bravo