Advanced Interactivity

advancedinteractivity1

download-source

This is just another example of how to do some advanced interactivity in Papervision 3D. This tutorial is just a slightly updated version of the #10 : Advanced Interactivity tutorial from a while back.

Here is what has been updated:
1) Removed InteractiveScene3DEvent and replaced it with standard MouseEvents
2) Updated to use papervision’s BasicView.as class

For a full description of what is going on please refer back to this link: #10 : Advanced Interactivity

package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.MovieMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.view.BasicView;
 
	/**
	 * ...
	 * @author Charlie Schulze, charlie[at]woveninteractive[dot]com
	 */
 
	public class Main extends BasicView 
	{
		protected var cube:Cube;
		protected var interactiveMats:Array;
		protected var materialsList:MaterialsList;
		protected var targetrotationX:Number;
		protected var targetrotationY:Number;
		protected var targetrotationZ:Number;
		protected var tweening:Boolean;
 
		public function Main():void 
		{
			super();
			init();
		}
		protected function init():void 
		{
			createChildren();
			startRendering();
		}
		protected function createChildren():void 
		{
			//Set the viewport to interactive
			viewport.interactive = true;
 
			//Create Materials:
			materialsList 			= new MaterialsList();
			interactiveMats 		= ["front", "back", "left", "right", "bottom", "top"];
			var colorsArray:Array 	= [0x76b6f8, 0x4291e1, 0x1f73c8, 0xe77111, 0xe8914c, 0xfad2b2];
 
			for (var i:int = 0; i < interactiveMats.length; i++)
			{
				//Create a color box so we can use our MouseEvents
				var colorBox:Sprite = new Sprite();
				colorBox.graphics.beginFill(colorsArray[i]);
				colorBox.graphics.drawRect(0, 0, 100, 100);
				colorBox.graphics.endFill();
				colorBox.name = interactiveMats[i];
 
				//Add a textField for reference
				var textField:TextField = new TextField()
				colorBox.addChild(textField)
				textField.text = interactiveMats[i];
 
				//Add a MouseEvent to the Sprite
				colorBox.mouseChildren = false;
				colorBox.addEventListener(MouseEvent.CLICK, onMovieMatClicked);
 
				//Create the MovieMat
				var movieMat:MovieMaterial 		= new MovieMaterial(colorBox, true, true);
				movieMat.interactive 			= true;
				movieMat.smooth 				= true;
				materialsList.addMaterial(movieMat, interactiveMats[i]);
			}
 
			//Create Cube
			cube 	= new Cube(materialsList, 100, 100, 100);
 
			//Add cube to the scene
			scene.addChild(cube);
		}
 
		protected function onMovieMatClicked(evt:MouseEvent):void 
		{
			if (tweening) 
			{
				// Let it rotate again
				tweening = false;
			}
			else 
			{
				switch(evt.target.name) {
					case "front":
						targetrotationX = 0;
						targetrotationY = 180;
						targetrotationZ = 0;
						tweening = true;
					break;
					case "back":
						targetrotationX = 0;
						targetrotationY = 0;
						targetrotationZ = 0;
						tweening = true;
					break;
					case "left":
						targetrotationX = 0;
						targetrotationY = -90;
						targetrotationZ = 0;
						tweening = true;
					break;
					case "right":
						targetrotationX = 0;
						targetrotationY = 90;
						targetrotationZ = 0;
						tweening = true;
					break;
					case "top":
						targetrotationX = -90;
						targetrotationY = 0;
						targetrotationZ = 0;
						tweening = true;
					break;
					case "bottom":
						targetrotationX = 90;
						targetrotationY = 0;
						targetrotationZ = 180;
						tweening = true;
					break;
				}
			}
		}
 
		override protected function onRenderTick(event:Event = null):void 
		{
			super.onRenderTick(event);
 
			if (tweening) {
				// If a face has been clicked
				if (camera.zoom <230) {
					// If the camera isn't zoomed enough then zoom in a bit more:
					camera.zoom += Math.sqrt(230-camera.zoom)/5;
				}
				// Test each rotation and rotate it towards the target rotation:
				// X axis:
				if (cube.rotationX < targetrotationX) 
				{
					cube.rotationX += Math.sqrt(targetrotationX-cube.rotationX);
					cube.rotationX = Math.round(cube.rotationX);
				}
				else if (cube.rotationX > targetrotationX) 
				{
					cube.rotationX -= Math.sqrt(cube.rotationX-targetrotationX);
					cube.rotationX = Math.round(cube.rotationX);
				}
 
				// Y axis:
				if (cube.rotationY < targetrotationY) 
				{
					cube.rotationY += Math.sqrt(targetrotationY-cube.rotationY);
					cube.rotationY = Math.round(cube.rotationY);
				}
				else if (cube.rotationY > targetrotationY) 
				{
					cube.rotationY -= Math.sqrt(cube.rotationY-targetrotationY);
					cube.rotationY = Math.round(cube.rotationY);
				}
 
				// Z axis:
				if (cube.rotationZ < targetrotationZ) 
				{
					cube.rotationZ += Math.sqrt(targetrotationZ-cube.rotationZ);
					cube.rotationZ = Math.round(cube.rotationZ);
				}
				else if (cube.rotationZ > targetrotationZ) 
				{
					cube.rotationZ -= Math.sqrt(cube.rotationZ-targetrotationZ);
					cube.rotationZ = Math.round(cube.rotationZ);
				}
			}
			else 
			{
				// If the camera is zoomed in, it shouldn't be now
				if (camera.zoom > 200) 
				{
					// So zoom out a bit.
					camera.zoom -= Math.sqrt(camera.zoom-2)/5;
				}
				// Rotate the cube a bit:
				cube.rotationX += 2;
				cube.rotationY += 2;
				// Make sure that we dont "wind up" the rotation
				if (cube.rotationX>= 360) cube.rotationX = 0;
				if (cube.rotationY>= 360) cube.rotationY = 0;
			}
		}		
	}
}

download-source

This entry was posted in Actionscript 3.0, Papervision 3D, Tutorials, TweenLite and tagged , , , , , , . Bookmark the permalink.

9 Responses to Advanced Interactivity

  1. Pingback: 10. Advanced Interactivity at Papervision 3D Tutorials

  2. Kim says:

    I’m wondering how I could use the array and iteration loop to work in combination with XML pushed images. I’m not lazy, I’ll try it myself, it will take some time though, I’m not a programmer. In any case, huge thanks for this one, I was trying to do something similar without success.

  3. Charlie says:

    Hey Kim,

    Which part were you stuck on? Were you able to get the XML loaded but not the images? Let me know what part you were stuck on and I can try to help.

    Charlie

  4. Kim says:

    Appreciate it.

    For some reason, I’m trying to use images instead of the proposed colorBox here, and listen to a click on the cube, so not on each instance of the image (although that might be a workaround for my problem).

    cube.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onCubeFaceClick);

    So nothing drastic here, but somehow if I trace the clicked event, I continuously get “3″ from DO3D and I don’t know why or what it means:


    Type : mouseClick, DO3D : 3: x:0 y:0 z:0 Sprite : [object ViewportBaseLayer] Face : [object Triangle3D]

    Your help will be much appreciated, but what would be really helpful is how I would go about solving this problem. What am I missing when browsing the documentation that I can’t see what’s wrong here? As you can probably tell by now, I’m not very experienced with coding.

    Thanks again.

  5. Ian says:

    Thanks for this tutorial, helped me a lot!

    I was wondering if there is a way to put an actual image on a face of the cube instead of a color?

  6. Charlie says:

    Absolutely. You can either load an image into the color box sprite we created:

    var colorBox:Sprite = new Sprite();

    or you could just use BitmapFileMaterial instead of MovieMaterial.

    The only parameter you will need to use is the first one – url:
    BitmapFileMaterial(url:String, initObject:Object = null)

  7. Peter says:

    I want to make a collada modell interactive.
    A simple table where you can click top, bottom and sides.

    Similar to this: http://www.gourmetkickzcreator.com/

    anyone can help?

  8. Gary says:

    Hi Charlie,

    Thanks for the great tutorials! I learned a lot from them.

    I was able to use BitmapFileMaterial(url:String, initObject:Object = null) to make the face of the cube into a picture, but when I do so, the interactivity goes away and when I try to click on the cube nothing happens.

    Is there something else that should be done after the image is applied?

    Thanks in advance,
    Gary

  9. billy says:

    hai guys.. can u help me how to make add Button to manually select the image like iTunes Flow?.. thanks:) so if i click right next button it will appear zoom in and we can select the next image.. need help n appreciate it!!..:)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>