Button Panel Inside a Panorama

Intro

I wrote this code a little time ago, but it’s got some good stuff in it. It demonstrates how to put a button panel inside of a panorama using multiple viewports and cameras. It also shows how to use the switch case to handle button interactivity.

I’ve already lost it once and had to decompile it from the web and reconstruct it. So don’t be surprised if you see the loc_2 variable. I decompiled my own code – the best use of sothink. To see a demo click the image below.

Button Panel Inside of a Panorama

Button Panel Inside of a Panorama

Demo: http://www.professionalpapervision.com/demos/web/buttonpano/

Download (buttonPano): http://code.google.com/p/flex3cookbook2/downloads

Discussion

This is essentially a combination of the button panel and panorama discussed in previous posts. But if you put them together they will not work. The button panel has sorting issues with the panorama. So the trick to make this work is to use 2 separate viewports and two separate cameras. One viewport for the button panel and one for the panorama and similarly for the cameras.

Important Trick(multiple viewports)

The use of multiple viewports to overcome sorting issues is an important trick in Papervision. In addition to solving sorting problems you can use multiple viewports to enhance application performance by separately throttling the viewports based on user interactions.

It’s easy to add more than one viewport, you just declare a new one and add it as shown below

viewport = new Viewport3D(800, 600, true, false);
viewport2 = new Viewport3D(800, 600, true, true);
viewport2.buttonMode=true;
pv3Canvas.rawChildren.addChild(viewport);
pv3Canvas.rawChildren.addChild(viewport2);

Note: This was a Flex program and required the use of rawChildren.

There is an important difference when working with Flex applications where you are using script tags (not an actionscript project). In order to add children to the Flex stage you must put them in a canvas or another component and use the rawChildren tag shown below.

pv3Canvas.rawChildren.addChild(viewport);

This modification allows you to add non-native Flex display Objects to the Flex display stack. This is essential in getting your MXML application to run, otherwise nothing will happen.

It is easy to add multiple cameras as well as shown below:

scene = new Scene3D();
camera = new FreeCamera3D();

scene2 = new Scene3D();
camera2 = new FreeCamera3D();

And when you render you must have two render functions as follows;

renderer.renderScene(scene, camera, viewport);
renderer.renderScene(scene2, camera2, viewport2);

Switch Case

If you’ve done any amount of game programming you’ll agree that switch case is your best friend and it comes in handy when working with the interactivity of our button panel as well. When you click on a button you can extract the buttons name using

param1.face3d.material.name

once you have the name of the button you clicked on you can put it in a switch case and associate it with a specific function for that name as shown below:

private function onClick(param1:InteractiveScene3DEvent) : void
{
switch(param1.face3d.material.name)
{
case “myMat00″:
{
navigateToURL(new URLRequest(“http://n2.nabble.com/Lively3D-f1514083.html”), “_blank”);
break;
}// end case
case “myMat01″:
{
navigateToURL(new URLRequest(“http://code.google.com/p/lively3d/”), “_blank”);
break;
}// end case
case “myMat02″:
{
navigateToURL(new URLRequest(“http://www.youtube.com/mikenku”), “_blank”);
break;
}// end case
case “myMat10″:
{
navigateToURL(new URLRequest(“http://code.google.com/p/flex3cookbook1/downloads/list”), “_blank”);
break;
}// end case
case “myMat11″:
{
navigateToURL(new URLRequest(“http://www.professionalpapervision.wordpress.com”), “_blank”);
break;
}// end case
case “myMat12″:
{
navigateToURL(new URLRequest(“http://www.nku.edu/”), “_blank”);
break;
}// end case
default:
{
break;
}
}

Click the more button to see the complete code.

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; layout=”absolute” creationComplete=”init()”>
<mx:Script>
<![CDATA[

import flash.events.Event;

import mx.core.MovieClipAsset;

import org.papervision3d.cameras.FreeCamera3D;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.objects.primitives.Sphere;

import caurina.transitions.*;
import flash.display.*;
import flash.events.*;
import flash.net.*;
import mx.containers.*;
import mx.controls.*;
import mx.core.*;
import mx.events.*;
import mx.styles.*;
import org.papervision3d.cameras.*;
import org.papervision3d.events.*;
import org.papervision3d.materials.*;
import org.papervision3d.materials.utils.*;
import org.papervision3d.objects.primitives.*;
import org.papervision3d.render.*;
import org.papervision3d.scenes.*;
import org.papervision3d.view.*;

private var renderer:BasicRenderEngine;
private var scene:Scene3D;
private var camera:FreeCamera3D;
private var viewport:Viewport3D;

private var scene2:Scene3D;
private var camera2:FreeCamera3D;
private var viewport2:Viewport3D;

private var panoSphere:Sphere;
private var sphereMat:MovieMaterial;

private var myMouseDown:Boolean = false;

[Embed(source=”assets/ampitheaterPanoWeb.swf”)]
private var panoAsset:Class;

private var oneIt:int=0;
private var plane:MultMatPlane;

private function init():void
{
//Declare Papervision Variables
viewport = new Viewport3D(800, 600, true, false);
viewport2 = new Viewport3D(800, 600, true, true);
viewport2.buttonMode=true;
pv3Canvas.rawChildren.addChild(viewport);
pv3Canvas.rawChildren.addChild(viewport2);
scene = new Scene3D();
camera = new FreeCamera3D();

scene2 = new Scene3D();
camera2 = new FreeCamera3D();

renderer = new BasicRenderEngine();

//Create the pano material
var movieAsset:MovieClipAsset = new panoAsset();
sphereMat = new MovieMaterial(movieAsset, false);
sphereMat.opposite = true;
sphereMat.animated = true;

//Smooth is heavy, but it makes stuff look nicer…you could make it switch dynamically.
sphereMat.smooth = true;

//Create the panosphere.
panoSphere = new Sphere(sphereMat, 25000, 30,30);

scene.addChild(panoSphere);

//position the camera in the center of the sphere, and set it’s properties for focus and zoom.
camera.x = camera.y = camera.z = 0;
camera.focus = 300;
camera.zoom = 2;

camera2.x = camera2.y = 0;
camera2.z = -100;
camera2.focus = 300;
camera2.zoom = 2;

//Add Button Primitive

var myBitmapFileMaterial00:BitmapFileMaterial = new BitmapFileMaterial(“assets/FinalPosterPres.jpg”);
myBitmapFileMaterial00.doubleSided = true;
myBitmapFileMaterial00.interactive = true;
myBitmapFileMaterial00.name = “myMat00″;
var myBitmapFileMaterial01:BitmapFileMaterial = new BitmapFileMaterial(“assets/MillerOilsPpt.jpg”);
myBitmapFileMaterial01.doubleSided = true;
myBitmapFileMaterial01.interactive = true;
myBitmapFileMaterial01.name = “myMat01″;
var myBitmapFileMaterial02:BitmapFileMaterial = new BitmapFileMaterial(“assets/PosterPres2008.jpg”);
myBitmapFileMaterial02.doubleSided = true;
myBitmapFileMaterial02.interactive = true;
myBitmapFileMaterial02.name = “myMat02″;
var myBitmapFileMaterial10:BitmapFileMaterial = new BitmapFileMaterial(“assets/RainesConference.jpg”);
myBitmapFileMaterial10.doubleSided = true;
myBitmapFileMaterial10.interactive = true;
myBitmapFileMaterial10.name = “myMat10″;
var myBitmapFileMaterial11:BitmapFileMaterial = new BitmapFileMaterial(“assets/SurveySummary.jpg”);
myBitmapFileMaterial11.doubleSided = true;
myBitmapFileMaterial11.interactive = true;
myBitmapFileMaterial11.name = “myMat11″;
var myBitmapFileMaterial12:BitmapFileMaterial = new BitmapFileMaterial(“assets/logo.png”);
myBitmapFileMaterial12.doubleSided = true;
myBitmapFileMaterial12.interactive = true;
myBitmapFileMaterial12.name = “myMat12″;

var materialsList:* = new MaterialsList();
materialsList.addMaterial(myBitmapFileMaterial00, “myMat00″);
materialsList.addMaterial(myBitmapFileMaterial01, “myMat01″);
materialsList.addMaterial(myBitmapFileMaterial02, “myMat02″);
materialsList.addMaterial(myBitmapFileMaterial10, “myMat10″);
materialsList.addMaterial(myBitmapFileMaterial11, “myMat11″);
materialsList.addMaterial(myBitmapFileMaterial12, “myMat12″);

plane = new MultMatPlane(materialsList, 10, 3, 2, 5, 5, 1, 1);
scene2.addChild(plane);

plane.y = 4;
plane.z = 0;
plane.scaleX = 10;
plane.scaleY = 10;
plane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onClick);

addEventListener(Event.ENTER_FRAME, onEnterFrame);

viewport.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
viewport.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
viewport.addEventListener(MouseEvent.ROLL_OVER, onMouseUp);

function onMouseDown() : void
{
myMouseDown = true;

};

function onMouseUp() : void
{
myMouseDown = false;

};

}

private function onEnterFrame(param1:Event = null) : void
{

if (myMouseDown)
{
camera.rotationY = camera.rotationY + (mouseX – stage.width / 2) / 50;
camera.rotationX = camera.rotationX – (mouseY – stage.height / 2) / 50;
if (camera.rotationX <= -90)
{
camera.rotationX = -90;
}
else if (camera.rotationX >= 90)
{
camera.rotationX = 90;
}// end else if
camera2.rotationY = camera2.rotationY + (mouseX – stage.width / 2) / 50;
camera2.rotationX = camera2.rotationX – (mouseY – stage.height / 2) / 50;
if (camera2.rotationX <= -90)
{
camera2.rotationX = -90;
}
else if (camera2.rotationX >= 90)
{
camera2.rotationX = 90;
}// end else if
camera2.z = -100 * Math.cos(camera2.rotationY * Math.PI / 180);
camera2.x = -100 * Math.sin(camera2.rotationY * Math.PI / 180);
var loc_2:Number = camera.rotationY – (stage.width / 2 – mouseX) / 10;
Tweener.addTween(camera, {rotationY:loc_2, time:0.25, transition:”linear”});
Tweener.addTween(camera2, {rotationY:loc_2, time:0.25, transition:”linear”});
//renderer.renderScene(scene, camera, viewport);
//renderer.renderScene(scene2, camera2, viewport2);
}

//if(oneIt<10){
renderer.renderScene(scene, camera, viewport);
renderer.renderScene(scene2, camera2, viewport2);
//oneIt++;

//}

}

private function onClick(param1:InteractiveScene3DEvent) : void
{
switch(param1.face3d.material.name)
{
case “myMat00″:
{
navigateToURL(new URLRequest(“http://n2.nabble.com/Lively3D-f1514083.html&#8221;), “_blank”);
break;
}// end case
case “myMat01″:
{
navigateToURL(new URLRequest(“http://code.google.com/p/lively3d/&#8221;), “_blank”);
break;
}// end case
case “myMat02″:
{
navigateToURL(new URLRequest(“http://www.youtube.com/mikenku&#8221;), “_blank”);
break;
}// end case
case “myMat10″:
{
navigateToURL(new URLRequest(“http://code.google.com/p/flex3cookbook1/downloads/list&#8221;), “_blank”);
break;
}// end case
case “myMat11″:
{
navigateToURL(new URLRequest(“http://www.professionalpapervision.wordpress.com&#8221;), “_blank”);
break;
}// end case
case “myMat12″:
{
navigateToURL(new URLRequest(“http://www.nku.edu/&#8221;), “_blank”);
break;
}// end case
default:
{
break;
}
}

}

]]>
</mx:Script>
<mx:Canvas x=”0″ y=”80″ width=”40″ height=”41″ id=”pv3Canvas”>
</mx:Canvas>
<mx:TextArea x=”10″ y=”6″ width=”687″ fontSize=”14″ textAlign=”center” color=”#FEFFFF” alpha=”0.41″>
<mx:text>Assessing the Impact of an Inexpensive Faculty Learning Community on Faculty Development, Institutional Services, and Student Learning</mx:text>
</mx:TextArea>
<mx:Label x=”386″ y=”53″ text=”Hold and Click the Mourse where you want to go.” color=”#FFFFFF” fontSize=”11″/>
</mx:Application>

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: