Hi Everyone!
Today I've been experimenting with Verlet physics, and using Papervision to render the results. Here's what I've come up with:
It's a little bit buggy, but pretty good for a quick papervision project!
I had to modify the DisplayObject3D class a bit, It's a tiny modification which just allows you to store an acceleration and "previous position" in any object. I added the variables because it was the easiest and quickest way to store this information.. And my physics formula needs them.
If you want to play with it, you'll have to download my modified DisplayObject3D class by clicking here
Just replace your current file (located in Greatwhite/src/org/papervision3d/objects) with my one. It won't affect the performance or anything on projects which also use this class (I've only added two or three lines).
Here is the code (Uses the base class and modified DisplayObject3D):
-
package {
-
-
import flash.display.StageQuality;
-
import org.papervision3d.core.geom.renderables.Vertex3D;
-
import org.papervision3d.lights.PointLight3D;
-
import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
-
import org.papervision3d.materials.shadematerials.PhongMaterial;
-
import org.papervision3d.objects.DisplayObject3D;
-
import org.papervision3d.objects.primitives.Plane;
-
import org.papervision3d.objects.primitives.Sphere;
-
-
public class Main extends PaperBase {
-
-
public var light:PointLight3D = new PointLight3D(true);
-
public var physBox:DisplayObject3D = new DisplayObject3D(); //We'll keep all of the physical objects in here..
-
public var sidemat:FlatShadeMaterial = new FlatShadeMaterial(light, 0xBBBBBB, 0x000000);
-
public var floor:Plane = new Plane(sidemat, 1100, 1100, 10, 10);
-
-
public function Main() {
-
stage.quality = StageQuality.LOW; //Set the stage quality to low (for speed)
-
init();
-
}
-
-
override protected function init3d():void {
-
//Position the floor
-
floor.y = -100;
-
floor.pitch(90);
-
default_scene.addChild(floor);
-
-
//Position the camera
-
default_camera.y = 300;
-
default_camera.z = 1500;
-
default_camera.lookAt(floor);
-
-
//Position the light
-
light.x = 0;
-
light.y = 300;
-
light.z = 500;
-
-
//Create 10 Spheres, and put them in our Physics Box (Anything you add to physbox will be simulated, only spheres look right)
-
for (var x:Number = 0; x <10; x++) {
-
var sph:Sphere = new Sphere(new PhongMaterial(light, 0xBBBBBB, Math.round(Math.random() * 10000), 20), 100, 10, 8);
-
sph.x = (Math.random() * 40) - 20; // Position it slightly randomly
-
sph.z = (Math.random() * 40) - 20;
-
sph.y = (300 * x); // Put it 300 px above the previous one
-
sph.PreviousPosition = new Vertex3D(sph.x, sph.y, sph.z); // This stops the verlet from going crazy
-
physBox.addChild(sph); // Add it to the physbox
-
}
-
default_scene.addChild(physBox); // Add the physbox to the scene
-
}
-
-
override protected function processFrame():void {
-
-
default_camera.moveLeft(20); //This will rotate our camera around the scene,
-
default_camera.lookAt(floor);//whilst keeping it looking at the middle.
-
-
for (var item:String in physBox.children) { // This loop is run for every sphere in our physBox.
-
var citem:DisplayObject3D = physBox.getChildByName(item); // Get the sphere.
-
var lastposTmp:Vertex3D = getPos(citem); // Temporarily store it's position.
-
// This line of code is known as "Verlet". Wikipedia it for more info.
-
setPos(citem, vertexAdd(getPos(citem), vertexAdd(vertexSubtract(lastposTmp, citem.PreviousPosition), citem.Acceleration)));
-
citem.PreviousPosition = lastposTmp; // Update the previous position..
-
citem.Acceleration = new Vertex3D(0, -8.3, 0); // Apply Gravity
-
constrain(citem); // This code checks if the sphere has collided with the environment.
-
-
for (var item2:String in physBox.children) { //Check to see if it's hit any other spheres.
-
if (item != item2) {
-
var pitem:DisplayObject3D = physBox.getChildByName(item2);
-
dohittest(pitem, citem); // Check
-
}
-
}
-
}
-
}
-
-
private function dohittest(o1:DisplayObject3D, o2:DisplayObject3D):void {
-
if (o1.hitTestObject(o2)) { // IF the two objects have collided, then
-
var xmag:Number = (o1.x - o2.x)/2.1; // Get the distance
-
var ymag:Number = (o1.y - o2.y)/2.1;
-
var zmag:Number = (o1.z - o2.z)/2.1;
-
// Move the objects away from eachother
-
setPos(o1, vertexAdd(new Vertex3D(xmag, ymag, zmag), getPos(o1)));
-
setPos(o2, vertexSubtract(getPos(o2),new Vertex3D(xmag, ymag, zmag)));
-
}
-
}
-
-
private function constrain(obj:DisplayObject3D):void {
-
if (obj.x <500 && obj.x> -500 && obj.z <500 && obj.z> -500){ // If the object is over the floor
-
if (obj.y <0) { // If it's hit the floor
-
// Move it out of the floor.
-
if((obj.y - obj.PreviousPosition.y) <-10){
-
obj.y = (obj.PreviousPosition.y * 1.2);
-
if (obj.y <0) {
-
obj.y = 0;
-
}
-
}else {
-
obj.y = 0;
-
}
-
}
-
}
-
// If the object is way off the screen, put it back at the top.
-
if (obj.y <-10000) {
-
obj.y = 300 + (Math.random() * 5000);
-
obj.x = (Math.random() * 20) - 40;
-
obj.z = (Math.random() * 20) - 40;
-
obj.PreviousPosition = new Vertex3D(obj.x, obj.y, obj.z);
-
}
-
}
-
-
// --- These functions are used to do general addition and stuff ---
-
-
private function vertexSubtract(v1:Vertex3D, v2:Vertex3D):Vertex3D {
-
return new Vertex3D(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
-
}
-
-
private function vertexAdd(v1:Vertex3D, v2:Vertex3D):Vertex3D {
-
return new Vertex3D(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
-
}
-
-
private function getPos(object:DisplayObject3D):Vertex3D {
-
return new Vertex3D(object.x, object.y, object.z);
-
}
-
-
private function setPos(object:DisplayObject3D, point:Vertex3D):void {
-
object.x = point.x;
-
object.y = point.y;
-
object.z = point.z;
-
}
-
// --- ---
-
}
-
}
I hope it's commented enough :D
Have fun!


If you have the time, could you do some demo using WOW. The engine looks very interesting, but the documentation available is very scarce. I need some besic demos to get the hang of it.
Would be very much appreciated.
Hi,
Coming across the demo is indeed very interesting. Great !
I am now currently working around quaternion physics. Cheers.
Hi Joakim,
If I get the time I will, I still haven’t looked into WOW yet though, and thanks for the comment cslamsg, would be cool to see what you come up with :)!
-Luke
Thanks for the great example!
Found something similar using papervision and the wow physics engine here: http://lab.tojio.com/projects/wowpv3dhelloworld/
Hi,
Thanks for the example. I’ve downloaded your modified version of DisplayObject3D and it doesn’t work. Apparently it doesn’t have the clone method and related properties. Any reason why these might be left out ?
Why not just create a DisplayObject3DPhys for example, that extends DisplayObject3D ?
What kind of Papervision3D version do you have???
Sorry, but GreatWhite doesn`t work. Phong shader materials classes is wrong ((
WoW where is your PaperBase Class? give me pleasssssse.
oh i see it.Thx
It doesn’t work… there seems a problem with the override function in the vertex3d class. i think something is wrong with your new “DisplayObject3D”!!! can u check this????
Hello Luke,
Papervision 2 it’s great i think that it was change interactivity on the web.
But i’m the same error that Maceo, i had to replace DisplayObject3D class but it doesn’t work and make trouble with another project like “Fun with Filters”.
Maybe it’s us can you check the new Displayobject class ? thx
Thank you soooo much for your brilliant examples. I was able to use your collision detection ideas to solve some frustrating issues I was having.
The solution to the DisplayObject3D is the following:
you insert these 2 lines in the class
public var Acceleration:Vertex3D = new Vertex3D(0, 0, 0);
public var PreviousPosition:Vertex3D = new Vertex3D(0,0,0);
and you import the Vertex3D class to the package.
That’s how I got mine to work.
Hi,
I have tried to demonstrate new physics engine jiglib on my bowling game :)
http://moth.cz/bowl/bowlec.html
This is great!
Do you have any mechanism worked into your code yet to give different objects different weights, for the bounces? And what about immovable objects?
If no, I’ll adapt DisplayObject3d.as to incorporate those.