Previous articles summary :
- First steps in Papervision3D : Part 1
Creation of a new Papervision3D project within eclipse or Flex Builder 3 and a simple example of a 3D scene illustrating some basic Papervision3D classes. - First steps in Papervision3D : Part 2
Illustration of use of new Papervision3D v2.0 class BasicView that encapsulates essential elements to rapidly start developing new 3D scenes.
Now that we are able to render simple 3D scenes, I’d like to add some animation. In the previous parts we saw that the initialisation of Papervision3D and the creation of the scene objects occurred in the constructor of our example classes. To add animation we need to update the scene at regular intervals which is done either by listening to the Event.FRAME_ENTER event as shown in Example001 or overloading the onRenderTick function of BasicView as shown in Example002 (which is in effect an encapsulation of the first option).
This example follows the code shown in Example002, so I’m using the BasicView.
package {
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.view.BasicView;
public class Example003 extends BasicView {
private static const ORBITAL_RADIUS:Number = 200;
private var sphere:Sphere;
private var theta:Number = 0;
public function Example003() {
super(0, 0, true, false);
// set up the stage
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
// Initialise Papervision3D
init3D();
// Create the 3D objects
createScene();
// Start rendering the scene
startRendering();
}
private function init3D():void {
// position the camera
camera.x = -200;
camera.y = 200;
camera.z = -500;
}
private function createScene():void {
// First object : a sphere
// Create a new material for the sphere : simple white wireframe
var sphereMaterial:MaterialObject3D = new WireframeMaterial(0xFFFFFF);
// Create a new sphere object using wireframe material, radius 50 with
// 10 horizontal and vertical segments
sphere = new Sphere(sphereMaterial, 50, 10, 10);
// Position the sphere (default = [0, 0, 0])
sphere.x = -ORBITAL_RADIUS;
// Second object : x-, y- and z-axis
// Create a default line material and a Lines3D object (container for Line3D objects)
var defaultMaterial:LineMaterial = new LineMaterial(0xFFFFFF);
var axes:Lines3D = new Lines3D(defaultMaterial);
// Create a different colour line material for each axis
var xAxisMaterial:LineMaterial = new LineMaterial(0xFF0000);
var yAxisMaterial:LineMaterial = new LineMaterial(0x00FF00);
var zAxisMaterial:LineMaterial = new LineMaterial(0x0000FF);
// Create a origin vertex
var origin:Vertex3D = new Vertex3D(0, 0, 0);
// Create a new line (length 100) for each axis using the different materials and a width of 2.
var xAxis:Line3D = new Line3D(axes, xAxisMaterial, 2, origin, new Vertex3D(100, 0, 0));
var yAxis:Line3D = new Line3D(axes, yAxisMaterial, 2, origin, new Vertex3D(0, 100, 0));
var zAxis:Line3D = new Line3D(axes, zAxisMaterial, 2, origin, new Vertex3D(0, 0, 100));
// Add lines to the Lines3D container
axes.addLine(xAxis);
axes.addLine(yAxis);
axes.addLine(zAxis);
// Add the sphere and the lines to the scene
scene.addChild(sphere);
scene.addChild(axes);
}
override protected function onRenderTick(event:Event=null):void {
// rotate the sphere
sphere.yaw(-4);
// change the position of the sphere
theta += 3;
var x:Number = - Math.cos(theta * Math.PI / 180) * ORBITAL_RADIUS;
var z:Number = Math.sin(theta * Math.PI / 180) * ORBITAL_RADIUS;
sphere.x = x;
sphere.z = z;
// call the renderer
super.onRenderTick(event);
}
}
}
As you can see below, we see as before the sphere and the axes, but we have added animation so that the sphere rotates on its z-axis and orbits the origin (click on image to launch animation).

Compared to Example002 shown in Part 2, there are very few differences in the construction of the scene. The initialisation of the 3D is identical except for the position of the camera. The observer is now positioned above the horizontal plane looking down at the scene (the camera is still targeted on the origin). The construction of the 3D objects is also virtually identical : the only difference being the initial position of the sphere.
The real difference comes for overloading the onRenderTick function which is called at every FRAME_ENTER event :
override protected function onRenderTick(event:Event=null):void {
// rotate the sphere
sphere.yaw(-4);
// change the position of the sphere
theta += 3;
var x:Number = - Math.cos(theta * Math.PI / 180) * ORBITAL_RADIUS;
var z:Number = Math.sin(theta * Math.PI / 180) * ORBITAL_RADIUS;
sphere.x = x;
sphere.z = z;
// call the renderer
super.onRenderTick(event);
}
As you can see, all that is necessary is to update the rotation and position of the sphere. The yaw function rotates a 3D object around its z-axis. A calculation is performed to convert an angle theta, that we increase at every frame, into x and z coordinates of the sphere. Note that we must call to super.onRenderTick(event) to display the updated scene.
A lot more can be performed at every frame - for example we could reposition the camera as well - but hopefully this gives a simple example showing how easy animation can be in Papervision3D!
Next article:
- First steps in Papervision3D : Part 4 - lighting and shading
A point light source is added to the scene. Fours materials with different characteristics are added to spheres to illustrate how Papervision3D performs shading.
Fisrt of all, I’m very thankfull for your tutorials here, It’s been very helpfull in many ways.
Now I’ve got a problem in this part 3: the output gives me a “Error #1009: Cannot access a property or method of a null object reference.” every time, it references the “onRenderTick(event:Event=null)” I guess…
Any ideias of what I’m doing wrong?
thx
Hi robson,
Sorry, not sure what the problem is. Try running in debug mode in eclipse/Flex Builder - in the console you should see what line the error occurs at and which object is null.
Great tutorials! Thanks!
I believe I also had the same problem as Robson. It was because of this line in createScene()
In Example002, its
var sphere:Sphere = new Sphere(sphereMaterial, 50, 10, 10);
In Example003, it is
sphere = new Sphere(sphereMaterial, 50, 10, 10);
which is correct.
Using the var sphere:Sphere…etc. from Example002 in Example003 creates a local sphere variable for the createScene function, so when sphere is used in onRenderTick it refers to the private sphere class variable which is null.
Yes, that would indeed explain the problem! Thanks Ed!
Hi … great post … can you say if its posible that the same DisplayObject3D will be add for two different group(DisplayObject3D)&
woooooooow, it’s so useful~~ Thanks a lot!