summaryrefslogtreecommitdiffstats
path: root/o3d/samples/box2d-3d/demos
diff options
context:
space:
mode:
authorgspencer@google.com <gspencer@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-27 23:15:42 +0000
committergspencer@google.com <gspencer@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-27 23:15:42 +0000
commit05b47f7a8c5451f858dc220df0e3a97542edace6 (patch)
treea2273d619f0625c9d44d40842845ccce2eac1045 /o3d/samples/box2d-3d/demos
parent5cdc8bdb4c847cefe7f4542bd10c9880c2c557a0 (diff)
downloadchromium_src-05b47f7a8c5451f858dc220df0e3a97542edace6.zip
chromium_src-05b47f7a8c5451f858dc220df0e3a97542edace6.tar.gz
chromium_src-05b47f7a8c5451f858dc220df0e3a97542edace6.tar.bz2
This is the O3D source tree's initial commit to the Chromium tree. It
is not built or referenced at all by the chrome build yet, and doesn't yet build in it's new home. We'll change that shortly. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17035 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d/samples/box2d-3d/demos')
-rw-r--r--o3d/samples/box2d-3d/demos/LICENSE.txt14
-rw-r--r--o3d/samples/box2d-3d/demos/README.o3d5
-rw-r--r--o3d/samples/box2d-3d/demos/compound.js71
-rw-r--r--o3d/samples/box2d-3d/demos/crank.js79
-rw-r--r--o3d/samples/box2d-3d/demos/demo_base.js59
-rw-r--r--o3d/samples/box2d-3d/demos/demos.js271
-rw-r--r--o3d/samples/box2d-3d/demos/draw_world.js90
-rw-r--r--o3d/samples/box2d-3d/demos/manager.js210
-rw-r--r--o3d/samples/box2d-3d/demos/pendulum.js25
-rw-r--r--o3d/samples/box2d-3d/demos/stack.js37
-rw-r--r--o3d/samples/box2d-3d/demos/top.js53
11 files changed, 914 insertions, 0 deletions
diff --git a/o3d/samples/box2d-3d/demos/LICENSE.txt b/o3d/samples/box2d-3d/demos/LICENSE.txt
new file mode 100644
index 0000000..c224b40
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/LICENSE.txt
@@ -0,0 +1,14 @@
+The zlib/libpng License
+
+Copyright (c) 2008 ANDO Yasushi
+
+This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
diff --git a/o3d/samples/box2d-3d/demos/README.o3d b/o3d/samples/box2d-3d/demos/README.o3d
new file mode 100644
index 0000000..2d3f954
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/README.o3d
@@ -0,0 +1,5 @@
+This directory contains a subset of Box2D-JS, available at
+http://box2d-js.sourceforge.net/ under the zlib/libpng license (see
+License.txt).
+The software was modified in certain places to make it work with O3D.
+Individual files are marked to indicate modifications occured.
diff --git a/o3d/samples/box2d-3d/demos/compound.js b/o3d/samples/box2d-3d/demos/compound.js
new file mode 100644
index 0000000..e63b983
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/compound.js
@@ -0,0 +1,71 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+demos.compound = {};
+demos.compound.createCompoundBall = function(world, x, y) {
+ var ballSd1 = new b2CircleDef();
+ ballSd1.density = 1.0;
+ ballSd1.radius = 20;
+ ballSd1.restitution = 0.2;
+ ballSd1.localPosition.Set(-20, 0);
+ var ballSd2 = new b2CircleDef();
+ ballSd2.density = 1.0;
+ ballSd2.radius = 20;
+ ballSd2.restitution = 0.2;
+ ballSd2.localPosition.Set(20, 0);
+ var ballBd = new b2BodyDef();
+ ballBd.AddShape(ballSd1);
+ ballBd.AddShape(ballSd2);
+ ballBd.position.Set(x, y);
+ // NOTE: Added the following line to create a 3d object to display.
+ ballBd.userData = g.mgr.createCompoundCylinder(20, -20, 20, 20);
+ return world.CreateBody(ballBd);
+}
+
+demos.compound.createCompoundPoly = function(world, x, y) {
+ var points = [[-30, 0], [30, 0], [0, 15]];
+ var polySd1 = new b2PolyDef();
+ polySd1.vertexCount = points.length;
+ for (var i = 0; i < points.length; i++) {
+ polySd1.vertices[i].Set(points[i][0], points[i][1]);
+ }
+ polySd1.localRotation = 0.3524 * Math.PI;
+ var R1 = new b2Mat22(polySd1.localRotation);
+ polySd1.localPosition = b2Math.b2MulMV(R1, new b2Vec2(30, 0));
+ polySd1.density = 1.0;
+ var polySd2 = new b2PolyDef();
+ polySd2.vertexCount = points.length;
+ for (var i = 0; i < points.length; i++) {
+ polySd2.vertices[i].Set(points[i][0], points[i][1]);
+ }
+ polySd2.localRotation = -0.3524 * Math.PI;
+ var R2 = new b2Mat22(polySd2.localRotation);
+ polySd2.localPosition = b2Math.b2MulMV(R2, new b2Vec2(-30, 0));
+ var polyBd = new b2BodyDef();
+ polyBd.AddShape(polySd1);
+ polyBd.AddShape(polySd2);
+ polyBd.position.Set(x,y);
+ // NOTE: Added the following line to create a 3d object to display.
+ polyBd.userData = g.mgr.createCompoundWedge(points,
+ polySd1.localPosition,
+ polySd1.localRotation,
+ points,
+ polySd2.localPosition,
+ polySd2.localRotation);
+ return world.CreateBody(polyBd)
+}
+
+demos.compound.initWorld = function(world) {
+ var i;
+ for (i = 1; i <= 4; i++) {
+ demos.compound.createCompoundPoly(world, 150 + 3 * Math.random(), 40 * i);
+ }
+ for (i = 1; i <= 4; i++) {
+ demos.compound.createCompoundBall(world, 350 + 3 * Math.random(), 45 * i);
+ }
+}
+demos.InitWorlds.push(demos.compound.initWorld);
+
+
diff --git a/o3d/samples/box2d-3d/demos/crank.js b/o3d/samples/box2d-3d/demos/crank.js
new file mode 100644
index 0000000..007c1dc
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/crank.js
@@ -0,0 +1,79 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+demos.crank = {};
+demos.crank.initWorld = function(world) {
+ var ground = world.m_groundBody;
+
+ // Define crank.
+ var sd = new b2BoxDef();
+ sd.extents.Set(5, 25);
+ sd.density = 1.0;
+
+ var bd = new b2BodyDef();
+ bd.userData = g.mgr.createBox(5, 25);
+ bd.AddShape(sd);
+
+ var rjd = new b2RevoluteJointDef();
+
+ var prevBody = ground;
+
+ bd.position.Set(500/2, 210);
+ bd.userData = g.mgr.createBox(5, 25);
+ var body = world.CreateBody(bd);
+
+ rjd.anchorPoint.Set(500/2, 235);
+ rjd.body1 = prevBody;
+ rjd.body2 = body;
+ rjd.motorSpeed = -1.0 * Math.PI;
+ rjd.motorTorque = 500000000.0;
+ rjd.enableMotor = true;
+ world.CreateJoint(rjd);
+
+ prevBody = body;
+
+ // Define follower.
+ sd.extents.Set(5, 45);
+ bd.position.Set(500/2, 140);
+ bd.userData = g.mgr.createBox(5, 45);
+ body = world.CreateBody(bd);
+
+ rjd.anchorPoint.Set(500/2, 185);
+ rjd.body1 = prevBody;
+ rjd.body2 = body;
+ rjd.enableMotor = false;
+ world.CreateJoint(rjd);
+
+ prevBody = body;
+
+ // Define piston
+ sd.extents.Set(20, 20);
+ bd.position.Set(500/2, 95);
+ bd.userData = g.mgr.createBox(20, 20);
+ body = world.CreateBody(bd);
+
+ rjd.anchorPoint.Set(500/2, 95);
+ rjd.body1 = prevBody;
+ rjd.body2 = body;
+ world.CreateJoint(rjd);
+
+ var pjd = new b2PrismaticJointDef();
+ pjd.anchorPoint.Set(500/2, 95);
+ pjd.body1 = ground;
+ pjd.body2 = body;
+ pjd.axis.Set(0.0, 1.0);
+ pjd.motorSpeed = 0.0; // joint friction
+ pjd.motorForce = 100000.0;
+ pjd.enableMotor = true;
+
+ world.CreateJoint(pjd);
+
+ // Create a payload
+ sd.density = 2.0;
+ bd.position.Set(500/2, 10);
+ bd.userData = g.mgr.createBox(20, 20);
+ world.CreateBody(bd);
+}
+demos.InitWorlds.push(demos.crank.initWorld);
diff --git a/o3d/samples/box2d-3d/demos/demo_base.js b/o3d/samples/box2d-3d/demos/demo_base.js
new file mode 100644
index 0000000..3379691
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/demo_base.js
@@ -0,0 +1,59 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+function createWorld() {
+ var worldAABB = new b2AABB();
+ worldAABB.minVertex.Set(-1000, -1000);
+ worldAABB.maxVertex.Set(1000, 1000);
+ var gravity = new b2Vec2(0, 300);
+ var doSleep = true;
+ var world = new b2World(worldAABB, gravity, doSleep);
+ createGround(world);
+ createBox(world, 0, 125, 10, 250);
+ createBox(world, 500, 125, 10, 250);
+ return world;
+}
+
+function createGround(world) {
+ var groundSd = new b2BoxDef();
+ groundSd.extents.Set(250, 50);
+ groundSd.restitution = 0.2;
+ var groundBd = new b2BodyDef();
+ groundBd.AddShape(groundSd);
+ groundBd.position.Set(250, 340);
+ // NOTE: Added the following line to create a 3d object to display.
+ groundBd.userData = g.mgr.createBox(250, 50);
+ return world.CreateBody(groundBd)
+}
+
+function createBall(world, x, y) {
+ var ballSd = new b2CircleDef();
+ ballSd.density = 1.0;
+ ballSd.radius = 20;
+ ballSd.restitution = 1.0;
+ ballSd.friction = 0;
+ var ballBd = new b2BodyDef();
+ ballBd.AddShape(ballSd);
+ ballBd.position.Set(x,y);
+ // NOTE: Added the following line to create a 3d object to display.
+ ballBd.userData = g.mgr.createCylinder(ballSd.radius);
+ return world.CreateBody(ballBd);
+}
+
+function createBox(world, x, y, width, height, fixed) {
+ if (typeof(fixed) == 'undefined') fixed = true;
+ var boxSd = new b2BoxDef();
+ if (!fixed) boxSd.density = 1.0;
+ boxSd.extents.Set(width, height);
+ var boxBd = new b2BodyDef();
+ // NOTE: Added the following line to create a 3d object to display.
+ boxBd.userData = g.mgr.createBox(width, height);
+ boxBd.AddShape(boxSd);
+ boxBd.position.Set(x,y);
+ return world.CreateBody(boxBd)
+}
+
+var demos = {};
+demos.InitWorlds = [];
diff --git a/o3d/samples/box2d-3d/demos/demos.js b/o3d/samples/box2d-3d/demos/demos.js
new file mode 100644
index 0000000..8834790
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/demos.js
@@ -0,0 +1,271 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+o3djs.require('o3djs.util');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.primitives');
+o3djs.require('o3djs.picking');
+
+var initId = 0;
+var world;
+var canvasWidth;
+var canvasHeight;
+var canvasTop;
+var canvasLeft;
+
+function setupWorld(did) {
+ var transforms = g.client.getObjectsByClassName('o3d.Transform');
+ for (var tt = 0; tt < transforms.length; ++tt) {
+ var transform = transforms[tt];
+ if (transform.clientId != g.root.clientId &&
+ transform.clientId != g.client.root.clientId) {
+ transform.parent = null;
+ g.pack.removeObject(transform);
+ }
+ }
+ if (!did) did = 0;
+ world = createWorld();
+ initId += did;
+ initId %= demos.InitWorlds.length;
+ if (initId < 0) initId = demos.InitWorlds.length + initId;
+ demos.InitWorlds[initId](world);
+}
+function setupNextWorld() { setupWorld(1); }
+function setupPrevWorld() { setupWorld(-1); }
+function step(elapsedTime) {
+ // NOTE: changed to use the renderEvent's elapsed time instead of
+ // javascript timers. The check below makes the physics never do a time step
+ // slower that 1/30th of a second because collision bugs will happen.
+ if (elapsedTime > 1 / 30) {
+ elapsedTime = 1 / 30;
+ }
+ var stepping = false;
+ var timeStep = elapsedTime;
+ var iteration = 1;
+ if (world) {
+ world.Step(timeStep, iteration);
+ drawWorld(world);
+ }
+}
+
+// When the sample is running in V8, window.g is the browser's global object and
+// g is v8's. When the sample is running only in the browser, they are the same
+// object.
+window.g = {};
+
+// A global object to track stuff with.
+var g = {
+ o3dWidth: -1, // width of our client area
+ o3dHeight: -1, // height of our client area
+ materials: [], // all our materials
+ shapes: [] // all our shapes
+};
+
+/**
+ * Sets up the o3d stuff.
+ * @param {HTML element} o3dElement The o3d object element.
+ */
+function setupO3D(o3dElement) {
+ // Initializes global variables and libraries.
+ g.o3dElement = o3dElement;
+ g.o3d = o3dElement.o3d;
+ g.math = o3djs.math;
+ g.client = o3dElement.client;
+ g.mgr = new O3DManager();
+
+ // The browser needs to be able to see these globals so that it can
+ // call unload later.
+ window.g.client = g.client;
+
+ // Get the width and height of our client area.
+ g.o3dWidth = g.client.width;
+ g.o3dHeight = g.client.height;
+
+ // Creates a pack to manage our resources/assets
+ g.pack = g.client.createPack();
+
+ // Create the render graph for a view.
+ g.viewInfo = o3djs.rendergraph.createBasicView(
+ g.pack,
+ g.client.root,
+ g.client.renderGraphRoot);
+
+ // Create an object to hold global params.
+ g.globalParamObject = g.pack.createObject('ParamObject');
+ g.lightWorldPosParam = g.globalParamObject.createParam('lightWorldPos',
+ 'ParamFloat3');
+ g.lightColorParam = g.globalParamObject.createParam('lightColor',
+ 'ParamFloat4');
+ g.lightWorldPosParam.value = [200, -1500, -1000];
+ g.lightColorParam.value = [1, 1, 1.0, 1.0];
+
+ // Create Materials.
+ g.materials = [];
+ var material = g.pack.createObject('Material');
+ var effect = g.pack.createObject('Effect');
+ effect.loadFromFXString(document.getElementById('shader').value);
+ material.effect = effect;
+ effect.createUniformParameters(material);
+ material.getParam('lightWorldPos').bind(g.lightWorldPosParam);
+ material.getParam('lightColor').bind(g.lightColorParam);
+ material.getParam('emissive').set(0, 0, 0, 1);
+ material.getParam('ambient').set(0, 0, 0, 1);
+ material.getParam('specular').set(1, 1, 1, 1);
+ material.getParam('shininess').value = 20;
+ material.drawList = g.viewInfo.performanceDrawList;
+ g.materials[0] = material;
+
+ // Create a kind of checkboardish texture.
+ var pixels = [];
+ for (var y = 0; y < 32; ++y) {
+ for (var x = 0; x < 32; ++x) {
+ var offset = (y * 32 + x) * 3; // rgb
+ var u = x / 32 * Math.PI * 0.5;
+ var v = y / 32 * Math.PI * 0.5;
+ pixels[offset + 0] = 1;//Math.sin(Math.PI * 32 / x) * 0.2 + 0.8; // red
+ pixels[offset + 1] = Math.floor(x / 8) % 2 * 0.2 + 0.8; // green
+ pixels[offset + 2] = Math.floor(y / 8) % 2 * 0.5 + 0.5; // blue
+ }
+ }
+ var texture = g.pack.createTexture2D(32, 32, g.o3d.Texture.XRGB8, 1, false);
+ texture.set(0, pixels);
+ var samplerParam = material.getParam('diffuseSampler');
+ var sampler = g.pack.createObject('Sampler');
+ samplerParam.value = sampler;
+ sampler.texture = texture;
+
+ // Creates a transform to put our data on.
+ g.root = g.pack.createObject('Transform');
+ g.root.parent = g.client.root;
+
+ // make a cube for drawing lines
+ g.lineShape = o3djs.primitives.createRainbowCube(
+ g.pack,
+ g.materials[0],
+ 1,
+ g.math.matrix4.translation([0, 0.5, 0]));
+
+ // Set the projection matrix
+ g.viewInfo.drawContext.projection = g.math.matrix4.perspective(
+ g.math.degToRad(45),
+ g.o3dWidth / g.o3dHeight,
+ 0.1,
+ 10000);
+
+ // Set the view matrix.
+ g.viewInfo.drawContext.view = g.math.matrix4.lookAt(
+ [100, -50, -600],
+ [250, 80, 0],
+ [0, -1, 0]);
+
+ // Make copies of the view and projection matrix to get fast access to them.
+ g.projectionMatrix = g.math.matrix4.copy(g.viewInfo.drawContext.projection);
+ g.viewMatrix = g.math.matrix4.copy(g.viewInfo.drawContext.view);
+
+ // Make a bounding box to use for picking.
+ g.worldBox = g.o3d.BoundingBox([0, -100, 0],
+ [500, 250, 5]);
+
+ // Steps the physics with a time of zero. This is left over from the orignial
+ // code.
+ step(0);
+
+ g.client.setRenderCallback(o3dOnRender);
+}
+
+/**
+ * Called just before rendering each frame.
+ * @param {o3d.RenderEvent} renderEvent The render event passed by
+ * o3d.
+ */
+function o3dOnRender(renderEvent) {
+ var newWidth = g.client.width;
+ var newHeight = g.client.height;
+ if (newWidth != g.o3dWidth || newHeight != g.o3dHeight) {
+ g.o3dWidth = newWidth;
+ g.o3dHeight = newHeight;
+
+ // Adjust the projection matrix.
+ var projectionMatrix = g.math.matrix4.perspective(g.math.degToRad(45),
+ g.o3dWidth / g.o3dHeight,
+ 0.1,
+ 10000);
+ g.viewInfo.drawContext.projection = projectionMatrix;
+ g.projectionMatrix = projectionMatrix;
+ }
+ step(renderEvent.elapsedTime);
+}
+
+/**
+ * This is the original setup code modified to work with o3d.
+ * @param {Array} clientElements Array of o3d objects.
+ */
+function setupStep2(clientElements) {
+ var canvasElm = clientElements[0];
+ canvasElm.id = 'canvas';
+ setupO3D(canvasElm);
+ setupWorld();
+ canvasWidth = g.client.width;
+ canvasHeight = g.client.height;
+ canvasTop = parseInt(canvasElm.style.top);
+ canvasLeft = parseInt(canvasElm.style.left);
+ o3djs.event.addEventListener(canvasElm, 'mousedown', function(e) {
+ if (e.shiftKey || e.button == g.o3d.Event.BUTTON_RIGHT) {
+ setupPrevWorld();
+ } else {
+ createNewRandomObject(world, e);
+ }
+ });
+
+ window.g_finished = true; // for selenium
+}
+
+/**
+ * Creates a new random object using 3d picking to figure out where to start it.
+ * @param {Object} world A B2World object.
+ * @param {Object} offset Mouse position relative to o3d area.
+ */
+function createNewRandomObject(world, offset) {
+ var worldRay = o3djs.picking.clientPositionToWorldRayEx(
+ offset.x,
+ offset.y,
+ g.viewMatrix,
+ g.projectionMatrix,
+ g.o3dWidth,
+ g.o3dHeight);
+ var rayIntersectionInfo = g.worldBox.intersectRay(worldRay.near,
+ worldRay.far);
+ if (rayIntersectionInfo.intersected) {
+ var position = rayIntersectionInfo.position;
+ if (Math.random() < 0.5) {
+ demos.top.createBall(world, position[0], position[1]);
+ } else {
+ createBox(world, position[0], position[1], 10, 10, false);
+ }
+ }
+}
+
+function init() {
+ window.g_finished = false; // for selenium.
+
+ // Runs the sample in V8. Comment out this line to run it in the browser
+ // JavaScript engine, for example if you want to debug it. This sample cannot
+ // currently run in V8 on IE because it access the DOM.
+ if (!o3djs.base.IsMSIE()) {
+ o3djs.util.setMainEngine(o3djs.util.Engine.V8);
+ o3djs.util.addScriptUri('third_party');
+ o3djs.util.addScriptUri('demos');
+ o3djs.util.addScriptUri('style');
+ }
+
+ o3djs.util.makeClients(setupStep2);
+}
+
+function uninit() {
+ if (g.client) {
+ g.client.cleanup();
+ }
+}
diff --git a/o3d/samples/box2d-3d/demos/draw_world.js b/o3d/samples/box2d-3d/demos/draw_world.js
new file mode 100644
index 0000000..b49ef1a
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/draw_world.js
@@ -0,0 +1,90 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+// NOTE: Changed this file pretty significantly. The original uses a
+// canvas element and drew lines on it. This one just updates the positions and
+// orientations of o3d objects to match the physics as well as using a
+// scaled box to stand in for joints.
+
+/**
+ * Draws all the object in the world.
+ * @param {Object} world A B2World object managing the physics world.
+ */
+function drawWorld(world) {
+ for (var j = world.m_jointList; j; j = j.m_next) {
+ drawJoint(j);
+ }
+ for (var b = world.m_bodyList; b; b = b.m_next) {
+ var o3dShape = b.GetUserData();
+ if (o3dShape) {
+ o3dShape.updateTransform(b);
+ }
+ }
+}
+/**
+ * Scales a joint transform to represnet a line.
+ * @param {Object} transformInfo An object with o3d information for the
+ * joint.
+ * @param {Object} p1 An object with x and y fields that specify the origin of
+ * the joint in 2d.
+ * @param {Object} p2 An object with x an dy fields that specify the far end of
+ * the joint in 2d.
+ */
+function scaleJointTransform(transformInfo, p1, p2) {
+ var dx = p2.x - p1.x;
+ var dy = p2.y - p1.y;
+ var length = Math.sqrt(dx * dx + dy * dy);
+ var transform = transformInfo.transform;
+ transform.identity();
+ transform.translate(p1.x, p1.y, 0);
+ transform.rotateZ(Math.atan2(-dx, dy));
+ transform.scale(2, length, 2);
+}
+
+/**
+ * Draws a joint
+ * @param {Object} joint A b2Joint object representing a joint.
+ */
+function drawJoint(joint) {
+ var transformInfo = joint.m_o3dTransformInfo;
+ if (!transformInfo) {
+ // This joint did not already have something in o3d to represent it
+ // so we create one here.
+ var transform = g.pack.createObject('Transform');
+ transform.parent = g.root;
+ transform.addShape(g.lineShape);
+ transformInfo = {
+ transform: transform
+ };
+ joint.m_o3dTransformInfo = transformInfo;
+ }
+ var b1 = joint.m_body1;
+ var b2 = joint.m_body2;
+ var x1 = b1.m_position;
+ var x2 = b2.m_position;
+ var p1 = joint.GetAnchor1();
+ var p2 = joint.GetAnchor2();
+ switch (joint.m_type) {
+ case b2Joint.e_distanceJoint:
+ scaleJointTransform(transformInfo, p1, p2);
+ break;
+
+ case b2Joint.e_pulleyJoint:
+ break;
+
+ default:
+ if (b1 == world.m_groundBody) {
+ scaleJointTransform(transformInfo, p1, x2);
+ }
+ else if (b2 == world.m_groundBody) {
+ scaleJointTransform(transformInfo, p1, x1);
+ }
+ else {
+ scaleJointTransform(transformInfo, x1, x2);
+ }
+ break;
+ }
+}
+
diff --git a/o3d/samples/box2d-3d/demos/manager.js b/o3d/samples/box2d-3d/demos/manager.js
new file mode 100644
index 0000000..8fc177b
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/manager.js
@@ -0,0 +1,210 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+/**
+ * O3DManager manages o3d objects for this demo.
+ * @constructor
+ */
+function O3DManager() {
+ this.shapes = [];
+}
+
+/**
+ * Gets or creates a cylinder shape. If a cylinder of the same radius already
+ * exists that one will be returned, otherwise a new one will be created.
+ * @param {number} radius Radius of cylinder to create.
+ * @return {o3d.Shape} The shape.
+ */
+O3DManager.prototype.createCylinder = function(radius) {
+ var id = 'cylinder-' + radius;
+ var shape = this.shapes[id];
+ if (!shape) {
+ shape = o3djs.primitives.createCylinder(g.pack,
+ g.materials[0],
+ radius, 40, 20, 1,
+ [[1, 0, 0, 0],
+ [0, 0, 1, 0],
+ [0, -1, 0, 0],
+ [0, 0, 0, 1]]);
+ this.shapes[id] = shape;
+ }
+ return new O3DShape({shape: shape});
+};
+
+/**
+ * Gets or creates a compound cylinder shape. If a compound cylinder shape of
+ * the same parameters already exists that one will be returned, otherwise a new
+ * one will be created.
+ * @param {number} radius1 Radius of first cylinder.
+ * @param {number} offset1 X Offset for first cylinder.
+ * @param {number} radius2 Radius of second cylinder.
+ * @param {number} offset2 X Offset for second cylinder.
+ * @return {o3d.Shape} The shape.
+ */
+O3DManager.prototype.createCompoundCylinder = function(radius1,
+ offset1,
+ radius2,
+ offset2) {
+ var id = 'compoundCylinder-' + radius1 + '-' + offset1 +
+ '-' + radius2 + '-' + offset2;
+ var shape = this.shapes[id];
+ if (!shape) {
+ shape = o3djs.primitives.createCylinder(
+ g.pack, g.materials[0], radius1, 40, 20, 1,
+ [[1, 0, 0, 0],
+ [0, 0, 1, 0],
+ [0, -1, 0, 0],
+ [offset1, 0, 0, 1]]);
+ shape2 = o3djs.primitives.createCylinder(
+ g.pack, g.materials[0], radius2, 40, 20, 1,
+ [[1, 0, 0, 0],
+ [0, 0, 1, 0],
+ [0, -1, 0, 0],
+ [offset2, 0, 0, 1]]);
+ shape2.elements[0].owner = shape;
+ g.pack.removeObject(shape2);
+ this.shapes[id] = shape;
+ }
+ return new O3DShape({shape: shape});
+};
+
+/**
+ * Gets or creates a box shape. If a box of the same width and height already
+ * exists that one will be returned, otherwise a new one will be created.
+ * @param {number} width Width of box.
+ * @param {number} height Height of box.
+ * @return {o3d.Shape} The shape.
+ */
+O3DManager.prototype.createBox = function(width, height) {
+ var name = 'box-' + width + '-' + height;
+ var shape = this.shapes[name];
+ if (!shape) {
+ shape = o3djs.primitives.createBox(g.pack,
+ g.materials[0],
+ width * 2, height * 2, 40);
+ this.shapes[name] = shape;
+ }
+ return new O3DShape({shape: shape});
+};
+
+/**
+ * Gets or creates a wedge shape. If a wedge of the same parametrs already
+ * exists that one will be returned, otherwise a new one will be created.
+ * @param {Array} points Array of points in the format
+ * [[x1, y1], [x2, y2], [x3, y3]] that describe a 2d triangle.
+ * @return {o3d.Shape} The shape.
+ */
+O3DManager.prototype.createWedge = function(points) {
+ var name = 'wedge';
+ for (var pp = 0; pp < points.length; ++pp) {
+ name += '-' + points[pp][0] + '-' + points[pp][1];
+ }
+ var shape = this.shapes[name];
+ if (!shape) {
+ shape = o3djs.primitives.createPrism(g.pack,
+ g.materials[0],
+ points, 40);
+ this.shapes[name] = shape;
+ }
+ return new O3DShape({shape: shape});
+};
+
+/**
+ * Gets or creates a compound wedge shape (2 wedges). If a compound wedge of the
+ * same parametrs already exists that one will be returned, otherwise a new one
+ * will be created.
+ * @param {Array} points1 Array of points that describe a 2d triangle for the
+ * first wedge in the format [[x1, y1], [x2, y2], [x3, y3]] .
+ * @param {Object} position1 An object with x and y properties used to offset
+ * the first wedge.
+ * @param {number} rotation1 Rotation in radians to rotate the first wedge on
+ * the z axis.
+ * @param {Array} points2 Array of points that describe a 2d triangle for the
+ * second wedge in the format [[x1, y1], [x2, y2], [x3, y3]] .
+ * @param {Object} position2 An object with x and y properties used to offset
+ * the second wedge.
+ * @param {number} rotation2 Rotation in radians to rotate the second wedge on
+ * the z axis.
+ * @return {o3d.Shape} The shape.
+ */
+O3DManager.prototype.createCompoundWedge = function(points1,
+ position1,
+ rotation1,
+ points2,
+ position2,
+ rotation2) {
+ var name = 'compoundWedge';
+ for (var pp = 0; pp < points1.length; ++pp) {
+ name += '-' + points1[pp][0] + '-' + points1[pp][1];
+ }
+ name += '-' + position1.x + '-' + position1.y + '-' + rotation1;
+ for (var pp = 0; pp < points2.length; ++pp) {
+ name += '-' + points2[pp][0] + '-' + points2[pp][1];
+ }
+ name += '-' + position2.x + '-' + position2.y + '-' + rotation2;
+ var shape = this.shapes[name];
+ if (!shape) {
+ shape = o3djs.primitives.createPrism(
+ g.pack,
+ g.materials[0],
+ points1,
+ 40,
+ g.math.matrix4.mul(
+ g.math.matrix4.rotationZ(rotation1),
+ g.math.matrix4.translation([position1.x, position1.y, 0])));
+ shape2 = o3djs.primitives.createPrism(
+ g.pack,
+ g.materials[0],
+ points2,
+ 40,
+ g.math.matrix4.mul(
+ g.math.matrix4.rotationZ(rotation2),
+ g.math.matrix4.translation([position2.x, position2.y, 0])));
+ shape2.elements[0].owner = shape;
+ g.pack.removeObject(shape2);
+ this.shapes[name] = shape;
+ }
+ return new O3DShape({shape: shape});
+};
+
+/**
+ * An O3DShape manages an O3D shape for the demo.
+ * @constructor
+ * @param {Object} spec An object that contains the fields needed to create the
+ * O3DShape. Currently only the field "shape" is needed.
+ */
+function O3DShape(spec) {
+ this.init(spec);
+}
+
+/**
+ * Initializes an O3DShape
+ * @param {Object} spec An object that contains the fields needed to create the
+ * O3DShape. Currently only the field "shape" is needed.
+ */
+O3DShape.prototype.init = function(spec) {
+ this.transform = g.pack.createObject('Transform');
+ this.transform.parent = g.root;
+ this.transform.addShape(spec.shape);
+ this.transform.createParam('colorMult', 'ParamFloat4').value =
+ [Math.random() * 0.8 + 0.2,
+ Math.random() * 0.8 + 0.2,
+ Math.random() * 0.8 + 0.2,
+ 1];
+};
+
+/**
+ * Updates the position and orientation of an O3DShape.
+ * @param {Object} body A B2Body object from the Box2djs library.
+ */
+O3DShape.prototype.updateTransform = function(body) {
+ var transform = this.transform;
+ var position = body.GetOriginPosition();
+ transform.identity();
+ transform.translate(position.x, position.y, 0);
+ transform.rotateZ(body.GetRotation());
+};
+
+
diff --git a/o3d/samples/box2d-3d/demos/pendulum.js b/o3d/samples/box2d-3d/demos/pendulum.js
new file mode 100644
index 0000000..730d039
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/pendulum.js
@@ -0,0 +1,25 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+demos.pendulum = {};
+demos.pendulum.initWorld = function(world) {
+ var i;
+ var ground = world.GetGroundBody();
+ var jointDef = new b2RevoluteJointDef();
+ var L = 150;
+ for (i = 0; i < 4; i++) {
+ jointDef.anchorPoint.Set(250 + 40 * i, 200 - L);
+ jointDef.body1 = ground;
+ jointDef.body2 = createBall(world, 250 + 40 * i, 200);
+ world.CreateJoint(jointDef);
+ }
+ jointDef.anchorPoint.Set(250 - 40, 200 - L);
+ jointDef.body1 = ground;
+ jointDef.body2 = createBall(world, 250 - 40 - L, 200 - L);
+ world.CreateJoint(jointDef);
+}
+demos.InitWorlds.push(demos.pendulum.initWorld);
+
+
diff --git a/o3d/samples/box2d-3d/demos/stack.js b/o3d/samples/box2d-3d/demos/stack.js
new file mode 100644
index 0000000..ffee25b
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/stack.js
@@ -0,0 +1,37 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+demos.stack = {};
+demos.stack.initWorld = function(world) {
+ var sd = new b2BoxDef();
+ var bd = new b2BodyDef();
+ bd.AddShape(sd);
+ sd.density = 1.0;
+ sd.friction = 0.5;
+ sd.extents.Set(10, 10);
+
+ var i;
+ for (i = 0; i < 8; i++) {
+ bd.position.Set(500/2-Math.random()*2-1, (250-5-i*22));
+ // NOTE: Added the following line to create a 3d object to display.
+ bd.userData = g.mgr.createBox(10, 10);
+ world.CreateBody(bd);
+ }
+ for (i = 0; i < 8; i++) {
+ bd.position.Set(500/2-100-Math.random()*5+i, (250-5-i*22));
+ // NOTE: Added the following line to create a 3d object to display.
+ bd.userData = g.mgr.createBox(10, 10);
+ world.CreateBody(bd);
+ }
+ for (i = 0; i < 8; i++) {
+ bd.position.Set(500/2+100+Math.random()*5-i, (250-5-i*22));
+ // NOTE: Added the following line to create a 3d object to display.
+ bd.userData = g.mgr.createBox(10, 10);
+ world.CreateBody(bd);
+ }
+}
+demos.InitWorlds.push(demos.stack.initWorld);
+
+
diff --git a/o3d/samples/box2d-3d/demos/top.js b/o3d/samples/box2d-3d/demos/top.js
new file mode 100644
index 0000000..e569e7e
--- /dev/null
+++ b/o3d/samples/box2d-3d/demos/top.js
@@ -0,0 +1,53 @@
+// This file comes from Box2D-JS, Copyright (c) 2008 ANDO Yasushi.
+// The original version is available at http://box2d-js.sourceforge.net/ under the
+// zlib/libpng license (see License.txt).
+// This version has been modified to make it work with O3D.
+
+demos.top = {};
+demos.top.createBall = function(world, x, y, rad, fixed) {
+ var ballSd = new b2CircleDef();
+ if (!fixed) ballSd.density = 1.0;
+ ballSd.radius = rad || 10;
+ ballSd.restitution = 0.2;
+ var ballBd = new b2BodyDef();
+ ballBd.AddShape(ballSd);
+ ballBd.position.Set(x,y);
+ // NOTE: Added the following line to create a 3d object to display.
+ ballBd.userData = g.mgr.createCylinder(ballSd.radius);
+ return world.CreateBody(ballBd);
+};
+demos.top.createPoly = function(world, x, y, points, fixed) {
+ var polySd = new b2PolyDef();
+ if (!fixed) polySd.density = 1.0;
+ polySd.vertexCount = points.length;
+ for (var i = 0; i < points.length; i++) {
+ polySd.vertices[i].Set(points[i][0], points[i][1]);
+ }
+ var polyBd = new b2BodyDef();
+ if (points.length == 3) {
+ // NOTE: Added the following line to create a 3d object to display.
+ polyBd.userData = g.mgr.createWedge(points);
+ }
+ polyBd.AddShape(polySd);
+ polyBd.position.Set(x,y);
+ return world.CreateBody(polyBd)
+};
+demos.top.initWorld = function(world) {
+ demos.top.createBall(world, 350, 100, 50, true);
+ demos.top.createPoly(world, 100, 100, [[0, 0], [10, 30], [-10, 30]], true);
+ demos.top.createPoly(world, 150, 150, [[0, 0], [10, 30], [-10, 30]], true);
+ var pendulum = createBox(world, 150, 100, 20, 20, false);
+ var jointDef = new b2RevoluteJointDef();
+ jointDef.body1 = pendulum;
+ jointDef.body2 = world.GetGroundBody();
+ jointDef.anchorPoint = pendulum.GetCenterPosition();
+ world.CreateJoint(jointDef);
+
+ var seesaw = demos.top.createPoly(world, 300, 200, [[0, 0], [100, 30], [-100, 30]]);
+ jointDef.body1 = seesaw;
+ jointDef.anchorPoint = seesaw.GetCenterPosition();
+ world.CreateJoint(jointDef);
+};
+demos.InitWorlds.push(demos.top.initWorld);
+
+