Home > JigLibFlash, Lab, papervision3d > JigLibFlash + Papervision3d : Quick run-through

JigLibFlash + Papervision3d : Quick run-through

April 3rd, 2009

Hi all:

So last night I got some time to set up a quick and dirty example demonstrating how easy it is to implement physics in 3D using the new “plugin” classes created by Bartek who, if I do say so myself, has done a beautiful job setting up the plugin system for both Papervision3D and Away3D [EDIT : he also set up a really cool post over in the project wiki!]. Check this out (use your arrow keys to move the sphere around):

And here is the code for it:

package
{
    import flash.display.Bitmap;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
   
    import jiglib.geometry.JSphere;
    import jiglib.math.JNumber3D;
    import jiglib.physics.RigidBody;
    import jiglib.plugin.papervision3d.Papervision3DPhysics;
    import jiglib.plugin.papervision3d.Pv3dMesh;
   
    import org.papervision3d.cameras.CameraType;
    import org.papervision3d.cameras.SpringCamera3D;
    import org.papervision3d.core.math.Number3D;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.BitmapMaterial;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.view.BasicView;
    import org.papervision3d.view.layer.util.ViewportLayerSortMode;
   
    /**
     * Simple Papervision3D + JigLibFlash example
     * @author Reynaldo a.k.a. reyco1
     *
     */

    [SWF(width="900", height="700", backgroundColor="#000000", frameRate="60")]
    public class RandomObjects extends BasicView
    {
        [Embed(source="assets/earthTexture512x256.jpg")]
        public var EarthTexture:Class;
       
        private var physics:Papervision3DPhysics;
        private var sphereObject:Sphere;
        private var physicsObject:RigidBody;       
        private var keyRight:Boolean = false;
        private var keyLeft:Boolean = false;
        private var keyForward:Boolean = false;
        private var keyReverse:Boolean = false;
        private var keyUp:Boolean = false;     
        private var moveForce:Number = 10;     
        private var springCamera:SpringCamera3D;
        private var cameraTarget:DisplayObject3D;
        private var sceneLight:PointLight3D;
       
        public function RandomObjects()
        {
            super(stage.stageWidth, stage.stageHeight, true, false, CameraType.TARGET);
            viewport.containerSprite.sortMode = ViewportLayerSortMode.INDEX_SORT;
            physics = new Papervision3DPhysics(scene, 1);
                       
            addKeyboardListeners();
            setupLighting();
            createFloor();
            setCamera();
            createSphere();
            createBoxes();     
            startRendering();
        }
       
        private function addKeyboardListeners():void
        {
            stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler );
            stage.addEventListener( KeyboardEvent.KEY_UP, keyUpHandler );
        }
       
        private function setupLighting():void
        {
            sceneLight = new PointLight3D(true, true);
            sceneLight.x = 0;
            sceneLight.y = 400;
            sceneLight.z = -300;
        }
       
        private function setCamera():void
        {
            springCamera = new SpringCamera3D();
            springCamera.mass = 10;
            springCamera.damping = 10;
            springCamera.stiffness = 1;
               
            springCamera.lookOffset = new Number3D(0, 20, 30);
            springCamera.positionOffset = new Number3D(0, 100, -1500);
           
            springCamera.focus = 100;
            springCamera.zoom = 10;
        }
       
        private function createSphere():void
        {
            var earthMaterial:BitmapMaterial = new BitmapMaterial(Bitmap(new EarthTexture()).bitmapData, true);
            earthMaterial.tiled = true;
            earthMaterial.smooth = true;
           
            sphereObject = new Sphere(earthMaterial, 100, 13, 11);
            scene.addChild(sphereObject);
           
            physicsObject = new JSphere(new Pv3dMesh(sphereObject), 100);
            physicsObject.y = 200;
            physicsObject.restitution = 3;
            physicsObject.mass = 1
            physics.addBody(physicsObject);
           
            cameraTarget = new DisplayObject3D();
            cameraTarget.copyPosition(sphereObject);
            scene.addChild(cameraTarget);
           
            springCamera.target = cameraTarget;
        }
       
        private function createBoxes():void
        {
            var randomBox:RigidBody;
            var material:MaterialsList = new MaterialsList();
            material.addMaterial(new FlatShadeMaterial(sceneLight, 0x77ee77), "all");
            //material.addMaterial(new ColorMaterial(0x77ee77), "all");
           
            for(var a:Number = 0; a<10; a++)
            {
                randomBox = physics.createCube(material, 100, 100, 100);
                randomBox.z = 1000;
                randomBox.y = a*100 + 55;
                randomBox.mass = .2;
            }
        }
       
        private function createFloor():void
        {
            physics.createGround(new WireframeMaterial(0xFFFFFF, 0), 1800, 0);
           
            var floor:Plane = new Plane(new WireframeMaterial(0xFFFFFF), 10000, 10000, 10000*0.001, 10000*0.001);
            floor.rotationX = 90;
            floor.y = -150
            scene.addChild(floor);
           
           /*  var floorViewportLayer:ViewportLayer = new ViewportLayer(viewport, floor);
            floorViewportLayer.addDisplayObject3D(floor, true);
            floorViewportLayer.layerIndex = 1;
           
            viewport.containerSprite.addLayer(floorViewportLayer); */

        }
       
        private function keyDownHandler(event:KeyboardEvent):void
        {
            switch(event.keyCode)
            {
                case Keyboard.UP:
                    keyForward = true;
                    keyReverse = false;
                    break;
   
                case Keyboard.DOWN:
                    keyReverse = true;
                    keyForward = false;
                    break;
   
                case Keyboard.LEFT:
                    keyLeft = true;
                    keyRight = false;
                    break;
   
                case Keyboard.RIGHT:
                    keyRight = true;
                    keyLeft = false;
                    break;
                case Keyboard.SPACE:
                    keyUp = true;
                    break;
            }
        }
       
        private function keyUpHandler(event:KeyboardEvent):void
        {
            switch(event.keyCode)
            {
                case Keyboard.UP:
                    keyForward = false;
                    break;
   
                case Keyboard.DOWN:
                    keyReverse = false;
                    break;
   
                case Keyboard.LEFT:
                    keyLeft = false;
                    break;
   
                case Keyboard.RIGHT:
                    keyRight = false;
                    break;
                case Keyboard.SPACE:
                    keyUp=false;
            }
        }
       
        override protected function onRenderTick(event:Event = null):void
        {
            if(keyLeft)
            {
                physicsObject.addWorldForce(new JNumber3D(-moveForce, 0, 0), physicsObject.currentState.position);
            }
            if(keyRight)
            {
                physicsObject.addWorldForce(new JNumber3D(moveForce, 0, 0), physicsObject.currentState.position);
            }
            if(keyForward)
            {
                physicsObject.addWorldForce(new JNumber3D(0, 0, moveForce), physicsObject.currentState.position);
            }
            if(keyReverse)
            {
                physicsObject.addWorldForce(new JNumber3D(0, 0, -moveForce), physicsObject.currentState.position);
            }
            if(keyUp)
            {
                physicsObject.addWorldForce(new JNumber3D(0, moveForce, 0), physicsObject.currentState.position);
            }
           
            cameraTarget.copyPosition(sphereObject);
           
            physics.step();
            renderer.renderScene(scene, springCamera, viewport);
        }
       
    }
}

Stripping out all the usual stuff from the code above, these are snippets that integrate the physics:

First thing we need to is set up and instance of the physics plugin

physics = new Papervision3DPhysics();

Now, there are two ways to apply physics to your 3d objects using the plugin system. In the example, I use both. The “manual” approach can be seen in the createSphere method:

First the Papervision3D sphere is created and added to the scene

var earthMaterial:BitmapMaterial = new BitmapMaterial(Bitmap(new EarthTexture()).bitmapData, true);
earthMaterial.tiled = true;
earthMaterial.smooth = true;
           
sphereObject = new Sphere(earthMaterial, 100, 13, 11);
scene.addChild(sphereObject);

Then we create a physics sphere and add it to the physics engine:

physicsObject = new JSphere(new Pv3dMesh(sphereObject), 100);
physicsObject.y = 200;
physicsObject.restitution = 3;
physicsObject.mass = 1;
physics.addBody(physicsObject);

That’s basically it. You can go through all those steps (which aren’t many actually) or you can use the shortcut method which I used for creating the cubes in the createBoxes method:

randomBox = physics.createCube(material, 100, 100, 100);
randomBox.z = 1000;
randomBox.y = a*100 + 55;
randomBox.mass = .2;

Basically, both the 3d object and the physics object are created by the engine. Just pass the same arguments you would pass to the 3d Object class, in this case a Cube.

You can access the DisplayObject3D class anytime by using the following method from the plugin

physics.getMesh(randomBox)

Applying forces to your 3D/physics objects is pretty simple too. I’ll go over it more in detail in a later post, but this is the line that makes it happen:

physicsObject.addWorldForce(new JNumber3D(moveForce, 0, 0), physicsObject.currentState.position);

Where the first parameter is a vector or JNumber indicating in what direction the force should be applied and the second parameter is the current position of the physics object to which the force is being applied to.

I recommend you guys jump into the JigLibFlash repo and start exploring. There’ll be more examples to come soon!

JigLibFlash, Lab, papervision3d

  1. April 3rd, 2009 at 08:01 | #1

    This is great, already giving me a lot of ideas on how to use this. How is the speed in more complex environments? I would be interested to know if the performance bottleneck would be on the pv3d or the physics side?

  2. April 3rd, 2009 at 08:24 | #2

    @Jesse Those are pretty good questions. We still have to fix a few bugs and make a couple more performance enhancements before I can answer those questions though. You can have up to 100 spheres with no problems but then 20 stacked cubes cause meltdown LOL. The library is still work in progress but you guys are welcome to poke around ;)

  3. Ryan Liu
    April 4th, 2009 at 01:25 | #3

    COOL.But I compiled the codes and it ran much slower than yours.Is there anything i did wrong? :(

  4. Ryan Liu
    April 4th, 2009 at 09:17 | #4

    Here’s my test.http://www.ryan-liu.com/demo/jiglib/jiglibboxes.html
    Two questions :
    - the boxes keep shaking sometimes,are they deactivated or not?
    - why i couldn’t get the correct rotationX from a RigidBody object,is it for read only?

  5. April 8th, 2009 at 02:43 | #5

    Hey i am using flex to run this and it’s very slow. Any idea why?? :(

  6. April 8th, 2009 at 07:03 | #6

    Hi Guys… Keep in mind that the engine is still in it’s alpha state. There are some issues with objects shaking along with some other stuff that speedok and muzer are looking into it. Actually speedok has been playing around with the timestep quite alot.

    @thivy debug mode probably? The debug player is way slower. Try putting the speed to 5.

    Too many objects slows it down a bit along with too much stacking also. Again, these are things that we are working on currently. Stay tuned though, we will probably be setting up a Q and A section in the JigLibFlash blog soon.

  7. April 11th, 2009 at 05:13 | #7

    Hey

    I am trying to make the iphone labyrinth with PV3D and jiglib.
    http://labyrinth.codify.se/

    i have a problem, i want to make a floor and four walls around it. And i want this to rotate all these walls respect to one point. how do i do this using jiglib and pv3d. i know i have to use jconstraintpoint, but it’s not working for me :( please help me.

    Thnaks

  8. April 29th, 2009 at 06:02 | #8

    I finally could mix jigLib with FLAR!
    check it here:
    http://www.arvertising.com/vDice.shtml

    as soon as I clean the code, i’ll post it somewhere :)

    cheers

  9. shajby
    May 8th, 2009 at 01:14 | #9

    wow, absolutely cool, thanks!!!

  10. mike m.
    June 5th, 2009 at 18:35 | #10

    hey was wondering if its possible to use a custom mesh inside of jiglib. i created a pyramid mesh class and tried importing it to jiglib as a rigidbody but it threw errors in detectAllCollisions function of CollisionSystem. I think its looking for a specified body type which obviously doesnt exist…

    does it not support custom mesh’s yet ?

  11. October 15th, 2009 at 05:50 | #11

    >April 4th, 2009 at 01:25 | #3
    >Reply | Quote

    >COOL.But I compiled the codes and it ran much slower than yours.Is >there >anything i did wrong?

    increase speed from 1 to 5 or more
    physics = new Papervision3DPhysics(scene, 1); => physics = new Papervision3DPhysics(scene, 5);

  12. Sherman
    December 26th, 2009 at 04:54 | #12

    Hi,
    I really like the work you do and I was admiring the first person camera system you also created. You mentioned a plug in system for collision of sorts in the post, and I was wondering if this is what you may have been alluding to?
    If so, do you think you could demonstrate how to set up your camera with this Jiglib physics?
    My goal is to have this first person camera collide with react to collada models that I have imported.
    Thanks

  13. zakwer
    February 15th, 2010 at 16:27 | #13

    Hey, really nice work!

    but trying your code i have two issues on compiling… any ideas?

    1136: Incorrect number of arguments. Expected 0.
    1067: Implicit coercion of a value of type jiglib.math:JNumber3D to an unrelated type flash.geom:Vector3D.

    i have both org and jiglib folders, maybe wrong version?
    i dont understand! :)

    thanks in advance
    zak

  1. April 23rd, 2009 at 00:38 | #1
  2. April 27th, 2009 at 06:07 | #2
Comments are closed.