Dragging an object to rotate

Thursday, January 15th, 2009 | examples

The cool thing about this example is you can really just drop any DisplayObject3D in to rotate it around. It’s not super exciting, but I bet many of you will find it useful.


source

package
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
 
	import org.papervision3d.core.math.Matrix3D;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.view.BasicView;
 
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
	public class Trackball extends BasicView
	{
		private static const FORWARD:Number3D = new Number3D(0, 0, 1);
 
		private var sphere:Sphere;
		private var previousMousePoint:Point = new Point();
		private var isMouseDown:Boolean = false;
 
		public function Trackball()
		{
			var light:PointLight3D = new PointLight3D();
			var flatShadeMaterial:FlatShadeMaterial = new FlatShadeMaterial(light, 0xcc0000, 0x222222);
			sphere = new Sphere(flatShadeMaterial, 500, 32, 24);
 
			scene.addChild(sphere);
			startRendering();
 
			stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler);
		}		
 
		private function stage_mouseDownHandler(event:MouseEvent):void
		{
			isMouseDown = true;
		}
 
		private function stage_mouseUpHandler(event:MouseEvent):void
		{
			isMouseDown = false;	
		}
 
		override protected function onRenderTick(event:Event=null):void
		{
			var currentMousePoint:Point = new Point(viewport.containerSprite.mouseX, viewport.containerSprite.mouseY);
 
			if(isMouseDown)
			{
				var difference:Point = currentMousePoint.subtract(previousMousePoint);
	 			var vector:Number3D = new Number3D(difference.x, difference.y, 0);
 
				var rotationAxis:Number3D = Number3D.cross(vector, FORWARD);
				rotationAxis.normalize();
 
				var distance:Number = Point.distance(currentMousePoint, previousMousePoint);
				var rotationMatrix:Matrix3D = Matrix3D.rotationMatrix(rotationAxis.x, -rotationAxis.y, rotationAxis.z, distance/250);
 
				sphere.transform.calculateMultiply3x3(rotationMatrix, sphere.transform);
			}
 
			previousMousePoint = currentMousePoint;
 
			super.onRenderTick(event);
		}
	}
}

Tags: , ,

  • derkoidus
    Is it possible to have it on scroll instead of on drag?
  • Dave
    Yes, I'd also really love to know how to add easing to this. Please help!
  • Kosta
    cool example. how would you modify this to use the rotation properties instead of the transform matrix? trying to custom rotate objects in space and save their rotation properties for later use.

    thanks.
  • Scott
    Richard & Yukimi,

    You need to use Interactive3DEvent rather than MouseEvent and set the world and the sphere's material to interactive.
  • yukimi
    I have the same problem as richard. sphere.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler) doesn't rotate the sphere. Is there a workaround for this? Please advise.
    Thanks.
  • richard
    Great job! Just one question... I want to do an eventlistener only on the earth and not for all the stage. When i change the vent listener by earth.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); it doesn't call the function... Do you have an idea ??
  • yukimi
    Hi, thanks for the great example. I copied and paste the above code and tried running it. It works fine BUT after I changed the material to MovieAssetMaterial, where I used a movie clip with a button inside, the button is not working even with onmouseover where it's supposed to change color. Is there a workaround for this problem?

    Please advise.
    Thanks!
  • mca
    Great example - much appreciated. Anyone know how to apply easing to this code?

    I am new to the idea using do3d.transform.calculateMultiply3x3(rotationMatrix, dod3d.transform);

    Feel like my head is going to explode.
  • harry
    hi John, thanks for the great examples. I have modified your code slightly so it is easier to control rotations for non-spherical objects. It gives a Sketchup look and feel. Here it is:

    if(isMouseDown)
    {
    var difference:Point = currentMousePoint.subtract(previousMousePoint);
    alXX-=difference.y/150;
    rotationMatrix1 = Matrix3D.rotationMatrix(1,0,0, -difference.y/150);
    rotationMatrix2 = Matrix3D.rotationMatrix(0, Math.cos(alXX), Math.sin(alXX), -difference.x/150);
    rotationMatrix= Matrix3D.multiply3x3 (rotationMatrix2,rotationMatrix1);
    triangleMesh3d.transform.calculateMultiply3x3(rotationMatrix, triangleMesh3d.transform);
    }
  • This is what i want for a long time!
  • Very userful indeed. Great Thanks.
blog comments powered by Disqus

Search

Recommended Books

Speaking at FITC Toronto

 

January 2009
M T W T F S S
« Dec   Feb »
 1234
567891011
12131415161718
19202122232425
262728293031  

Preferred Video Tutorial Resolution

  • 1024x768 (53%, 85 Votes)
  • 1280x1024 (15%, 24 Votes)
  • 1920x1080 (15%, 24 Votes)
  • 800x600 (13%, 20 Votes)
  • 480x320 (4%, 6 Votes)
  • 640x480 (0%, 2 Votes)

Total Voters: 160

Loading ... Loading ...