Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit 543fc9584967c2efccd32c726b3dd3e72238d5dd 0 parents
Jerome Etienne authored

Showing 73 changed files with 15,801 additions and 0 deletions. Show diff stats Hide diff stats

  1. +22 0 RequestAnimationFrame.js
  2. +419 0 Three-r36.js
  3. +682 0 Three.js
  4. +175 0 geom/Matrix3D.js
  5. +224 0 geom/Vector3D.js
  6. +1,834 0 geom/glMatrix.js
  7. +28 0 jiglibjs2/cof/JConfig.js
  8. +488 0 jiglibjs2/collision/CollDetectBoxBox.js
  9. +296 0 jiglibjs2/collision/CollDetectBoxMesh.js
  10. +128 0 jiglibjs2/collision/CollDetectBoxPlane.js
  11. +116 0 jiglibjs2/collision/CollDetectBoxTerrain.js
  12. +67 0 jiglibjs2/collision/CollDetectCapsuleBox.js
  13. +144 0 jiglibjs2/collision/CollDetectCapsuleCapsule.js
  14. +135 0 jiglibjs2/collision/CollDetectCapsulePlane.js
  15. +123 0 jiglibjs2/collision/CollDetectCapsuleTerrain.js
  16. +44 0 jiglibjs2/collision/CollDetectFunctor.js
  17. +38 0 jiglibjs2/collision/CollDetectInfo.js
  18. +146 0 jiglibjs2/collision/CollDetectSphereBox.js
  19. +141 0 jiglibjs2/collision/CollDetectSphereCapsule.js
  20. +142 0 jiglibjs2/collision/CollDetectSphereMesh.js
  21. +115 0 jiglibjs2/collision/CollDetectSpherePlane.js
  22. +118 0 jiglibjs2/collision/CollDetectSphereSphere.js
  23. +99 0 jiglibjs2/collision/CollDetectSphereTerrain.js
  24. +49 0 jiglibjs2/collision/CollPointInfo.js
  25. +42 0 jiglibjs2/collision/CollisionInfo.js
  26. +217 0 jiglibjs2/collision/CollisionSystemAbstract.js
  27. +81 0 jiglibjs2/collision/CollisionSystemBrute.js
  28. +362 0 jiglibjs2/collision/CollisionSystemGrid.js
  29. +71 0 jiglibjs2/collision/CollisionSystemGridEntry.js
  30. +31 0 jiglibjs2/data/CollOutBodyData.js
  31. +32 0 jiglibjs2/data/CollOutData.js
  32. +26 0 jiglibjs2/data/ContactData.js
  33. +28 0 jiglibjs2/data/EdgeData.js
  34. +76 0 jiglibjs2/data/OctreeCell.js
  35. +90 0 jiglibjs2/data/PlaneData.js
  36. +26 0 jiglibjs2/data/SpanData.js
  37. +29 0 jiglibjs2/data/TerrainData.js
  38. +30 0 jiglibjs2/data/TriangleVertexIndices.js
  39. +160 0 jiglibjs2/debug/Stats.js
  40. +21 0 jiglibjs2/events/JCollisionEvent.js
  41. +310 0 jiglibjs2/geometry/JAABox.js
  42. +370 0 jiglibjs2/geometry/JBox.js
  43. +141 0 jiglibjs2/geometry/JCapsule.js
  44. +102 0 jiglibjs2/geometry/JIndexedTriangle.js
  45. +350 0 jiglibjs2/geometry/JOctree.js
  46. +119 0 jiglibjs2/geometry/JPlane.js
  47. +43 0 jiglibjs2/geometry/JRay.js
  48. +1,034 0 jiglibjs2/geometry/JSegment.js
  49. +126 0 jiglibjs2/geometry/JSphere.js
  50. +245 0 jiglibjs2/geometry/JTerrain.js
  51. +376 0 jiglibjs2/geometry/JTriangle.js
  52. +160 0 jiglibjs2/geometry/JTriangleMesh.js
  53. +13 0 jiglibjs2/jiglib.js
  54. +73 0 jiglibjs2/math/JMath3D.js
  55. +151 0 jiglibjs2/math/JMatrix3D.js
  56. +74 0 jiglibjs2/math/JNumber3D.js
  57. +43 0 jiglibjs2/physics/BodyPair.js
  58. +30 0 jiglibjs2/physics/CachedImpulse.js
  59. +239 0 jiglibjs2/physics/HingeJoint.js
  60. +27 0 jiglibjs2/physics/MaterialProperties.js
  61. +50 0 jiglibjs2/physics/PhysicsController.js
  62. +43 0 jiglibjs2/physics/PhysicsState.js
  63. +1,199 0 jiglibjs2/physics/PhysicsSystem.js
  64. +1,205 0 jiglibjs2/physics/RigidBody.js
  65. +54 0 jiglibjs2/physics/constraint/JConstraint.js
  66. +157 0 jiglibjs2/physics/constraint/JConstraintMaxDistance.js
  67. +158 0 jiglibjs2/physics/constraint/JConstraintPoint.js
  68. +130 0 jiglibjs2/physics/constraint/JConstraintWorldPoint.js
  69. +208 0 jiglibjs2/vehicles/JCar.js
  70. +41 0 jiglibjs2/vehicles/JChassis.js
  71. +428 0 jiglibjs2/vehicles/JWheel.js
  72. +505 0 jiglibjs2_vehicle_physics_webgl.html
  73. +502 0 pool.html
22 RequestAnimationFrame.js
... ... @@ -0,0 +1,22 @@
  1 +/**
  2 + * Provides requestAnimationFrame in a cross browser way.
  3 + * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  4 + */
  5 +
  6 +if ( !window.requestAnimationFrame ) {
  7 +
  8 + window.requestAnimationFrame = ( function() {
  9 +
  10 + return window.webkitRequestAnimationFrame ||
  11 + window.mozRequestAnimationFrame || // comment out if FF4 is slow (it caps framerate at ~30fps: https://bugzilla.mozilla.org/show_bug.cgi?id=630127)
  12 + window.oRequestAnimationFrame ||
  13 + window.msRequestAnimationFrame ||
  14 + function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
  15 +
  16 + window.setTimeout( callback, 1000 / 60 );
  17 +
  18 + };
  19 +
  20 + } )();
  21 +
  22 +}
419 Three-r36.js
419 additions, 0 deletions not shown
682 Three.js
682 additions, 0 deletions not shown
175 geom/Matrix3D.js
... ... @@ -0,0 +1,175 @@
  1 +(function(jiglib) {
  2 +
  3 + // var mat4 = jigLib.mat4;
  4 +
  5 + var Matrix3D = function(v)
  6 + {
  7 + if (v)
  8 + {
  9 + this._rawData = mat4.create(v);
  10 + }
  11 + else
  12 + {
  13 + this._rawData = mat4.create([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
  14 + }
  15 + };
  16 +
  17 +
  18 + Matrix3D.prototype._rawData = null;
  19 +
  20 +
  21 + // A Vector of 16 Numbers, where every four elements can be a row or a column of a 4x4 matrix.
  22 + Matrix3D.prototype.get_rawData = function()
  23 + {
  24 + return this._rawData;
  25 + };
  26 +
  27 + // [read-only] A Number that determines whether a matrix is invertible.
  28 + // return void
  29 + Matrix3D.prototype.get_determinant = function()
  30 + {
  31 + return mat4.determinant(this._rawData);
  32 + };
  33 +
  34 + // Appends the matrix by multiplying another Matrix3D object by the current Matrix3D object.
  35 + // return void
  36 + Matrix3D.prototype.append = function(m)
  37 + {
  38 + mat4.multiply(this._rawData, m._rawData);
  39 + };
  40 +
  41 + // Appends an incremental rotation to a Matrix3D object.
  42 + // return void
  43 + Matrix3D.prototype.appendRotation = function(angle, axis, pivot)
  44 + {
  45 + // angle = angle/(3.14159*2);
  46 + angle = angle * Math.PI / 180;
  47 + if (pivot)
  48 + {
  49 + var npivot = pivot.clone().negate();
  50 + this.appendTranslation(npivot.x, npivot.y, npivot.z);
  51 + }
  52 + var naxis = axis.clone().negate();
  53 + mat4.rotate(this._rawData, angle, [ naxis.x, naxis.y, naxis.z ]);
  54 + if (pivot)
  55 + {
  56 + this.appendTranslation(pivot.x, pivot.y, pivot.z);
  57 + }
  58 + };
  59 +
  60 +
  61 + // Appends an incremental scale change along the x, y, and z axes to a Matrix3D object.
  62 + // return void
  63 + Matrix3D.prototype.appendScale = function(x, y, z)
  64 + {
  65 + mat4.scale(this._rawData, [ x, y, z ]);
  66 + };
  67 +
  68 +
  69 + // Appends an incremental translation, a repositioning along the x, y, and z axes, to a Matrix3D object.
  70 + // return void
  71 + Matrix3D.prototype.appendTranslation = function(x, y, z)
  72 + {
  73 + this.append(Matrix3D.createTranslateMatrix(x, y, z));
  74 + };
  75 +
  76 +
  77 + // Returns a new Matrix3D object that is an exact copy of the current Matrix3D object.
  78 + // return new Matrix3D
  79 + Matrix3D.prototype.clone = function()
  80 + {
  81 + return new Matrix3D(this._rawData);
  82 + };
  83 +
  84 + // Converts the current matrix to an identity or unit matrix.
  85 + // return void
  86 + Matrix3D.prototype.identity = function()
  87 + {
  88 + mat4.identity(this._rawData);
  89 + };
  90 +
  91 + // [static] Simplifies the interpolation from one frame of reference to another by interpolating a display object a percent point closer to a target display object.
  92 + // Matrix3D.interpolate = function() { };
  93 +
  94 + // Interpolates the display object's matrix a percent closer to a target's matrix.
  95 + // Matrix3D.prototype.interpolateTo = function() { };
  96 +
  97 +
  98 + // Inverts the current matrix.
  99 + // return Boolean true if the matrix was successfully inverted.
  100 + Matrix3D.prototype.invert = function()
  101 + {
  102 + mat4.inverse(this._rawData);
  103 + };
  104 +
  105 +
  106 + // Rotates the display object so that it faces a specified position.
  107 + // return void
  108 + // Matrix3D.prototype.pointAt = function(pos, at, up) { };
  109 +
  110 +
  111 + // Prepends a matrix by multiplying the current Matrix3D object by another Matrix3D object.
  112 + // return void
  113 + Matrix3D.prototype.prepend = function(m)
  114 + {
  115 + mat4.multiply(m._rawData, this._rawData, this._rawData);
  116 + };
  117 +
  118 +
  119 + // Prepends an incremental scale change along the x, y, and z axes to a Matrix3D object.
  120 + // return void
  121 + Matrix3D.prototype.prependScale = function(x, y, z)
  122 + {
  123 + this.prepend(Matrix3D.createScaleMatrix(x, y, z));
  124 + };
  125 +
  126 +
  127 + // Prepends an incremental translation, a repositioning along the x, y, and z axes, to a Matrix3D object.
  128 + // return void
  129 + Matrix3D.prototype.prependTranslation = function(x, y, z)
  130 + {
  131 + this.prepend(Matrix3D.createTranslateMatrix(x, y, z));
  132 + };
  133 +
  134 +
  135 + // Uses the transformation matrix to transform a Vector3D object from one space coordinate to another.
  136 + // return Vector3D with the transformed coordinates.
  137 + Matrix3D.prototype.transformVector = function(vector)
  138 + {
  139 + var vec = mat4.multiplyVec3(mat4.transpose(this._rawData, mat4.create()), [ vector.x, vector.y, vector.z ]);
  140 + return new Vector3D(vec[0], vec[1], vec[2]);
  141 + };
  142 +
  143 +
  144 + // Converts the current Matrix3D object to a matrix where the rows and columns are swapped.
  145 + Matrix3D.prototype.transpose = function()
  146 + {
  147 + mat4.transpose(this._rawData);
  148 + };
  149 +
  150 +
  151 + Matrix3D.createTranslateMatrix = function(x, y, z)
  152 + {
  153 + return new Matrix3D([
  154 + 1,0,0,x,
  155 + 0,1,0,y,
  156 + 0,0,1,z,
  157 + 0,0,0,1
  158 + ]);
  159 + };
  160 +
  161 +
  162 + Matrix3D.createScaleMatrix = function(x, y, z)
  163 + {
  164 + return new Matrix3D([
  165 + x,0,0,0,
  166 + 0,y,0,0,
  167 + 0,0,z,0,
  168 + 0,0,0,1
  169 + ]);
  170 + };
  171 +
  172 +
  173 + jiglib.Matrix3D = Matrix3D;
  174 +
  175 +})(jiglib);
224 geom/Vector3D.js
... ... @@ -0,0 +1,224 @@
  1 +(function(jiglib) {
  2 +
  3 + Vector3D = function(x, y, z, w)
  4 + {
  5 + this.x = x ? x : 0;
  6 + this.y = y ? y : 0;
  7 + this.z = z ? z : 0;
  8 + this.w = w ? w : 0;
  9 + }
  10 +
  11 + Vector3D.prototype.x = null;
  12 + Vector3D.prototype.y = null;
  13 + Vector3D.prototype.z = null;
  14 + Vector3D.prototype.w = null;
  15 +
  16 + //add(a:Vector3D):Vector3D
  17 + //Adds the value of the x, y, and z elements of the current Vector3D object to the values of the x, y, and z elements of another Vector3D object.
  18 + Vector3D.prototype.add = function(a)
  19 + {
  20 + return new Vector3D(this.x + a.x, this.y + a.y, this.z + a.z, this.w /* + a.w */);
  21 + }
  22 +
  23 + Vector3D.prototype.setTo = function(xa, ya, za)
  24 + {
  25 + this.x = xa;
  26 + this.y = ya;
  27 + this.z = za;
  28 + return this;
  29 + }
  30 +
  31 + //angleBetween(a:Vector3D, b:Vector3D):Number
  32 + //[static] Returns the angle in radians between two vectors.
  33 + Vector3D.angleBetween = function(a, b)
  34 + {
  35 + return a.dotProduct(b);
  36 + // var an = a.clone();
  37 + // var bn = b.clone();
  38 + // an.normalize();
  39 + // bn.normalize();
  40 + // d = an.dotProduct(bn);
  41 + // if (d < -1) d = -1;
  42 + // else if (d > 1) d = 1;
  43 + // return Math.acos(d);
  44 + }
  45 +
  46 + //clone():Vector3D
  47 + //Returns a new Vector3D object that is an exact copy of the current Vector3D object.
  48 + Vector3D.prototype.clone = function()
  49 + {
  50 + return new Vector3D(this.x, this.y, this.z, this.w);
  51 + }
  52 +
  53 +
  54 + //crossProduct(a:Vector3D):Vector3D
  55 + //Returns a new Vector3D object that is perpendicular (at a right angle) to the current Vector3D and another Vector3D object.
  56 + Vector3D.prototype.crossProduct = function(a)
  57 + {
  58 + var x1 = this.x, y1 = this.y, z1 = this.z, x2 = a.x, y2 = a.y, z2 = a.z;
  59 + return new Vector3D(
  60 + y1 * z2 - z1 * y2,
  61 + z1 * x2 - x1 * z2,
  62 + x1 * y2 - y1 * x2, 0);
  63 + }
  64 +
  65 + //decrementBy(a:Vector3D):void
  66 + //Decrements the value of the x, y, and z elements of the current Vector3D object by the values of the x, y, and z elements of specified Vector3D object.
  67 + Vector3D.prototype.decrementBy = function(a)
  68 + {
  69 + this.x -= a.x;
  70 + this.y -= a.y;
  71 + this.z -= a.z;
  72 + this.w -= a.w;
  73 + return this;
  74 + }
  75 +
  76 + //distance(pt1:Vector3D, pt2:Vector3D):Number
  77 + //[static] Returns the distance between two Vector3D objects.
  78 + Vector3D.distance = function(pt1, pt2)
  79 + {
  80 + var pow = Math.pow;
  81 + var x = pow(pt1.x - pt2.x, 2);
  82 + var y = pow(pt1.y - pt2.y, 2);
  83 + var z = pow(pt1.z - pt2.z, 2);
  84 + return Math.sqrt(x + y + z);
  85 + }
  86 +
  87 + //dotProduct(a:Vector3D):Number
  88 + //If the current Vector3D object and the one specified as the parameter are unit vertices, this method returns the cosine of the angle between the two vertices.
  89 + Vector3D.prototype.dotProduct = function(a)
  90 + {
  91 + var d = (this.x * a.x) + (this.y * a.y) + (this.z * a.z);
  92 + // return (this.get_length() == 1 && a.get_length() == 1) ? Math.acos(d) : d;
  93 + return d;
  94 + }
  95 +
  96 + //equals(toCompare:Vector3D, allFour:Boolean = false):Boolean
  97 + //Determines whether two Vector3D objects are equal by comparing the x, y, and z elements of the current Vector3D object with a specified Vector3D object.
  98 + Vector3D.prototype.equals = function(toCompare, allFour)
  99 + {
  100 + if (allFour)
  101 + return (this.x == toCompare.x && this.y == toCompare.y && this.z == toCompare.z && this.w == toCompare.w);
  102 + else
  103 + return (this.x == toCompare.x && this.y == toCompare.y && this.z == toCompare.z);
  104 + }
  105 +
  106 + //incrementBy(a:Vector3D):void
  107 + //Increments the value of the x, y, and z elements of the current Vector3D object by the values of the x, y, and z elements of a specified Vector3D object.
  108 + Vector3D.prototype.incrementBy = function(a)
  109 + {
  110 + this.x += a.x;
  111 + this.y += a.y;
  112 + this.z += a.z;
  113 + this.w += a.w;
  114 + return this;
  115 + }
  116 +
  117 + //nearEquals(toCompare:Vector3D, tolerance:Number, allFour:Boolean = false):Boolean
  118 + //Compares the elements of the current Vector3D object with the elements of a specified Vector3D object to determine whether they are nearly equal.
  119 + Vector3D.prototype.nearEquals = function(toCompare, tolerance, allFour)
  120 + {
  121 + var abs = Math.abs;
  122 + if (allFour)
  123 + return (abs(this.x - toCompare.x) < tolerance
  124 + && abs(this.y - toCompare.y) < tolerance
  125 + && abs(this.z - toCompare.z) < tolerance
  126 + && abs(this.w - toCompare.w) < tolerance);
  127 + else
  128 + return (abs(this.x - toCompare.x) < tolerance
  129 + && abs(this.y - toCompare.y) < tolerance
  130 + && abs(this.z - toCompare.z) < tolerance);
  131 + }
  132 +
  133 + //negate():void
  134 + //Sets the current Vector3D object to its inverse.
  135 + Vector3D.prototype.negate = function()
  136 + {
  137 + this.x *= -1;
  138 + this.y *= -1;
  139 + this.z *= -1;
  140 + return this;
  141 + }
  142 +
  143 + //normalize():Number
  144 + //Converts a Vector3D object to a unit vector by dividing the first three elements (x, y, z) by the length of the vector.
  145 + Vector3D.prototype.normalize = function()
  146 + {
  147 + var f = this.get_length();
  148 + if (f > 0)
  149 + {
  150 + this.x = this.x / f;
  151 + this.y = this.y / f;
  152 + this.z = this.z / f;
  153 + }
  154 + return f;
  155 + }
  156 +
  157 +
  158 + //project():void
  159 + //Divides the value of the x, y, and z properties of the current Vector3D object by the value of its w property.
  160 + Vector3D.prototype.project = function()
  161 + {
  162 + var w = this.w;
  163 + this.x /= w;
  164 + this.y /= w;
  165 + this.z /= w;
  166 + this.w = 1;
  167 + return this;
  168 + }
  169 +
  170 + //scaleBy(s:Number):void
  171 + //Scales the current Vector3D object by a scalar, a magnitude.
  172 + Vector3D.prototype.scaleBy = function(s)
  173 + {
  174 + this.x *= s;
  175 + this.y *= s;
  176 + this.z *= s;
  177 + return this;
  178 + }
  179 +
  180 + //subtract(a:Vector3D):Vector3D
  181 + //Subtracts the value of the x, y, and z elements of the current Vector3D object from the values of the x, y, and z elements of another Vector3D object.
  182 + Vector3D.prototype.subtract = function(a)
  183 + {
  184 + return new Vector3D(this.x - a.x, this.y - a.y, this.z - a.z, this.w /* - a.w */);
  185 + }
  186 +
  187 + //toString():String
  188 + //Returns a string representation of the current Vector3D object.
  189 + Vector3D.prototype.toString = function()
  190 + {
  191 + return '[ ' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ' ]';
  192 + }
  193 +
  194 +
  195 + /**
  196 + * @function get_length determines the length of a vector
  197 + * @param v {array} in the format [x,y,z,w]
  198 + * @type number
  199 + **/
  200 + Vector3D.prototype.get_length = function()
  201 + {
  202 + var sq = this.get_lengthSquared();
  203 + return (sq > 0) ? Math.pow(sq, 0.5) : 0.0;
  204 + };
  205 +
  206 + /**
  207 + * @function get_length_squared determines the length squared of a vector
  208 + * @param v {array} in the format [x,y,z,w]
  209 + * @type number
  210 + **/
  211 + Vector3D.prototype.get_lengthSquared = function()
  212 + {
  213 + var x = this.x, y = this.y, z = this.z;
  214 + return x * x + y * y + z * z;
  215 + };
  216 +
  217 + Vector3D.X_AXIS = new Vector3D(1, 0, 0, 0);
  218 + Vector3D.Y_AXIS = new Vector3D(0, 1, 0, 0);
  219 + Vector3D.Z_AXIS = new Vector3D(0, 0, 1, 0);
  220 +
  221 +
  222 + jiglib.Vector3D = Vector3D;
  223 +
  224 +})(jiglib);
1,834 geom/glMatrix.js
... ... @@ -0,0 +1,1834 @@
  1 +/*
  2 + * glMatrix.js - High performance matrix and vector operations for WebGL
  3 + * version 0.9.6
  4 + */
  5 +
  6 +/*
  7 + * Copyright (c) 2011 Brandon Jones
  8 + *
  9 + * This software is provided 'as-is', without any express or implied
  10 + * warranty. In no event will the authors be held liable for any damages
  11 + * arising from the use of this software.
  12 + *
  13 + * Permission is granted to anyone to use this software for any purpose,
  14 + * including commercial applications, and to alter it and redistribute it
  15 + * freely, subject to the following restrictions:
  16 + *
  17 + * 1. The origin of this software must not be misrepresented; you must not
  18 + * claim that you wrote the original software. If you use this software
  19 + * in a product, an acknowledgment in the product documentation would be
  20 + * appreciated but is not required.
  21 + *
  22 + * 2. Altered source versions must be plainly marked as such, and must not
  23 + * be misrepresented as being the original software.
  24 + *
  25 + * 3. This notice may not be removed or altered from any source
  26 + * distribution.
  27 + */
  28 +
  29 +// Fallback for systems that don't support WebGL
  30 +if(typeof Float32Array != 'undefined') {
  31 + glMatrixArrayType = Float32Array;
  32 +} else if(typeof WebGLFloatArray != 'undefined') {
  33 + glMatrixArrayType = WebGLFloatArray; // This is officially deprecated and should dissapear in future revisions.
  34 +} else {
  35 + glMatrixArrayType = Array;
  36 +}
  37 +
  38 +/*
  39 + * vec3 - 3 Dimensional Vector
  40 + */
  41 +var vec3 = {};
  42 +
  43 +/*
  44 + * vec3.create
  45 + * Creates a new instance of a vec3 using the default array type
  46 + * Any javascript array containing at least 3 numeric elements can serve as a vec3
  47 + *
  48 + * Params:
  49 + * vec - Optional, vec3 containing values to initialize with
  50 + *
  51 + * Returns:
  52 + * New vec3
  53 + */
  54 +vec3.create = function(vec) {
  55 + var dest = new glMatrixArrayType(3);
  56 +
  57 + if(vec) {
  58 + dest[0] = vec[0];
  59 + dest[1] = vec[1];
  60 + dest[2] = vec[2];
  61 + }
  62 +
  63 + return dest;
  64 +};
  65 +
  66 +/*
  67 + * vec3.set
  68 + * Copies the values of one vec3 to another
  69 + *
  70 + * Params:
  71 + * vec - vec3 containing values to copy
  72 + * dest - vec3 receiving copied values
  73 + *
  74 + * Returns:
  75 + * dest
  76 + */
  77 +vec3.set = function(vec, dest) {
  78 + dest[0] = vec[0];
  79 + dest[1] = vec[1];
  80 + dest[2] = vec[2];
  81 +
  82 + return dest;
  83 +};
  84 +
  85 +/*
  86 + * vec3.add
  87 + * Performs a vector addition
  88 + *
  89 + * Params:
  90 + * vec - vec3, first operand
  91 + * vec2 - vec3, second operand
  92 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  93 + *
  94 + * Returns:
  95 + * dest if specified, vec otherwise
  96 + */
  97 +vec3.add = function(vec, vec2, dest) {
  98 + if(!dest || vec == dest) {
  99 + vec[0] += vec2[0];
  100 + vec[1] += vec2[1];
  101 + vec[2] += vec2[2];
  102 + return vec;
  103 + }
  104 +
  105 + dest[0] = vec[0] + vec2[0];
  106 + dest[1] = vec[1] + vec2[1];
  107 + dest[2] = vec[2] + vec2[2];
  108 + return dest;
  109 +};
  110 +
  111 +/*
  112 + * vec3.subtract
  113 + * Performs a vector subtraction
  114 + *
  115 + * Params:
  116 + * vec - vec3, first operand
  117 + * vec2 - vec3, second operand
  118 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  119 + *
  120 + * Returns:
  121 + * dest if specified, vec otherwise
  122 + */
  123 +vec3.subtract = function(vec, vec2, dest) {
  124 + if(!dest || vec == dest) {
  125 + vec[0] -= vec2[0];
  126 + vec[1] -= vec2[1];
  127 + vec[2] -= vec2[2];
  128 + return vec;
  129 + }
  130 +
  131 + dest[0] = vec[0] - vec2[0];
  132 + dest[1] = vec[1] - vec2[1];
  133 + dest[2] = vec[2] - vec2[2];
  134 + return dest;
  135 +};
  136 +
  137 +/*
  138 + * vec3.negate
  139 + * Negates the components of a vec3
  140 + *
  141 + * Params:
  142 + * vec - vec3 to negate
  143 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  144 + *
  145 + * Returns:
  146 + * dest if specified, vec otherwise
  147 + */
  148 +vec3.negate = function(vec, dest) {
  149 + if(!dest) { dest = vec; }
  150 +
  151 + dest[0] = -vec[0];
  152 + dest[1] = -vec[1];
  153 + dest[2] = -vec[2];
  154 + return dest;
  155 +};
  156 +
  157 +/*
  158 + * vec3.scale
  159 + * Multiplies the components of a vec3 by a scalar value
  160 + *
  161 + * Params:
  162 + * vec - vec3 to scale
  163 + * val - Numeric value to scale by
  164 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  165 + *
  166 + * Returns:
  167 + * dest if specified, vec otherwise
  168 + */
  169 +vec3.scale = function(vec, val, dest) {
  170 + if(!dest || vec == dest) {
  171 + vec[0] *= val;
  172 + vec[1] *= val;
  173 + vec[2] *= val;
  174 + return vec;
  175 + }
  176 +
  177 + dest[0] = vec[0]*val;
  178 + dest[1] = vec[1]*val;
  179 + dest[2] = vec[2]*val;
  180 + return dest;
  181 +};
  182 +
  183 +/*
  184 + * vec3.normalize
  185 + * Generates a unit vector of the same direction as the provided vec3
  186 + * If vector length is 0, returns [0, 0, 0]
  187 + *
  188 + * Params:
  189 + * vec - vec3 to normalize
  190 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  191 + *
  192 + * Returns:
  193 + * dest if specified, vec otherwise
  194 + */
  195 +vec3.normalize = function(vec, dest) {
  196 + if(!dest) { dest = vec; }
  197 +
  198 + var x = vec[0], y = vec[1], z = vec[2];
  199 + var len = Math.sqrt(x*x + y*y + z*z);
  200 +
  201 + if (!len) {
  202 + dest[0] = 0;
  203 + dest[1] = 0;
  204 + dest[2] = 0;
  205 + return dest;
  206 + } else if (len == 1) {
  207 + dest[0] = x;
  208 + dest[1] = y;
  209 + dest[2] = z;
  210 + return dest;
  211 + }
  212 +
  213 + len = 1 / len;
  214 + dest[0] = x*len;
  215 + dest[1] = y*len;
  216 + dest[2] = z*len;
  217 + return dest;
  218 +};
  219 +
  220 +/*
  221 + * vec3.cross
  222 + * Generates the cross product of two vec3s
  223 + *
  224 + * Params:
  225 + * vec - vec3, first operand
  226 + * vec2 - vec3, second operand
  227 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  228 + *
  229 + * Returns:
  230 + * dest if specified, vec otherwise
  231 + */
  232 +vec3.cross = function(vec, vec2, dest){
  233 + if(!dest) { dest = vec; }
  234 +
  235 + var x = vec[0], y = vec[1], z = vec[2];
  236 + var x2 = vec2[0], y2 = vec2[1], z2 = vec2[2];
  237 +
  238 + dest[0] = y*z2 - z*y2;
  239 + dest[1] = z*x2 - x*z2;
  240 + dest[2] = x*y2 - y*x2;
  241 + return dest;
  242 +};
  243 +
  244 +/*
  245 + * vec3.length
  246 + * Caclulates the length of a vec3
  247 + *
  248 + * Params:
  249 + * vec - vec3 to calculate length of
  250 + *
  251 + * Returns:
  252 + * Length of vec
  253 + */
  254 +vec3.length = function(vec){
  255 + var x = vec[0], y = vec[1], z = vec[2];
  256 + return Math.sqrt(x*x + y*y + z*z);
  257 +};
  258 +
  259 +/*
  260 + * vec3.dot
  261 + * Caclulates the dot product of two vec3s
  262 + *
  263 + * Params:
  264 + * vec - vec3, first operand
  265 + * vec2 - vec3, second operand
  266 + *
  267 + * Returns:
  268 + * Dot product of vec and vec2
  269 + */
  270 +vec3.dot = function(vec, vec2){
  271 + return vec[0]*vec2[0] + vec[1]*vec2[1] + vec[2]*vec2[2];
  272 +};
  273 +
  274 +/*
  275 + * vec3.direction
  276 + * Generates a unit vector pointing from one vector to another
  277 + *
  278 + * Params:
  279 + * vec - origin vec3
  280 + * vec2 - vec3 to point to
  281 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  282 + *
  283 + * Returns:
  284 + * dest if specified, vec otherwise
  285 + */
  286 +vec3.direction = function(vec, vec2, dest) {
  287 + if(!dest) { dest = vec; }
  288 +
  289 + var x = vec[0] - vec2[0];
  290 + var y = vec[1] - vec2[1];
  291 + var z = vec[2] - vec2[2];
  292 +
  293 + var len = Math.sqrt(x*x + y*y + z*z);
  294 + if (!len) {
  295 + dest[0] = 0;
  296 + dest[1] = 0;
  297 + dest[2] = 0;
  298 + return dest;
  299 + }
  300 +
  301 + len = 1 / len;
  302 + dest[0] = x * len;
  303 + dest[1] = y * len;
  304 + dest[2] = z * len;
  305 + return dest;
  306 +};
  307 +
  308 +/*
  309 + * vec3.lerp
  310 + * Performs a linear interpolation between two vec3
  311 + *
  312 + * Params:
  313 + * vec - vec3, first vector
  314 + * vec2 - vec3, second vector
  315 + * lerp - interpolation amount between the two inputs
  316 + * dest - Optional, vec3 receiving operation result. If not specified result is written to vec
  317 + *
  318 + * Returns:
  319 + * dest if specified, vec otherwise
  320 + */
  321 +vec3.lerp = function(vec, vec2, lerp, dest){
  322 + if(!dest) { dest = vec; }
  323 +
  324 + dest[0] = vec[0] + lerp * (vec2[0] - vec[0]);
  325 + dest[1] = vec[1] + lerp * (vec2[1] - vec[1]);
  326 + dest[2] = vec[2] + lerp * (vec2[2] - vec[2]);
  327 +
  328 + return dest;
  329 +}
  330 +
  331 +/*
  332 + * vec3.str
  333 + * Returns a string representation of a vector
  334 + *
  335 + * Params:
  336 + * vec - vec3 to represent as a string
  337 + *
  338 + * Returns:
  339 + * string representation of vec
  340 + */
  341 +vec3.str = function(vec) {
  342 + return '[' + vec[0] + ', ' + vec[1] + ', ' + vec[2] + ']';
  343 +};
  344 +
  345 +/*
  346 + * mat3 - 3x3 Matrix
  347 + */
  348 +var mat3 = {};
  349 +
  350 +/*
  351 + * mat3.create
  352 + * Creates a new instance of a mat3 using the default array type
  353 + * Any javascript array containing at least 9 numeric elements can serve as a mat3
  354 + *
  355 + * Params:
  356 + * mat - Optional, mat3 containing values to initialize with
  357 + *
  358 + * Returns:
  359 + * New mat3
  360 + */
  361 +mat3.create = function(mat) {
  362 + var dest = new glMatrixArrayType(9);
  363 +
  364 + if(mat) {
  365 + dest[0] = mat[0];
  366 + dest[1] = mat[1];
  367 + dest[2] = mat[2];
  368 + dest[3] = mat[3];
  369 + dest[4] = mat[4];
  370 + dest[5] = mat[5];
  371 + dest[6] = mat[6];
  372 + dest[7] = mat[7];
  373 + dest[8] = mat[8];
  374 + }
  375 +
  376 + return dest;
  377 +};
  378 +
  379 +/*
  380 + * mat3.set
  381 + * Copies the values of one mat3 to another
  382 + *
  383 + * Params:
  384 + * mat - mat3 containing values to copy
  385 + * dest - mat3 receiving copied values
  386 + *
  387 + * Returns:
  388 + * dest
  389 + */
  390 +mat3.set = function(mat, dest) {
  391 + dest[0] = mat[0];
  392 + dest[1] = mat[1];
  393 + dest[2] = mat[2];
  394 + dest[3] = mat[3];
  395 + dest[4] = mat[4];
  396 + dest[5] = mat[5];
  397 + dest[6] = mat[6];
  398 + dest[7] = mat[7];
  399 + dest[8] = mat[8];
  400 + return dest;
  401 +};
  402 +
  403 +/*
  404 + * mat3.identity
  405 + * Sets a mat3 to an identity matrix
  406 + *
  407 + * Params:
  408 + * dest - mat3 to set
  409 + *
  410 + * Returns:
  411 + * dest
  412 + */
  413 +mat3.identity = function(dest) {
  414 + dest[0] = 1;
  415 + dest[1] = 0;
  416 + dest[2] = 0;
  417 + dest[3] = 0;
  418 + dest[4] = 1;
  419 + dest[5] = 0;
  420 + dest[6] = 0;
  421 + dest[7] = 0;
  422 + dest[8] = 1;
  423 + return dest;
  424 +};
  425 +
  426 +/*
  427 + * mat4.transpose
  428 + * Transposes a mat3 (flips the values over the diagonal)
  429 + *
  430 + * Params:
  431 + * mat - mat3 to transpose
  432 + * dest - Optional, mat3 receiving transposed values. If not specified result is written to mat
  433 + *
  434 + * Returns:
  435 + * dest is specified, mat otherwise
  436 + */
  437 +mat3.transpose = function(mat, dest) {
  438 + // If we are transposing ourselves we can skip a few steps but have to cache some values
  439 + if(!dest || mat == dest) {
  440 + var a01 = mat[1], a02 = mat[2];
  441 + var a12 = mat[5];
  442 +
  443 + mat[1] = mat[3];
  444 + mat[2] = mat[6];
  445 + mat[3] = a01;
  446 + mat[5] = mat[7];
  447 + mat[6] = a02;
  448 + mat[7] = a12;
  449 + return mat;
  450 + }
  451 +
  452 + dest[0] = mat[0];
  453 + dest[1] = mat[3];
  454 + dest[2] = mat[6];
  455 + dest[3] = mat[1];
  456 + dest[4] = mat[4];
  457 + dest[5] = mat[7];
  458 + dest[6] = mat[2];
  459 + dest[7] = mat[5];
  460 + dest[8] = mat[8];
  461 + return dest;
  462 +};
  463 +
  464 +/*
  465 + * mat3.toMat4
  466 + * Copies the elements of a mat3 into the upper 3x3 elements of a mat4
  467 + *
  468 + * Params:
  469 + * mat - mat3 containing values to copy
  470 + * dest - Optional, mat4 receiving copied values
  471 + *
  472 + * Returns:
  473 + * dest if specified, a new mat4 otherwise
  474 + */
  475 +mat3.toMat4 = function(mat, dest) {
  476 + if(!dest) { dest = mat4.create(); }
  477 +
  478 + dest[0] = mat[0];
  479 + dest[1] = mat[1];
  480 + dest[2] = mat[2];
  481 + dest[3] = 0;
  482 +
  483 + dest[4] = mat[3];
  484 + dest[5] = mat[4];
  485 + dest[6] = mat[5];
  486 + dest[7] = 0;
  487 +
  488 + dest[8] = mat[6];
  489 + dest[9] = mat[7];
  490 + dest[10] = mat[8];
  491 + dest[11] = 0;
  492 +
  493 + dest[12] = 0;
  494 + dest[13] = 0;
  495 + dest[14] = 0;
  496 + dest[15] = 1;
  497 +
  498 + return dest;
  499 +}
  500 +
  501 +/*
  502 + * mat3.str
  503 + * Returns a string representation of a mat3
  504 + *
  505 + * Params:
  506 + * mat - mat3 to represent as a string
  507 + *
  508 + * Returns:
  509 + * string representation of mat
  510 + */
  511 +mat3.str = function(mat) {
  512 + return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] +
  513 + ', ' + mat[3] + ', '+ mat[4] + ', ' + mat[5] +
  514 + ', ' + mat[6] + ', ' + mat[7] + ', '+ mat[8] + ']';
  515 +};
  516 +
  517 +/*
  518 + * mat4 - 4x4 Matrix
  519 + */
  520 +var mat4 = {};
  521 +
  522 +/*
  523 + * mat4.create
  524 + * Creates a new instance of a mat4 using the default array type
  525 + * Any javascript array containing at least 16 numeric elements can serve as a mat4
  526 + *
  527 + * Params:
  528 + * mat - Optional, mat4 containing values to initialize with
  529 + *
  530 + * Returns:
  531 + * New mat4
  532 + */
  533 +mat4.create = function(mat) {
  534 + var dest = new glMatrixArrayType(16);
  535 +
  536 + if(mat) {
  537 + dest[0] = mat[0];
  538 + dest[1] = mat[1];
  539 + dest[2] = mat[2];
  540 + dest[3] = mat[3];
  541 + dest[4] = mat[4];
  542 + dest[5] = mat[5];
  543 + dest[6] = mat[6];
  544 + dest[7] = mat[7];
  545 + dest[8] = mat[8];
  546 + dest[9] = mat[9];
  547 + dest[10] = mat[10];
  548 + dest[11] = mat[11];
  549 + dest[12] = mat[12];
  550 + dest[13] = mat[13];
  551 + dest[14] = mat[14];
  552 + dest[15] = mat[15];
  553 + }
  554 +
  555 + return dest;
  556 +};
  557 +
  558 +/*
  559 + * mat4.set
  560 + * Copies the values of one mat4 to another
  561 + *
  562 + * Params:
  563 + * mat - mat4 containing values to copy
  564 + * dest - mat4 receiving copied values
  565 + *
  566 + * Returns:
  567 + * dest
  568 + */
  569 +mat4.set = function(mat, dest) {
  570 + dest[0] = mat[0];
  571 + dest[1] = mat[1];
  572 + dest[2] = mat[2];
  573 + dest[3] = mat[3];
  574 + dest[4] = mat[4];
  575 + dest[5] = mat[5];
  576 + dest[6] = mat[6];
  577 + dest[7] = mat[7];
  578 + dest[8] = mat[8];
  579 + dest[9] = mat[9];
  580 + dest[10] = mat[10];
  581 + dest[11] = mat[11];
  582 + dest[12] = mat[12];
  583 + dest[13] = mat[13];
  584 + dest[14] = mat[14];
  585 + dest[15] = mat[15];
  586 + return dest;
  587 +};
  588 +
  589 +/*
  590 + * mat4.identity
  591 + * Sets a mat4 to an identity matrix
  592 + *
  593 + * Params:
  594 + * dest - mat4 to set
  595 + *
  596 + * Returns:
  597 + * dest
  598 + */
  599 +mat4.identity = function(dest) {
  600 + dest[0] = 1;
  601 + dest[1] = 0;
  602 + dest[2] = 0;
  603 + dest[3] = 0;
  604 + dest[4] = 0;
  605 + dest[5] = 1;
  606 + dest[6] = 0;
  607 + dest[7] = 0;
  608 + dest[8] = 0;
  609 + dest[9] = 0;
  610 + dest[10] = 1;
  611 + dest[11] = 0;
  612 + dest[12] = 0;
  613 + dest[13] = 0;
  614 + dest[14] = 0;
  615 + dest[15] = 1;
  616 + return dest;
  617 +};
  618 +
  619 +/*
  620 + * mat4.transpose
  621 + * Transposes a mat4 (flips the values over the diagonal)
  622 + *
  623 + * Params:
  624 + * mat - mat4 to transpose
  625 + * dest - Optional, mat4 receiving transposed values. If not specified result is written to mat
  626 + *
  627 + * Returns:
  628 + * dest is specified, mat otherwise
  629 + */
  630 +mat4.transpose = function(mat, dest) {
  631 + // If we are transposing ourselves we can skip a few steps but have to cache some values
  632 + if(!dest || mat == dest) {
  633 + var a01 = mat[1], a02 = mat[2], a03 = mat[3];
  634 + var a12 = mat[6], a13 = mat[7];
  635 + var a23 = mat[11];
  636 +
  637 + mat[1] = mat[4];
  638 + mat[2] = mat[8];
  639 + mat[3] = mat[12];
  640 + mat[4] = a01;
  641 + mat[6] = mat[9];
  642 + mat[7] = mat[13];
  643 + mat[8] = a02;
  644 + mat[9] = a12;
  645 + mat[11] = mat[14];
  646 + mat[12] = a03;
  647 + mat[13] = a13;
  648 + mat[14] = a23;
  649 + return mat;
  650 + }
  651 +
  652 + dest[0] = mat[0];
  653 + dest[1] = mat[4];
  654 + dest[2] = mat[8];
  655 + dest[3] = mat[12];
  656 + dest[4] = mat[1];
  657 + dest[5] = mat[5];
  658 + dest[6] = mat[9];
  659 + dest[7] = mat[13];
  660 + dest[8] = mat[2];
  661 + dest[9] = mat[6];
  662 + dest[10] = mat[10];
  663 + dest[11] = mat[14];
  664 + dest[12] = mat[3];
  665 + dest[13] = mat[7];
  666 + dest[14] = mat[11];
  667 + dest[15] = mat[15];
  668 + return dest;
  669 +};
  670 +
  671 +/*
  672 + * mat4.determinant
  673 + * Calculates the determinant of a mat4
  674 + *
  675 + * Params:
  676 + * mat - mat4 to calculate determinant of
  677 + *
  678 + * Returns:
  679 + * determinant of mat
  680 + */
  681 +mat4.determinant = function(mat) {
  682 + // Cache the matrix values (makes for huge speed increases!)
  683 + var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  684 + var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  685 + var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  686 + var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
  687 +
  688 + return a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
  689 + a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
  690 + a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
  691 + a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
  692 + a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
  693 + a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
  694 +};
  695 +
  696 +/*
  697 + * mat4.inverse
  698 + * Calculates the inverse matrix of a mat4
  699 + *
  700 + * Params:
  701 + * mat - mat4 to calculate inverse of
  702 + * dest - Optional, mat4 receiving inverse matrix. If not specified result is written to mat
  703 + *
  704 + * Returns:
  705 + * dest is specified, mat otherwise
  706 + */
  707 +mat4.inverse = function(mat, dest) {
  708 + if(!dest) { dest = mat; }
  709 +
  710 + // Cache the matrix values (makes for huge speed increases!)
  711 + var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
  712 + var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
  713 + var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
  714 + var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
  715 +
  716 + var b00 = a00*a11 - a01*a10;
  717 + var b01 = a00*a12 - a02*a10;
  718 + var b02 = a00*a13 - a03*a10;
  719 + var b03 = a01*a12 - a02*a11;
  720 + var b04 = a01*a13 - a03*a11;
  721 + var b05 = a02*a13 - a03*a12;
  722 + var b06 = a20*a31 - a21*a30;
  723 + var b07 = a20*a32 - a22*a30;
  724 + var b08 = a20*a33 - a23*a30;
  725 + var b09 = a21*a32 - a22*a31;
  726 + var b10 = a21*a33 - a23*a31;
  727 + var b11 = a22*a33 - a23*a32;
  728 +
  729 + // Calculate the determinant (inlined to avoid double-caching)
  730 + var invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
  731 +
  732 + dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet;
  733 + dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet;
  734 + dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet;
  735 + dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet;
  736 + dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet;
  737 + dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet;
  738 + dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet;
  739 + dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet;
  740 + dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet;
  741 + dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet;
  742 + dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet;
  743 + dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet;
  744 + dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet;
  745 + dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet;
  746 + dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet;
  747 + dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet;
  748 +
  749 + return dest;
  750 +};
  751 +
  752 +/*
  753 + * mat4.toRotationMat
  754 + * Copies the upper 3x3 elements of a mat4 into another mat4
  755 + *
  756 + * Params:
  757 + * mat - mat4 containing values to copy
  758 + * dest - Optional, mat4 receiving copied values
  759 + *