PV3D – Playing with light and cubes

Posted on February 5, 2009
Filed Under Actionscript 3.0, experiments, Papervision | 8 Comments

Little thingy in between, playing with light in the most simplest way there is. It has no purpose…, but thought he why not. Click and drag the cube. On click the light will tween out of the center outside the cubes, onrelease move back to the center. At this point i’m still looking around to play with multiple lights so if anyone has suggestions of ideas…leave a message

And here is the code:

  1. package
  2. {
  3.  // tweener
  4.  import gs.easing.Back;
  5.  import caurina.transitions.Tweener;
  6.  
  7.  // flash
  8.  import flash.events.MouseEvent;
  9.  import flash.filters.BlurFilter;
  10.  import flash.events.Event;
  11.  import flash.display.Sprite;
  12.  
  13.  // papervision
  14.  import org.papervision3d.view.BasicView;
  15.  import org.papervision3d.objects.DisplayObject3D;
  16.  import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
  17.  import org.papervision3d.objects.primitives.Cube;
  18.  import org.papervision3d.lights.PointLight3D;
  19.  import org.papervision3d.materials.utils.MaterialsList;
  20.  import org.papervision3d.view.AbstractView;
  21.  import org.papervision3d.core.proto.CameraObject3D;
  22.  import org.papervision3d.core.proto.MaterialObject3D;
  23.  
  24.  [SWF(width="500", height="500", backgroundColor="#000000", frameRate="60")]
  25.  public class LightDemo3D extends Sprite
  26.  {
  27.   //
  28.   // private constants
  29.   //
  30.   private static const GRID_SPACE:int = 50;
  31.   private static const CUBE_SIZE:int = 150;
  32.  
  33.   //
  34.   // private properties
  35.   //
  36.   private var _viewBasic:BasicView;
  37.   private var _mList:MaterialsList;
  38.   private var _pl:PointLight3D;
  39.   private var _flatMat:FlatShadeMaterial;
  40.   private var _mainCube:DisplayObject3D;
  41.   private var _isDown:Boolean;
  42.   private var _prevMouseX:Number;
  43.   private var _prevMouseY:Number;
  44.   private var _cameraPitch:Number = 90;
  45.   private var _cameraYaw:Number = 270;
  46.   private var _cameraTarget:DisplayObject3D;
  47.  
  48.   //////////////////////////////////////////////////////////////////////////////////////
  49.   //
  50.   // Constructor
  51.   //
  52.   //////////////////////////////////////////////////////////////////////////////////////
  53.  
  54.   // ———————————————————————————–
  55.   public function LightDemo3D()
  56.   {
  57.    addEventListener(Event.ADDED_TO_STAGE, initialize);
  58.   }
  59.  
  60.   //////////////////////////////////////////////////////////////////////////////////////
  61.   //
  62.   // Public methods
  63.   //
  64.   //////////////////////////////////////////////////////////////////////////////////////
  65.  
  66.   // ———————————————————————————–
  67.   // none
  68.  
  69.   //////////////////////////////////////////////////////////////////////////////////////
  70.   //
  71.   // Private methods
  72.   //
  73.   //////////////////////////////////////////////////////////////////////////////////////
  74.  
  75.   // ———————————————————————————–
  76.   private function initialize(event:Event):void
  77.   {
  78.    removeEventListener(Event.ADDED_TO_STAGE, initialize);
  79.  
  80.    // setup view
  81.    initView();
  82.  
  83.    // materials
  84.    initMaterials();
  85.  
  86.    // objects
  87.    initObjects();
  88.  
  89.    // listeners
  90.    addEventListener(Event.ENTER_FRAME, render);
  91.  
  92.    stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  93.    stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  94.    stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
  95.    stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
  96.   }
  97.  
  98.   private function initView():void
  99.   {
  100.    _viewBasic = new BasicView(800, 600, true, true);
  101.    addChild(_viewBasic);
  102.  
  103.    _viewBasic.viewport.filters = [new BlurFilter(2,2,1)];
  104.  
  105.    // Camera
  106.    _cameraTarget = _viewBasic.scene.addChild(new DisplayObject3D());
  107.    _viewBasic.camera.lookAt(_cameraTarget);
  108.    _viewBasic.camera.z = -1200;
  109.  
  110.    // PointLight
  111.    _pl = new PointLight3D(true);
  112.  
  113.   }
  114.  
  115.   private function initMaterials():void
  116.   {
  117.    _flatMat = new FlatShadeMaterial(_pl, 0x7DC202, 0×000000);
  118.    _flatMat.doubleSided = false;
  119.    _flatMat.fillAlpha = .85;
  120.  
  121.    _mList = new MaterialsList();
  122.    _mList.addMaterial(_flatMat, "all");
  123.   }
  124.  
  125.   private function initObjects():void
  126.   {
  127.    /*
  128.     * create grid of 4x4x4 cubes with a
  129.     * space of 10px between all objects
  130.     */
  131.    var rows:int = 0;
  132.    var cols:int = 0;
  133.    var depth:int = 0;
  134.  
  135.    _mainCube = new DisplayObject3D();
  136.     _viewBasic.scene.addChild(_mainCube);
  137.  
  138.    for (var i:int = 0; i < 64; i++)
  139.    {
  140.     var cube:Cube = new Cube(_mList, CUBE_SIZE, CUBE_SIZE, CUBE_SIZE, 2, 2, 2);
  141.     cube.name = "cube_" + i;
  142.     cube.x = -320 + rows * (CUBE_SIZE + GRID_SPACE);
  143.     cube.y = -320 + cols * (CUBE_SIZE + GRID_SPACE);
  144.     cube.z = -320 + depth * (CUBE_SIZE + GRID_SPACE);
  145.  
  146.     if (++rows > 3)
  147.     {
  148.      rows = 0;
  149.      if (++depth > 3)
  150.      {
  151.       depth = 0;
  152.       cols++;
  153.      }
  154.     }
  155.  
  156.     _mainCube.addChild(cube);
  157.    }
  158.  
  159.    // place light in the center
  160.    _pl.x = _mainCube.x;
  161.    _pl.y = _mainCube.y;
  162.    _pl.z = _mainCube.z;
  163.   }
  164.  
  165.   private function mouseDownHandler(event:MouseEvent):void
  166.   {
  167.    _isDown = true;
  168.    _prevMouseX = event.stageX;
  169.    _prevMouseY = event.stageY;
  170.  
  171.    Tweener.addTween(_pl, {time: 2, z: 1500, transition: Back.easeInOut});
  172.   }
  173.  
  174.   private function mouseUpHandler(event:MouseEvent = null):void
  175.   {
  176.    _isDown = false;
  177.  
  178.    Tweener.addTween(_pl, {time: 2, z: -320, transition: Back.easeInOut});
  179.   }
  180.  
  181.   private function mouseMoveHandler(event:MouseEvent):void
  182.   {
  183.    var differenceX:Number = event.stageX – _prevMouseX;
  184.    var differenceY:Number = event.stageY – _prevMouseY;
  185.  
  186.    if(_isDown)
  187.    {
  188.     // with many thanx to Lee Brimelow
  189.     // blog post: http://pv3d.org/tag/orbit/
  190.     _cameraPitch += differenceY;
  191.     _cameraYaw += differenceX;
  192.  
  193.     _cameraPitch %= 360;
  194.     _cameraYaw %= 360;
  195.  
  196.     _cameraPitch = _cameraPitch > 0 ? _cameraPitch : 0.0001;
  197.     _cameraPitch = _cameraPitch < 90 ? _cameraPitch : 89.9999;
  198.  
  199.     _prevMouseX = event.stageX;
  200.     _prevMouseY = event.stageY;
  201.  
  202.     _viewBasic.camera.orbit(_cameraPitch, _cameraYaw, true, _mainCube);
  203.    }
  204.  
  205.   }
  206.  
  207.   private function mouseLeaveHandler(event:Event):void
  208.   {
  209.    mouseUpHandler();
  210.   }
  211.  
  212.   private function render(event:Event):void
  213.   {
  214.    _viewBasic.singleRender();
  215.   }
  216.  }
  217. }

Comments

8 Responses to “PV3D – Playing with light and cubes”

  1. Ryan on March 5th, 2009 10:11 pm

    Very cool. I have a question though. How do you apply lighting to a Cube with a different MovieMaterial applied to all sides.

    Thanks.

  2. Jan Willem on March 5th, 2009 11:30 pm

    He Ryan, you could create for all sides of a cube a different FlatShadedMaterial. e.g.
    var leftShadedMat:FlatShadedMaterial = new FlatShadedMaterial(_pl, 0×7DC202, 0×000000);

    var frontShadedMat:FlatShadedMaterial = new FlatShadedMaterial(_pl, 0xFF0000, 0×666666)

    and you keep doing that for all sites, hope this helps. otherwise drop me a line!

  3. Ryan on March 5th, 2009 11:53 pm

    Thanks Jan –

    I understand applying the items to each side but is it possible to apply a shader along with MovieClips for every side? Sort of doubling up each side of the cube if that makes sense. That’s the part I’m having trouble getting to work.

    Thanks.

  4. Jan Willem on March 6th, 2009 12:14 am

    If I understand it correctly you have a MovieMaterial you want to apply to the cube and on top a shader? If thats what you want you could do it like this:
    var cellShader:CellShader = new CellShader(_light, 0xffffff, 0×000000, 3);

    var movieMaterial:MovieAssetMaterial = new MovieAssetMaterial(“linkageToYourMC”)

    and than combine the two with:
    var shadedMaterial: ShadedMaterial = new ShadedMaterial(movieMaterial, _cellShader);

    Up till now i’ve only used it with BitmapFileMaterial, but i can imagine it will work with MovieAssetMaterial.

  5. Ryan on March 6th, 2009 4:23 pm

    Jan –

    I actually figured it out. I needed to put the CellShader inside the loop.

    Thanks Jan. BTW you have a great site here.

  6. Ryan on March 6th, 2009 5:28 pm

    Jan —

    Hopefully the last question. Now that I have the shader applied my Mouse Clicks have stopped working. I tried applying an event listener to the shaders on each side but it’s now working. Is it still possible to have my Mouse events with the shader applied to the movie clips?

  7. Jan Willem on March 6th, 2009 5:48 pm

    @Ryan: Just send you some emails :-)

  8. Jan Willem on March 8th, 2009 1:00 pm

    With the following code you’ll have an interactive cube with shadedMaterials:

    package
    {
    import org.papervision3d.materials.shaders.PhongShader;
    import org.papervision3d.materials.shaders.ShadedMaterial;
    import org.papervision3d.materials.shaders.CellShader;
    import org.papervision3d.materials.shaders.Shader;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.events.InteractiveScene3DEvent;

    import flash.events.Event;

    import org.papervision3d.materials.MovieAssetMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.view.BasicView;
    import org.papervision3d.core.proto.CameraObject3D;
    import org.papervision3d.core.proto.MaterialObject3D;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.core.geom.renderables.Triangle3D;

    public class DemoShader extends BasicView
    {
    private var _clipsAndSides:Array;
    private var _light:PointLight3D;
    private var _cube:Cube;

    public function DemoShader()
    {
    // linked library assets and the cubeSides we want it to belong to
    _clipsAndSides = [ {linkageId: "clip_1", cubeSide:"front" },
    {linkageId: "clip_2", cubeSide:"back" },
    {linkageId: "clip_3", cubeSide:"top" },
    {linkageId: "clip_4", cubeSide:"bottom"},
    {linkageId: "clip_5", cubeSide:"left"},
    {linkageId: "clip_6", cubeSide:"right"}
    ];

    // light
    _light = new PointLight3D();
    _light.z = camera.z;
    _light.x = camera.x;
    _light.y = 250;

    // place camera a bit higher up
    camera.y = 500;

    viewport.buttonMode = true;
    viewport.interactive = true;

    var mList:MaterialsList = new MaterialsList();
    for (var i:int = 0; i < _clipsAndSides.length; i++)
    {
    var ma:MovieAssetMaterial = new MovieAssetMaterial(_clipsAndSides[i].linkageId);
    var phongShader:PhongShader = new PhongShader(_light, 0xFFFFFF, 0×333333);
    var shadedMaterial:ShadedMaterial = new ShadedMaterial(ma, phongShader);
    shadedMaterial.interactive = true;
    shadedMaterial.name = _clipsAndSides[i].linkageId;
    mList.addMaterial(shadedMaterial, _clipsAndSides[i].cubeSide);
    }

    _cube = new Cube(mList, 500, 500, 500, 2, 2, 2);
    _cube.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, objectClicked);
    scene.addChild(_cube);

    // render
    addEventListener(Event.ENTER_FRAME, update);
    }

    private function objectClicked(event:InteractiveScene3DEvent):void
    {
    switch(event.face3d.material.name)
    {
    case “clip_1″:
    trace(“clip 1 clicked”);
    break;

    case “clip_2″:
    trace(“clip 2 clicked”);
    break;

    case “clip_3″:
    trace(“clip 3 clicked”);
    break;

    case “clip_4″:
    trace(“clip 4 clicked”);
    break;

    case “clip_5″:
    trace(“clip 5 clicked”);
    break;

    case “clip_6″:
    trace(“clip 6 clicked”);
    break;
    }
    }

    private function update(event:Event):void
    {
    camera.lookAt(_cube);

    _cube.yaw(1.5); // y-axis
    _cube.pitch(1.5); // x-axis

    singleRender();
    }
    }
    }

-->