PV3D – Interactive Shaded Cube

Posted on March 8, 2009
Filed Under Actionscript 3.0, experiments, Papervision | 11 Comments

protoshader

Ryan and myself wanted to figure out how to create have an interactive cube which uses a ShadedMaterial (MovieMaterial + Shader). Problem was that when you had a shadedmaterial you didn’t get any interactiveScene3DEvent’s back, when you used only the MovieMaterial and set it to interactive=true everything worked fine, but in combination with a shader it created a problem. So I had a look at it today and came up with the following solution.

  1. package
  2. {
  3.  import flash.events.Event;
  4.  
  5.  import org.papervision3d.materials.shaders.PhongShader;
  6.  import org.papervision3d.materials.shaders.ShadedMaterial;
  7.  import org.papervision3d.events.InteractiveScene3DEvent;
  8.  import org.papervision3d.materials.MovieAssetMaterial;
  9.  import org.papervision3d.materials.utils.MaterialsList;
  10.  import org.papervision3d.objects.primitives.Cube;
  11.  import org.papervision3d.lights.PointLight3D;
  12.  import org.papervision3d.view.BasicView;
  13.  import org.papervision3d.core.proto.CameraObject3D;
  14.  import org.papervision3d.core.proto.MaterialObject3D;
  15.  import org.papervision3d.objects.DisplayObject3D;
  16.  import org.papervision3d.core.geom.renderables.Triangle3D;
  17.  
  18.  public class DemoShader extends BasicView
  19.  {
  20.   private var _clipsAndSides:Array;
  21.   private var _light:PointLight3D;
  22.   private var _cube:Cube;
  23.  
  24.   public function DemoShader()
  25.   {
  26.    // linked library assets and the cubeSides we want it to belong to
  27.    _clipsAndSides = [  {linkageId: "clip_1", cubeSide:"front" },
  28.         {linkageId: "clip_2", cubeSide:"back" },
  29.         {linkageId: "clip_3", cubeSide:"top" },
  30.         {linkageId: "clip_4", cubeSide:"bottom"},
  31.         {linkageId: "clip_5", cubeSide:"left"},
  32.         {linkageId: "clip_6", cubeSide:"right"}
  33.        ];
  34.  
  35.    // light
  36.    _light = new PointLight3D();
  37.    _light.z = camera.z;
  38.    _light.x = camera.x;
  39.    _light.y = 250;
  40.  
  41.    // place camera a bit higher up
  42.    camera.y = 500;
  43.  
  44.    viewport.buttonMode = true;
  45.    viewport.interactive = true;
  46.  
  47.    var mList:MaterialsList = new MaterialsList();
  48.    for (var i:int = 0; i < _clipsAndSides.length; i++)
  49.    {
  50.     var ma:MovieAssetMaterial = new MovieAssetMaterial(_clipsAndSides[i].linkageId);
  51.     var phongShader:PhongShader = new PhongShader(_light, 0xFFFFFF, 0×333333);
  52.     var shadedMaterial:ShadedMaterial = new ShadedMaterial(ma, phongShader);
  53.     shadedMaterial.interactive = true;
  54.     shadedMaterial.name = _clipsAndSides[i].linkageId;
  55.     mList.addMaterial(shadedMaterial, _clipsAndSides[i].cubeSide);
  56.    }
  57.  
  58.    _cube = new Cube(mList, 500, 500, 500, 2, 2, 2);
  59.    _cube.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, objectClicked);
  60.    scene.addChild(_cube);
  61.  
  62.    // render
  63.    addEventListener(Event.ENTER_FRAME, update);
  64.   }
  65.  
  66.   private function objectClicked(event:InteractiveScene3DEvent):void
  67.   {
  68.    switch(event.face3d.material.name)
  69.    {
  70.     case "clip_1":
  71.      trace("clip 1 clicked");
  72.      break;
  73.  
  74.     case "clip_2":
  75.      trace("clip 2 clicked");
  76.      break;
  77.  
  78.     case "clip_3":
  79.      trace("clip 3 clicked");
  80.      break;
  81.  
  82.     case "clip_4":
  83.      trace("clip 4 clicked");
  84.      break;
  85.  
  86.     case "clip_5":
  87.      trace("clip 5 clicked");
  88.      break;
  89.  
  90.     case "clip_6":
  91.      trace("clip 6 clicked");
  92.      break;
  93.    }
  94.   }
  95.  
  96.   private function update(event:Event):void
  97.   {
  98.    camera.lookAt(_cube);
  99.  
  100.    _cube.yaw(1.5); // y-axis
  101.    _cube.pitch(1.5); // x-axis
  102.  
  103.    singleRender();
  104.   }
  105.  }
  106. }

Hope everything is clear and if you have a better solution please comment a post!

Comments

11 Responses to “PV3D – Interactive Shaded Cube”

  1. Gackson on May 4th, 2009 12:25 pm

    This helps a lot, thx!

  2. Ryan on May 28th, 2009 3:18 pm

    Hey Jan —

    I forgot to ask you, do you notice a drop in the frame rate when you do this?

  3. Ryan on May 28th, 2009 3:42 pm

    After looking at my original code to yours I had some minor errors that probably caused some rendering errors.

    Have you ever worked with reflections. I’m going to play around and see if I can get a reflection from this cube.

  4. Ryan on June 2nd, 2009 6:03 pm

    Hey Jan –

    I noticed a weird problem when shading the cube. My shading will be jumpy as the cube is spinning. When a face is not directly in front, that face will be at it’s darkest. Then when it gets close to the front it jumps to the lightest value. You know of any reason for that?

    Thanks!

  5. aaa on January 7th, 2010 4:52 pm

    i like your header.swf very nice. thanks for the tutorial.

  6. Ray on March 10th, 2010 7:24 pm

    didnt work for meh…
    changes:

    var mList:MaterialsList = new MaterialsList();

    for (var i:int = 0; i < _clipsAndSides.length; i++)
    {
    var bg:Sprite = new Sprite();
    bg.graphics.clear();
    bg.graphics.beginFill(0xFafafa,1);
    bg.graphics.drawRect(0, 0, 100,100);
    bg.graphics.endFill();
    bg.buttonMode = true;
    var ma:MovieMaterial = new MovieMaterial(bg);
    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);
    }

  7. keerthi on July 19th, 2010 10:11 am

    Nice tutorial, could u help to implement the same thing in android using open gl es, i want identify which face of the cube is touched.

  8. David on November 12th, 2010 10:14 pm

    For me it’s BAD SOURCE WHY YOU PUT A BAD SOURCE WITH MANY ERROR YOU DISTURBE US

    Please REMOVE IT

  9. Guy on December 20th, 2010 6:03 am

    You guys obviously don’t know how to code. I can already tell you one of the problems is when he defines the colors. I’m sure you can figure out the rest of the errors for yourself.

    Awesome example by the way ;)

  10. koblongata on December 23rd, 2010 8:41 am

    this solves the problem to detect clicks on each cube face.

    how about interactive movieclips as materials? can i detect mouse events within a movieclip?? :P

  11. freelance on January 11th, 2011 5:46 pm

    I really enjoyed reading this post, big fan. Keep up the good work and please tell me when can you publish more articles or where can I read
    more on the subject?

-->