PV3D - Interactive Shaded Cube
Posted on March 8, 2009
Filed Under Actionscript 3.0, Papervision, experiments |
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.
-
package
-
{
-
import flash.events.Event;
-
-
import org.papervision3d.materials.shaders.PhongShader;
-
import org.papervision3d.materials.shaders.ShadedMaterial;
-
import org.papervision3d.events.InteractiveScene3DEvent;
-
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();
-
}
-
}
-
}
Hope everything is clear and if you have a better solution please comment a post!
Comments
7 Responses to “PV3D - Interactive Shaded Cube”
Leave a Reply
This helps a lot, thx!
Hey Jan —
I forgot to ask you, do you notice a drop in the frame rate when you do this?
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.
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!
i like your header.swf very nice. thanks for the tutorial.
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);
}
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.