Bringing Physics to Sandy 3D, using JigLibFlash (recurring balls)
The application shows balls rolling on slopes
Extending the BasicView sets up the Sandy scen for us :)
To get a nice bouncing, I mosty play with restitution.
No doubt this could be enhanced in quite a few ways
Go on and fork me :)
@author petit@petitpub.com
// forked from petit's Bringing Physics to Sandy 3D, using JigLibFlash
package
{
import flash.events.Event;
import jiglib.math.JNumber3D;
import jiglib.plugin.sandy3d.Sandy3DPhysics;
import jiglib.plugin.sandy3d.Sandy3DMesh;
import sandy.view.BasicView;
import sandy.materials.attributes.LightAttributes;
import sandy.materials.attributes.LineAttributes;
import sandy.materials.attributes.PhongAttributes;
import sandy.materials.attributes.MaterialAttributes;
import sandy.materials.attributes.GouraudAttributes;
import sandy.materials.ColorMaterial;
import sandy.materials.Appearance;
import jiglib.physics.RigidBody;
/**
* The application shows balls rolling on slopes
* Extending the BasicView sets up the Sandy scen for us :)
* To get a nice bouncing, I mosty play with restitution.
* No doubt this could be enhanced in quite a few ways
* Go on and fork me :)
*
* @author petit@petitpub.com
*/
public class BallsOnSlopes extends BasicView
{
private var physics:Sandy3DPhysics; // The physic engine adapter class
private var ground:RigidBody;
private var balls:Array; // An array of chained objects
private const NUM_BALLS:int = 3;
/**
* Set up the experiment
*/
public function BallsOnSlopes(){
super.init(600,400);
balls = new Array();
scene.light.setDirection(1,-1,2);
camera.z = -800; camera.y = 200; camera.lookAt(0, 200, 0);
// Create an instance of the physics engine
physics = new Sandy3DPhysics(scene, 3);
createObjects();
render();
// reset on click
stage.addEventListener ("click", click);
}
/**
* Create the ground, ramps and balls
*/
private function createObjects():void {
// Create some materials
var groundAttributes:MaterialAttributes = new MaterialAttributes( new LineAttributes(0.5,0xECECEC,0.6), new LightAttributes(true));
var groundMaterial:ColorMaterial = new ColorMaterial(0x26A6D0, 1, groundAttributes);
var backMaterial:ColorMaterial = new ColorMaterial(0xFF552A, 0.6);
var slopeAttributes:MaterialAttributes = new MaterialAttributes( new LightAttributes(true));
var slopeMaterial:ColorMaterial = new ColorMaterial(0x1B9A1B, 0.8, slopeAttributes);
slopeMaterial.lightingEnable = true;
var ballAttributes:MaterialAttributes = new MaterialAttributes( new PhongAttributes(true,0.2,15,2 ));
var ballMaterial:ColorMaterial = new ColorMaterial(0xFFAA2A, 1, ballAttributes);
ballMaterial.lightingEnable = true;
// Create the ground
ground = physics.createGround("ground", new Appearance(groundMaterial), 800, 0, 10);
physics.getMesh(ground).enableForcedDepth = true;
physics.getMesh(ground).forcedDepth = 40040;
ground.restitution = 0.6;
// Create the back wall
var backWall:RigidBody = physics.createCube("back", new Appearance( backMaterial ), 600, 2, 400, 2);
physics.getMesh(backWall).forcedDepth = 40020;
backWall.z = 200;
backWall.y = 200;
backWall.restitution = 1.6;
backWall.movable = false;
// Create the slopes
var slope1:RigidBody = physics.createCube("slope1", new Appearance(slopeMaterial), 50, 200, 8, 2);
physics.getMesh(slope1).useSingleContainer = false;
slope1.x = -250; slope1.y = 300; slope1.z = 100;
slope1.rotationX = -25;
slope1.movable = false;
var slope2:RigidBody = physics.createCube("slope2", new Appearance(slopeMaterial), 50, 300, 8, 2);
physics.getMesh(slope2).useSingleContainer = false;
slope2.x = -250; slope2.y = 200; slope2.z = -100;
slope2.rotationX = 35;
slope2.movable = false;
// Create multiple balls
for ( var i:int = 0; i < NUM_BALLS; i++) {
balls[i]=physics.createSphere("ball" + 1, new Appearance(ballMaterial), 20, 8, 8);
balls[i].x = -250; balls[i].y = 400 + 40 * i; balls[i].z = 160;
//physics.getMesh(balls[i]).useSingleContainer = false;
balls[i].restitution = 1.8;
}
}
/**
* Overrides the simpleRender method to call the time step method of the rendering engine.
* @param event The ENTER_FRAME or timer event - the heart beat of Sandy
*/
override public function simpleRender( event:Event = null ):void {
physics.step( );
super.simpleRender( event );
for ( var i:int = 0; i < NUM_BALLS; i++) {
if (balls [i].z < camera.z) {
balls[i].x = -250; balls[i].y = 400 + 40 * i; balls[i].z = 16;
}
}
}
public function click( event:Event = null ):void {
for ( var i:int = 0; i < NUM_BALLS; i++) {
balls[i].x = -250; balls[i].y = 400 + 40 * i; balls[i].z = 16; balls[i].setActive();
}
}
}
}