Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

wip bullet/webgl demo

  • Loading branch information...
commit 98a9576c6e3c357960bd7741f9e0ad964f206e29 1 parent 54b3d3e
@azakai azakai authored
View
142 demos/webgl/HelloWorld.cpp
@@ -0,0 +1,142 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2007 Erwin Coumans http://continuousphysics.com/Bullet/
+
+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.
+*/
+
+
+#include "btBulletDynamicsCommon.h"
+#include <stdio.h>
+
+/// This is a Hello World program for running a basic Bullet physics simulation
+
+ btDefaultCollisionConfiguration* zz_collisionConfiguration;
+ btCollisionDispatcher* zz_dispatcher;
+ btBroadphaseInterface* zz_overlappingPairCache;
+ btSequentialImpulseConstraintSolver* zz_solver;
+ btDiscreteDynamicsWorld* zz_dynamicsWorld;
+
+void zz_prepare()
+{
+
+ int i;
+
+ ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration.
+ zz_collisionConfiguration = new btDefaultCollisionConfiguration();
+
+ ///use the default collision zz_dispatcher. For parallel processing you can use a diffent zz_dispatcher (see Extras/BulletMultiThreaded)
+ zz_dispatcher = new btCollisionDispatcher(zz_collisionConfiguration);
+
+ ///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
+ zz_overlappingPairCache = new btDbvtBroadphase();
+
+ ///the default constraint zz_solver. For parallel processing you can use a different zz_solver (see Extras/BulletMultiThreaded)
+ zz_solver = new btSequentialImpulseConstraintSolver;
+
+ zz_dynamicsWorld = new btDiscreteDynamicsWorld(zz_dispatcher,zz_overlappingPairCache,zz_solver,zz_collisionConfiguration);
+
+ zz_dynamicsWorld->setGravity(btVector3(0,-10,0));
+
+ ///create a few basic rigid bodies
+ btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(btScalar(0.),btScalar(1.),btScalar(0.)), 0);
+
+ btTransform groundTransform;
+ groundTransform.setIdentity();
+ groundTransform.setOrigin(btVector3(0,-6,0));
+
+ {
+ btScalar mass(0.);
+
+ //rigidbody is dynamic if and only if mass is non zero, otherwise static
+ bool isDynamic = (mass != 0.f);
+
+ btVector3 localInertia(0,0,0);
+ if (isDynamic)
+ groundShape->calculateLocalInertia(mass,localInertia);
+
+ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+
+ //add the body to the dynamics world
+ zz_dynamicsWorld->addRigidBody(body);
+ }
+
+
+ for (int i = 0; i < 5; i++)
+ {
+ //create a dynamic rigidbody
+
+ btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1));
+ //btCollisionShape* colShape = new btSphereShape(btScalar(1.));
+
+ /// Create Dynamic Objects
+ btTransform startTransform;
+ startTransform.setIdentity();
+
+ btScalar mass(1.f);
+
+ //rigidbody is dynamic if and only if mass is non zero, otherwise static
+ bool isDynamic = (mass != 0.f);
+
+ btVector3 localInertia(0,0,0);
+ if (isDynamic)
+ colShape->calculateLocalInertia(mass,localInertia);
+
+ startTransform.setOrigin(btVector3(0,4+i*2.1,0));
+
+ //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
+ btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
+ btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
+ btRigidBody* body = new btRigidBody(rbInfo);
+
+ zz_dynamicsWorld->addRigidBody(body);
+ }
+}
+
+
+/// Do some simulation
+
+
+void zz_simulate(float diff) {
+ zz_dynamicsWorld->stepSimulation(diff);
+}
+
+void zz_read(int j, btVector3& location, btQuaternion& rotation)
+{
+ {
+ btCollisionObject* obj = zz_dynamicsWorld->getCollisionObjectArray()[j];
+ btRigidBody* body = btRigidBody::upcast(obj);
+ if (body && body->getMotionState())
+ {
+ btTransform trans;
+ body->getMotionState()->getWorldTransform(trans);
+ location = trans.getOrigin();
+ rotation = trans.getRotation();
+ //printf("world pos = %.5f,%.5f,%.5f\n",float(location.getX()),float(location.getY()),float(location.getZ()));
+ }
+ }
+}
+
+int main(int argc, char** argv)
+{
+ zz_prepare();
+ zz_simulate(1/60.);//new btVector3);
+ btVector3 location;
+ btQuaternion rotation;
+ zz_read(1, location, rotation);
+ printf("world pos = %.5f,%.5f,%.5f rot=%.5f,%.5f,%.5f,%.5f\n",float(location.getX()),float(location.getY()),float(location.getZ()),
+ float(rotation.getX()), float(rotation.getY()), float(rotation.getZ()), float(rotation.getW())
+ );
+}
+
View
9 demos/webgl/README.txt
@@ -0,0 +1,9 @@
+work-in-progress demo with bullet and webgl (glge)
+
+run ./server.sh (chrome does not like XHR on file://), then run one of
+
+ google-chrome --enable-webgl 127.0.0.1:8991/demo.html
+ firefox 127.0.0.1:8991/demo.html
+
+(for firefox, requires beta7, preferably minefield/nightly builds).
+
View
206,722 demos/webgl/bullet.js
206,722 additions, 0 deletions not shown
View
31 demos/webgl/bullet_demo.js
@@ -0,0 +1,31 @@
+print = alert;
+
+function prepareBulletDemo() {
+ Bullet.__Z10zz_preparev();
+}
+
+function simulateBulletDemo(dt) {
+ Bullet.__Z11zz_simulatef(dt);
+}
+
+var tempVector3 = Bullet._.btVector3.__new__();
+var tempQuaternion = Bullet._malloc(50);
+
+function readBulletObject(i) {
+ Bullet.__Z7zz_readiR9btVector3R12btQuaternion(i, tempVector3, tempQuaternion);
+ return [ Bullet.FHEAP[Bullet._.btVector3.getX(tempVector3)],
+ Bullet.FHEAP[Bullet._.btVector3.getY(tempVector3)],
+ Bullet.FHEAP[Bullet._.btVector3.getZ(tempVector3)],
+ Bullet.FHEAP[Bullet.__ZNK10btQuadWord4getXEv(tempQuaternion)],
+ Bullet.FHEAP[Bullet.__ZNK10btQuadWord4getYEv(tempQuaternion)],
+ Bullet.FHEAP[Bullet.__ZNK10btQuadWord4getZEv(tempQuaternion)],
+ Bullet.FHEAP[Bullet.__ZNK12btQuaternion4getWEv(tempQuaternion)] ];
+//print('pSIm: ' + Bullet.FHEAP[Bullet._.btVector3.getX(_t)] + ',' + Bullet.FHEAP[Bullet._.btVector3.getY(_t)] + ',' + Bullet.FHEAP[Bullet._.btVector3.getZ(_t)]);
+}
+
+function applyBulletObject(glgeObject, bulletObject) {
+//alert(bulletObject);
+ glgeObject.setLoc.apply(glgeObject, bulletObject.slice(0,3));
+ glgeObject.setQuat.apply(glgeObject, bulletObject.slice(3,7));
+}
+
View
80 demos/webgl/demo.html
@@ -0,0 +1,80 @@
+<html>
+ <head>
+ <title>Bullet/WebGL Demo</title>
+ <script type="text/javascript" src="glge_math.js"></script>
+ <script type="text/javascript" src="glge.js"></script>
+ <script type="text/javascript" src="bullet.js"></script>
+ <script ty[e="text/javascript" src="bullet_demo.js"></script>
+ <style type="text/css">
+ body { background-color: #eee; }
+ </style>
+ </head>
+ <body>
+ <center>
+ <canvas id="canvas" width="500" height="500"></canvas>
+ <script type="text/javascript">
+ var doc = new GLGE.Document();
+
+ doc.onLoad = function() {
+ prepareBulletDemo();
+
+ var boxes = [];
+
+ function simulatePhysics(diff) {
+ simulateBulletDemo(diff);
+ for (var i = 0; i < 5; i++)
+ applyBulletObject(boxes[i], readBulletObject(i+1));
+ }
+
+ var renderer = new GLGE.Renderer(document.getElementById("canvas"));
+ var scene = doc.getElement("mainscene");
+ renderer.setScene(scene);
+
+ var mesh = doc.getElement("Box");
+ for (var i = 0; i < 5; i++) {
+ var box = new GLGE.Object('box_' + i);
+ box.setMesh(mesh);
+ box.setMaterial(doc.getElement("boxmaterial" + (i%2 == 0 ? 1 : 3)));
+ box.setId('box_' + i);
+ box.setLoc(i*2, 10, 0);
+ box.setScale(1, 1, 1);
+ scene.addChild(box);
+ boxes.push(box);
+ }
+
+ var t = Date.now();
+ var lastHUD = 0;
+ var diffs = 0, num = 0;
+ function render() {
+ var now = Date.now();
+ var diff = (now - t)/1000;
+
+ // Simulate
+ simulatePhysics(diff);
+
+ // Render
+ renderer.render();
+
+ // Show FPS
+ diffs += diff;
+ num++;
+ if (now - lastHUD > 250) {
+ document.getElementById('out').innerHTML = '<b>FPS:' + Math.ceil(1/(diffs/num)) + '</b>';
+ lastHUD = now;
+ diffs = 0;
+ num = 0;
+ }
+ t = now;
+ }
+
+ setInterval(render, 1000/60.);
+ }
+
+ doc.load("http://127.0.0.1:8991/scene.xml");
+ </script>
+ <br><br>
+ <div id="out">waka</div>
+ </center>
+ </body>
+</html>
+
View
14 demos/webgl/doit.sh
@@ -0,0 +1,14 @@
+echo "gccing... (run me in bullet/demos/HelloWorld)"
+~/Dev/llvm-gcc-4.2-2.8.source/cbuild/install/bin/llvm-g++ -c HelloWorld.cpp -I../../src -emit-llvm -o HelloWorld.o
+#echo "linking..."
+#~/Dev/llvm-2.8/cbuild/Release/bin/llvm-link HelloWorld.o /dev/shm/tmp/libBullet.bc -o /dev/shm/tmp/bulletTest.bc
+#echo "dissing..."
+#~/Dev/llvm-2.8/cbuild/Release/bin/llvm-dis -show-annotations /dev/shm/tmp/bulletTest.bc
+#echo "emscriptening..."
+#python ~/Dev/emscripten/emscripten.py /dev/shm/tmp/bulletTest.ll > /dev/shm/tmp/bulletTest.js
+
+echo "dissing..."
+~/Dev/llvm-2.8/cbuild/Release/bin/llvm-dis -show-annotations HelloWorld.o
+echo "emscriptening..."
+python ~/Dev/emscripten/emscripten.py HelloWorld.o.ll ~/Dev/tracemonkey/js/src/js '{ "USE_TYPED_ARRAYS": 1 }' &> HelloWorld.js
+
View
7,883 demos/webgl/glge.js
7,883 additions, 0 deletions not shown
View
1,158 demos/webgl/glge_math.js
@@ -0,0 +1,1158 @@
+/*
+GLGE WebGL Graphics Engine
+Copyright (c) 2010, Paul Brunt
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of GLGE nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @fileOverview
+ * @name GLGE_math.js
+ */
+
+ if(!window["GLGE"]){
+ /**
+ * @namespace Holds the functionality of the library
+ */
+ window["GLGE"]={};
+}
+
+(function(GLGE){
+
+GLGE.Vec=function(array) {
+ return array.slice(0);
+}
+
+/**
+* The Vec3 Class creates a vector
+* @param {Array} array An array of 3 floats
+*/
+GLGE.Vec3=function(x,y,z){
+ return [x,y,z];
+}
+
+/**
+* The Vec4 Class creates a vector
+* @param {Array} array An array of 4 floats
+*/
+GLGE.Vec4=function(x,y,z,w){
+ return [x,y,z,w];
+}
+
+/**
+* Gets the nth element (1 indexed) from the array
+* @param {Array} v A vector with 4 elements
+* @param {number} i The index from one
+*/
+GLGE.get1basedVec4=function(v,i){
+ return v[i-1];
+};
+/**
+* Gets the nth element (1 indexed) from the array
+* @param {Array} v A vector with 3 elements
+* @param {number} i The index from one
+*/
+GLGE.get1basedVec3=function(v,i){
+ return v[i-1];
+};
+
+/**
+* Gets the nth element (1 indexed) from the array
+* @param {Array} v A vector with 4 elements
+* @param {number} i The index from one
+*/
+GLGE.getVec4=function(v,i){
+ return v[i];
+};
+/**
+* Gets the nth element (1 indexed) from the array
+* @param {Array} v A vector with 3 elements
+* @param {number} i The index from one
+*/
+GLGE.getVec3=function(v,i){
+ return v[i];
+};
+
+
+
+/**
+* Adds a GLGE.Vec4 to this Vec4
+* @param {Array} a The first value to add
+* * @param {Array} b The second value to add
+*/
+GLGE.addVec4=function(a,b) {
+ return [a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]];
+}
+/**
+* Adds a GLGE.Vec3 to this GLGE.Vec3
+* @param {Array} a The first value to add
+* @param {Array} b The second value to add
+*/
+GLGE.addVec3=function(a,b) {
+ return [a[0]+b[0],a[1]+b[1],a[2]+b[2]];
+}
+
+
+/**
+* Adds a GLGE.Vec4 to this Vec4
+* @param {Array} a The first value
+* * @param {Array} b The second value to subtract from the first
+*/
+GLGE.subVec4=function(a,b) {
+ return [a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]];
+}
+/**
+* Adds a GLGE.Vec3 to this GLGE.Vec3
+* @param {Array} a The first value
+* @param {Array} b The second value to subtract from the first
+*/
+GLGE.subVec3=function(a,b) {
+ return [a[0]-b[0],a[1]-b[1],a[2]-b[2]];
+}
+
+
+/**
+* Gets the dot product between this and the input vector
+* @param {Array} a the first value to dot
+* @param {Array} b the second value to dot
+*/
+GLGE.dotVec3=function(a,b) {
+ return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
+}
+
+
+/**
+* Gets the dot product between this and the input vector
+* @param {Array} a the first value to dot
+* @param {Array} b the second value to dot
+*/
+GLGE.dotVec4=function(a,b) {
+ return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
+}
+
+/**
+* Gets the dot product between this and the input vector
+* @param {Array} a the vector to scale
+* @param {Number} b the scalar
+*/
+GLGE.scaleVec4=function(a,b) {
+ return [a[0]*b,a[1]*b,a[2]*b,a[3]*b];
+}
+
+/**
+* Gets the dot product between this and the input vector
+* @param {Array} a the vector to scale
+* @param {Number} b the scalar
+*/
+GLGE.scaleVec3=function(a,b) {
+ return [a[0]*b,a[1]*b,a[2]*b];
+}
+
+
+/**
+* Gets the cross product between this and the input vector
+* @param {Array} a the first value to dot
+* @param {Array} b the second value to dot
+*/
+GLGE.crossVec3=function(a,b) {
+ return [a[1]*b[2]-a[2]*b[1],
+ a[2]*b[0]-a[0]*b[2],
+ a[0]*b[1]-a[1]*b[0]];
+}
+
+/**
+* Returns a unitized version of the input vector3
+* @param {Array} a the vector3 to be unitized
+*/
+GLGE.toUnitVec3=function(a) {
+ var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
+ var f=1.0;
+ if (sq>0) {
+ f=Math.pow(sq,0.5);
+ }
+ return [a[0]/f,a[1]/f,a[2]/f];
+};
+
+/**
+* Returns a unitized version of the input vector4
+* @param {Array} a the vector4 to be unitized
+*/
+GLGE.toUnitVec4=function(a) {
+ var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3];
+ var f=1.0;
+ if (sq>0) {
+ f=Math.pow(sq,0.5);
+ }
+ return [a[0]/f,a[1]/f,a[2]/f,a[3]/f];
+};
+
+
+/**
+* Returns the length of a vector3
+* @param {Array} a the vector to be measured
+*/
+GLGE.lengthVec3=function(a) {
+ return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],0.5);
+};
+
+/**
+* Returns the distance between 2 vector3s
+* @param {Array} a the first vector
+* @param {Array} b the second vector
+*/
+GLGE.distanceVec3=function(a,b){
+ return GLGE.lengthVec3(GLGE.subVec3(a,b));
+};
+
+/**
+* Returns the length of a vector3
+* @param {Array} a the vector to be measured
+*/
+GLGE.lengthVec4=function(a,b) {
+ return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3],0.5);
+};
+
+/**
+* Returns the distance between 2 vector4s
+* @param {Array} a the first vector
+* @param {Array} b the second vector
+*/
+GLGE.distanceVec4=function(a,b){
+ return GLGE.lengthVec4(GLGE.subVec4(a,b));
+};
+
+
+/**
+* Returns the angle between 2 vector3s in radians
+* @param {Array} a the first vector
+* @param {Array} b the second vector
+*/
+GLGE.angleVec3=function(a,b){
+ a=GLGE.toUnitVec3(a);
+ b=GLGE.toUnitVec3(b);
+ d=GLGE.dotVec3(a,b);
+ if (d<-1)
+ d=-1;
+ if (d>1)
+ d=1;
+ return Math.acos(d);
+};
+
+/**
+* Returns the angle between 2 vector4s in radians
+* @param {Array} a the first vector
+* @param {Array} b the second vector
+*/
+GLGE.angleVec4=function(a,b){
+ a=GLGE.toUnitVec4(a);
+ b=GLGE.toUnitVec4(b);
+ d=GLGE.dotVec4(a,b);
+ if (d<-1)
+ d=-1;
+ if (d>1)
+ d=1;
+ return Math.acos(d);
+};
+
+GLGE_math_use_webgl_float=false;
+
+/**
+* The Mat class creates a matrix from an array
+* @param {Array} array An array of 9 or 16 floats
+*/
+GLGE.Mat3=GLGE_math_use_webgl_float?function(array) {
+ if (array.length==9) {
+ return new Float32Array(array);
+ }else if (array.length==16) {
+ return new Float32Array([array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]]);
+ }else {
+ throw "invalid matrix length";
+ }
+}:function(array) {
+ var retval;
+ if (array.length==9) {
+ retval=array.slice(0);
+ }else if (array.length==16) {
+ retval=[array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]];
+ }else {
+ throw "invalid matrix length";
+ }
+ retval.get=function(i){return this[i];};
+ return retval;
+};
+GLGE.Mat=GLGE_math_use_webgl_float?function(array) {
+ return new Float32Array(array);
+}:function(array){
+ var retval=array.slice(0);
+ retval.get=function(i){return this[i];};
+ return retval;
+};
+GLGE.Mat4=function(array) {
+ var retval;
+ if (array.length==9) {
+ retval=[array[0],array[1],array[2],0,array[3],array[4],array[5],0,array[6],array[7],array[8],0,0,0,0,1];
+ }else if (array.length==16) {
+ retval=array.slice(0);
+ }else {
+ throw "invalid matrix length";
+ }
+ retval.get=function(i){return this[i];};
+ return retval;
+};
+/**
+* Finds the determinate of the matrix
+* @returns {number} the determinate
+*/
+GLGE.determinantMat4=function(m) {
+ return m[12] * m[9] * m[6] * m[3] - m[8] * m[13] * m[6] * m[3] - m[12] * m[5] * m[10] * m[3] + m[4] * m[13] * m[10] * m[3] + m[8] * m[5] * m[14] * m[3] - m[4] * m[9] * m[14] * m[3] - m[12] * m[9] * m[2] * m[7] + m[8] * m[13] * m[2] * m[7] + m[12] * m[1] * m[10] * m[7] - m[0] * m[13] * m[10] * m[7] - m[8] * m[1] * m[14] * m[7] + m[0] * m[9] * m[14] * m[7] + m[12] * m[5] * m[2] * m[11] - m[4] * m[13] * m[2] * m[11] - m[12] * m[1] * m[6] * m[11] + m[0] * m[13] * m[6] * m[11] + m[4] * m[1] * m[14] * m[11] - m[0] * m[5] * m[14] * m[11] - m[8] * m[5] * m[2] * m[15] + m[4] * m[9] * m[2] * m[15] + m[8] * m[1] * m[6] * m[15] - m[0] * m[9] * m[6] * m[15] - m[4] * m[1] * m[10] * m[15] + m[0] * m[5] * m[10] * m[15];
+};
+
+/**
+* Finds the inverse of the matrix
+* @returns {GLGE.Mat} the inverse
+*/
+GLGE.inverseMat4=function(mat){
+ // Cache the matrix values (makes for huge speed increases!)
+ var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
+ var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
+ var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
+ var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
+
+ var d = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
+ a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
+ a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
+ a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
+ a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
+ a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
+
+ return [ (a21*a32*a13 - a31*a22*a13 + a31*a12*a23 - a11*a32*a23 - a21*a12*a33 + a11*a22*a33)/d,
+ (a31*a22*a03 - a21*a32*a03 - a31*a02*a23 + a01*a32*a23 + a21*a02*a33 - a01*a22*a33)/d,
+ (a11*a32*a03 - a31*a12*a03 + a31*a02*a13 - a01*a32*a13 - a11*a02*a33 + a01*a12*a33)/d,
+ (a21*a12*a03 - a11*a22*a03 - a21*a02*a13 + a01*a22*a13 + a11*a02*a23 - a01*a12*a23)/d,
+ (a30*a22*a13 - a20*a32*a13 - a30*a12*a23 + a10*a32*a23 + a20*a12*a33 - a10*a22*a33)/d,
+ (a20*a32*a03 - a30*a22*a03 + a30*a02*a23 - a00*a32*a23 - a20*a02*a33 + a00*a22*a33)/d,
+ (a30*a12*a03 - a10*a32*a03 - a30*a02*a13 + a00*a32*a13 + a10*a02*a33 - a00*a12*a33)/d,
+ (a10*a22*a03 - a20*a12*a03 + a20*a02*a13 - a00*a22*a13 - a10*a02*a23 + a00*a12*a23)/d,
+ (a20*a31*a13 - a30*a21*a13 + a30*a11*a23 - a10*a31*a23 - a20*a11*a33 + a10*a21*a33)/d,
+ (a30*a21*a03 - a20*a31*a03 - a30*a01*a23 + a00*a31*a23 + a20*a01*a33 - a00*a21*a33)/d,
+ (a10*a31*a03 - a30*a11*a03 + a30*a01*a13 - a00*a31*a13 - a10*a01*a33 + a00*a11*a33)/d,
+ (a20*a11*a03 - a10*a21*a03 - a20*a01*a13 + a00*a21*a13 + a10*a01*a23 - a00*a11*a23)/d,
+ (a30*a21*a12 - a20*a31*a12 - a30*a11*a22 + a10*a31*a22 + a20*a11*a32 - a10*a21*a32)/d,
+ (a20*a31*a02 - a30*a21*a02 + a30*a01*a22 - a00*a31*a22 - a20*a01*a32 + a00*a21*a32)/d,
+ (a30*a11*a02 - a10*a31*a02 - a30*a01*a12 + a00*a31*a12 + a10*a01*a32 - a00*a11*a32)/d,
+ (a10*a21*a02 - a20*a11*a02 + a20*a01*a12 - a00*a21*a12 - a10*a01*a22 + a00*a11*a22)/d]
+};
+
+/**
+* multiplies two mat4's
+* @returns {GLGE.Mat} the matrix multiplication of the matrices
+*/
+GLGE.mulMat4Vec4=function(mat1,vec2){
+ return GLGE.Vec4(mat1[0]*vec2[0]+mat1[1]*vec2[1]+mat1[2]*vec2[2]+mat1[3]*vec2[3],
+ mat1[4]*vec2[0]+mat1[5]*vec2[1]+mat1[6]*vec2[2]+mat1[7]*vec2[3],
+ mat1[8]*vec2[0]+mat1[9]*vec2[1]+mat1[10]*vec2[2]+mat1[11]*vec2[3],
+ mat1[12]*vec2[0]+mat1[13]*vec2[1]+mat1[14]*vec2[2]+mat1[15]*vec2[3]);
+};
+
+/**
+* multiplies a Mat4 by a scalar value
+* @returns {GLGE.Mat} the matrix multiplication of the matrices
+*/
+GLGE.scaleMat4=function(m,value) {
+ return GLGE.Mat([m[0]*value,m[1]*value,m[2]*value,m[3]*value,
+ m[4]*value,m[5]*value,m[6]*value,m[7]*value,
+ m[8]*value,m[9]*value,m[10]*value,m[11]*value,
+ m[12]*value,m[13]*value,m[14]*value,m[15]*value]);
+};
+/**
+* multiplies a Mat4 by a scalar value in place without allocation
+* @returns {GLGE.Mat} the input matrix, modified
+*/
+GLGE.scaleInPlaceMat4=function(m,value) {
+ m.set(0,m[0]*value);
+ m.set(1,m[1]*value);
+ m.set(2,m[2]*value);
+ m.set(3,m[3]*value);
+ m.set(4,m[4]*value);
+ m.set(5,m[5]*value);
+ m.set(6,m[6]*value);
+ m.set(7,m[7]*value);
+ m.set(8,m[8]*value);
+ m.set(9,m[9]*value);
+ m.set(10,m[10]*value);
+ m.set(11,m[11]*value);
+ m.set(12,m[12]*value);
+ m.set(13,m[13]*value);
+ m.set(14,m[14]*value);
+ m.set(15,m[15]*value);
+ return m;
+};
+
+/**
+* adds a Mat4 to another Mat4 in place without allocation
+* @returns {GLGE.Mat} the first input matrix, modified to be added
+*/
+GLGE.addInPlaceMat4=function(m,value) {
+ m.set(0,m[0]+value[0]);
+ m.set(1,m[1]+value[1]);
+ m.set(2,m[2]+value[2]);
+ m.set(3,m[3]+value[3]);
+ m.set(4,m[4]+value[4]);
+ m.set(5,m[5]+value[5]);
+ m.set(6,m[6]+value[6]);
+ m.set(7,m[7]+value[7]);
+ m.set(8,m[8]+value[8]);
+ m.set(9,m[9]+value[9]);
+ m.set(10,m[10]+value[10]);
+ m.set(11,m[11]+value[11]);
+ m.set(12,m[12]+value[12]);
+ m.set(13,m[13]+value[13]);
+ m.set(14,m[14]+value[14]);
+ m.set(15,m[15]+value[15]);
+ return m;
+};
+
+
+
+/**
+* adds two Mat4 together
+* @returns {GLGE.Mat} a new, added Mat4
+*/
+GLGE.addMat4=function(m,value) {
+return GLGE.Mat([m[0]+value[0],
+ m[1]+value[1],
+ m[2]+value[2],
+ m[3]+value[3],
+ m[4]+value[4],
+ m[5]+value[5],
+ m[6]+value[6],
+ m[7]+value[7],
+ m[8]+value[8],
+ m[9]+value[9],
+ m[10]+value[10],
+ m[11]+value[11],
+ m[12]+value[12],
+ m[13]+value[13],
+ m[14]+value[14],
+ m[15]+value[15]]);
+ return m;
+};
+
+
+
+/**
+* subs a Mat4 from another Mat4 in place without allocation
+* @returns {GLGE.Mat} the first input matrix, modified to have the second subtacted
+*/
+GLGE.subInPlaceMat4=function(m,value) {
+ m.set(0,m[0]-value[0]);
+ m.set(1,m[1]-value[1]);
+ m.set(2,m[2]-value[2]);
+ m.set(3,m[3]-value[3]);
+ m.set(4,m[4]-value[4]);
+ m.set(5,m[5]-value[5]);
+ m.set(6,m[6]-value[6]);
+ m.set(7,m[7]-value[7]);
+ m.set(8,m[8]-value[8]);
+ m.set(9,m[9]-value[9]);
+ m.set(10,m[10]-value[10]);
+ m.set(11,m[11]-value[11]);
+ m.set(12,m[12]-value[12]);
+ m.set(13,m[13]-value[13]);
+ m.set(14,m[14]-value[14]);
+ m.set(15,m[15]-value[15]);
+ return m;
+};
+
+
+
+/**
+* subtracts the second matrix from the first
+* @returns {GLGE.Mat} a new, subed Mat4
+*/
+GLGE.subMat4=function(m,value) {
+return GLGE.Mat([m[0]-value[0],
+ m[1]-value[1],
+ m[2]-value[2],
+ m[3]-value[3],
+ m[4]-value[4],
+ m[5]-value[5],
+ m[6]-value[6],
+ m[7]-value[7],
+ m[8]-value[8],
+ m[9]-value[9],
+ m[10]-value[10],
+ m[11]-value[11],
+ m[12]-value[12],
+ m[13]-value[13],
+ m[14]-value[14],
+ m[15]-value[15]]);
+ return m;
+};
+
+
+/**
+* Finds the matrix multiplication with another GLGE.Mat or GLGE.vec or an Array of length 3-4
+* @param {object} value An GLGE.Mat, GLGE.vec or Array
+* @returns {GLGE.Mat|GLGE.Vec}
+*/
+GLGE.mulMat4=function(mat2,mat1){
+
+ var a00 = mat1[0], a01 = mat1[1], a02 = mat1[2], a03 = mat1[3];
+ var a10 = mat1[4], a11 = mat1[5], a12 = mat1[6], a13 = mat1[7];
+ var a20 = mat1[8], a21 = mat1[9], a22 = mat1[10], a23 = mat1[11];
+ var a30 = mat1[12], a31 = mat1[13], a32 = mat1[14], a33 = mat1[15];
+
+ var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
+ var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
+ var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
+ var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
+ return [b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
+ b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
+ b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
+ b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
+
+ b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
+ b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
+ b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
+ b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
+
+ b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
+ b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
+ b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
+ b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
+
+ b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
+ b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
+ b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
+ b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33];
+};
+
+GLGE.transposeInPlaceMat4=function(m) {
+ var v=m[1];
+ m.set(1,m[4]);
+ m.set(4,v);
+
+
+ v=m[8];
+ m.set(8,m[2]);
+ m.set(2,v);
+
+
+ v=m[3];
+ m.set(3,m[12]);
+ m.set(12,v);
+
+ v=m[9];
+ m.set(9,m[6]);
+ m.set(6,v);
+
+ v=m[13];
+ m.set(13,m[7]);
+ m.set(7,v);
+
+ v=m[14];
+ m.set(14,m[11]);
+ m.set(11,v);
+
+};
+
+/**
+* Builds the transpose of the matrix
+* @returns {GLGE.Mat} the transposed matrix
+*/
+GLGE.transposeMat4=function(m) {
+ return GLGE.Mat4([m[0],m[4],m[8],m[12],
+ m[1],m[5],m[9],m[13],
+ m[2],m[6],m[10],m[14],
+ m[3],m[7],m[11],m[15]]);
+};
+
+/**
+* copys a js array into a webglarray
+* @param {array} mat the source array
+* @param {webglarray} glarray the destination array
+*/
+GLGE.mat4gl=function(mat,glarray){
+ glarray[0]=mat[0];
+ glarray[1]=mat[1];
+ glarray[2]=mat[2];
+ glarray[3]=mat[3];
+ glarray[4]=mat[4];
+ glarray[5]=mat[5];
+ glarray[6]=mat[6];
+ glarray[7]=mat[7];
+ glarray[8]=mat[8];
+ glarray[9]=mat[9];
+ glarray[10]=mat[10];
+ glarray[11]=mat[11];
+ glarray[12]=mat[12];
+ glarray[13]=mat[13];
+ glarray[14]=mat[14];
+ glarray[15]=mat[15];
+};
+
+/**
+* Sets the value at the specified index
+* @param {number} i the first index 1 offset
+* @param {number} j the second index 1 offset
+* @param {number} value the value to set
+*/
+GLGE.set1basedMat4=function(m,i,j,value){
+ m[(i-1)*4+(j-1)]=value;
+ if(m.glData!==undefined){
+ delete m.glData;
+ }
+};
+
+/**
+* Sets the value at the specified index
+* @param {number} i the first index from zero
+* @param {number} j the second index from zero
+* @param {number} value the value to set
+*/
+GLGE.setMat4=function(m,i,j,value){
+ m[i*4+j]=value;
+ if(m.glData!==undefined){
+ delete m.glData;
+ }
+};
+
+/**
+* Gets the value at the specified index
+* @param {number} i the first index from one
+* @param {number} j the second index from one
+* @returns {number} the value at the given index
+*/
+GLGE.get1basedMat4=function(m,i,j){
+ return m.get((i-1)*4+(j-1));
+};
+
+/**
+* Gets the value at the specified index
+* @param {number} i the first index from zero
+* @param {number} j the second index from zero
+* @returns {number} the value at the given index
+*/
+GLGE.getMat4=function(m,i,j){
+ return m[i*4+j];
+};
+/**
+* gets the a webgl float array for this Matrix, once generated it will cache it so it doesn't need to recreate everytime
+* @returns {Float32Array} the webgl array for this Matrix
+* @private
+*/
+GLGE.glDataMat4=function(m) {
+ m.glArray=new Float32Array(m);
+ return m.glArray;
+};
+/**
+ * Creates an identity matrix
+ * @returns {GLGE.Mat} the identity matrix
+ */
+GLGE.identMatrix=function(){
+ return GLGE.Mat([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);
+};
+/**
+ * Creates a translation matrix
+ * @returns {Array} value an array GLGE.Vec or 3 paramters
+ * @returns {GLGE.Mat} the translation matrix
+ */
+GLGE.translateMatrix=function(value){
+ var x;
+ var y;
+ var z;
+ if(arguments.length==3){
+ x=arguments[0];
+ y=arguments[1];
+ z=arguments[2];
+ }
+ else if(value.data){
+ x=value.data[0];
+ y=value.data[1];
+ z=value.data[2];
+ }
+ else if(value instanceof Array){
+ x=value[0];
+ y=value[1];
+ z=value[2];
+ }
+ return GLGE.Mat([
+ 1,0,0,x,
+ 0,1,0,y,
+ 0,0,1,z,
+ 0,0,0,1
+ ]);
+};
+/**
+ * Creates a scale matrix
+ * @returns {Array} value an array GLGE.Vec or 3 paramters
+ * @returns {GLGE.Mat} the scale matrix
+ */
+GLGE.scaleMatrix=function(value){
+ var x;
+ var y;
+ var z;
+ if(arguments.length==3){
+ x=arguments[0];
+ y=arguments[1];
+ z=arguments[2];
+ }
+ else if(value.data){
+ x=value.data[0];
+ y=value.data[1];
+ z=value.data[2];
+ }
+ else if(value instanceof Array){
+ x=value[0];
+ y=value[1];
+ z=value[2];
+ }
+ return GLGE.Mat([
+ x,0,0,0,
+ 0,y,0,0,
+ 0,0,z,0,
+ 0,0,0,1
+ ]);
+}
+/**
+* @constant
+* @description Enum for XYZ rotation order
+*/
+GLGE.ROT_XYZ=1;
+/**
+* @constant
+* @description Enum for XZY rotation order
+*/
+GLGE.ROT_XZY=2;
+/**
+* @constant
+* @description Enum for YXZ rotation order
+*/
+GLGE.ROT_YXZ=3;
+/**
+* @constant
+* @description Enum for YZX rotation order
+*/
+GLGE.ROT_YZX=4;
+/**
+* @constant
+* @description Enum for ZXY rotation order
+*/
+GLGE.ROT_ZXY=5;
+/**
+* @constant
+* @description Enum for ZYX rotation order
+*/
+GLGE.ROT_ZYX=6;
+/**
+ * Creates a rotation matrix
+ * @returns {Array} value an array GLGE.Vec or 3 paramters
+ * @returns {GLGE.Mat} the rotation matrix
+ */
+GLGE.rotateMatrix=function(value,type) {
+ var x;
+ var y;
+ var z;
+ if(arguments.length>2){
+ x=arguments[0];
+ y=arguments[1];
+ z=arguments[2];
+ type=arguments[3];
+ }
+ else if(value.data){
+ x=value.data[0];
+ y=value.data[1];
+ z=value.data[2];
+ }
+ else if(value instanceof Array){
+ x=value[0];
+ y=value[1];
+ z=value[2];
+ }
+ if(!type) type=GLGE.ROT_XYZ;
+ var cosx=Math.cos(x);
+ var sinx=Math.sin(x);
+ var cosy=Math.cos(y);
+ var siny=Math.sin(y);
+ var cosz=Math.cos(z);
+ var sinz=Math.sin(z);
+ var rotx=GLGE.Mat([1,0,0,0,0,cosx,-sinx,0,0,sinx,cosx,0,0,0,0,1]);
+ var roty=GLGE.Mat([cosy,0,siny,0,0,1,0,0,-siny,0,cosy,0,0,0,0,1]);
+ var rotz=GLGE.Mat([cosz,-sinz,0,0,sinz,cosz,0,0,0,0,1,0,0,0,0,1]);
+ switch(type){
+ case GLGE.ROT_XYZ:
+ return GLGE.mulMat4(rotx,GLGE.mulMat4(roty,rotz));
+ break;
+ case GLGE.ROT_XZY:
+ return GLGE.mulMat4(rotx,GLGE.mulMat4(rotz,roty));
+ break;
+ case GLGE.ROT_YXZ:
+ return GLGE.mulMat4(roty,GLGE.mulMat4(rotx,rotz));
+ break;
+ case GLGE.ROT_YZX:
+ return GLGE.mulMat4(roty,GLGE.mulMat4(rotz,rotx));
+ break;
+ case GLGE.ROT_ZXY:
+ return GLGE.mulMat4(rotz,GLGE.mulMat4(rotx,roty));
+ break;
+ case GLGE.ROT_ZYX:
+ return GLGE.mulMat4(rotz,GLGE.mulMat4(roty,rotx));
+ break;
+ }
+}
+
+
+GLGE.angleAxis=function(angle, axis) {
+ var xmx,ymy,zmz,xmy,ymz,zmx,xms,yms,zms;
+ axis=[axis[0],axis[1],axis[2],0];
+
+ var x = axis[0];
+ var y = axis[1];
+ var z = axis[2];
+
+
+ var cos = Math.cos(angle);
+ var cosi = 1.0 - cos;
+ var sin = Math.sin(angle);
+
+ xms = x * sin;yms = y * sin;zms = z * sin;
+ xmx = x * x;ymy = y * y;zmz = z * z;
+ xmy = x * y;ymz = y * z;zmx = z * x;
+
+ var matrix = [(cosi * xmx) + cos,(cosi * xmy) - zms,(cosi * zmx) + yms,0,
+ (cosi * xmy) + zms,(cosi * ymy) + cos,(cosi * ymz) - xms,0,
+ (cosi * zmx) - yms,(cosi * ymz) + xms,(cosi * zmz) + cos,0,
+ 0,0,0,1];
+
+ return GLGE.Mat(matrix);
+};
+
+GLGE.quatRotation=function(qx,qy,qz,qw){
+ return GLGE.Mat([
+ 1 - 2*qy*qy - 2*qz*qz,2*qx*qy - 2*qz*qw,2*qx*qz + 2*qy*qw,0,
+ 2*qx*qy + 2*qz*qw,1 - 2*qx*qx - 2*qz*qz,2*qy*qz - 2*qx*qw,0,
+ 2*qx*qz - 2*qy*qw,2*qy*qz + 2*qx*qw,1 - 2*qx*qx - 2*qy*qy,0,
+ 0,0,0,1
+ ]);
+};
+
+GLGE.makeOrtho=function(left,right,bottom,top,near,far){
+ var x = -(right+left)/(right-left);
+ var y = -(top+bottom)/(top-bottom);
+ var z = -(far+near)/(far-near);
+
+ return GLGE.Mat([2/(right-left), 0, 0, x,
+ 0, 2/(top-bottom), 0, y,
+ 0, 0, -2/(far-near), z,
+ 0, 0, 0, 1]);
+};
+
+GLGE.makeFrustum=function(left,right,bottom,top,near,far){
+ var x = 2*near/(right-left);
+ var y = 2*near/(top-bottom);
+ var a = (right+left)/(right-left);
+ var b = (top+bottom)/(top-bottom);
+ var c = -(far+near)/(far-near);
+ var d = -2*far*near/(far-near);
+ return GLGE.Mat([x, 0, a, 0,
+ 0, y, b, 0,
+ 0, 0, c, d,
+ 0, 0, -1, 0]);
+};
+
+GLGE.makePerspective=function(fovy, aspect, near, far){
+ var ymax = near * Math.tan(fovy * 0.00872664625972);
+ var ymin = -ymax;
+ var xmin = ymin * aspect;
+ var xmax = ymax * aspect;
+ return GLGE.makeFrustum(xmin, xmax, ymin, ymax, near, far);
+};
+
+GLGE.matrix2Scale=function(m){
+ var m1=m[0];
+ var m2=m[1];
+ var m3=m[2];
+ var m4=m[4];
+ var m5=m[5];
+ var m6=m[6];
+ var m7=m[8];
+ var m8=m[9];
+ var m9=m[10];
+ var scaleX=Math.sqrt(m1*m1+m2*m2+m3*m3);
+ var scaleY=Math.sqrt(m4*m4+m5*m5+m6*m6);
+ var scaleZ=Math.sqrt(m7*m7+m8*m8+m9*m9);
+ return [scaleX,scaleY,scaleZ]
+}
+
+
+GLGE.rotationMatrix2Quat=function(m){
+ var tr = m[0] + m[5] + m[10]+1.0;
+ var S,x,y,z,w;
+
+ if (tr > 0) {
+ S = 0.5/Math.sqrt(tr);
+ w = 0.25 / S;
+ x = (m[9] - m[6]) * S;
+ y = (m[2] - m[8]) * S;
+ z = (m[4] - m[1]) * S;
+ } else if ((m[0] > m[5])&&(m[0] > m[10])) {
+ S = Math.sqrt(1.0 + m[0] - m[5] - m[10]) * 2;
+ w = (m[9] - m[6]) / S;
+ x = 0.25 / S;
+ y = (m[1] + m[4]) / S;
+ z = (m[2] + m[8]) / S;
+ } else if (m[5] > m[10]) {
+ S = Math.sqrt(1.0 + m[5] - m[0] - m[10]) * 2;
+ w = (m[2] - m[8]) / S;
+ x = (m[1] + m[4]) / S;
+ y = 0.25 / S;
+ z = (m[6] + m[9]) / S;
+ } else {
+ S = Math.sqrt(1.0 + m[10] - m[0] - m[5]) * 2;
+ w = (m[4] - m[1]) / S;
+ x = (m[2] + m[8]) / S;
+ y = (m[6] + m[9]) / S;
+ z = 0.25 / S;
+ }
+ var N=Math.sqrt(x*x+y*y+z*z+w*w)
+
+ return [x/N,y/N,z/N,w/N];
+}
+
+
+
+//returns plane as array [X,Y,Z,D]
+GLGE.rayToPlane=function(origin,dir){
+ var dirnorm=GLGE.toUnitVec3(dir);
+ return [dirnorm[0],dirnorm[1],dirnorm[2],GLGE.dotVec3(origin,dirnorm)];
+}
+
+GLGE.rayIntersectPlane=function(origin,dir,plane){
+ var planeN=[plane[0],plane[1],plane[2]];
+ var planeD=plane[3];
+ var vdir=GLGE.dotVec3(planeN,dir);
+ if(vdir<=0){
+ //ray in wrong direction
+ return false;
+ }
+ var vo=-(GLGE.dotVec3(planeN,origin)+planeD);
+ var t=vo/vdir;
+ if(t<=0){
+ return false;
+ }
+ return GLGE.addVec3(origin,GLGE.scaleVec3(dir,t));
+}
+//assumes perspective projection
+GLGE.screenToDirection=function(x,y,width,height,proj){
+ xcoord = -( ( ( 2 * x ) / width ) - 1 ) / proj[0];
+ ycoord =( ( ( 2 * y ) / height ) - 1 ) / proj[5];
+ zcoord = 1;
+ return GLGE.toUnitVec3([xcoord,ycoord,zcoord]);
+}
+
+GLGE.BoundingVolume=function(minX,maxX,minY,maxY,minZ,maxZ){
+ var dims=[maxX-minX,maxY-minY,maxZ-minZ];
+ this.dims=dims;
+ this.center=[dims[0]/2+minX,dims[1]/2+minY,dims[2]/2+minZ];
+}
+
+//returns the center of the bounding area
+GLGE.BoundingVolume.prototype.getCenter=function(matrix){
+ return GLGE.mulMat4Vec4(matrix,this.center);
+}
+
+//returns box point
+GLGE.BoundingVolume.prototype.getBoxPoint=function(matrix,point){
+ var coord=[this.dims[0]/2*point[0]+this.center[0],this.dims[1]/2*point[1]+this.center[1],this.dims[2]/2*point[2]+this.center[2]];
+ return GLGE.mulMat4Vec4(matrix,coord);
+}
+
+//returns the radius of a bounding sphere
+GLGE.BoundingVolume.prototype.getSphereRadius=function(){
+ return Math.pow((this.dims[0]*this.dims[0]+this.dims[1]*this.dims[1]+this.dims[2]*this.dims[2])/4,0.5);
+}
+
+//adds an additional bounding volume to resize the current and returns the result
+GLGE.BoundingVolume.prototype.addBoundingVolume=function(vol){
+ var minX=Math.min(this.center[0]-this.dims[0]/2,vol.center[0]-vol.dims[0]/2);
+ var maxX=Math.max(this.center[0]+this.dims[0]/2,vol.center[0]+vol.dims[0]/2);
+ var minY=Math.min(this.center[1]-this.dims[1]/2,vol.center[1]-vol.dims[1]/2);
+ var maxY=Math.max(this.center[1]+this.dims[1]/2,vol.center[1]+vol.dims[1]/2);
+ var minZ=Math.min(this.center[2]-this.dims[2]/2,vol.center[2]-vol.dims[2]/2);
+ var maxZ=Math.max(this.center[2]+this.dims[2]/2,vol.center[2]+vol.dims[2]/2);
+ var dims=[maxX-minX,maxY-minY,maxZ-minZ];
+ this.dims=dims;
+ this.center=[dims[0]/2+minX,dims[1]/2+minY,dims[2]/2+minZ];
+}
+
+//scales a volume based on a transform matrix
+GLGE.BoundingVolume.prototype.applyMatrixScale=function(matrix){
+ var scaleX=GLGE.lengthVec3([matrix[0],matrix[4],matrix[8]]);
+ var scaleY=GLGE.lengthVec3([matrix[1],matrix[5],matrix[9]]);
+ var scaleZ=GLGE.lengthVec3([matrix[2],matrix[6],matrix[10]]);
+ var minX=(this.center[0]-this.dims[0]/2)*scaleX;
+ var maxX=(this.center[0]+this.dims[0]/2)*scaleX;
+ var minY=(this.center[1]-this.dims[1]/2)*scaleY;
+ var maxY=(this.center[1]+this.dims[1]/2)*scaleY;
+ var minZ=(this.center[2]-this.dims[2]/2)*scaleZ;
+ var maxZ=(this.center[2]+this.dims[2]/2)*scaleZ;
+ var dims=[maxX-minX,maxY-minY,maxZ-minZ];
+ this.dims=dims;
+ this.center=[dims[0]/2+minX,dims[1]/2+minY,dims[2]/2+minZ];
+}
+
+GLGE.BoundingVolume.prototype.clone=function(){
+ var minX=this.center[0]-this.dims[0]/2;
+ var maxX=this.center[0]+this.dims[0]/2;
+ var minY=this.center[1]-this.dims[1]/2;
+ var maxY=this.center[1]+this.dims[1]/2;
+ var minZ=this.center[2]-this.dims[2]/2;
+ var maxZ=this.center[2]+this.dims[2]/2;
+ return new GLGE.BoundingVolume(minX,maxX,minY,maxY,minZ,maxZ);
+}
+
+GLGE.BoundingVolume.prototype.toString=function(){
+ var minX=this.center[0]-this.dims[0]/2;
+ var maxX=this.center[0]+this.dims[0]/2;
+ var minY=this.center[1]-this.dims[1]/2;
+ var maxY=this.center[1]+this.dims[1]/2;
+ var minZ=this.center[2]-this.dims[2]/2;
+ var maxZ=this.center[2]+this.dims[2]/2;
+ return [minX,maxX,minY,maxY,minZ,maxZ].toString();
+}
+
+
+function GLGE_mathUnitTest() {
+ var a=GLGE.Vec([1,2,3,4]);
+ var b=GLGE.Vec4(GLGE.getVec4(a,3),
+ GLGE.get1basedVec4(a,3),
+ GLGE.getVec4(a,1),
+ GLGE.getVec4(a,0));
+ var c=GLGE.identMatrix();
+ var d=GLGE.mulMat4Vec4(c,b);
+ if (GLGE.getVec4(d,0)!=4||
+ GLGE.getVec4(d,1)!=3||
+ GLGE.getVec4(d,2)!=2||
+ GLGE.getVec4(d,3)!=1) {
+ throw "Unit Test 1 failed MatVecMul "+d;
+ }
+ var m=GLGE.Mat4([3,4,5,0,.5,.75,0,0,.75,.5,0,0,.25,.25,1,1]);
+ var m1=GLGE.Mat4([2,1,8,2,1,4,3,2,1,.5,6.5,2,8,3,1,.25]);
+ var mm1=GLGE.mulMat4(m,m1);
+ var am1=GLGE.Mat4([15,21.5,68.5,24,
+ 1.75,3.5,6.25,2.5,
+ 2,2.75,7.5,2.5,
+ 9.75,4.75,10.25,3.25]);
+ for (var i=0;i<4;++i) {
+ for (var j=0;j<4;++j) {
+ var diff=GLGE.getMat4(mm1,i,j)-GLGE.getMat4(am1,i,j);
+ if (diff<.000001&&diff>-.000001) {
+
+ }else {
+ throw "Unit Test 1 failed Multiplication "+GLGE.getMat4(mm1,i,j)+" != "+GLGE.getMat4(am1,i,j);
+ }
+ }
+ }
+ var inv = GLGE.inverseMat4(m);
+ var k = GLGE.mulMat4(m,inv);
+ var l = GLGE.mulMat4(inv,m);
+ for (var i=0;i<4;++i) {
+ for (var j=0;j<4;++j) {
+ var diff=GLGE.getMat4(k,i,j)-GLGE.getMat4(c,i,j);
+ if (diff<.0001&&diff>-.0001) {
+ }else {
+ throw "Unit Test 1 failed Inverse "+GLGE.getMat4(k,i,j)+" != "+GLGE.getMat4(c,i,j);
+ }
+ }
+ }
+}
+GLGE_mathUnitTest() ;
+
+
+//Closure Export
+GLGE["Vec3"]=GLGE.Vec3;
+GLGE["Vec4"]=GLGE.Vec4;
+GLGE["get1basedVec4"]=GLGE.get1basedVec4;
+GLGE["get1basedVec3"]=GLGE.get1basedVec3;
+GLGE["getVec4"]=GLGE.getVec4;
+GLGE["getVec3"]=GLGE.getVec3;
+GLGE["addVec4"]=GLGE.addVec4;
+GLGE["addVec3"]=GLGE.addVec3;
+GLGE["subVec4"]=GLGE.subVec4;
+GLGE["subVec3"]=GLGE.subVec3;
+GLGE["dotVec3"]=GLGE.dotVec3;
+GLGE["dotVec4"]=GLGE.dotVec4;
+GLGE["scaleVec4"]=GLGE.scaleVec4;
+GLGE["scaleVec3"]=GLGE.scaleVec3;
+GLGE["crossVec3"]=GLGE.crossVec3;
+GLGE["toUnitVec3"]=GLGE.toUnitVec3;
+GLGE["toUnitVec4"]=GLGE.toUnitVec4;
+GLGE["lengthVec3"]=GLGE.lengthVec3;
+GLGE["distanceVec3"]=GLGE.distanceVec3;
+GLGE["lengthVec4"]=GLGE.lengthVec4;
+GLGE["distanceVec4"]=GLGE.distanceVec4;
+GLGE["angleVec3"]=GLGE.angleVec3;
+GLGE["angleVec4"]=GLGE.angleVec4;
+GLGE["Mat3"]=GLGE.Mat3;
+GLGE["Mat"]=GLGE.Mat;
+GLGE["Mat4"]=GLGE.Mat4;
+GLGE["determinantMat4"]=GLGE.determinantMat4;
+GLGE["inverseMat4"]=GLGE.inverseMat4;
+GLGE["mulMat4Vec4"]=GLGE.mulMat4Vec4;
+GLGE["scaleMat4"]=GLGE.scaleMat4;
+GLGE["scaleInPlaceMat4"]=GLGE.scaleInPlaceMat4;
+GLGE["addInPlaceMat4"]=GLGE.addInPlaceMat4;
+GLGE["addMat4"]=GLGE.addMat4;
+GLGE["subInPlaceMat4"]=GLGE.subInPlaceMat4;
+GLGE["subMat4"]=GLGE.subMat4;
+GLGE["mulMat4"]=GLGE.mulMat4;
+GLGE["transposeInPlaceMat4"]=GLGE.transposeInPlaceMat4;
+GLGE["transposeMat4"]=GLGE.transposeMat4;
+GLGE["set1basedMat4"]=GLGE.set1basedMat4;
+GLGE["setMat4"]=GLGE.setMat4;
+GLGE["get1basedMat4"]=GLGE.get1basedMat4;
+GLGE["getMat4"]=GLGE.getMat4;
+GLGE["glDataMat4"]=GLGE.glDataMat4;
+GLGE["identMatrix"]=GLGE.identMatrix;
+GLGE["translateMatrix"]=GLGE.translateMatrix;
+GLGE["scaleMatrix"]=GLGE.scaleMatrix;
+GLGE["ROT_XYZ"]=GLGE.ROT_XYZ;
+GLGE["ROT_XZY"]=GLGE.ROT_XZY;
+GLGE["ROT_YXZ"]=GLGE.ROT_YXZ;
+GLGE["ROT_YZX"]=GLGE.ROT_YZX;
+GLGE["ROT_ZXY"]=GLGE.ROT_ZXY;
+GLGE["ROT_ZYX"]=GLGE.ROT_ZYX;
+GLGE["rotateMatrix"]=GLGE.rotateMatrix;
+GLGE["angleAxis"]=GLGE.angleAxis;
+GLGE["quatRotation"]=GLGE.quatRotation;
+GLGE["makeOrtho"]=GLGE.makeOrtho;
+GLGE["makeFrustum"]=GLGE.makeFrustum;
+GLGE["makePerspective"]=GLGE.makePerspective;
+GLGE["matrix2Scale"]=GLGE.matrix2Scale;
+GLGE["rotationMatrix2Quat"]=GLGE.rotationMatrix2Quat;
+GLGE["mat4gl"]=GLGE.mat4gl;
+
+
+})(window["GLGE"]);
View
44 demos/webgl/scene.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glge>
+ <mesh id="Box">
+ <positions>
+ 1, 1, 1, 1, 1,-1,-1, 1,-1, 1, 1, 1,-1, 1,-1,-1, 1, 1,
+ -1,-1,-1,-1,-1, 1,-1, 1, 1,-1,-1,-1,-1, 1, 1,-1, 1,-1,
+ 1,-1,-1, 1,-1, 1,-1,-1,-1, 1,-1, 1,-1,-1, 1,-1,-1,-1,
+ 1, 1,-1, 1, 1, 1, 1,-1,-1, 1, 1, 1, 1,-1, 1, 1,-1,-1,
+ 1, 1, 1,-1, 1, 1, 1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 1,
+ 1, 1,-1, 1,-1,-1,-1,-1,-1, 1, 1,-1,-1,-1,-1,-1, 1,-1
+ </positions>
+ <normals>
+ 0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-1,0,-0,-0,-1,-0,-0,-1,-0,-0,-1,-0,-0,-1,0,-0,-1,0,-0,-1,0,1,0,-0,1,0,-0,1,0,-0,1,0,0,1,0,0,1,0,0,-0,-0,1,-0,-0,1,-0,-0,1,0,-0,1,0,-0,1,0,-0,1,0,0,-1,0,0,-1,0,0,-1,0,-0,-1,0,-0,-1,0,-0
+ </normals>
+ <uv1>
+ 0,0,1,0,1,1, 0,0,1,1,0,1,
+ 0,0,1,0,1,1, 0,0,1,1,0,1,
+ 0,0,0,1,1,0, 0,0,1,0,1,1,
+ 0,0,0,1,1,0, 0,0,1,0,1,1,
+ 0,0,0,1,1,0, 0,0,1,0,1,1,
+ 0,0,1,0,1,1, 0,0,1,1,0,1,
+ </uv1>
+ <faces>0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35</faces>
+ </mesh>
+
+ <camera id="maincamera" loc_y="3" loc_z="35"/>
+
+ <material id="boxmaterial1">
+ <texture id="boxtexture1" src="skin1.jpg"/>
+ <material_layer texture="#boxtexture1" mapinput="UV1" mapto="M_COLOR"/>
+ </material>
+ <material id="boxmaterial2">
+ <texture id="boxtexture2" src="skin2.jpg"/>
+ <material_layer texture="#boxtexture2" mapinput="UV1" mapto="M_COLOR"/>
+ </material>
+ <material id="boxmaterial3">
+ <texture id="boxtexture3" src="skin3.jpg"/>
+ <material_layer texture="#boxtexture3" mapinput="UV1" mapto="M_COLOR"/>
+ </material>
+
+ <scene id="mainscene" camera="#maincamera" ambient_color="#fff">
+ <!--light id="mainlight" loc_y="5" type="L_POINT"/-->
+ </scene>
+</glge>
View
2  demos/webgl/server.sh
@@ -0,0 +1,2 @@
+python -m SimpleHTTPServer 8991
+
View
BIN  demos/webgl/skin1.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  demos/webgl/skin3.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
2  src/library.js
@@ -212,6 +212,8 @@ var Library = {
asinf: 'Math.asin',
atan: 'Math.atan',
atanf: 'Math.atan',
+ atan2: 'Math.atan2',
+ atan2f: 'Math.atan2',
sqrt: 'Math.sqrt',
sqrtf: 'Math.sqrt',
fabs: 'Math.abs',
Please sign in to comment.
Something went wrong with that request. Please try again.