Author: Max Pellizzaro
Date: November 3rd 2007
Update: July 12th 2009
version: 3.1.1
This is the first of a series of tutorial that will talk about how to render the models you have build or imported in your Scene3D.
We have already seen in a previous tutorial how to apply a simple Material to a cube. We will start from there and we will move to more sophisticated effects learning all the possibility that Sandy can give us when rendering Shape3D elements.
First of all, before facing each single Material Type, we need to have a deeper knowledge of the concept of Attributes, which is the scope of this tutorial.
The Document class must be changed to Example008.as The name of the class in the .as file and the name of the constructor now is: Example008.
The new updated version can be found here:
example008_v3.1.1.zip
package
{
import flash.display.Sprite;
import flash.events.*;
import flash.ui.*;
import sandy.core.Scene3D;
import sandy.core.data.*;
import sandy.core.scenegraph.*;
import sandy.materials.*;
import sandy.materials.attributes.*;
import sandy.primitive.*;
public class Example008 extends Sprite
{
private var scene:Scene3D;
private var camera:Camera3D;
private var box:Box;
private var app01:Appearance;
private var app02:Appearance;
private var app03:Appearance;
public function Example008()
{
// We create the camera
camera = new Camera3D( 300, 300 );
camera.z = -400;
// We create the "group" that is the tree of all the visible objects
var root:Group = createScene();
// We create a Scene and we add the camera and the objects tree
scene = new Scene3D( "scene", this, camera, root );
// Listen to the heart beat and render the scene
addEventListener( Event.ENTER_FRAME, enterFrameHandler );
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
}
// Create the scene graph based on the root Group of the scene
private function createScene():Group
{
// Create the root Group
var g:Group = new Group();
// Create a cube so we have something to show
box = new Box( "box",100,100,100,"quad");
box.rotateX = 30;
box.rotateY = 30;
// we define a new material -- 01 --
var materialAttr01:MaterialAttributes = new MaterialAttributes(
new LightAttributes( true, 0.1)
);
var material01:Material = new ColorMaterial( 0xFFCC33, 1, materialAttr01 );
material01.lightingEnable = true;
material01.autoDispose=false;
app01 = new Appearance( material01 );
// we define a new material -- 02 --
var materialAttr02:MaterialAttributes = new MaterialAttributes(
new LightAttributes( true, 0.1), new LineAttributes(3, 0xF43582, 1)
);
var material02:Material = new ColorMaterial( 0xAAEE99, 1, materialAttr02 );
material02.lightingEnable = true;
material02.autoDispose=false;
app02 = new Appearance( material02 );
// we define a new material -- 03 --
var materialAttr03:MaterialAttributes = new MaterialAttributes(
new LightAttributes( true, 0.1), new OutlineAttributes(3, 0xFC5858, 1),
new LineAttributes(1, 0x000000, 1)
);
var material03:Material = new ColorMaterial( 0x9DCCEA, 1, materialAttr03 );
material03.lightingEnable = true;
material03.autoDispose=false;
app03 = new Appearance( material03 );
box.appearance = app01;
// We need to add the cube to the group
g.addChild( box );
return g;
}
// The Event.ENTER_FRAME event handler tells the Scene3D to render
private function enterFrameHandler( event : Event ) : void
{
box.tilt += 1;
box.pan += 1;
scene.render();
}
// The KeyboardEvent.KEY_DOWN event handler manage key pressed by user
private function keyPressed(event:KeyboardEvent):void
{
switch(event.keyCode) {
case Keyboard.UP:
box.appearance = app01;
break;
case Keyboard.DOWN:
box.aPolygons[0].appearance = app01;
box.aPolygons[1].appearance = app02;
box.aPolygons[2].appearance = app03;
box.aPolygons[3].appearance = app02;
box.aPolygons[4].appearance = app01;
box.aPolygons[5].appearance = app03;
break;
case Keyboard.RIGHT:
box.appearance = app02;
break;
case Keyboard.LEFT:
box.appearance = app03;
break;
}
}
}
}
private var app01:Appearance; private var app02:Appearance; private var app03:Appearance;
This is because we want to use user Key interaction to change to appearance to our object: our little cube.
In this tutorial we define three types of Appearance (app01, app02, app03), all of them us the same Color Material Type, but they different by the Attributes we define for them. In fact we want to learn in detail the Attributes we can set before covering the Material Type stuff. So let’s dig into the Attributes we can define in Sandy 3D.
var materialAttr01:MaterialAttributes = new MaterialAttributes( new LightAttributes( true, 0.1) );
Light attributes allows you to define how the engine will render the light when enabling the light by setting lightingEnable = true to the Material you are using. Keep in mind that NOT all material allows to use light, so sometimes you will not need this, but in our examples we are using ColorMaterial that allows using LightAttributes. Light Attributes comes with two parameters: the first one tells the rendering engine to use a wider range of light, and the second one tells the engine the level of light to use.
var materialAttr02:MaterialAttributes = new MaterialAttributes( new LightAttributes( true, 0.1), new LineAttributes(3, 0xF43582, 1) ); var material02:Material = new ColorMaterial( 0xAAEE99, 1, materialAttr02 ); material02.lightingEnable = true; app02 = new Appearance( material02 );
The LineAttributes define how to render the lines that builds up our model. The number of lines that build our models depends on the mode you have selected to render to model. In our case we have used a “quad” Mode, so the middle line on each face will not show up. LineAttribues come with three parameters: the thickness of the line, its color and the alpha value in percent of full opacity.
var materialAttr03:MaterialAttributes = new MaterialAttributes( new LightAttributes( true, 0.1), new OutlineAttributes(3, 0xFC5858, 1), new LineAttributes(1, 0x000000, 1) ); var material03:Material = new ColorMaterial( 0x9DCCEA, 1, materialAttr03); material03.lightingEnable = true; app03 = new Appearance( material03 );
This type of attributes allows you to define the appearance of a perimeter of your object. The perimeter is a closed line that runs around the entire object. The number and type of parameters of this Attributes are the same as the previous one.
You might have notice something nice: we have been able to combine all these Attributes, since the Material constructor allows us to pass a variable number of parameters.
Another thing that is important to remember: in all our examples we have passed in the constructor of the Appearance only one Material. Sandy allows us to pass two materials: one for the front face, and the other for the back face. If only one is passed it will be used for both sides. With more complicated examples it might comes handy to use two different type of Materials for the same Shape3D object.
box.aPolygons[0].appearance = app01; box.aPolygons[1].appearance = app02; box.aPolygons[2].appearance = app03; box.aPolygons[3].appearance = app02; box.aPolygons[4].appearance = app01; box.aPolygons[5].appearance = app03;
What we did is to access to each face of the cube using the property aPolygons and set one of the appearance we have previously defined.
So let’s see the result !!
Double click on the cube and move the arrow keys to change to appearance of the cube.
↑ simple light attributes
→ light and line attributes
← outline attributes
↓ a combination of the previous ones for each side