Carousel with proper rotation and reflection
I’m going to go out on a limb and say that this post will be popular
package { import flash.display.Bitmap; import flash.events.Event; import flash.filters.BlurFilter; import org.papervision3d.core.effects.view.ReflectionView; import org.papervision3d.core.math.Quaternion; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.materials.BitmapMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Plane; [SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")] public class ClickThenRotateCarousel extends ReflectionView { [Embed(source="assets/pic.jpg")] private var picAsset:Class; private const RADIUS:Number = 400; private const NUM_OF_PLANES:int = 9; private var carousel:DisplayObject3D = new DisplayObject3D(); private var currentQuat:Quaternion = new Quaternion(); private var targetQuat:Quaternion = new Quaternion(); private var slerp:Number = 0; public function ClickThenRotateCarousel() { viewportReflection.filters = [new BlurFilter(3,3,3)]; viewport.interactive = true; surfaceHeight = -100; camera.z = 800; //move camera to the front var pic:Bitmap = Bitmap(new picAsset()); for(var i:int = 0; i < NUM_OF_PLANES; i++) { var material:BitmapMaterial = new BitmapMaterial(pic.bitmapData, true); material.doubleSided = true; material.interactive = true; var plane:Plane = new Plane(material, 100, 100); plane.rotationY = 360 / NUM_OF_PLANES * i; plane.moveForward(RADIUS); plane.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, objectOverHandler); plane.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, objectOutHandler); plane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, objectClickHandler); carousel.addChild(plane); } scene.addChild(carousel); addEventListener(Event.ENTER_FRAME, enterFrameHandler); } private function objectOverHandler(event:InteractiveScene3DEvent):void { viewport.buttonMode = true; } private function objectOutHandler(event:InteractiveScene3DEvent):void { viewport.buttonMode = false; } private function objectClickHandler(event:InteractiveScene3DEvent):void { var radians:Number = (carousel.rotationY - event.displayObject3D.rotationY) * Quaternion.DEGTORAD; slerp = 0; currentQuat = Quaternion.createFromMatrix(carousel.transform); targetQuat = Quaternion.createFromAxisAngle(0, 1, 0, radians); } private function enterFrameHandler(event:Event):void { slerp += (1 - slerp) * .05; var quat:Quaternion = Quaternion.slerp(currentQuat, targetQuat, slerp); carousel.transform = quat.matrix; singleRender(); } } }
21 Comments to Carousel with proper rotation and reflection
Pretty nice but I would recommend the carousels at http://www.gotoandlearn.com/ unless you need the full Papervision3D api.
They should perform a bit better and be easier to implement.
December 1, 2008
@Allan - This post shows a full 3D Carousel in Flash Player 9 that rotates in the proper direction when clicked and has a simple reflection.
Lee’s tutorials offer solutions for simpler carousels.
@Allan I am not 100% convinced that FP10 built in 3D performs so much better than PV3D. During my experiments I found out the performance is mainly dependent on how a tool is used and not which tool you choose. In this case, the above example seems to run much smoother that the carousel on gotoandlearn.
The usability is much better here too. This has, of course, nothing to do with which 3d engine was used, but adds a lot to the final effect.
@Allan - if you have the time to spare to get to grips with PV3D, then it will offer you a world of possibilities that the FP10 3D classes do not offer.
December 17, 2008
Hi,
Thanks for the reflection code. I used in my project the same,where i got the actual plane image turned up-side down. Could anyone tell me the suggestion?
Thanks in advance.
Bas.S
December 19, 2008
Hi,
I’ve noticed that using an enter frame event with singleRender() can really slow down performance. Is there are way to use ReflectionView with startRendering()?
January 6, 2009
This code works exactly the other way around for me than it does on this site. So all my images move to the back instead of to the front. So this makes my front images mirrored. Anyone?
January 6, 2009
@Piet - did you set the camera.z to the front?
January 8, 2009
Hi, this example is awesome and I´m trying to run it, but I haven´t find the way, I just want to know what version of papervision3D was used. In the rev851 from google code, the ReflectionView.as is missed. Thanks.
January 8, 2009
@rd - if you open the source files, in the “lib” folder you’ll see Papervision3D_rev804.swc. That means this example uses rev 804. That being said, ReflectionView is not missing from 851.
January 9, 2009
nice one!
did you test this with materials showing text?
I tried with both images containing text and TextFields in MovieMatarial. not quite sure if this is what Piet is talking about, but using the code -as is- the materials appear mirrored horizontically. a bug in pv3d? used rev 858.
a quick’n'dirty fix:
plane.moveBackward(RADIUS); // instead of forward -> “fixes” the mirroring
var radians:Number = (carousel.rotationY - event.displayObject3D.rotationY + 180) * Quaternion.DEGTORAD; // “fixes” the target rotation that breaks when moving backwards
January 9, 2009
@img - I fixed the mirroring with
plane.scaleX = -1;
Mainly because I couldn’t figure out the math for the rotation. =(
thanks!
January 9, 2009
does anyone know how (or where I can find how) to make this scale when the stage is resized?
Thank you.
March 10, 2009
ermm what if we wanted to have only some object reflective in the viewport and not everyth?
March 17, 2009
Could you please recommend a simple practical explanation or tutorial about the use of Quaternion for the rotation in Papervision3d?
All I was able to find on the web is either code or abstract math lectures and nothing in between. Both are very hard to understand for a beginner.
Thank you.
April 7, 2009
Hey John,
Excellent, excellent!
I’ve fallen a few months behind on my pv3d and had a project like this (though a bit more elaborate) in mind just before my hiatus. This will make it much easier! I’ll re-post when it’s functional some weeks from now.
May 3, 2009
Why is everything shown only in flex!!!! SO frustrating! How would I implement in the flash cs3 IDE and please don’t say document class. That is so limiting. I tried the code and i get tons of error because Flex imports images differently (among other things). Flash IDE freaks when you use embed.
May 3, 2009
Can you guys post something that you don’t have to use flex for? I mean really. Its either flex or the document class.
May 13, 2009
[...] -http://pv3d.org/2008/12/01/carousel-with-proper-rotation-and-reflection/comment-page-1/ [...]
May 19, 2009
Yes, I do agree. With the threat of Silverlight in the horizon, we as a community should help each other. The strength of FLASH lies in the designers and developers banded together. There are designers who wants to dip their hands into programming once in a while and they prefer using Flash CS3 or CS4 IDE. Papervision should be for both. I hope that every Flex (Flash Builder)sample should come with a Flash example, hope I am not asking too much.
I hope to see more real-world examples. thanks
June 11, 2009
Recently I was playing with this tutorial and I wanted a way to keep the carousel planes front facing, the other front facing tutorial is not that helpful, so i added some stuff to this one, I am assuming we are creating 5 planes, planes is an array, and planesRotations is another array:
plane.rotationY = 360 / 5 * i;
if (plane.rotationY > 0 && plane.rotationY < 0.01)
plane.rotationY = 0;
planesRotations.push(plane.rotationY);
plane.y = 100;
plane.moveForward(400);
plane.rotationY = 0;
planes.push(plane);
—————————————
Notice the planes are saved in an array and their corresponding rotations too, then they are reset to 0 so they are front facing.
Now when a plane is clicked, the carousel is rotated, to keep the planes front facing, a small hack is needed to apply the inverse of the quaternion rotation to each plane:
private function objectClickHandler(event:InteractiveScene3DEvent):void
{
var idx:int = planes.indexOf(event.displayObject3D);
//use the saved original rotation
var radians:Number = (carousel.rotationY - planesRotations[idx]) * Quaternion.DEGTORAD;
slerp = 0;
currentQuat = Quaternion.createFromMatrix(carousel.transform);
targetQuat = Quaternion.createFromAxisAngle(0, 1, 0, radians);
}
—————————————–
private function enterFrameHandler(event:Event):void
{
slerp += (1 - slerp) * .05;
var quat:Quaternion = Quaternion.slerp(currentQuat, targetQuat, slerp);
carousel.transform = quat.matrix;
var nb:Number3D = (quat.toEuler());
nb.x *= 180 / Math.PI; //this is the rotation angle transformed to degrees
for (var i:int = 0; i < planes.length; ++i)
{
planes[i].rotationY = -(nb.x);
}
singleRender();
}
Leave a comment
Search
Recent Posts
- MorphController - Mighty Morphing Papervision3D
- End dump
- Test if a plane is within the view of the camera (aka testing if culled)
- Materials Reference
- Perlin Blob
- Dynamic Text on a Plane
- Maya Texture Baking
- Creating a Custom VectorVision Font
- Workshop video and example dump
- 3D Math Book Recommendation
- Heading to New York. brb ;)
- Launching Flex4.org
- Flex 4 Layouts and Groups
- Flex 4 States
- How to click on stuff in Papervision3D - Viewport, ViewportLayers, InteractiveScene3DEvent, Mouse3D, and MovieMaterial Buttons
Recent Comments
- alexxcz on MorphController - Mighty Morphing Papervision3D
- andre venancio on 3D Math Book Recommendation
- DS on Dynamic Text on a Plane
- John Lindquist on Maya Texture Baking
- Itai on Maya Texture Baking
- Javier on End dump
- samBrown on End dump
- tf on archive
- Pan on requests
- Martin Lindelöf on requests


December 1, 2008