Archive for November, 2008

Distance between two Number3Ds

Sunday, November 30th, 2008 | snippets | Comments
var n1:Number3D = new Number3D(500, 0, 0);
var n2:Number3D = new Number3D(0, 0, 500);
var distance:Number = Number3D.sub(n1, n2).modulo;

Tags:

Adding a BasicView to a Flex UIComponent

Saturday, November 29th, 2008 | snippets | Comments

While I would always encourage to separate your code into separate classes to follow best OOP practices, the example below will “get the job done”.

Since the Flex framework is based off UIComponents and you can’t directly add Sprites (or BasicViews) to a UIComponent, you have to dig into the UIComponents rawChildren (meaning Sprites) to add Papervision3D.

source

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
	width="640"
	height="480"
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="absolute" 
	applicationComplete="applicationComplete()">
	<mx:Script>
		<![CDATA[
/*			There are two similar methods:
			1. using rawChildren
			2. using $addChild with the mx_interal namespace
			Method #2 is commented out below
*/	
//			use namespace mx_internal; //method #2
 
			import org.papervision3d.objects.primitives.Sphere;
			import org.papervision3d.view.BasicView;
			private function applicationComplete():void
			{
				var basicView:BasicView = new BasicView();
				var sphere:Sphere = new Sphere();
				basicView.scene.addChild(sphere);
				basicView.startRendering();
				pv3dPanel.rawChildren.addChild(basicView); //method #1
//				pv3dPanel.$addChild(basicView); //method #2
			}
		]]>
	</mx:Script>
	<mx:Panel id="pv3dPanel" title="Papervision3D Panel" width="640" height="480"/>
</mx:Application>

Tags: ,

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

 

November 2008
M T W T F S S
    Dec »
 12
3456789
10111213141516
17181920212223
24252627282930

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 ...