quaternion

Free rotation using Quaternions

Saturday, November 29th, 2008 | examples, requests | Comments


source

package
{
	import flash.display.Bitmap;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.core.math.Plane3D;
	import org.papervision3d.core.math.Quaternion;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.view.BasicView;
 
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
	public class QuaternionExample extends BasicView
	{
		private const XYPLANE:Number3D = new Number3D(0, 0, 1);
		private const RADIUS:Number = 400;
		private const SPEED:Number = .05;
 
		private var plane3D:Plane3D  = new Plane3D(XYPLANE, Number3D.ZERO);;
		private var sphere:Sphere;
 
		[Embed(source="assets/lake_640.jpg")]
		private var materialAsset:Class;
 
 
		public function QuaternionExample() 
		{
			var light:PointLight3D = new PointLight3D();
			var bitmap:Bitmap = new materialAsset() as Bitmap;
			var material:BitmapMaterial = new BitmapMaterial(bitmap.bitmapData);
			sphere = new Sphere(material, RADIUS, 30, 30);
 
			scene.addChild(sphere);
 
			startRendering();
 
			stage.addEventListener(MouseEvent.CLICK, clickHandler);
		}
 
		private function clickHandler(event:MouseEvent):void
		{
			//quick reset
			sphere.copyTransform(new DisplayObject3D());
		}
 
		override protected function onRenderTick(event:Event=null):void
		{
			var ray:Number3D = camera.unproject(viewport.containerSprite.mouseX, viewport.containerSprite.mouseY);
			ray = Number3D.add(ray, camera.position);
 
			var cameraVertex3D:Vertex3D = new Vertex3D(camera.x, camera.y, camera.z);
			var rayVertex3D:Vertex3D = new Vertex3D(ray.x, ray.y, ray.z);
 
			var intersectPoint:Vertex3D = plane3D.getIntersectionLine(cameraVertex3D, rayVertex3D);
 
			var velocityX:Number = intersectPoint.x * SPEED;
			var velocityY:Number = intersectPoint.y * SPEED;
			var velocityZ:Number = intersectPoint.y * SPEED;
 
			var difference:Number3D = new Number3D(-velocityX, -velocityY, -velocityZ);
			var distance:Number = Math.sqrt(difference.x * difference.x + difference.y * difference.y);
 
			var rotationAxis:Number3D = Number3D.cross(difference, XYPLANE);
			rotationAxis.normalize();
 
			var rotation:Quaternion = Quaternion.createFromAxisAngle(rotationAxis.x, rotationAxis.y, rotationAxis.z, distance/RADIUS);
			rotation.normalize();
 
			sphere.transform.calculateMultiply3x3(rotation.matrix, sphere.transform);
 
			renderer.renderScene(scene, camera, viewport);
		}
	}
 
}

I hope to be able to do a write-up explaining Quaternions next week.

Tags: ,

Using Slerp to move around a Sphere

Saturday, November 29th, 2008 | examples, requests | Comments


source

package
{
	import flash.events.Event;
 
	import org.papervision3d.core.math.Quaternion;
	import org.papervision3d.core.utils.Mouse3D;
	import org.papervision3d.events.InteractiveScene3DEvent;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.view.layer.ViewportLayer;
	import org.papervision3d.view.layer.util.ViewportLayerSortMode;
 
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
	public class SlerpExample extends BasicView
	{
		private const RADIUS:Number = 400;
 
		private var planeQuat:Quaternion = new Quaternion();
		private var mouseQuat:Quaternion = new Quaternion();
		private var slerpQuat:Quaternion = new Quaternion();
		private var plane:Plane;
		private var sphere:Sphere;
		private var mouse3D:Mouse3D;
 
		private var slerp:Number = 0;
 
		public function SlerpExample() 
		{
			viewport.interactive = true;
			Mouse3D.enabled = true;
			mouse3D = viewport.interactiveSceneManager.mouse3D;
 
			var light:PointLight3D = new PointLight3D();
			var material:FlatShadeMaterial = new FlatShadeMaterial(light, 0xffffff);
			material.interactive = true;
			plane = new Plane(new ColorMaterial(0xcc0000), 50, 50);
 
			plane.z = -RADIUS;
 
			viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;
			var planeViewportLayer:ViewportLayer = new ViewportLayer(viewport, plane);
			planeViewportLayer.layerIndex = 1;
			viewport.containerSprite.addLayer(planeViewportLayer);
 
			sphere = new Sphere(material, RADIUS, 30, 30);		
			sphere.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, objectClickHandler);
 
			scene.addChild(sphere);
			scene.addChild(plane);
 
			startRendering();
		}
 
		private function resetQuats():void
		{
			slerp = 0;
			planeQuat = Quaternion.createFromMatrix(plane.transform);
			mouseQuat = Quaternion.createFromMatrix(mouse3D.transform);
		}
 
		private function objectClickHandler(event:InteractiveScene3DEvent):void
		{
			resetQuats();
		}
 
		override protected function onRenderTick(event:Event=null):void
		{
			slerp += (1 - slerp) * .1;
			slerpQuat = Quaternion.slerp(planeQuat, mouseQuat, slerp);
 
			plane.transform = slerpQuat.matrix;
			plane.moveBackward(RADIUS);
 
			renderer.renderScene(scene, camera, viewport);
		}
 
	}
}

Tags: , ,

Search

Recommended Books

Speaking at FITC Toronto

Recent Comments

 

July 2010
M T W T F S S
« May    
 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 ...