Erain 3D
-->

Author: Max Pellizzaro
Date: November 14th 2007
version: 3.0

Using light with Sandy3D

Objective of the tutorial

In this tutorial, I have decided to show the capabilities of Sandy related to lights. When you want to render your objects, and you also want to use the light effect which is built-in capability of every objects.

You might be satisfied with the default setting, but you might want to be able to modify the intensity of your light, or to modify the direction of your light.

In this tutorial you will learn how.

How to

Set up

The Document class must be changed to Example0041.as The name of the class written inside the .as file and the name of the constructor now is: Example0041

example0041.rar

The AS Code

In this section, we report the AS code as a reference, and it will be explained in the next paragraph.

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 Example0041 extends Sprite {
      private var scene:Scene3D;
      private var camera:Camera3D;
      private var tg:TransformGroup;
      private var lightX = 0;
      private var lightY = 0;
      private var lightZ = 10;
 
      public function Example0041() { 
         camera = new Camera3D( 300, 300 );
         camera.z = -400;
 
         var root:Group = createScene();
 
         scene = new Scene3D( "scene", this, camera, root );
         scene.light.setDirection(lightX, lightY, lightZ);
 
         addEventListener( Event.ENTER_FRAME, enterFrameHandler ); 
         stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
      }
 
      private function createScene():Group {
         var g:Group = new Group();
         tg = new TransformGroup();
 
         var materialAttr:MaterialAttributes = new MaterialAttributes(
                           new LineAttributes( 0, 0x2111BB, 0 ),
                           new LightAttributes( true, 0.1)
                        );
 
         var material:Material = new ColorMaterial( 0xFFCC33, 1, materialAttr );
         material.lightingEnable = true;
         var app:Appearance = new Appearance( material );
 
         var materialAttr2:MaterialAttributes = new MaterialAttributes( 
                           new LineAttributes( 0, 0x2111BB, 0 ),
                           new LightAttributes( true, 0.1)
                        );
 
         var material2:Material = new ColorMaterial( 0xCC0000, 1, materialAttr );
         material2.lightingEnable = true;
         var app2:Appearance = new Appearance( material2 );
 
         var materialAttr3:MaterialAttributes = new MaterialAttributes(
                           new LineAttributes( 0, 0x2111BB, 0 ),
                           new LightAttributes( true, 0.1)
                        );
 
         var material3:Material = new ColorMaterial( 0x008AE6, 1, materialAttr );
         material3.lightingEnable = true;
         var app3:Appearance = new Appearance( material3 );
 
         var table = new Box( "table", 10, 150, 200, PrimitiveMode.QUAD, 1 );
         //table.enableBackFaceCulling = false;
         table.useSingleContainer = false;
         table.appearance = app;
         table.rotateY = 90;
         table.rotateX = 90;
 
         var leg01:Cylinder = new Cylinder( "leg01", 5, 80 );
         leg01.appearance = app;
         leg01.x = -80;
         leg01.y = -45;
         leg01.z = 50;
 
         var leg02:Cylinder = new Cylinder( "leg02", 5, 80 );
         leg02.appearance = app;
         leg02.x = 80;
         leg02.y = -45;
         leg02.z = 50;
 
         var leg03:Cylinder = new Cylinder( "leg02", 5, 80 );
         leg03.appearance = app;
         leg03.x = -80;
         leg03.y = -45;
         leg03.z = -50;
 
         var leg04:Cylinder = new Cylinder( "leg02", 5, 80 );
         leg04.appearance = app;
         leg04.x = 80;
         leg04.y = -45;
         leg04.z = -50;
 
         var mySphere:Sphere = new Sphere( "theSphere", 20, 20, 8);
         mySphere.useSingleContainer = true;
         mySphere.appearance = app2;
         mySphere.y = 25;
         mySphere.x = -30;
 
         var myBox:Box = new Box( "theBox", 60, 60, 60, PrimitiveMode.TRI, 3 );
         myBox.useSingleContainer = true;
         myBox.appearance = app3;
         myBox.rotateY = 30;
         myBox.y = 35;
         myBox.x = 40;
 
         tg.addChild(table);
         tg.addChild(leg01);
         tg.addChild(leg02);
         tg.addChild(leg03);
         tg.addChild(leg04);
         tg.addChild(mySphere);
         tg.addChild(myBox);
 
         tg.rotateX = 5;
 
         g.addChild( tg );
 
         return g;
      }
 
      private function enterFrameHandler( event : Event ) : void {
         scene.render();
      }
 
      private function keyPressed(event:KeyboardEvent):void {
         switch(event.keyCode) {
            case Keyboard.PAGE_DOWN:
               scene.light.setPower(scene.light.getPower() - 5);
               break;
            case Keyboard.PAGE_UP:
               scene.light.setPower(scene.light.getPower() + 5);
               break;	
            case Keyboard.UP:
               lightY+=10;
               scene.light.setDirection(lightX, lightY, lightZ);
               break;
            case Keyboard.DOWN:
               lightY-=10;
               scene.light.setDirection(lightX, lightY, lightZ);
               break;
            case Keyboard.RIGHT:
               lightX+=10;
               scene.light.setDirection(lightX, lightY, lightZ);
               break;
            case Keyboard.LEFT:
               lightX-=10;
               scene.light.setDirection(lightX, lightY, lightZ);
               break;
         }
      }
   }
}

Examining the code

Let’s see what we did in the code…

X, Y, Z variables

private var lightX = 0;
private var lightY = 0;
private var lightZ = 10;

Setting these three values does not make much difference with the default value (I did not check the default value, but visually I did not found the difference, so I’ll stay with that).

Setting the light's location

scene.light.setDirection(lightX, lightY, lightZ);

As you can see, you just need to get the light property that belongs to the Scene3D object and set the value you have decide to set.

Creating the input handler

case Keyboard.PAGE_DOWN:
   scene.light.setPower(scene.light.getPower() - 5);
   break;
case Keyboard.PAGE_UP:
   scene.light.setPower(scene.light.getPower() + 5);
   break;	
case Keyboard.UP:
   lightY+=10;
   scene.light.setDirection(lightX, lightY, lightZ);
   break;
case Keyboard.DOWN:
   lightY-=10;
   scene.light.setDirection(lightX, lightY, lightZ);
   break;
case Keyboard.RIGHT:
   lightX+=10;
   scene.light.setDirection(lightX, lightY, lightZ);
   break;
case Keyboard.LEFT:
   lightX-=10;
   scene.light.setDirection(lightX, lightY, lightZ);
   break;

With the page UP, page DOWN key you control the intensity of the light, while with the arrow key you control the direction of the light. Simple!

Note Just as simple note on the code. As you might have noticed I have used a transformation Group object. This is NOT needed, since I have use it for testing purpose to rotate all the objects together. If you will not move the object around you don’t need to create this transformation group.

And now let’s see the result together…

The output

For this Flash, you have the UP, DOWN, RIGHT and LEFT key to control the direction of the light. The Page Up and Page Down key to control the intensity of the light.