how it works

Slerp Explorer

Tuesday, December 30th, 2008 | how it works | Comments

Slerp allows you to find the quickest path from one rotation to another rotation. In Papervision3D, slerp is a static function of the Quaternion class. The following code shows all the pieces you’ll need to use slerp in your projects:

//the values from your start axis and rotation (x,y,z,rotation)
startQuaternion = new Quaternion(0, 1, 0, 1);
//the values from your end axis and rotation
endQuaternion = new Quaternion(0, 1, 0, 1);
 
/* the next section would go in an update event, like Event.ENTER_FRAME or TimerEvent.TIMER */
 
//if slerp is 0, the rotation will reflect the startQuaternion
//if slerp is 1, the rotation will reflect the endQuaternion
//any value between 0 and 1 will be a percentage of the rotation
//between the start and end. For example, .5 would be halfway between
//start and end.
slerp = 0; //transition this up to 1, something like slerp += .01;
 
//the main quaternion that you copy the rotation from
quaternion = Quaternion.slerp(startQuaternion, endQuaternion, slerp);
//Copies the rotation from the main quaternion into the cube's matrix
cube.transform.copy3x3(quaternion.matrix);

To use this example:

  1. Move the axis and rotation sliders then click “set start”.
  2. Move the axis and rotation sliders and click “set end”
  3. Click “slerp from start to end” and you’ll see the cube rotate from the start rotation to the end rotation.

Focus on how the cube is rotating and how you could use that in your projects. Don’t get distracted by the reference axis.

Tags: ,

Quaternion Explorer

Monday, December 29th, 2008 | how it works | Comments

The definition of Quaternion is a little more complex, but the use-case of a Quaternion is actually pretty easy to show. In this explorer, you’ll see how you define an axis with the sliders on the left then define the rotation around that axis with the slider on the right. This essentially shows you everything you need to create a Quaternion: an axis defined by three variables (x, y, z) and a rotation around that axis.

Please note that no matter what the axis is, if the rotation is zero, then the “Back” face of Cube looks straight at you. So try changing the axis sliders, scrub the rotation slider from 0 to 360 and back. Then change the axis sliders again, scrub from 0 to 360 again and you’ll notice how the rotation around the axis differs. Also, (0,0,0) isn’t an axis, so you can’t rotate around it :)

*update

Allow me to explain this a bit more. Here’s a few things to try to “orient” yourself :)

rotationX (x:1, y:0, z:0)

Move all the axis sliders to those values, then move the rotation slider from 0 – 360 and you’ll see your traditional rotationX (since it rotates around the X axis). You may be thinking to yourself, “Why do I need this? Why don’t I just use rotationX?” I would answer, “Because this way, you don’t limit yourself to just rotationX. You can define ANY rotation with these four numbers.” If you’ve ever tried to control a combination of rotationX, rotationY, and rotationZ at the same time, I’m sure you’ve run into difficulty.

Here are two other axes you’re familiar with:
rotationY (x:0, y:1, z:0)
rotationZ (x:0, y:0, z:1)

As a follow-up post, I’m working on a slerp explorer that will show you how to transition from any rotation to any other rotation which is where the power of Quaternions really shine.

As a final note, try leaving the rotation slider at 180 then adjusting the axis sliders. You will see the cube move at the same time as the axis, but it may look like it’s “lagging behind”. This effect comes from the cube adjusting itself to be rotated 180 around the axis. The cube is not following the axis in any way.

Don’t be distracted by the axis, it’s only there for reference. What’s important is the cube rotates around the axis.

Tags:

TriangleMesh3D – Create your own mesh

Saturday, December 13th, 2008 | examples, how it works | Comments

This shows you how to make little baby triangles. If you put enough of these together with the proper coordinates and rotations, you could make a Tyrannosaurs Rex!


source

package
{
	import flash.events.Event;
 
	import org.papervision3d.core.geom.TriangleMesh3D;
	import org.papervision3d.core.geom.renderables.Triangle3D;
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.view.BasicView;
 
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
	public class TriangleMesh3DExample extends BasicView
	{
		private var triangleMesh3d:TriangleMesh3D;
 
		public function TriangleMesh3DExample()
		{
			var material:ColorMaterial = new ColorMaterial(0xcc0000);
			material.doubleSided = true;
 
			//all the 200's are points of a triangle
			var vertex3D_1:Vertex3D = new Vertex3D(-200, -200, 0);
			var vertex3D_2:Vertex3D = new Vertex3D(200, -200, 0);
			var vertex3D_3:Vertex3D = new Vertex3D(-200, 200, 0);
 
			var triangleVertices:Array = [vertex3D_1, vertex3D_2, vertex3D_3];
 
			//use null because we haven't created its parent mesh yet			
			var triangle3d:Triangle3D = new Triangle3D(null, triangleVertices, material);
			var triangleFaces:Array = [triangle3d];
 
			triangleMesh3d = new TriangleMesh3D(material, triangleVertices, triangleFaces, null);
			//for the triangle to be "renderable", it needs to know who its daddy is
			//this is the same property as the "null" parameter a few lines above
			triangle3d.instance = triangleMesh3d;
 
			scene.addChild(triangleMesh3d);
			startRendering();
		}
 
		override protected function onRenderTick(event:Event=null):void
		{
			triangleMesh3d.rotationY = -viewport.containerSprite.mouseX / 2;
			super.onRenderTick(event);
		}
	}
}

Tags: , ,

What is BasicView?

Saturday, December 6th, 2008 | how it works, tutorials | Comments

I use BasicView in all of my examples. This post explains why:


1. BasicView is a Sprite

Every ActionScript 3 project requires a “document class“. Since BasicView subclasses Sprite, you can extend BasicView to create your document class:

public class MyAwesomeDocumentClass extends BasicView

*note – You’ve probably heard the terms subclass, inherits, inheritance, extends, or others before. All those terms just mean you take advantage of the variables and functions of a specific class by writing another class that extends it. See Wikipedia’s Inheritance Page.

If you look at the docs, you’ll see the inheritance chain: BasicView->AbstractView->Sprite.


2. BasicView provides a viewport, scene, camera, and renderer

Every Papervision3D project requires a viewport, scene, camera, and renderer which are all classes in the Papervision3D library. If you don’t use BasicView, you have to do something like this:

package
{
	import flash.display.Sprite;
	import flash.events.Event;
 
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
 
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
	public class ImTooCoolForBasicView extends Sprite
	{
		private var viewport:Viewport3D;
		private var scene:Scene3D;
		private var camera:Camera3D;
		private var renderer:BasicRenderEngine;
 
		public function ImTooCoolForBasicView()
		{
			viewport = new Viewport3D();
			addChild(viewport);
 
			scene = new Scene3D();
			camera = new Camera3D();
			renderer = new BasicRenderEngine();
 
			var sphere:Sphere = new Sphere();
			scene.addChild(sphere);
 
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
 
		private function enterFrameHandler(event:Event):void
		{
			renderer.renderScene(scene, camera, viewport);
		}
 
	}
}

Phew, that was a lot of work! Let’s look at what it looks like when you use BasicView:

package
{
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.view.BasicView;
 
	[SWF(width="640", height="480", backgroundColor="#000000", frameRate="60")]
	public class SmartGuysUseBasicView extends BasicView
	{
		public function SmartGuysUseBasicView()
		{
			var sphere:Sphere = new Sphere();
			scene.addChild(sphere);
			startRendering();
		}
 
	}
}

Much better!

You probably also noticed that the second example has the handy little “startRendering()” function. StartRendering does the exact same thing as the addEventListener(Event.ENTER_FRAME, enterFrameHandler); line in the first example. The addEventListener line is hidden away in AbstractView:

http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/view/AbstractView.as#29

Hiding functionality like that example is called encapsulation, but who really cares what it’s called as long as it makes it easier :)


3. What’s this override protected function onRenderTick thing in the examples?

onRenderTick is the enter frame event listener called when you use startRendering(). If you look at the code, you’ll notice onRenderTick is a protected function. Using protected allows you to change what the function does by overriding it.

*note – The keyword protected is one of ActionScript 3’s “accessibility modifiers”. You may be familiar with other keywords: public, private, internal, and final. To learn how each of these “control access” to functions, read through adobe’s keyword page: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/statements.html

By default, you just type startRendering(); and onRenderTick will just do the following each frame (you don’t have to type this out since it’s included in AbstractView):

renderer.renderScene(scene, camera, viewport);

You can change what onRenderTick does by writing it out like this:

override protected function onRenderTick(event:Event=null):void
{
	sphere.yaw(1);
	renderer.renderScene(scene, camera, viewport);
}

When overriding a function, remember that the parameters (event:Event=null) and the return type (void) have to remain exactly the same.


4. I get it! BasicView simply sets up what you need for Papervision3D!

Bingo! But that doesn’t mean you have to use BasicView. In fact, maybe your project requires multiple viewports or cameras and you’ll need to write out the code without BasicView. In the end, use what’s best for you.

As for me and my examples, I’ll be sticking with BasicView. :D

*final note – If you found how BasicView works interesting, I recommend reading up on the Template Pattern and the Facade Pattern.

Tags:

Search

Recommended Books

Speaking at FITC Toronto

 

February 2012
M T W T F S S
« May    
 12345
6789101112
13141516171819
20212223242526
272829  

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