Archive

Posts Tagged ‘as3’

Dragging objects in Papervision3D

December 26th, 2008

A few months ago, Andy Zupko added some methods to Papervision3D which facilitated the ability to drag objects in 3d space. I collected those methods and placed them in a static class called RayTracer. The class currently has only one method which returns a Number3D object with the coordinates in 3D space based on the position of your mouse on a Plane3D object.

Andy says:

In lay terms – this basically shoots a ray from the camera, through where the mouse is, into 3D space. You can then do whatever you want knowing where that ray is.

This is the code for the test above:

package
{
    import flash.events.Event;
   
    import org.papervision3d.core.math.Number3D;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;

    public class Dragging3D extends BasicView
    {
       
        private var sphere:Sphere;
       
        public function Dragging3D()
        {
            initialize();
            createObjects();
            startRendering();
        }
       
        private function initialize():void
        {
            camera.zoom = 11;
            camera.focus = 100;
            camera.z = -2000;
            camera.y = 200;
        }
       
        private function createObjects():void
        {
            var plane:Plane = new Plane(new ColorMaterial(0x0FFFF00), 1000, 1000, 10, 10);
            plane.rotationX = 90;
            scene.addChild(plane);
           
            var wireMaterial:WireframeMaterial = new WireframeMaterial();
            sphere = new Sphere(wireMaterial, 50, 10, 10);
            sphere.useOwnContainer = true;
            sphere.y = 25;
            scene.addChild(sphere);
        }
       
        override protected function onRenderTick(event:Event = null):void
        {
            super.onRenderTick(event);
           
            var intersect:Number3D = RayTracer.getIntersection(viewport, camera, [0, 1, 0]);

            sphere.x = intersect.x;
            sphere.z = intersect.z;
        }
    }
}

The magic happens in the onRenderTick method. This is where we added the RayTracer static method. The first two arguments are self explanatory. The final argument is an array representing the “normal” on an imaginary plane:

[0, 1, 0] = XY plane = objects dragged on the x and z axises
[1, 0, 0] = YZ plane = objects dragged on the y and z axises
[0, 0, 1] = XZ plane = objects dragged on the x and y axises

This is the RayTracer class:

package
{
    import org.papervision3d.core.math.Number3D;
    import org.papervision3d.core.math.Plane3D;
    import org.papervision3d.core.proto.CameraObject3D;
    import org.papervision3d.view.Viewport3D;

    public class RayTracer
    {
       
        public static function getIntersection(viewport:Viewport3D, camera:CameraObject3D, normal:Array):Number3D
        {
            var plane3D:Plane3D = new Plane3D(new Number3D(normal[0], normal[1], normal[2]), new Number3D(0, 0, 0));
            var cameraPosition:Number3D = new Number3D(camera.x, camera.y, camera.z);
            var ray:Number3D = camera.unproject(viewport.containerSprite.mouseX, viewport.containerSprite.mouseY);
            ray = Number3D.add(ray, cameraPosition);
            var intersect:Number3D = plane3D.getIntersectionLineNumbers(cameraPosition, ray);
            return intersect;
        }
       
    }
}

Should be pretty simple to implement. Hit me back if you have any questions!

Experiment, Lab , ,

Crates with physics: Papervision3D + WOWEngine

December 5th, 2008
Comments Off

Needed to quickly prototype crates falling from the sky with some physics applied for this cool project on working on.

I used a Factory Class to create the crates for me, very efficient stuff! What the class does is create both the papervision and wowengine objects and returns them in an object under the values “crate” and “fisixCrate”.

package
{
    import fr.seraf.wow.core.WOWEngine;
    import fr.seraf.wow.primitive.WSphere;
   
    import org.papervision3d.materials.MovieAssetMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.Cube;

    public class CrateFactory
    {
       
        public static function buildCrate($material:String, $width:Number = 500, $height:Number = 500):Object
        {
            // display object 3d
            var crateMat:MovieAssetMaterial = new MovieAssetMaterial($material);
            var materialsList:MaterialsList = new MaterialsList({ all:crateMat });
            var crate:Cube = new Cube(materialsList);
           
            // fisix object
            var wowCube:WSphere = new WSphere(crate.x, -3500, crate.z, 250, false);
            wowCube.mass = 10000;
            wowCube.elasticity = 0;
            wowCube.friction = 0;
           
            return {crate:crate, fisixCrate:wowCube};
        }
       
    }
}

In my document class, I have a function which uses the CrateFactory to build the crates for me at random places. It adds the papervision object to the scene and the wow particle to the wow engine:

private function buildCrate():void
{
    var objCrate:Object = CrateFactory.buildCrate("CrateMaterial");
    scene.addChild(objCrate.crate);
    wow.addParticle(objCrate.fisixCrate);
    arrCrates.push(objCrate);
    objCrate.fisixCrate.px = MathUtil.random(1500, -1500);
    objCrate.fisixCrate.pz = MathUtil.random(500, -300);
}

All the returned objects are placed in an “arrCrates” array. This array is used in the ENTER_FRAME listener to render out both the 3d and physics objects accordingly. My main class extends BasicView so I override the “onRenderTick” event handler:

override protected function onRenderTick(event:Event=null):void
{
    wow.step();
   
    for(var a:Number = 0; a<arrCrates.length; a++){
        var crate3D:Cube = arrCrates[a].crate;
        var fisixCrate:WSphere = arrCrates[a].fisixCrate;
        crate3D.x = fisixCrate.px;
        crate3D.y = -fisixCrate.py;
        crate3D.z = fisixCrate.pz;
    }
   
    var rotY: Number = (mouseY-(stage.stageHeight/2))/(stage.height/2)*(300);
    var rotX: Number = (mouseX-(stage.stageWidth/2))/(stage.width/2)*(-300);
    camera.x= camera.x+(rotX-camera.x)/5;
    camera.y= camera.y+(rotY-camera.y)/5;              

    renderer.renderScene(scene, _camera, viewport);
}

Experiment, Lab , , ,