Physics

JigLibFlash Physics

Code

Δ

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.text.TextField;
  import flash.text.TextFieldAutoSize;
  import flash.text.TextFormat;
  import flash.ui.Keyboard;

  import jiglib.geometry.JBox;
  import jiglib.geometry.JPlane;
  import jiglib.geometry.JSphere;
  import jiglib.math.JMatrix3D;
  import jiglib.math.JNumber3D;
  import jiglib.physics.PhysicsSystem;
  import jiglib.physics.RigidBody;
  import jiglib.plugin.papervision3d.Pv3dMesh;

  import org.papervision3d.cameras.Camera3D;
  import org.papervision3d.materials.ColorMaterial;
  import org.papervision3d.materials.WireframeMaterial;
  import org.papervision3d.materials.special.CompositeMaterial;
  import org.papervision3d.materials.utils.MaterialsList;
  import org.papervision3d.objects.DisplayObject3D;
  import org.papervision3d.objects.primitives.Cube;
  import org.papervision3d.objects.primitives.Plane;
  import org.papervision3d.objects.primitives.Sphere;
  import org.papervision3d.render.QuadrantRenderEngine;
  import org.papervision3d.scenes.Scene3D;
  import org.papervision3d.view.Viewport3D;

  public class JigLibFlashPhysics extends Sprite
  {
    private var scene            :Scene3D;
    private var camera           :Camera3D;
    private var viewport         :Viewport3D;
    private var renderer         :QuadrantRenderEngine;
    private var material         :ColorMaterial;
    private var materialActive   :CompositeMaterial;
    private var materialInactive :CompositeMaterial;
    private var materialMoveable :CompositeMaterial;
    private var materials        :MaterialsList;

    private var jCube   :Array = new Array();
    private var jSphere :Array = new Array();

    private var keyForward  :Boolean = false;
    private var keyBackward :Boolean = false;
    private var keyLeft     :Boolean = false;
    private var keyRight    :Boolean = false;
    private var keyUp       :Boolean = false;

    private var field :TextField;

    public function JigLibFlashPhysics()
    {
      scene = new Scene3D();

      camera   = new Camera3D();
      camera.x = 0;
      camera.y = 500;
      camera.z = -400;

      camera.target   = new DisplayObject3D();
      camera.target.x = 0;
      camera.target.y = 250;
      camera.target.z = 0;

      viewport                  = new Viewport3D();
      viewport.autoScaleToStage = true;
      addChild(viewport);

      renderer = new QuadrantRenderEngine(1);

      material = new ColorMaterial(0x000000);

      materialActive = new CompositeMaterial();
      materialActive.addMaterial(new ColorMaterial(0x00ff00, 0.5));
      materialActive.addMaterial(new WireframeMaterial(0x00ff00));

      materialInactive = new CompositeMaterial();
      materialInactive.addMaterial(new ColorMaterial(0xff0000, 0.5));
      materialInactive.addMaterial(new WireframeMaterial(0xff0000));

      materialMoveable = new CompositeMaterial();
      materialMoveable.addMaterial(new ColorMaterial(0xffff00, 0.5));
      materialMoveable.addMaterial(new WireframeMaterial(0xffff00));

      materials = new MaterialsList();
      materials.addMaterial(material, "all");

      var ground :Cube = new Cube(materials, 500, 500, 500);
      scene.addChild(ground);

      var jGround :JBox = new JBox(new Pv3dMesh(ground), 500, 500, 500);
      jGround.movable = false;
      jGround.moveTo(JNumber3D.ZERO);
      jGround.setOrientation(JMatrix3D.rotationX(Math.PI / 2.5));
      PhysicsSystem.getInstance().addBody(jGround);

      var cube :Cube;
      for (var i:int = 0; i < 6; i++) {
        cube = new Cube(materials, 40, 40, 40);
        scene.addChild(cube);

        jCube[i]      = new JBox(new Pv3dMesh(cube), 40, 40, 40);
        jCube[i].mass = 3;
        jCube[i].moveTo(new JNumber3D((Math.random() * 100), 240 + (60 * Number(i) + 60), (Math.random() * -100)));
        PhysicsSystem.getInstance().addBody(jCube[i]);
      }

      var sphere :Sphere;
      for (i = 0; i < 12; i++) {
        if (i == 0) {
          sphere = new Sphere(materialMoveable, 20, 6);
        } else {
          sphere = new Sphere(materialActive, 20, 6);
        }
        scene.addChild(sphere);

        jSphere[i]      = new JSphere(new Pv3dMesh(sphere), 20);
        jSphere[i].mass = 3;
        jSphere[i].moveTo(new JNumber3D(((Math.random() * 500) - 250), 240 + (60 * Number(i) + 60), ((Math.random() * 500) - 250)));
        PhysicsSystem.getInstance().addBody(jSphere[i]);
      }

      field                   = new TextField();
      field.autoSize          = TextFieldAutoSize.LEFT;
      field.defaultTextFormat = new TextFormat("verdana");
      field.selectable        = false;
      addChild(field);
      instructions();

      stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown);
      stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyUp);
      addEventListener(Event.ENTER_FRAME, handleEnterFrame);
    }

    private function handleEnterFrame(e:Event):void
    {
      if (keyForward) {
        jSphere[0].addWorldForce(new JNumber3D(0, 0, 100), jSphere[0].currentState.position);
      }
      if (keyBackward) {
        jSphere[0].addWorldForce(new JNumber3D(0, 0, -100), jSphere[0].currentState.position);
      }
      if (keyLeft) {
        jSphere[0].addWorldForce(new JNumber3D(-100, 0, 0), jSphere[0].currentState.position);
      }
      if (keyRight) {
        jSphere[0].addWorldForce(new JNumber3D(100, 0, 0), jSphere[0].currentState.position);
      }
      if (keyUp) {
        jSphere[0].addWorldForce(new JNumber3D(0, 100, 0), jSphere[0].currentState.position);
      }
      for (var i:String in jCube) {
        if (jCube[i].isActive()) {
          jCube[i].skin.mesh.material = materialActive;
        } else {
          jCube[i].skin.mesh.material = materialInactive;
        }
        if (jCube[i].currentState.position.y < 0) {
          jCube[i].moveTo(new JNumber3D(((Math.random() * 500) - 250), 250, ((Math.random() * 500) - 250)));
        }
      }
      for (i in jSphere) {
        if (Number(i) != 0) {
          if (jSphere[i].isActive()) {
            jSphere[i].skin.mesh.material = materialActive;
          } else {
            jSphere[i].skin.mesh.material = materialInactive;
          }
        }
        if (jSphere[i].currentState.position.y < 0) {
          jSphere[i].moveTo(new JNumber3D(((Math.random() * 800) - 400), 240 + (60 * Number(i) + 60), ((Math.random() * 800) - 400)));
        }
      }
      PhysicsSystem.getInstance().integrate(0.1);
      renderer.renderScene(scene, camera, viewport);
    }

    private function handleKeyDown(e:KeyboardEvent):void
    {
      switch(e.keyCode) {
        case Keyboard.ENTER:
          field.visible = field.visible ? false : true;
          break;
        case Keyboard.UP:
        case "W".charCodeAt():
          keyForward  = true;
          keyBackward = false;
          break;
        case Keyboard.DOWN:
        case "S".charCodeAt():
          keyBackward = true;
          keyForward  = false;
          break;
        case Keyboard.LEFT:
        case "A".charCodeAt():
          keyLeft  = true;
          keyRight = false;
          break;
        case Keyboard.RIGHT:
        case "D".charCodeAt():
          keyRight = true;
          keyLeft  = false;
          break;
      }
    }

    private function handleKeyUp(e:KeyboardEvent):void
    {
      switch(e.keyCode) {
        case Keyboard.UP:
        case "W".charCodeAt():
          keyForward = false;
          break;
        case Keyboard.DOWN:
        case "S".charCodeAt():
          keyBackward = false;
          break;
        case Keyboard.LEFT:
        case "A".charCodeAt():
          keyLeft = false;
          break;
        case Keyboard.RIGHT:
        case "D".charCodeAt():
          keyRight = false;
          break;
      }
    }

    private function instructions():void
    {
      field.text = "Click\tStart"
        + "\nEnter\tInstructions"
        + "\nW\t\tForward"
        + "\nS\t\tBackward"
        + "\nA\t\tLeft"
        + "\nD\t\tRight";
    }
  }
}

Download