From c5a3abd914042c3fb3eb9b7ab061fbcca6fc0196 Mon Sep 17 00:00:00 2001 From: Nikos M Date: Tue, 3 Jan 2023 16:37:45 +0200 Subject: [PATCH] v.1.0.0 --- api-reference.md | 62 +- beeld.config | 52 +- build-bundle.bat => build-min.bat | 6 +- build/MOD3.min.js | 11 +- build/classy.js | 10 - build/mod3.bundle.js | 21 - build/mod3.js | 2514 +++++++++++++++++ examples/Copperlicht/Bend.html | 2 +- examples/Copperlicht/Bloat.html | 2 +- examples/Copperlicht/Break.html | 2 +- examples/Copperlicht/Noise.html | 2 +- examples/Copperlicht/Skew.html | 2 +- examples/Copperlicht/Taper.html | 2 +- examples/Copperlicht/Twist.html | 2 +- examples/CubicVR/Bend.html | 2 +- examples/CubicVR/Bloat.html | 2 +- examples/CubicVR/Break.html | 2 +- examples/CubicVR/Noise.html | 2 +- examples/CubicVR/Perlin.html | 2 +- examples/CubicVR/Skew.html | 2 +- examples/CubicVR/Taper.html | 2 +- examples/CubicVR/Twist.html | 2 +- examples/J3D/Bend.html | 2 +- examples/J3D/Noise.html | 2 +- examples/J3D/Perlin.html | 2 +- examples/J3D/Skew.html | 2 +- examples/J3D/Taper.html | 2 +- examples/J3D/Twist.html | 2 +- examples/OSG/Bend.html | 2 +- examples/OSG/Bloat.html | 2 +- examples/OSG/Perlin.html | 2 +- examples/OSG/Skew.html | 2 +- examples/OSG/Taper.html | 2 +- examples/OSG/Twist.html | 2 +- examples/Pre3D/Bend.html | 2 +- examples/Pre3D/Twist.html | 2 +- examples/Three/Bend.html | 2 +- examples/Three/Bloat.html | 2 +- examples/Three/Break.html | 2 +- examples/Three/DisplaceMap.html | 2 +- examples/Three/Noise.html | 2 +- examples/Three/Perlin.html | 2 +- examples/Three/Skew.html | 2 +- examples/Three/Taper.html | 2 +- examples/Three/Twist.html | 2 +- examples/Three/flipbook3/FlipBook3D.js | 133 +- .../Three/flipbook3/FlipBook3DApplication.js | 104 +- examples/Three/flipbook3/index.html | 2 +- readme.md | 41 +- src/MOD3.js | 18 +- src/core/Mesh.js | 430 ++- src/core/ModifierStack.js | 122 +- src/footer.js | 3 + src/header.js | 81 + src/math/List.js | 120 +- src/math/Matrix.js | 112 +- src/math/Matrix4.js | 231 +- src/math/ModConstant.js | 68 +- src/math/Phase.js | 41 +- src/math/Point.js | 27 +- src/math/Range.js | 51 +- src/math/Vector3.js | 321 +-- src/math/XMath.js | 63 +- src/modifiers/Bend.js | 84 +- src/modifiers/Bloat.js | 51 +- src/modifiers/Break.js | 60 +- src/modifiers/DisplaceMap.js | 80 +- src/modifiers/Noise.js | 86 +- src/modifiers/Perlin.js | 107 +- src/modifiers/Pivot.js | 53 +- src/modifiers/Skew.js | 96 +- src/modifiers/Taper.js | 68 +- src/modifiers/Twist.js | 66 +- src/modifiers/Wheel.js | 117 +- src/plugins/Copperlicht/Copperlicht.js | 99 +- src/plugins/Copperlicht/Copperlicht.min.js | 2 +- src/plugins/CubicVR/CubicVR.js | 86 +- src/plugins/CubicVR/CubicVR.min.js | 2 +- src/plugins/J3D/J3D.js | 84 +- src/plugins/J3D/J3D.min.js | 2 +- src/plugins/OSG/OSG.js | 86 +- src/plugins/OSG/OSG.min.js | 2 +- src/plugins/Pre3D/Pre3D.js | 86 +- src/plugins/Pre3D/Pre3D.min.js | 2 +- src/plugins/Three/Three.js | 86 +- src/plugins/Three/Three.min.js | 2 +- 86 files changed, 4183 insertions(+), 1944 deletions(-) rename build-bundle.bat => build-min.bat (80%) delete mode 100644 build/classy.js delete mode 100644 build/mod3.bundle.js create mode 100644 build/mod3.js create mode 100644 src/footer.js create mode 100644 src/header.js diff --git a/api-reference.md b/api-reference.md index 799fb43..d3fa500 100644 --- a/api-reference.md +++ b/api-reference.md @@ -1,10 +1,10 @@ -### Pivot modifier +### Pivot modifier Allows to move the pivot point of a 3D mesh. @author Bartek Drozdz - + @@ -17,16 +17,16 @@ Bends an object along an axis. -### Bloat modifier +### Bloat modifier Bloats a mesh by forcing vertices out of specified sphere @author makc - -### Twist modifier + +### Twist modifier Twist mesh along an axis Adapted from the Twist modifier for PV3D @@ -34,90 +34,90 @@ Adapted from the Twist modifier for PV3D -### Skew modifier +### Skew modifier Skew mesh along an axis @author Bartek Drozdz - -### Taper modifier + +### Taper modifier The taper modifier displaces the vertices on two axes proportionally to their position on the third axis. @author Bartek Drozdz - -### Wheel modifier + +### Wheel modifier Use it with vehicle models for wheels. -The usual problem with a 3d wheel in a vahicle is that it is -supposed to turn (steer) and roll in the same time. +The usual problem with a 3d wheel in a vahicle is that it is +supposed to turn (steer) and roll in the same time. So, this code: ```javascript wheel.rotationY = 10; // Steer 10deg to the left -wheel.rotationZ +- 5; // Roll with a speed of 5 +wheel.rotationZ += 5; // Roll with a speed of 5 ``` This will make the wheel roll incorectly. -A usual way to solve this problem is to put the wheel in another DisplayObject3D/Mesh, +A usual way to solve this problem is to put the wheel in another DisplayObject3D/Mesh, turn the parent and roll the child, like that: ```javascript steer.rotationY = 10; // Steer 10deg to the left -steer.wheel.rotationZ +- 5; // Roll with a speed of 5 +steer.wheel.rotationZ += 5; // Roll with a speed of 5 ``` That will make the wheel behave correctly. But it can be uncomfortanble to apply, especially to imported complex Collada models. -The Wheel modifier elegantly solves this problem by doind the proper math in order to steer and roll -a single mesh at the same time. The only thing you need to do is to specify a steer vector and +The Wheel modifier elegantly solves this problem by doind the proper math in order to steer and roll +a single mesh at the same time. The only thing you need to do is to specify a steer vector and roll vector - usually it will be 2 of the cardinal axes. The default value is: -* steer - along the Y axis / new Vector3(0, 1, 0) -* roll - along the Z axis / new Vector3(0, 0, 1) +* steer - along the Y axis / new Vector3(0, 1, 0) +* roll - along the Z axis / new Vector3(0, 0, 1) It should work with most car models imported from 3D editors as this is the natural position of a wheel. -Please note, that Papervision primitive cylinder, which may also be used as wheel, will require different axes -(Y for roll and Z or X for steer). +*Please note, that Papervision primitive cylinder, which may also be used as wheel, will require different axes +(Y for roll and Z or X for steer).* @author Bartek Drozdz -### Break modifier +### Break modifier Allow to break a mesh @author Bartek Drozdz - -### Noise modifier + +### Noise modifier Randomly displaces each vertex in all 3 axes - -### DisplaceMap (BitmapDisplacement) Modifier -Displaces vertices based on RGB values of bitmapData pixels. +### DisplaceMap (BitmapDisplacement) Modifier + +Displaces vertices based on RGB values of bitmapData pixels. BitmapDisplacement is inspired by both the AS3 built-in DisplacementMapFilter. It allows to use color values for each channels of a bitmap to modify the position of vertices in a mesh. -The displacement takes place along the cardinal axes, and each axis is mapped to a +The displacement takes place along the cardinal axes, and each axis is mapped to a channel in the bitmap: X for Red, Y for Green and Z for Blue. @author Bartek Drozdz @@ -125,14 +125,14 @@ channel in the bitmap: X for Red, Y for Green and Z for Blue. -### Perlin modifier +### Perlin modifier Displaces vertices based on a perlin/simplex noise source. Accepts a perlin/simplex noise data (with width and height information) and displaces vertices based on the value of each point of the noise map. - + @author Bartek Drozdz @uses: https://github.com/josephg/noisejs for JavaScript - + diff --git a/beeld.config b/beeld.config index e02da0b..8281af8 100644 --- a/beeld.config +++ b/beeld.config @@ -6,6 +6,7 @@ ################################################### settings ={} + Xpresion = "Xpresion::" RegExp = "RegExp::" @ @@ -21,8 +22,7 @@ tasks =[{}] build =[{}] src =[] - - !tpl:umd-header-deps.tpl.js # include a umd-header template + ./src/header.js # core ./src/MOD3.js @@ -74,21 +74,16 @@ tasks =[{}] ## Support for Pre3D #./src/plugins/Pre3D/Pre3D.js - !tpl:umd-footer.tpl.js # include a umd-footer template + ./src/footer.js @ # extract header from this file - header = ./src/MOD3.js + header = ./src/header.js replace =[{}] - - "@@ROOT@@" = "this" - "@@MODULE@@" = "MOD3" - "@@DEPS@@" = "Classy" - "@@VERSION@@" = "0.6.0" - "@@USE_STRICT@@" = '"use strict";' - + "@@VERSION@@" = "1.0.0" + "@@DATE@@" = Xpresion::date("Y-m-d H:i:s") @ # extract documentation @@ -99,44 +94,33 @@ tasks =[{}] "output" = "./api-reference.md" @ + out = ./build/mod3.js + @ + + minify =[{}] + + src =[] + ./build/mod3.js + @ + # Minify the Package (map of lists) minify ={} - # Options for Node UglifyJS Compiler (if used, default), (mangle and compress) uglifyjs =[] -m -c @ - + # Options for Java Closure Compiler (if used) closure =[] "--language_in=ECMASCRIPT5_STRICT" @ - + # Options for Java YUI Compressor Compiler (if used) yui =[] --preserve-semi @ - @ - - out = ./build/mod3.min.js - - @ - - - bundle =[{}] - - bundle =[] - - # bundle-in external dependencies - ./build/classy.js - ./build/mod3.min.js - - @ - - - out = ./build/mod3.bundle.js + out = ./build/mod3.min.js @ - @ diff --git a/build-bundle.bat b/build-min.bat similarity index 80% rename from build-bundle.bat rename to build-min.bat index fc6d99d..c097751 100644 --- a/build-bundle.bat +++ b/build-min.bat @@ -8,10 +8,10 @@ REM # REM ################################################### REM to use the python build tool do: -REM python %BUILDTOOLS%\Beeld.py --config ".\beeld.config" --tasks bundle +REM python %BUILDTOOLS%\Beeld.py --config ".\beeld.config" --tasks minify REM to use the php build tool do: -REM php -f %BUILDTOOLS%\Beeld.php -- --config=".\beeld.config" --tasks=bundle +REM php -f %BUILDTOOLS%\Beeld.php -- --config=".\beeld.config" --tasks=minify REM to use the node build tool do: -node %BUILDTOOLS%\Beeld.js --config ".\beeld.config" --tasks bundle +node %BUILDTOOLS%\Beeld.js --config ".\beeld.config" --tasks minify diff --git a/build/MOD3.min.js b/build/MOD3.min.js index 06030a8..224a976 100644 --- a/build/MOD3.min.js +++ b/build/MOD3.min.js @@ -1,11 +1,8 @@ /** -* -* MOD3.js -* @version: 0.6.0 -* @dependencies: Classy.js -* -* MOD3 3D Modifier Library for JavaScript +* MOD3 3D Modifier Library for JavaScript * port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/) +* +* @version 1.0.0 (2023-01-03 16:08:34) * https://github.com/foo123/MOD3 * -**/!function(t,n,e){"use strict";function r(t,n,e,r){return t?n.map(function(n,i){return(e?t[i]:t[n])||(r?r(n):null)}):[]}var i="Classy".split(/\s*,\s*/);"object"==typeof module&&module.exports?(module.$deps=module.$deps||{})&&(module.exports=module.$deps[n]=e.apply(t,r(module.$deps,i,!1,function(t){return require("./"+t.toLowerCase())}))):"function"==typeof define&&define.amd&&"function"==typeof require&&"function"==typeof require.specified&&require.specified(n)?define(n,["module"].concat(i),function(n){return e.moduleUri=n.uri,e.apply(t,r(Array.prototype.slice.call(arguments,1),i,!0))}):n in t||(t[n]=e.apply(t,r(t,i)))&&"function"==typeof define&&define.amd&&define(function(){return t[n]})}(this,"MOD3",function(t){"use strict";var n={VERSION:"0.6.0",Class:t.Class,StaticClass:function(n){return t.Class(t.STATIC,n)}};return!function(t,n){t.Constants={PI:Math.PI,invPI:1/Math.PI,halfPI:.5*Math.PI,doublePI:2*Math.PI,toRad:Math.PI/180,toDeg:180/Math.PI},t.ModConstant={NONE:0,LEFT:-1,RIGHT:1,X:1,Y:2,Z:4,Xi:0,Yi:1,Zi:2},t.XYZi=[null,0,1,null,2],t.iXYZ=[1,2,4],t.xyz=["x","y","z"],t.XYZ=["X","Y","Z"],t.Array32F="undefined"!=typeof Float32Array?Float32Array:Array,t.Array64F="undefined"!=typeof Float64Array?Float64Array:Array,t.Array8I="undefined"!=typeof Int8Array?Int8Array:Array,t.Array16I="undefined"!=typeof Int16Array?Int16Array:Array,t.Array32I="undefined"!=typeof Int32Array?Int32Array:Array,t.Array8U="undefined"!=typeof Uint8Array?Uint8Array:Array,t.Array16U="undefined"!=typeof Uint16Array?Uint16Array:Array,t.Array32U="undefined"!=typeof Uint32Array?Uint32Array:Array,t.VecArray=t.Array32F}(n),!function(t,n){var e,r=t.Constants.toRad,i=t.Constants.toDeg,o=(Math.min,Math.max,Math.pow),s=Math.round,a=Math.floor,u=Math.ceil,l=t.XMath=t.StaticClass({normalize:function(t,n,r){var i=n-t;return 0===i?1:e(0,1,(r-t)/n)},toRange:function(t,n,e){var r=n-t;return 0===r?0:t+r*e},inRange:function(t,n,e,r){return!1!==r?e>=t&&n>=e:e>t&&n>e},sign:function(t,n){return 0==t?n||0:t>0?1:-1},trim:function(t,n,e){return t>e?t:e>n?n:e},wrap:function(t,n,e){var r=n-t;return t>e?e+r:e>=n?e-r:e},degToRad:function(t){return t*r},radToDeg:function(t){return t*i},presicion:function(t,n){var e=o(10,n);return s(t*e)/e},uceil:function(t){return 0>t?a(t):u(t)}});e=l.clamp=l.trim}(n),!function(t,n){var e=t.XMath.normalize,r=t.XMath.toRange,i=t.XMath.trim;t.Range=t.Class({constructor:function o(t,n){var e=this;return e instanceof o?(e.start=null!=t?t:0,void(e.end=null!=n?n:1)):new o(t,n)},name:"Range",start:0,end:1,dispose:function(){var t=this;return t.start=null,t.end=null,t},getSize:function(){return this.end-this.start},move:function(t){this.start+=t,this.end+=t},isIn:function(t){return t>=this.start&&t<=this.end},normalize:function(t){return e(this.start,this.end,t)},toRange:function(t){return r(this.start,this.end,t)},trim:function(t){return i(this.start,this.end,t)},interpolate:function(t,n){return r(this.start,this.end,n.normalize(t))},toString:function(){return"["+this.start+" - "+this.end+"]"}})}(n),!function(t,n){var e=Math.sin,r=Math.abs;t.Phase=t.Class({constructor:function i(t){var n=this;return n instanceof i?void(n.value=t||0):new i(t)},name:"Phase",value:0,dispose:function(){return this.value=null,this},getPhasedValue:function(){return e(this.value)},getAbsPhasedValue:function(){return r(e(this.value))},getNormValue:function(){return.5*(e(this.value)+1)}})}(n),!function(t,n){var e=t.Point=t.Class({constructor:function r(t,n){var e=this;return e instanceof r?(e.x=null==t?0:t,void(e.y=null==n?0:n)):new r(t,n)},name:"Point",x:0,y:0,dispose:function(){var t=this;return t.x=null,t.y=null,t},clone:function(){return new e(this.x,this.y)}})}(n),!function(t,n){var e=Math.sin,r=Math.cos,i=t.Point,o=t.VecArray,s=t.Matrix=t.Class({__static__:{transform:function(t,n){var e=t.m,r=n[0],i=n[1];return n[0]=e[0]*r+e[1]*i,n[1]=e[2]*r+e[3]*i,n},mult:function(t,n){var e=t.m,r=n.m,i=e[0],o=e[1],s=e[2],a=e[3];return e[0]=i*r[0]+o*r[2],e[1]=i*r[1]+o*r[3],e[2]=s*r[0]+a*r[2],e[3]=s*r[1]+a*r[3],t}},constructor:function a(t,e,r,i){var s=this;return s instanceof a?void(s.m=new o([t===n?1:t,e===n?0:e,r===n?0:r,i===n?1:i])):new a(t,e,r,i)},name:"Matrix",m:null,dispose:function(){return this.m=null,this},reset:function(){var t=this.m;return t[0]=1,t[1]=0,t[2]=0,t[3]=1,this},rotate:function(t){var n=this.m,i=r(t),o=e(t);return n[0]=i,n[1]=-o,n[2]=o,n[3]=i,this},scale:function(t,e){var r=this.m;return r[0]=1,r[1]=0,r[2]=0,r[3]=1,t!==n&&(r[0]=t,r[3]=t),e!==n&&(r[3]=e),this},multiply:function(t){return s.mult(this,t)},transformPoint:function(t){var n=s.transform(this,[t.x,t.y]);return new i(n[0],n[1])},transformPointSelf:function(t){var n=s.transform(this,[t.x,t.y]);return t.x=n[0],t.y=n[1],t},clone:function(){var t=this.m;return new s(t[0],t[1],t[2],t[3])}})}(n),!function(t,n){var e=Math.sqrt,r=t.VecArray,i=t.Vector3=t.Class({__static__:{ZERO:function(){return new i(0,0,0)},X:function(t){return!1===t?new i(0,1,1):new i(1,0,0)},Y:function(t){return!1===t?new i(1,0,1):new i(0,1,0)},Z:function(t){return!1===t?new i(1,1,0):new i(0,0,1)},dot:function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},equals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]},cross:function(t,n){var e=new r(3);return e[0]=t[1]*n[2]-t[2]*n[1],e[1]=t[2]*n[0]-t[0]*n[2],e[2]=t[0]*n[1]-t[1]*n[0],e},mod:function(t){var n=t[0],r=t[1],i=t[2];return e(n*n+r*r+i*i)},dist:function(t,n){var r=t[0]-n[0],i=t[1]-n[1],o=t[2]-n[2];return e(r*r+i*i+o*o)},add:function(t,n){return t[0]+=n[0],t[1]+=n[1],t[2]+=n[2],t},sub:function(t,n){return t[0]-=n[0],t[1]-=n[1],t[2]-=n[2],t},mul:function(t,n){return t[0]*=n[0],t[1]*=n[1],t[2]*=n[2],t},muls:function(t,n){return t[0]*=n,t[1]*=n,t[2]*=n,t},norm:function(t){var n,r=t[0],i=t[1],o=t[2],s=r*r+i*i+o*o;return s>0&&(n=e(s),r/=n,i/=n,o/=n),t[0]=r,t[1]=i,t[2]=o,t}},constructor:function o(t,n,e){var i=this;if(!(i instanceof o))return new o(t,n,e);var s=new r(3);t&&3===t.length?(s[0]=t[0]||0,s[1]=t[1]||0,s[2]=t[2]||0):(s[0]=t||0,s[1]=n||0,s[2]=e||0),i.xyz=s},name:"Vector3",xyz:null,dispose:function(){return this.xyz=null,this},getXYZ:function(){return new r(this.xyz)},getXYZRef:function(){return this.xyz},setXYZ:function(t){var n=this.xyz;return n[0]=t[0],n[1]=t[1],n[2]=t[2],this},setXYZRef:function(t){return this.xyz=t,this},clone:function(){return new i(this.xyz)},equalsSelf:function(t){var n=this.xyz,e=t.xyz;return n[0]===e[0]&&n[1]===e[1]&&n[2]===e[2]},zeroSelf:function(){var t=this.xyz;return t[0]=0,t[1]=0,t[2]=0,this},negate:function(){var t=this.xyz;return new i(-t[0],-t[1],-t[2])},negateSelf:function(){var t=this.xyz;return t[0]=-t[0],t[1]=-t[1],t[2]=-t[2],this},add:function(t){var n=this.xyz,e=t.xyz;return new i(n[0]+e[0],n[1]+e[1],n[2]+e[2])},addSelf:function(t){var n=this.xyz,e=t.xyz;return n[0]+=e[0],n[1]+=e[1],n[2]+=e[2],this},subtract:function(t){var n=this.xyz,e=t.xyz;return new i(n[0]-e[0],n[1]-e[1],n[2]-e[2])},subtractSelf:function(t){var n=this.xyz,e=t.xyz;return n[0]-=e[0],n[1]-=e[1],n[2]-=e[2],this},multiplyScalar:function(t){var n=this.xyz;return new i(n[0]*t,n[1]*t,n[2]*t)},multiplyScalarSelf:function(t){var n=this.xyz;return n[0]*=t,n[1]*=t,n[2]*=t,this},multiply:function(t){var n=this.xyz,e=t.xyz;return new i(n[0]*e[0],n[1]*e[1],n[2]*e[2])},multiplySelf:function(t){var n=this.xyz,e=t.xyz;return n[0]*=e[0],n[1]*=e[1],n[2]*=e[2],this},divide:function(t){var n=this.xyz;return new i(n[0]/t,n[1]/t,n[2]/t)},divideSelf:function(t){var n=this.xyz;return n[0]/=t,n[1]/=t,n[2]/=t,this},normalize:function(){var t,n=this.xyz,r=n[0],o=n[1],s=n[2],a=r*r+o*o+s*s;return a>0&&(t=e(a),r/=t,o/=t,s/=t),new i(r,o,s)},normalizeSelf:function(){var t,n=this.xyz,r=n[0],i=n[1],o=n[2],s=r*r+i*i+o*o;return s>0&&(t=e(s),r/=t,i/=t,o/=t),n[0]=r,n[1]=i,n[2]=o,this},getMagnitude:function(){var t=this.xyz,n=t[0],r=t[1],i=t[2];return e(n*n+r*r+i*i)},setMagnitude:function(t){this.normalizeSelf();var n=this.xyz;return n[0]*=t,n[1]*=t,n[2]*=t,this},dot:function(t){var n=this.xyz,e=t.xyz;return n[0]*e[0]+n[1]*e[1]+n[2]*e[2]},cross:function(t){var n=this.xyz,e=t.xyz,r=n[0],o=n[1],s=n[2],a=e[0],u=e[1],l=e[2];return new i(o*l-s*u,s*a-r*l,r*u-o*a)},crossSelf:function(t){var t=this.xyz,n=b.xyz,e=t[0],r=t[1],i=t[2],o=n[0],s=n[1],a=n[2];return t[0]=r*a-i*s,t[1]=i*o-e*a,t[2]=e*s-r*o,this},distance:function(t){var n=this.xyz,r=t.xyz,i=n[0]-r[0],o=n[1]-r[1],s=n[2]-r[2];return e(i*i+o*o+s*s)},toString:function(){var t=this.xyz;return"["+t[0]+" , "+t[1]+" , "+t[2]+"]"}});i.modulo=i.mod,i.distance=i.dist,i.prototype.dotSelf=i.prototype.dot,i.prototype.distanceSelf=i.prototype.distance}(n),!function(t,n){var e=Math.sin,r=Math.cos,i=t.VecArray,o=t.Matrix4=t.Class({__static__:{multXYZ:function(t,n){var e=t.m,r=n[0],i=n[1],o=n[2];return n[0]=r*e[0]+i*e[1]+o*e[2]+e[3],n[1]=r*e[4]+i*e[5]+o*e[6]+e[7],n[2]=r*e[8]+i*e[9]+o*e[10]+e[11],n},mult:function(t,n){var e=t.m,r=n.m,i=e[0],o=r[0],s=e[4],a=r[4],u=e[8],l=r[8],c=e[1],f=r[1],h=e[5],d=r[5],p=e[9],v=r[9],m=e[2],y=r[2],x=e[6],g=r[6],M=e[10],w=r[10],A=e[3],z=r[3],Y=e[7],X=r[7],Z=e[11],V=r[11];return e[0]=i*o+c*a+m*l,e[1]=i*f+c*d+m*v,e[2]=i*y+c*g+m*w,e[3]=i*z+c*X+m*V+A,e[4]=s*o+h*a+x*l,e[5]=s*f+h*d+x*v,e[6]=s*y+h*g+x*w,e[7]=s*z+h*X+x*V+Y,e[8]=u*o+p*a+M*l,e[9]=u*f+p*d+M*v,e[10]=u*y+p*g+M*w,e[11]=u*z+p*X+M*V+Z,t}},constructor:function s(t,e,r,o,a,u,l,c,f,h,d,p,v,m,y,x){var g=this;return g instanceof s?void(g.m=new i([t===n?1:t,e===n?0:e,r===n?0:r,o===n?0:o,a===n?0:a,u===n?1:u,l===n?0:l,c===n?0:c,f===n?0:f,h===n?0:h,d===n?1:d,p===n?0:p,v===n?0:v,m===n?0:m,y===n?0:y,x===n?1:x])):new s(t,e,r,o,a,u,l,c,f,h,d,p,v,m,y,x)},name:"Matrix4",m:null,dispose:function(){return this.m=null,this},reset:function(){var t=this.m;return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this},translate:function(t,n,e,r){var i=this.m;return!0===r&&(i[0]=1,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=1,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=1,i[11]=0,i[12]=0,i[13]=0,i[14]=0,i[15]=1),i[3]=t,i[7]=n,i[11]=e,this},scale:function(t,n,e,r){var i=this.m;return!0===r&&(i[0]=1,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=1,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=1,i[11]=0,i[12]=0,i[13]=0,i[14]=0,i[15]=1),i[0]=t,i[5]=n,i[10]=e,this},rotate:function(t,n,i,o,s){var a=this.m,u=r(o),l=e(o),c=1-u,f=t*n*c,h=n*i*c,d=t*i*c,p=l*i,v=l*n,m=l*t;return!0===s&&(a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1),a[0]=u+t*t*c,a[1]=-p+f,a[2]=v+d,a[3]=0,a[4]=p+f,a[5]=u+n*n*c,a[6]=-m+h,a[7]=0,a[8]=-v+d,a[9]=m+h,a[10]=u+i*i*c,a[11]=0,this},translateFromVector:function(t,n){return this.translate(t.xyz[0],t.xyz[1],t.xyz[2],n)},scaleFromVector:function(t,n){return this.scale(t.xyz[0],t.xyz[1],t.xyz[2],n)},rotateFromVector:function(t,n,e){return this.rotate(t.xyz[0],t.xyz[1],t.xyz[2],n,e)},multiply:function(t){return o.mult(this,t)},multiplyVector:function(t){return o.multXYZ(this,t.xyz),t}});o.prototype.translationMatrix=o.prototype.translate,o.prototype.scaleMatrix=o.prototype.scale,o.prototype.rotationMatrix=o.prototype.rotate,o.prototype.translationMatrixFromVector=o.prototype.translateFromVector,o.prototype.scaleMatrixFromVector=o.prototype.scaleFromVector,o.prototype.rotationMatrixFromVector=o.prototype.rotateFromVector}(n),!function(t,n){t.List={operate:function(t,n,e,r,i,o){var s=t.length;if(arguments.length<5&&(i=s-1),0>i&&(i+=s),arguments.length<4&&(r=0),r>i)return e;if(!0===o){var a,u,l=i-r+1,c=l-1,f=15&l,h=1&f,d=c-f,p=h?n(e,t[i],i):e;for(a=c-h;a>d;a-=2)u=r+a,p=n(n(p,t[u],u),t[u-1],u-1);for(a=d;a>=0;a-=16)u=r+a,p=n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(p,t[u],u),t[u-1],u-1),t[u-2],u-2),t[u-3],u-3),t[u-4],u-4),t[u-5],u-5),t[u-6],u-6),t[u-7],u-7),t[u-8],u-8),t[u-9],u-9),t[u-10],u-10),t[u-11],u-11),t[u-12],u-12),t[u-13],u-13),t[u-14],u-14),t[u-15],u-15)}else{var a,u,l=i-r+1,f=15&l,h=1&f,p=h?n(e,t[r],r):e;for(a=h;f>a;a+=2)u=r+a,p=n(n(p,t[u],u),t[u+1],u+1);for(a=f;l>a;a+=16)u=r+a,p=n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(p,t[u],u),t[u+1],u+1),t[u+2],u+2),t[u+3],u+3),t[u+4],u+4),t[u+5],u+5),t[u+6],u+6),t[u+7],u+7),t[u+8],u+8),t[u+9],u+9),t[u+10],u+10),t[u+11],u+11),t[u+12],u+12),t[u+13],u+13),t[u+14],u+14),t[u+15],u+15)}return p},each:function(t,n,e,r,i){if(null==t||!t.length)return t;var o=t.length;if(arguments.length<4&&(r=o-1),0>r&&(r+=o),arguments.length<3&&(e=0),e>r)return t;var s,a,u,l,c,f,h=r-e+1;if(!0===i){for(u=h-1,c=15&h,f=1&c,l=u-c,f&&n(t[r]),s=u-f;s>l;s-=2)a=e+s,n(t[a]),n(t[a-1]);for(s=l;s>=0;s-=16)a=e+s,n(t[a]),n(t[a-1]),n(t[a-2]),n(t[a-3]),n(t[a-4]),n(t[a-5]),n(t[a-6]),n(t[a-7]),n(t[a-8]),n(t[a-9]),n(t[a-10]),n(t[a-11]),n(t[a-12]),n(t[a-13]),n(t[a-14]),n(t[a-15])}else{for(c=15&h,f=1&c,f&&n(t[e]),s=f;c>s;s+=2)a=e+s,n(t[a]),n(t[a+1]);for(s=c;h>s;s+=16)a=e+s,n(t[a]),n(t[a+1]),n(t[a+2]),n(t[a+3]),n(t[a+4]),n(t[a+5]),n(t[a+6]),n(t[a+7]),n(t[a+8]),n(t[a+9]),n(t[a+10]),n(t[a+11]),n(t[a+12]),n(t[a+13]),n(t[a+14]),n(t[a+15])}return t}}}(n),!function(t,n){var e,r,i,o,s=t.ModConstant,a=s.X,u=s.Y,l=s.Z,c=t.XYZi,f=(t.Vector3,t.VecArray),h=Math.min,d=Math.max,p=t.List.each,v=function(t){t.dispose()},m=function(t){t.reset()},y=function(t){t.collapse()};e=t.FaceProxy=t.Class({constructor:function(){this.vertices=[]},name:"FaceProxy",vertices:null,dispose:function(){var t=this;return t.vertices=null,t},addVertex:function(t){this.vertices.push(t)},getVertices:function(){return this.vertices}}),r=t.VertexProxy=t.Class({constructor:function(t,n){var e=this;e.mesh=n||null,e.original=new f([0,0,0]),e.ratio=new f([0,0,0]),null!=t&&e.setVertex(t)},name:"VertexProxy",mesh:null,vertex:null,original:null,ratio:null,dispose:function(){var t=this;return t.mesh=null,t.vertex=null,t.original=null,t.ratio=null,t},setVertex:function(t){var n=this;return n.vertex=t,n},getRatioVector:function(){var t=this.ratio,n=new f(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},getRatio:function(t){return this.ratio[c[t]]||0},setRatios:function(t,e,r){var i=this.ratio;return i[0]=t===n?0:t,i[1]=e===n?0:e,i[2]=r===n?0:r,this},getOriginalValue:function(t){return this.original[c[t]]||0},setOriginalPosition:function(t,e,r){var i=this.original;return i[0]=t===n?0:t,i[1]=e===n?0:e,i[2]=r===n?0:r,this},getXYZ:function(){return new f([0,0,0])},getX:function(){return 0},getY:function(){return 0},getZ:function(){return 0},getValue:function(t){var n=this;return a===t?n.getX():u===t?n.getY():l===t?n.getZ():0},setXYZ:function(t){return this},setX:function(t){return this},setY:function(t){return this},setZ:function(t){return this},setValue:function(t,n){var e=this;return a===t?e.setX(n):u===t?e.setY(n):l===t&&e.setZ(n),e},reset:function(){var t=this;return t.setXYZ(t.original),t},collapse:function(){var t=this,n=t.getXYZ(),e=t.original;return e[0]=n[0],e[1]=n[1],e[2]=n[2],t}}),i=t.MeshProxy=t.Class({constructor:function(t){var n=this;n.maxX=0,n.maxY=0,n.maxZ=0,n.minX=0,n.minY=0,n.minZ=0,n.maxAxis=0,n.midAxis=0,n.minAxis=0,n.width=0,n.height=0,n.depth=0,n.vertices=null,n.faces=null,n.mesh=null,null!=t&&n.setMesh(t)},name:"MeshProxy",maxX:0,maxY:0,maxZ:0,minX:0,minY:0,minZ:0,maxAxis:0,midAxis:0,minAxis:0,width:0,height:0,depth:0,vertices:null,faces:null,mesh:null,v:null,dispose:function(){var t=this;return t.maxX=null,t.maxY=null,t.maxZ=null,t.minX=null,t.minY=null,t.minZ=null,t.maxAxis=null,t.midAxis=null,t.minAxis=null,t.width=null,t.height=null,t.depth=null,t.disposeFaces(),t.disposeVertices(),t.mesh=null,t.v=null,t},disposeVertices:function(){var t=this;return p(t.vertices,v),t.vertices=null,t},disposeFaces:function(){var t=this;return p(t.faces,v),t.faces=null,t},init:function(t){var n=this;return n.mesh=t,n},setMesh:function(t){return this.init(t).preApply().analyzeGeometry().postApply()},getVertices:function(){return this.vertices},getFaces:function(){return this.faces},applyModifiers:function(t){var n,e,r=this;for(e=0,n=t.length;n>e;e++)t[e].enabled&&t[e].apply(r);return r},analyzeGeometry:function(){var t,n,e,r=this,i=r.vertices,o=0,s=0,c=0,f=0,v=0,m=0,y=0,x=0,g=0;return i&&i.length?(e=i[0].getXYZ(),o=e[0],s=e[1],c=e[2],f=e[0],v=e[1],m=e[2],p(i,function(t){var n=t.getXYZ(),e=n[0],r=n[1],i=n[2];o=h(o,e),s=h(s,r),c=h(c,i),f=d(f,e),v=d(v,r),m=d(m,i),t.setOriginalPosition(e,r,i)}),y=f-o,x=v-s,g=m-c,r.width=y,r.height=x,r.depth=g,r.minX=o,r.maxX=f,r.minY=s,r.maxY=v,r.minZ=c,r.maxZ=m,t=d(y,x,g),n=h(y,x,g),t===y&&n===x?(r.minAxis=u,r.midAxis=l,r.maxAxis=a):t===y&&n===g?(r.minAxis=l,r.midAxis=u,r.maxAxis=a):t===x&&n===y?(r.minAxis=a,r.midAxis=l,r.maxAxis=u):t===x&&n===g?(r.minAxis=l,r.midAxis=a,r.maxAxis=u):t===g&&n===y?(r.minAxis=a,r.midAxis=u,r.maxAxis=l):t===g&&n===x&&(r.minAxis=u,r.midAxis=a,r.maxAxis=l),p(i,function(t){var n=t.getXYZ();t.setRatios(y>0?(n[0]-o)/y:0,x>0?(n[1]-s)/x:0,g>0?(n[2]-c)/g:0)}),r):r},resetGeometry:function(){var t=this;return p(t.vertices,m),t},collapseGeometry:function(){var t=this;return p(t.vertices,y),t.analyzeGeometry()},getMin:function(t){var n=this;return a===t?n.minX:u===t?n.minY:l===t?n.minZ:-1},getMax:function(t){var n=this;return a===t?n.maxX:u===t?n.maxY:l===t?n.maxZ:-1},getSize:function(t){var n=this;return a===t?n.width:u===t?n.height:l===t?n.depth:-1},update:function(){return this},preApply:function(){return this},postApply:function(){return this},updateMeshPosition:function(t){return this}}),t.Library3d={id:"Library3d",Mesh:i,Vertex:r},o=t.Factory=t.StaticClass({getLibrary:function(n){return n&&n.library&&t[n.library]?t[n.library]:t.Library3d},getMeshProxy:function(t){return arguments.length&&t.Mesh?new t.Mesh:null},getModifier:function(n){return n&&n.modifier&&t[n.modifier]?new t[n.modifier]:null}})}(n),!function(t,n){var e,r,i=0,o=t.ModConstant.NONE,s=t.Factory.getMeshProxy;e=t.Modifier=t.Class({constructor:function(){var t=this;t.id=++i,t.name="Modifier",t.axes=o,t.constraint=o,t.enabled=!0},id:null,name:"Modifier",axes:null,constraint:null,enabled:!0,dispose:function(){var t=this;return t.name=null,t.axes=null,t.constraint=null,t},enable:function(t){return arguments.length?(this.enabled=!!t,this):this.enabled},constraintAxes:function(t){return this.axes=t||o,this},setConstraint:function(t){return this.constraint=t||o,this},apply:function(t){return this},toString:function(){return"[Modifier "+this.name+"]"}}),r=t.ModifierStack=t.Class({constructor:function a(t,n){var e=this;return e instanceof a?(e.stack=[],void e.setModifiable(s(t),n)):new a(t,n)},name:"ModifierStack",modifiable:null,stack:null,dispose:function(t){var n=this;if(t&&n.stack)for(;n.stack.length;)n.stack.pop().dispose();return n.modifiable&&n.modifiable.dispose(),n.stack=null,n.modifiable=null,n},getModifiable:function(){return this.modifiable},setModifiable:function(t,n){var e=this;return e.modifiable=t,n&&e.modifiable.setMesh(n),e},add:function(t){var n=this;return t&&n.stack.push(t),n},apply:function(){var t=this,n=t.modifiable,e=t.stack;return n&&e&&e.length&&n.preApply().resetGeometry().applyModifiers(e).postApply().update(),t},collapse:function(){var t=this,n=t.modifiable;return n&&t.stack&&t.stack.length&&(n.preApply().resetGeometry().applyModifiers(t.stack).collapseGeometry().postApply().update(),t.stack.length=0),t},clear:function(){var t=this;return t.stack&&(t.stack.length=0),t}}),r.prototype.getMeshInfo=r.prototype.getModifiable,r.prototype.addModifier=r.prototype.add}(n),!function(t,n){var e=t.Vector3,r=t.List.each,i=e.add;t.Pivot=t.Class(t.Modifier,{constructor:function o(t,n,r){var i=this;return i instanceof o?(i.$super("constructor"),i.name="Pivot",void(i.vector=new e(t||0,n||0,r||0))):new o(t,n,r)},vector:null,dispose:function(){var t=this;return t.vector.dispose(),t.vector=null,t.$super("dispose"),t},setMeshCenter:function(t){var n=this;return n.vector=new e(-(t.minX+.5*t.width),-(t.minY+.5*t.height),-(t.minZ+.5*t.depth)),n},apply:function(t){var n=this,e=n.vector,o=e.xyz;return r(t.vertices,function(t){t.setXYZ(i(t.getXYZ(),o))}),t.updateMeshPosition(e.negate()),n}})}(n),!function(t,n){var e=t.ModConstant.NONE,r=t.ModConstant.LEFT,i=t.ModConstant.RIGHT,o=t.XYZi,s=t.Matrix,a=(Math.atan,Math.atan2,Math.sin),u=Math.cos,l=t.Constants.PI,c=t.Constants.halfPI,f=t.Constants.doublePI,h=Math.max,d=Math.min,p=t.List.each,v=s.transform;t.Bend=t.Class(t.Modifier,{constructor:function m(t,n,r){var i=this;return i instanceof m?(i.$super("constructor"),i.name="Bend",i.constraint=e,i.switchAxes=!1,i.force=t||0,i.offset=n||0,void(i.angle=r||0)):new m(t,n,r)},force:0,offset:0,angle:0,switchAxes:!1,dispose:function(){var t=this;return t.force=null,t.offset=null,t.angle=null,t.switchAxes=null,t.$super("dispose"),t},apply:function(t){var n=this;if(0==n.force)return n;var e=n.constraint,m=n.switchAxes,y=n.force,x=d(1,h(0,n.offset)),g=n.angle,M=m?t.midAxis:t.maxAxis,w=t.minAxis,A=m?t.maxAxis:t.midAxis,z=t.getSize(M),Y=(t.getSize(A),t.getMin(M)),X=(new s).rotate(g),Z=(new s).rotate(-g),V=Y+z*x,C=z/l/y,b=f*(z/(C*f));return p(t.vertices,function(t){var n,s,l,f,h,d=t.getXYZ(),p=d[o[M]],m=d[o[A]],y=d[o[w]],g=v(X,[p,m]);p=g[0],m=g[1],n=(p-Y)/z,r===e&&x>=n||i===e&&n>=x||(s=c-b*x+b*n,l=a(s)*(C+y),f=u(s)*(C+y),y=l-C,p=V-f),h=v(Z,[p,m]),p=h[0],m=h[1],d[o[M]]=p,d[o[A]]=m,d[o[w]]=y,t.setXYZ(d)}),n}})}(n),!function(t,n){var e=t.Vector3,r=Math.max,i=Math.exp,o=t.List.each,s=e.add,a=e.sub,u=e.muls,l=e.mod,c=e.norm;t.Bloat=t.Class(t.Modifier,{constructor:function f(t,n,r){var i=this;return i instanceof f?(i.$super("constructor"),i.name="Bloat",i.radius=t||0,i.a=null==n?.01:n,void(i.center=r||e.ZERO())):new f(t,n,r)},radius:0,a:.01,center:null,dispose:function(){var t=this;return t.center.dispose(),t.center=null,t.radius=null,t.a=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.center.xyz,f=r(0,n.radius),h=r(0,n.a);return o(t.vertices,function(t){var n=a(t.getXYZ(),e),r=l(n);u(c(n),r+f*i(-r*h)),t.setXYZ(s(n,e))}),n}})}(n),!function(t,n){var e=t.Vector3,r=(Math.sqrt,t.Matrix4),i=t.List.each,o=r.mult,s=e.dot,a=e.mod;t.Twist=t.Class(t.Modifier,{constructor:function u(t,n,r){var i=this;return i instanceof u?(i.$super("constructor"),i.name="Twist",i.angle=t||0,i.vector=n||e.Y(),void(i.center=r||e.ZERO())):new u(t,n,r)},angle:0,vector:null,center:null,dispose:function(){var t=this;return t.vector.dispose(),t.vector=null,t.angle=null,t.center.dispose(),t.center=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.vector.normalizeSelf().xyz,u=n.angle,l=n.center.xyz,c=a([.5*t.maxX,.5*t.maxY,.5*t.maxZ]),f=-s(e,l),h=new r,d=new r;return i(t.vertices,function(t){var n=t.getXYZ(),r=(s(n,e)+f)*u/c,i=o(d.rotate(e[0],e[1],e[2],r,!0),h.translate(n[0],n[1],n[2],!0));t.setXYZ([i.m[3],i.m[7],i.m[11]])}),n}})}(n),!function(t,n){var e=Math.abs,r=Math.pow,i=Math.max,o=Math.min,s=t.ModConstant,a=s.NONE,u=s.LEFT,l=s.RIGHT,c=s.X,f=s.Y,h=s.Z,d=t.List.each;t.Skew=t.Class(t.Modifier,{constructor:function p(t,e,r,i){var o=this;return o instanceof p?(o.$super("constructor"),o.name="Skew",o.constraint=a,o.force=t!==n?t:0,o.offset=e!==n?e:.5,o.power=r!==n?r:1,o.falloff=i!==n?i:1,o.inverseFalloff=!1,o.oneSide=!1,o.swapAxes=!1,void(o.skewAxis=0)):new p(t,e,r,i)},force:0,skewAxis:0,offset:.5,power:1,falloff:1,inverseFalloff:!1,oneSide:!1,swapAxes:!1,dispose:function(){var t=this;return t.force=null,t.skewAxis=null,t.offset=null,t.power=null,t.falloff=null,t.inverseFalloff=null,t.oneSide=null,t.swapAxes=null,t.$super("dispose"),t},apply:function(t){var n=this,s=n.constraint,a=n.skewAxis||t.maxAxis,p=n.swapAxes,v=o(1,i(0,n.offset)),m=n.oneSide,y=!!n.inverseFalloff,x=o(1,i(0,n.falloff)),g=1-x,M=n.power,w=n.force,A=c===a?p?h:f:f===a?p?h:c:h===a?p?f:c:0;return d(t.vertices,function(t){var n,i,o,c,f;f=t.getRatio(a),u===s&&v>=f||l===s&&f>v||(n=f-v,m&&0>n&&(n=-n),i=t.getRatio(A),y&&(i=1-i),o=x+i*g,c=(0>n?-1:1)*r(e(n),M),t.setValue(A,t.getValue(A)+w*c*o))}),n}})}(n),!function(t,n){var e=t.Vector3,r=t.Matrix4,i=Math.pow,o=e.mul,s=e.mod,a=t.List.each,u=r.multXYZ;t.Taper=t.Class(t.Modifier,{constructor:function l(t,r,i,o){var s=this;return s instanceof l?(s.$super("constructor"),s.name="Taper",s.force=t!==n?t:0,s.power=r!==n?r:1,s.vector=i||e.Y(!1),void(s.vector2=o||e.Y())):new l(t,r,i,o)},force:0,power:1,vector:null,vector2:null,dispose:function(){var t=this;return t.vector.dispose(),t.vector2.dispose(),t.vector=null,t.vector2=null,t.force=null,t.power=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.vector.xyz,l=n.vector2.xyz,c=n.force,f=n.power,h=new r;return a(t.vertices,1!=f?function(t){var n=s(o(t.getRatioVector(),l)),r=c*i(n,f);t.setXYZ(u(h.scale(1+r*e[0],1+r*e[1],1+r*e[2]),t.getXYZ()))}:function(t){var n=s(o(t.getRatioVector(),l)),r=c*n;t.setXYZ(u(h.scale(1+r*e[0],1+r*e[1],1+r*e[2]),t.getXYZ()))}),n}})}(n),!function(t,n){var e=(t.Constants.invPI,t.Constants.doublePI,t.Vector3),r=t.Matrix4,i=t.List.each,o=r.multXYZ;t.Wheel=t.Class(t.Modifier,{constructor:function s(t,n,r,i,o){var a=this;return a instanceof s?(a.$super("constructor"),a.name="Wheel",a.speed=t||0,a.turn=n||0,a.roll=r||0,a.steerVector=i||e.Y(),void(a.rollVector=o||e.Z())):new s(t,n,r,i,o)},speed:0,turn:0,roll:0,steerVector:null,rollVector:null,dispose:function(){var t=this;return t.speed=null,t.turn=null,t.roll=null,t.steerVector.dispose(),t.rollVector.dispose(),t.steerVector=null,t.rollVector=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.steerVector.normalizeSelf(),s=n.rollVector.normalizeSelf(),a=n.turn,u=n.roll,l=null,c=null;return n.roll+=n.speed,a?(c=(new r).rotateFromVector(e,a),l=(new r).rotateFromVector(c.multiplyVector(s.clone()),u)):l=(new r).rotateFromVector(s,u),i(t.vertices,c?function(t){t.setXYZ(o(l,o(c,t.getXYZ())))}:function(t){t.setXYZ(o(l,t.getXYZ()))}),n}})}(n),!function(t,n){var e=t.Vector3,r=t.Range,i=t.Matrix4,o=Math.max,s=Math.min,a=t.List.each,u=i.multXYZ;t.Break=t.Class(t.Modifier,{constructor:function l(t,n,i){var o=this;return o instanceof l?(o.$super("constructor"),o.name="Break",o.offset=t||0,o.angle=n||0,o.vector=i||e.Y(),void(o.range=new r(0,1))):new l(t,n,i)},offset:0,angle:0,vector:null,range:null,dispose:function(){var t=this;return t.vector.dispose(),t.range.dispose(),t.vector=null,t.range=null,t.offset=null,t.angle=null,t.$super("dispose"),t},apply:function(t){var n,e,r=this,l=s(1,o(0,r.offset)),c=r.range,f=r.angle,h=r.vector.normalizeSelf().xyz;return n=t.minZ+t.depth*l,e=(new i).rotate(h[0],h[1],h[2],f),a(t.vertices,function(t){var r=t.getXYZ();r[2]-=n,0<=r[2]&&c.isIn(t.ratio[1])&&u(e,r),r[2]+=n,t.setXYZ(r)}),r}})}(n),!function(t,n){var e=(t.ModConstant.NONE,t.ModConstant.X),r=t.ModConstant.Y,i=t.ModConstant.Z,o=Math.random,s=t.List.each;t.Noise=t.Class(t.Modifier,{constructor:function a(t){var n=this;return n instanceof a?(n.$super("constructor"),n.name="Noise",n.force=t||0,n.start=0,n.end=1,void(n.axes=e|r|i)):new a(t)},force:0,start:0,end:1,dispose:function(){var t=this;return t.force=null,t.start=null,t.end=null,t.$super("dispose"),t},setFalloff:function(t,e){var r=this;return r.start=t!==n?t:0,r.end=e!==n?e:1,r},apply:function(t){var n=this,a=n.axes,u=n.start,l=n.end,c=n.force,f=.5*c,h=t.maxAxis;return 0==a||0==c?n:(s(t.vertices,function(t){var n,s,d=o()*c-f,p=t.getRatio(h);l>u?u>p?p=0:p>l&&(p=1):u>l?(p=1-p,p>u?p=0:l>p&&(p=1)):p=1,n=d*p,s=t.getXYZ(),t.setXYZ([s[0]+(a&e?n:0),s[1]+(a&r?n:0),s[2]+(a&i?n:0)])}),n)}})}(n),!function(t,n){var e=t.ModConstant,r=(e.NONE,e.X),i=e.Y,o=e.Z,s=t.List.each;t.DisplaceMap=t.Class(t.Modifier,{constructor:function a(t,n,e){var s=this;return s instanceof a?(s.$super("constructor"),s.name="DisplaceMap",+t==t?(s.force=t||1,s.offset=null==n?127:n):(s.setBitmap(t),s.force=n||1,s.offset=null==e?127:e),void(s.axes=r|i|o)):new a(t,n,e)},width:null,height:null,bmpData:null,force:1,offset:127,dispose:function(){var t=this;return t.bmpData=null,t.width=null,t.height=null,t.force=null,t.offset=null,t.$super("dispose"),t},setBitmap:function(t){var n=this;return n.bmpData=t?t.data:null,n.width=t?t.width:0,n.height=t?t.height:0,n},apply:function(t){var n=this,e=n.axes,a=n.width,u=n.height,l=n.bmpData,c=n.force,f=n.offset;return e&&l?(s(t.vertices,function(t){var n,s,h,d=t.getXYZ();s=~~((a-1)*t.ratio[0]),h=~~((u-1)*t.ratio[2]),n=h*a+s<<2,t.setXYZ([d[0]+(e&r?((255&l[n])-f)*c:0),d[1]+(e&i?((255&l[n+1])-f)*c:0),d[2]+(e&o?((255&l[n+2])-f)*c:0)])}),n):n}})}(n),!function(t,n){function e(t,n,e,i,o){var s,a,u,l,c,f=n*e,h=new r(f);for(0>i&&(i+=n),0>o&&(o+=e),i=~~i,o=~~o,s=0,a=0,c=0;f>c;c++,s++)s>=n&&(s=0,a++),u=(s+i)%n,l=(a+o)%e,h[c]=t[u+l*n];return h}var r=(t.Vector3,Math.round,t.VecArray),i=t.ModConstant,o=(i.NONE,i.X),s=i.Y,a=i.Z,u=t.List.each;t.Perlin=t.Class(t.Modifier,{constructor:function l(t,e,r){var i=this;return i instanceof l?(i.$super("constructor"),i.name="Perlin",i.force=n!==t?t:1,i.perlin=e,i.autoRun=n!==r?!!r:!0,void(i.axes=o|s|a)):new l(t,e,r)},speedX:1,speedY:1,perlin:null,force:1,offset:0,autoRun:!0,dispose:function(){var t=this;return t.perlin=null,t.speedX=null,t.speedY=null,t.force=null,t.offset=null,t.autoRun=null,t.$super("dispose"),t},setSpeed:function(t,n){var e=this;return e.speedX=t,e.speedY=n,e},apply:function(t){var n=this,r=n.axes,i=n.force,l=n.offset,c=n.perlin,f=c.width,h=c.height;return r&&c?(n.autoRun&&(c=n.perlin=e(c,f,h,n.speedX,n.speedY),c.width=f,c.height=h),u(t.vertices,function(t){var n=t.getXYZ(),e=~~((f-1)*t.ratio[0]),u=~~((h-1)*t.ratio[2]),d=e+u*f;t.setXYZ([n[0]+(r&o?(c[d]-l)*i:0),n[1]+(r&s?(c[d]-l)*i:0),n[2]+(r&a?(c[d]-l)*i:0)])}),n):n}})}(n),n}); \ No newline at end of file +**/!function(n,t,e){"use strict";"object"==typeof module&&module.exports?(module.$deps=module.$deps||{})&&(module.exports=module.$deps[t]=e.call(n)):"function"==typeof define&&define.amd&&"function"==typeof require&&"function"==typeof require.specified&&require.specified(t)?define(t,["module"],function(t){return e.moduleUri=t.uri,e.call(n)}):t in n||(n[t]=e.call(n)||1)&&"function"==typeof define&&define.amd&&define(function(){return n[t]})}("undefined"!=typeof self?self:this,"MOD3",function(){"use strict";var a=Object.prototype.hasOwnProperty,t=Object.prototype.toString,d=(Object.defineProperty,Math),n=d.PI,e=2*n,r=n/2,i=1/n,u=function(){};"undefined"!=typeof global&&t.call(global),"undefined"!=typeof window&&t.call(window);var y={VERSION:"1.0.0",Class:function(t,n,e){arguments.length<2&&(n=t,t=null);var r,i,o,s=a.call(n,"constructor")?n.constructor:function(){};for(r in t?(s.prototype=Object.create(t.prototype),s.prototype.$super=(i=t,o={},function(t,n){var e=":"+t;return 1===o[e]?(i.prototype.$super||u).call(this,t,n):(o[e]=1,n=("constructor"===t?i:i.prototype[t]||u).apply(this,n||[]),o[e]=0,n)})):s.prototype.$super=u,s.prototype.constructor=s,n)a.call(n,r)&&"constructor"!==r&&(s.prototype[r]=n[r]);if(e)for(r in e)a.call(e,r)&&(s[r]=e[r]);return s}};function o(t){t.dispose()}function s(t){t.reset()}function l(t){t.collapse()}y.Constants={PI:n,invPI:i,halfPI:r,doublePI:e,toRad:n/180,toDeg:180/n},y.ModConstant={NONE:0,LEFT:-1,RIGHT:1,X:1,Y:2,Z:4,Xi:0,Yi:1,Zi:2},y.XYZi=[null,0,1,null,2],y.iXYZ=[1,2,4],y.xyz=["x","y","z"],y.XYZ=["X","Y","Z"],y.Array32F="undefined"!=typeof Float32Array?Float32Array:Array,y.Array64F="undefined"!=typeof Float64Array?Float64Array:Array,y.Array8I="undefined"!=typeof Int8Array?Int8Array:Array,y.Array16I="undefined"!=typeof Int16Array?Int16Array:Array,y.Array32I="undefined"!=typeof Int32Array?Int32Array:Array,y.Array8U="undefined"!=typeof Uint8Array?Uint8Array:Array,y.Array16U="undefined"!=typeof Uint16Array?Uint16Array:Array,y.Array32U="undefined"!=typeof Uint32Array?Uint32Array:Array,y.VecArray=y.Array32F,y.XMath={normalize:function(t,n,e){return 0==n-t?1:y.XMath.trim(0,1,(e-t)/n)},toRange:function(t,n,e){n-=t;return 0==n?0:t+n*e},inRange:function(t,n,e,r){return!1!==r?t<=e&&e<=n:t=this.start&&t<=this.end},normalize:function(t){return y.XMath.normalize(this.start,this.end,t)},toRange:function(t){return y.XMath.toRange(this.start,this.end,t)},trim:function(t){return y.XMath.trim(this.start,this.end,t)},interpolate:function(t,n){return y.XMath.toRange(this.start,this.end,n.normalize(t))},toString:function(){return"["+this.start+" - "+this.end+"]"}}),y.Phase=y.Class({constructor:function t(n){if(!(this instanceof t))return new t(n);this.value=n||0},name:"Phase",value:0,dispose:function(){return this.value=null,this},getPhasedValue:function(){return d.sin(this.value)},getAbsPhasedValue:function(){return d.abs(d.sin(this.value))},getNormValue:function(){return.5*(d.sin(this.value)+1)}}),y.Point=y.Class({constructor:function t(n,e){if(!(this instanceof t))return new t(n,e);this.x=n||0,this.y=e||0},name:"Point",x:0,y:0,dispose:function(){return this.x=null,this.y=null,this},clone:function(){return new y.Point(this.x,this.y)}}),y.Matrix=y.Class(null,{constructor:function t(n,e,r,i){if(!(this instanceof t))return new t(n,e,r,i);this.m=new y.VecArray([null==n?1:n,null==e?0:e,null==r?0:r,null==i?1:i])},name:"Matrix",m:null,dispose:function(){return this.m=null,this},reset:function(){var t=this.m;return t[0]=1,t[1]=0,t[2]=0,t[3]=1,this},rotate:function(t){var n=this.m,e=d.cos(t),t=d.sin(t);return n[0]=e,n[1]=-t,n[2]=t,n[3]=e,this},scale:function(t,n){var e=this.m;return e[0]=1,e[1]=0,e[2]=0,e[3]=1,null!=t&&(e[0]=t,e[3]=t),null!=n&&(e[3]=n),this},multiply:function(t){return y.Matrix.mult(this,t)},transformPoint:function(t){t=y.Matrix.transform(this,[t.x,t.y]);return new y.Point(t[0],t[1])},transformPointSelf:function(t){var n=y.Matrix.transform(this,[t.x,t.y]);return t.x=n[0],t.y=n[1],t},clone:function(){var t=this.m;return new y.Matrix(t[0],t[1],t[2],t[3])}},{transform:function(t,n){var e=t.m,r=n[0],t=n[1];return n[0]=e[0]*r+e[1]*t,n[1]=e[2]*r+e[3]*t,n},mult:function(t,n){var e=t.m,r=n.m,i=e[0],o=e[1],s=e[2],n=e[3];return e[0]=i*r[0]+o*r[2],e[1]=i*r[1]+o*r[3],e[2]=s*r[0]+n*r[2],e[3]=s*r[1]+n*r[3],t}}),y.Vector3=y.Class(null,{constructor:function t(n,e,r){if(!(this instanceof t))return new t(n,e,r);var i=new y.VecArray(3);n&&3===n.length?(i[0]=n[0]||0,i[1]=n[1]||0,i[2]=n[2]||0):(i[0]=n||0,i[1]=e||0,i[2]=r||0),this.xyz=i},name:"Vector3",xyz:null,dispose:function(){return this.xyz=null,this},getXYZ:function(){return new y.VecArray(this.xyz)},getXYZRef:function(){return this.xyz},setXYZ:function(t){var n=this.xyz;return n[0]=t[0],n[1]=t[1],n[2]=t[2],this},setXYZRef:function(t){return this.xyz=t,this},clone:function(){return new y.Vector3(this.xyz)},equalsSelf:function(t){var n=this.xyz,t=t.xyz;return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]},zeroSelf:function(){var t=this.xyz;return t[0]=0,t[1]=0,t[2]=0,this},negate:function(){var t=this.xyz;return new y.Vector3(-t[0],-t[1],-t[2])},negateSelf:function(){var t=this.xyz;return t[0]=-t[0],t[1]=-t[1],t[2]=-t[2],this},add:function(t){var n=this.xyz,t=t.xyz;return new y.Vector3(n[0]+t[0],n[1]+t[1],n[2]+t[2])},addSelf:function(t){var n=this.xyz,t=t.xyz;return n[0]+=t[0],n[1]+=t[1],n[2]+=t[2],this},subtract:function(t){var n=this.xyz,t=t.xyz;return new y.Vector3(n[0]-t[0],n[1]-t[1],n[2]-t[2])},subtractSelf:function(t){var n=this.xyz,t=t.xyz;return n[0]-=t[0],n[1]-=t[1],n[2]-=t[2],this},multiplyScalar:function(t){var n=this.xyz;return new y.Vector3(n[0]*t,n[1]*t,n[2]*t)},multiplyScalarSelf:function(t){var n=this.xyz;return n[0]*=t,n[1]*=t,n[2]*=t,this},multiply:function(t){var n=this.xyz,t=t.xyz;return new y.Vector3(n[0]*t[0],n[1]*t[1],n[2]*t[2])},multiplySelf:function(t){var n=this.xyz,t=t.xyz;return n[0]*=t[0],n[1]*=t[1],n[2]*=t[2],this},divide:function(t){var n=this.xyz;return new y.Vector3(n[0]/t,n[1]/t,n[2]/t)},divideSelf:function(t){var n=this.xyz;return n[0]/=t,n[1]/=t,n[2]/=t,this},normalize:function(){var t=this.xyz,n=t[0],e=t[1],r=t[2],t=n*n+e*e+r*r;return 0i;i++)-1l;l++)if(i=a[l],O===B(i))for(r in i)i[E](r)&&i[_](r)&&(t=i[r],u=B(t),P&u?n[r]=0+t:(C|N)&u?n[r]=t.slice(0):n[r]=t);return n},Q=function(e,i,t){var r,l,u=!!i;if(u||t)if(r={},i=u?i+"$":i,t&&R===B(t))for(l in e)e[E](l)&&(n!==l?(u&&R===B(e[l])&&(r[i+l]=e[l]),r[t(l,e[l])]=e[l]):r[l]=e[l]);else for(l in e)e[E](l)&&(n!==l?(u&&R===B(e[l])&&(r[i+l]=e[l]),t&&l in t?r[t[l]]=e[l]:r[l]=e[l]):r[l]=e[l]);else r=e;return r},W=function(e){var n=e[u]||H,i=e[u+"v"]||H,t=null;return[function(i,r,l,u,a,o,f,c,s,b,d){var m,p;return t===i?m=n.call(this,i,r,l,u,a,o,f,c,s,b,d):(p=e[i])&&(t=i,m=p.call(this,r,l,u,a,o,f,c,s,b,d),t=null),m},function(n,r){var l,u;return t===n?l=i.call(this,n,r):(u=e[n])&&(t=n,l=r&&r.length?u.apply(this,r):u.call(this),t=null),l}]},X=function(e,n){return this instanceof X?(this.factory=e,void(this.qualifier=(P===B(n)?n:0)|c)):new X(e,n)},Y=function(e,n){return this instanceof Y?(this.prop=e,void(this.qualifier=(P===B(n)?n:0)|c)):new Y(e,n)},Z=function(t,c,p,v){t=t||m,c=c||{};var g,h,y,x,w,j,_,I,$,A,S=t[a]||null,T=t[o]||{},M=t[i],F=null,L=K({},T),U=null,V={};c[E](n)||(c[n]=function(){}),g=c[n],c[E](l)&&(V=c[l]||{},delete c[l]),c[E](r)&&(F=c[r],U=q(F),delete c[r]);for($ in c)if(c[E]($)){if(A=c[$],A instanceof X){if(b&A.qualifier){d&A.qualifier?L[$]=A:((F=F||{})[$]=A.factory(t,V,g),(U=U||[]).push($)),delete c[$];continue}if(s&A.qualifier){V[$]=A,delete c[$];continue}A=c[$]=A.factory(M,V,g)}R===B(A)&&(A[u]=M[$]||H)}for($ in V)V[E]($)&&(A=V[$],A instanceof X&&(A=V[$]=A.factory(M,V,g)),R!==B(A)&&delete V[$]);if(g[i]=Q(J(M),p,v),g[i]=K(g[i],c),h=W(M),w={},w[f]=w[n]={value:g,enumerable:!1,writable:!0,configurable:!0},w[u]={value:h[0],enumerable:!1,writable:!0,configurable:!0},w[u+"v"]={value:h[1],enumerable:!1,writable:!0,configurable:!0},G(g[i],w),w={},S||U)for(S=D(S||[],U||[]),x=S.length,y=0;x>y;y++){if(j=S[y],_=null,F&&e!==F[j]){if((A=F[j])instanceof X){if((b|d)&A.qualifier){L[j]=A;continue}_=A.factory(t,V,g)}else{if(L[E](j))continue;_=F[j]}R===B(_)&&(_[u]=t[j]||H)}else e!==t[j]&&(I=B(t[j]),_=O===I?K(null,t[j]):(C|N)&I?t[j].slice(0):P&I?0+t[j]:t[j]);w[j]={value:_,enumerable:!1,writable:!0,configurable:!0}}for(j in L)L[E](j)&&(_=L[j].factory(t,V,g),w[j]={value:_,enumerable:!1,writable:!0,configurable:!0});return w[a]={value:S,enumerable:!1,writable:!0,configurable:!0},w[o]={value:L,enumerable:!1,writable:!0,configurable:!0},w[u]={value:t,enumerable:!1,writable:!0,configurable:!0},G(g,w),g},ee=K,ne=K,ie=function(n){var t,r,l,c;if(R===B(n)){if(u in n&&(n[u]=e),f in n&&(n[f]=e),o in n&&(n[o]=e),a in n){for(l=n[a],t=0,r=l.length;r>t;t++)c=l[t],c in n&&(R===B(n[c])&&n[c][u]&&(n[c][u]=e),n[c]=e);n[a]=e}l=n[i];for(c in l)R===B(l[c])&&(l[c][u]&&(l[c][u]=e),l[c]=e);l[u]=e,l[u+"v"]=e}},te=function(){var e=arguments,n=e.length,t=null;if(b===e[0])return e[1]||{};if(n>=2){var r=B(e[0]);r=R===r?{Extends:e[0]}:O===r?e[0]:{Extends:m};var l,u,a=e[1]||{},o={},f=r[E]("Extends")?r.Extends:r[E]("extends")?r["extends"]:m,c=r[E]("Implements")?r.Implements:r[E]("implements")?r["implements"]:null,s=r[E]("Mixin")?r.Mixin:r[E]("mixin")?r.mixin:null,d=null;if(c=c?[].concat(c):null,s=s?[].concat(s):null)for(l=0,u=s.length;u>l;l++)O===B(s[l])?s[l][E]("mixin")&&s[l].mixin&&s[l].mixin[i]&&(d=Q(s[l].mixin[i],s[l].namespace||null,s[l].as||null),o=ne(o,d)):s[l][i]&&(d=s[l][i],o=ne(o,d));if(c)for(l=0,u=c.length;u>l;l++)O===B(c[l])?c[l][E]("implements")&&c[l]["implements"]&&c[l]["implements"][i]&&(d=Q(c[l]["implements"][i],c[l].namespace||null,c[l].as||null),o=ee(o,d)):c[l][i]&&(d=c[l][i],o=ee(o,d));t=O===B(f)?Z(f["extends"]||m,K(o,a),f.namespace||null,f.as||null):Z(f,K(o,a))}else t=Z(m,e[0]);return t},re={VERSION:"0.9.3",PUBLIC:c,STATIC:b,LATE:d,PRIVATE:s,Type:B,Create:J,Merge:K,Alias:Q,Implements:ee,Mixin:ne,Extends:Z,Dispose:ie,Method:X,Prop:Y,Class:te};return re}); \ No newline at end of file diff --git a/build/mod3.bundle.js b/build/mod3.bundle.js deleted file mode 100644 index 928f7db..0000000 --- a/build/mod3.bundle.js +++ /dev/null @@ -1,21 +0,0 @@ -/** -* -* Classy.js -* @version: 0.9.3 -* @built on 2016-07-19 17:09:27 -* -* Object-Oriented micro-framework for JavaScript -* https://github.com/foo123/classy.js -* -**/!function(e,n,i){"use strict";"object"==typeof module&&module.exports?(module.$deps=module.$deps||{})&&(module.exports=module.$deps[n]=i.call(e)):"function"==typeof define&&define.amd&&"function"==typeof require&&"function"==typeof require.specified&&require.specified(n)?define(n,["module"],function(n){return i.moduleUri=n.uri,i.call(e)}):n in e||(e[n]=i.call(e)||1)&&"function"==typeof define&&define.amd&&define(function(){return e[n]})}(this,"Classy",function(){"use strict";var e=void 0,n="constructor",i="prototype",t="__proto__",r="__static__",l="__private__",u="$super",a="$static",o="$latestatic",f="$class",c=2,s=4,b=8,d=256,m=Object,p=m[i],v=Function,g=v[i],h=String,y=Number,x=RegExp,w=Array,j=p.toString,E=(g.call.bind(g.toString),"hasOwnProperty"),_="propertyIsEnumerable",q=m.keys,I=m.defineProperty,$=function(e){return typeof e},A=function(e){throw new TypeError(e)},P=2,S=3,T=4,C=8,M=9,N=16,O=32,R=64,F=128,L=256,U=512,V=1024,k={"[object Array]":N,"[object RegExp]":F,"[object Number]":P,"[object String]":C,"[object Function]":R,"[object Object]":O},B=function(n){var i;return null===n?L:!0===n||!1===n?T:e===n?U:(i=j.call(n),i=k[i]||V,P===i||n instanceof y?isNaN(n)?S:P:C===i||n instanceof h?1===n.length?M:C:N===i||n instanceof w?N:F===i||n instanceof x?F:R===i||n instanceof v?R:O===i?O:V)},D=function(e,n){var i,t=n.length,r=[].concat(e);for(i=0;t>i;i++)-1l;l++)if(i=a[l],O===B(i))for(r in i)i[E](r)&&i[_](r)&&(t=i[r],u=B(t),P&u?n[r]=0+t:(C|N)&u?n[r]=t.slice(0):n[r]=t);return n},Q=function(e,i,t){var r,l,u=!!i;if(u||t)if(r={},i=u?i+"$":i,t&&R===B(t))for(l in e)e[E](l)&&(n!==l?(u&&R===B(e[l])&&(r[i+l]=e[l]),r[t(l,e[l])]=e[l]):r[l]=e[l]);else for(l in e)e[E](l)&&(n!==l?(u&&R===B(e[l])&&(r[i+l]=e[l]),t&&l in t?r[t[l]]=e[l]:r[l]=e[l]):r[l]=e[l]);else r=e;return r},W=function(e){var n=e[u]||H,i=e[u+"v"]||H,t=null;return[function(i,r,l,u,a,o,f,c,s,b,d){var m,p;return t===i?m=n.call(this,i,r,l,u,a,o,f,c,s,b,d):(p=e[i])&&(t=i,m=p.call(this,r,l,u,a,o,f,c,s,b,d),t=null),m},function(n,r){var l,u;return t===n?l=i.call(this,n,r):(u=e[n])&&(t=n,l=r&&r.length?u.apply(this,r):u.call(this),t=null),l}]},X=function(e,n){return this instanceof X?(this.factory=e,void(this.qualifier=(P===B(n)?n:0)|c)):new X(e,n)},Y=function(e,n){return this instanceof Y?(this.prop=e,void(this.qualifier=(P===B(n)?n:0)|c)):new Y(e,n)},Z=function(t,c,p,v){t=t||m,c=c||{};var g,h,y,x,w,j,_,I,$,A,S=t[a]||null,T=t[o]||{},M=t[i],F=null,L=K({},T),U=null,V={};c[E](n)||(c[n]=function(){}),g=c[n],c[E](l)&&(V=c[l]||{},delete c[l]),c[E](r)&&(F=c[r],U=q(F),delete c[r]);for($ in c)if(c[E]($)){if(A=c[$],A instanceof X){if(b&A.qualifier){d&A.qualifier?L[$]=A:((F=F||{})[$]=A.factory(t,V,g),(U=U||[]).push($)),delete c[$];continue}if(s&A.qualifier){V[$]=A,delete c[$];continue}A=c[$]=A.factory(M,V,g)}R===B(A)&&(A[u]=M[$]||H)}for($ in V)V[E]($)&&(A=V[$],A instanceof X&&(A=V[$]=A.factory(M,V,g)),R!==B(A)&&delete V[$]);if(g[i]=Q(J(M),p,v),g[i]=K(g[i],c),h=W(M),w={},w[f]=w[n]={value:g,enumerable:!1,writable:!0,configurable:!0},w[u]={value:h[0],enumerable:!1,writable:!0,configurable:!0},w[u+"v"]={value:h[1],enumerable:!1,writable:!0,configurable:!0},G(g[i],w),w={},S||U)for(S=D(S||[],U||[]),x=S.length,y=0;x>y;y++){if(j=S[y],_=null,F&&e!==F[j]){if((A=F[j])instanceof X){if((b|d)&A.qualifier){L[j]=A;continue}_=A.factory(t,V,g)}else{if(L[E](j))continue;_=F[j]}R===B(_)&&(_[u]=t[j]||H)}else e!==t[j]&&(I=B(t[j]),_=O===I?K(null,t[j]):(C|N)&I?t[j].slice(0):P&I?0+t[j]:t[j]);w[j]={value:_,enumerable:!1,writable:!0,configurable:!0}}for(j in L)L[E](j)&&(_=L[j].factory(t,V,g),w[j]={value:_,enumerable:!1,writable:!0,configurable:!0});return w[a]={value:S,enumerable:!1,writable:!0,configurable:!0},w[o]={value:L,enumerable:!1,writable:!0,configurable:!0},w[u]={value:t,enumerable:!1,writable:!0,configurable:!0},G(g,w),g},ee=K,ne=K,ie=function(n){var t,r,l,c;if(R===B(n)){if(u in n&&(n[u]=e),f in n&&(n[f]=e),o in n&&(n[o]=e),a in n){for(l=n[a],t=0,r=l.length;r>t;t++)c=l[t],c in n&&(R===B(n[c])&&n[c][u]&&(n[c][u]=e),n[c]=e);n[a]=e}l=n[i];for(c in l)R===B(l[c])&&(l[c][u]&&(l[c][u]=e),l[c]=e);l[u]=e,l[u+"v"]=e}},te=function(){var e=arguments,n=e.length,t=null;if(b===e[0])return e[1]||{};if(n>=2){var r=B(e[0]);r=R===r?{Extends:e[0]}:O===r?e[0]:{Extends:m};var l,u,a=e[1]||{},o={},f=r[E]("Extends")?r.Extends:r[E]("extends")?r["extends"]:m,c=r[E]("Implements")?r.Implements:r[E]("implements")?r["implements"]:null,s=r[E]("Mixin")?r.Mixin:r[E]("mixin")?r.mixin:null,d=null;if(c=c?[].concat(c):null,s=s?[].concat(s):null)for(l=0,u=s.length;u>l;l++)O===B(s[l])?s[l][E]("mixin")&&s[l].mixin&&s[l].mixin[i]&&(d=Q(s[l].mixin[i],s[l].namespace||null,s[l].as||null),o=ne(o,d)):s[l][i]&&(d=s[l][i],o=ne(o,d));if(c)for(l=0,u=c.length;u>l;l++)O===B(c[l])?c[l][E]("implements")&&c[l]["implements"]&&c[l]["implements"][i]&&(d=Q(c[l]["implements"][i],c[l].namespace||null,c[l].as||null),o=ee(o,d)):c[l][i]&&(d=c[l][i],o=ee(o,d));t=O===B(f)?Z(f["extends"]||m,K(o,a),f.namespace||null,f.as||null):Z(f,K(o,a))}else t=Z(m,e[0]);return t},re={VERSION:"0.9.3",PUBLIC:c,STATIC:b,LATE:d,PRIVATE:s,Type:B,Create:J,Merge:K,Alias:Q,Implements:ee,Mixin:ne,Extends:Z,Dispose:ie,Method:X,Prop:Y,Class:te};return re}); -/** -* -* MOD3.js -* @version: 0.6.0 -* @dependencies: Classy.js -* -* MOD3 3D Modifier Library for JavaScript -* port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/) -* https://github.com/foo123/MOD3 -* -**/!function(t,n,e){"use strict";function r(t,n,e,r){return t?n.map(function(n,i){return(e?t[i]:t[n])||(r?r(n):null)}):[]}var i="Classy".split(/\s*,\s*/);"object"==typeof module&&module.exports?(module.$deps=module.$deps||{})&&(module.exports=module.$deps[n]=e.apply(t,r(module.$deps,i,!1,function(t){return require("./"+t.toLowerCase())}))):"function"==typeof define&&define.amd&&"function"==typeof require&&"function"==typeof require.specified&&require.specified(n)?define(n,["module"].concat(i),function(n){return e.moduleUri=n.uri,e.apply(t,r(Array.prototype.slice.call(arguments,1),i,!0))}):n in t||(t[n]=e.apply(t,r(t,i)))&&"function"==typeof define&&define.amd&&define(function(){return t[n]})}(this,"MOD3",function(t){"use strict";var n={VERSION:"0.6.0",Class:t.Class,StaticClass:function(n){return t.Class(t.STATIC,n)}};return!function(t,n){t.Constants={PI:Math.PI,invPI:1/Math.PI,halfPI:.5*Math.PI,doublePI:2*Math.PI,toRad:Math.PI/180,toDeg:180/Math.PI},t.ModConstant={NONE:0,LEFT:-1,RIGHT:1,X:1,Y:2,Z:4,Xi:0,Yi:1,Zi:2},t.XYZi=[null,0,1,null,2],t.iXYZ=[1,2,4],t.xyz=["x","y","z"],t.XYZ=["X","Y","Z"],t.Array32F="undefined"!=typeof Float32Array?Float32Array:Array,t.Array64F="undefined"!=typeof Float64Array?Float64Array:Array,t.Array8I="undefined"!=typeof Int8Array?Int8Array:Array,t.Array16I="undefined"!=typeof Int16Array?Int16Array:Array,t.Array32I="undefined"!=typeof Int32Array?Int32Array:Array,t.Array8U="undefined"!=typeof Uint8Array?Uint8Array:Array,t.Array16U="undefined"!=typeof Uint16Array?Uint16Array:Array,t.Array32U="undefined"!=typeof Uint32Array?Uint32Array:Array,t.VecArray=t.Array32F}(n),!function(t,n){var e,r=t.Constants.toRad,i=t.Constants.toDeg,o=(Math.min,Math.max,Math.pow),s=Math.round,a=Math.floor,u=Math.ceil,l=t.XMath=t.StaticClass({normalize:function(t,n,r){var i=n-t;return 0===i?1:e(0,1,(r-t)/n)},toRange:function(t,n,e){var r=n-t;return 0===r?0:t+r*e},inRange:function(t,n,e,r){return!1!==r?e>=t&&n>=e:e>t&&n>e},sign:function(t,n){return 0==t?n||0:t>0?1:-1},trim:function(t,n,e){return t>e?t:e>n?n:e},wrap:function(t,n,e){var r=n-t;return t>e?e+r:e>=n?e-r:e},degToRad:function(t){return t*r},radToDeg:function(t){return t*i},presicion:function(t,n){var e=o(10,n);return s(t*e)/e},uceil:function(t){return 0>t?a(t):u(t)}});e=l.clamp=l.trim}(n),!function(t,n){var e=t.XMath.normalize,r=t.XMath.toRange,i=t.XMath.trim;t.Range=t.Class({constructor:function o(t,n){var e=this;return e instanceof o?(e.start=null!=t?t:0,void(e.end=null!=n?n:1)):new o(t,n)},name:"Range",start:0,end:1,dispose:function(){var t=this;return t.start=null,t.end=null,t},getSize:function(){return this.end-this.start},move:function(t){this.start+=t,this.end+=t},isIn:function(t){return t>=this.start&&t<=this.end},normalize:function(t){return e(this.start,this.end,t)},toRange:function(t){return r(this.start,this.end,t)},trim:function(t){return i(this.start,this.end,t)},interpolate:function(t,n){return r(this.start,this.end,n.normalize(t))},toString:function(){return"["+this.start+" - "+this.end+"]"}})}(n),!function(t,n){var e=Math.sin,r=Math.abs;t.Phase=t.Class({constructor:function i(t){var n=this;return n instanceof i?void(n.value=t||0):new i(t)},name:"Phase",value:0,dispose:function(){return this.value=null,this},getPhasedValue:function(){return e(this.value)},getAbsPhasedValue:function(){return r(e(this.value))},getNormValue:function(){return.5*(e(this.value)+1)}})}(n),!function(t,n){var e=t.Point=t.Class({constructor:function r(t,n){var e=this;return e instanceof r?(e.x=null==t?0:t,void(e.y=null==n?0:n)):new r(t,n)},name:"Point",x:0,y:0,dispose:function(){var t=this;return t.x=null,t.y=null,t},clone:function(){return new e(this.x,this.y)}})}(n),!function(t,n){var e=Math.sin,r=Math.cos,i=t.Point,o=t.VecArray,s=t.Matrix=t.Class({__static__:{transform:function(t,n){var e=t.m,r=n[0],i=n[1];return n[0]=e[0]*r+e[1]*i,n[1]=e[2]*r+e[3]*i,n},mult:function(t,n){var e=t.m,r=n.m,i=e[0],o=e[1],s=e[2],a=e[3];return e[0]=i*r[0]+o*r[2],e[1]=i*r[1]+o*r[3],e[2]=s*r[0]+a*r[2],e[3]=s*r[1]+a*r[3],t}},constructor:function a(t,e,r,i){var s=this;return s instanceof a?void(s.m=new o([t===n?1:t,e===n?0:e,r===n?0:r,i===n?1:i])):new a(t,e,r,i)},name:"Matrix",m:null,dispose:function(){return this.m=null,this},reset:function(){var t=this.m;return t[0]=1,t[1]=0,t[2]=0,t[3]=1,this},rotate:function(t){var n=this.m,i=r(t),o=e(t);return n[0]=i,n[1]=-o,n[2]=o,n[3]=i,this},scale:function(t,e){var r=this.m;return r[0]=1,r[1]=0,r[2]=0,r[3]=1,t!==n&&(r[0]=t,r[3]=t),e!==n&&(r[3]=e),this},multiply:function(t){return s.mult(this,t)},transformPoint:function(t){var n=s.transform(this,[t.x,t.y]);return new i(n[0],n[1])},transformPointSelf:function(t){var n=s.transform(this,[t.x,t.y]);return t.x=n[0],t.y=n[1],t},clone:function(){var t=this.m;return new s(t[0],t[1],t[2],t[3])}})}(n),!function(t,n){var e=Math.sqrt,r=t.VecArray,i=t.Vector3=t.Class({__static__:{ZERO:function(){return new i(0,0,0)},X:function(t){return!1===t?new i(0,1,1):new i(1,0,0)},Y:function(t){return!1===t?new i(1,0,1):new i(0,1,0)},Z:function(t){return!1===t?new i(1,1,0):new i(0,0,1)},dot:function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},equals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]},cross:function(t,n){var e=new r(3);return e[0]=t[1]*n[2]-t[2]*n[1],e[1]=t[2]*n[0]-t[0]*n[2],e[2]=t[0]*n[1]-t[1]*n[0],e},mod:function(t){var n=t[0],r=t[1],i=t[2];return e(n*n+r*r+i*i)},dist:function(t,n){var r=t[0]-n[0],i=t[1]-n[1],o=t[2]-n[2];return e(r*r+i*i+o*o)},add:function(t,n){return t[0]+=n[0],t[1]+=n[1],t[2]+=n[2],t},sub:function(t,n){return t[0]-=n[0],t[1]-=n[1],t[2]-=n[2],t},mul:function(t,n){return t[0]*=n[0],t[1]*=n[1],t[2]*=n[2],t},muls:function(t,n){return t[0]*=n,t[1]*=n,t[2]*=n,t},norm:function(t){var n,r=t[0],i=t[1],o=t[2],s=r*r+i*i+o*o;return s>0&&(n=e(s),r/=n,i/=n,o/=n),t[0]=r,t[1]=i,t[2]=o,t}},constructor:function o(t,n,e){var i=this;if(!(i instanceof o))return new o(t,n,e);var s=new r(3);t&&3===t.length?(s[0]=t[0]||0,s[1]=t[1]||0,s[2]=t[2]||0):(s[0]=t||0,s[1]=n||0,s[2]=e||0),i.xyz=s},name:"Vector3",xyz:null,dispose:function(){return this.xyz=null,this},getXYZ:function(){return new r(this.xyz)},getXYZRef:function(){return this.xyz},setXYZ:function(t){var n=this.xyz;return n[0]=t[0],n[1]=t[1],n[2]=t[2],this},setXYZRef:function(t){return this.xyz=t,this},clone:function(){return new i(this.xyz)},equalsSelf:function(t){var n=this.xyz,e=t.xyz;return n[0]===e[0]&&n[1]===e[1]&&n[2]===e[2]},zeroSelf:function(){var t=this.xyz;return t[0]=0,t[1]=0,t[2]=0,this},negate:function(){var t=this.xyz;return new i(-t[0],-t[1],-t[2])},negateSelf:function(){var t=this.xyz;return t[0]=-t[0],t[1]=-t[1],t[2]=-t[2],this},add:function(t){var n=this.xyz,e=t.xyz;return new i(n[0]+e[0],n[1]+e[1],n[2]+e[2])},addSelf:function(t){var n=this.xyz,e=t.xyz;return n[0]+=e[0],n[1]+=e[1],n[2]+=e[2],this},subtract:function(t){var n=this.xyz,e=t.xyz;return new i(n[0]-e[0],n[1]-e[1],n[2]-e[2])},subtractSelf:function(t){var n=this.xyz,e=t.xyz;return n[0]-=e[0],n[1]-=e[1],n[2]-=e[2],this},multiplyScalar:function(t){var n=this.xyz;return new i(n[0]*t,n[1]*t,n[2]*t)},multiplyScalarSelf:function(t){var n=this.xyz;return n[0]*=t,n[1]*=t,n[2]*=t,this},multiply:function(t){var n=this.xyz,e=t.xyz;return new i(n[0]*e[0],n[1]*e[1],n[2]*e[2])},multiplySelf:function(t){var n=this.xyz,e=t.xyz;return n[0]*=e[0],n[1]*=e[1],n[2]*=e[2],this},divide:function(t){var n=this.xyz;return new i(n[0]/t,n[1]/t,n[2]/t)},divideSelf:function(t){var n=this.xyz;return n[0]/=t,n[1]/=t,n[2]/=t,this},normalize:function(){var t,n=this.xyz,r=n[0],o=n[1],s=n[2],a=r*r+o*o+s*s;return a>0&&(t=e(a),r/=t,o/=t,s/=t),new i(r,o,s)},normalizeSelf:function(){var t,n=this.xyz,r=n[0],i=n[1],o=n[2],s=r*r+i*i+o*o;return s>0&&(t=e(s),r/=t,i/=t,o/=t),n[0]=r,n[1]=i,n[2]=o,this},getMagnitude:function(){var t=this.xyz,n=t[0],r=t[1],i=t[2];return e(n*n+r*r+i*i)},setMagnitude:function(t){this.normalizeSelf();var n=this.xyz;return n[0]*=t,n[1]*=t,n[2]*=t,this},dot:function(t){var n=this.xyz,e=t.xyz;return n[0]*e[0]+n[1]*e[1]+n[2]*e[2]},cross:function(t){var n=this.xyz,e=t.xyz,r=n[0],o=n[1],s=n[2],a=e[0],u=e[1],l=e[2];return new i(o*l-s*u,s*a-r*l,r*u-o*a)},crossSelf:function(t){var t=this.xyz,n=b.xyz,e=t[0],r=t[1],i=t[2],o=n[0],s=n[1],a=n[2];return t[0]=r*a-i*s,t[1]=i*o-e*a,t[2]=e*s-r*o,this},distance:function(t){var n=this.xyz,r=t.xyz,i=n[0]-r[0],o=n[1]-r[1],s=n[2]-r[2];return e(i*i+o*o+s*s)},toString:function(){var t=this.xyz;return"["+t[0]+" , "+t[1]+" , "+t[2]+"]"}});i.modulo=i.mod,i.distance=i.dist,i.prototype.dotSelf=i.prototype.dot,i.prototype.distanceSelf=i.prototype.distance}(n),!function(t,n){var e=Math.sin,r=Math.cos,i=t.VecArray,o=t.Matrix4=t.Class({__static__:{multXYZ:function(t,n){var e=t.m,r=n[0],i=n[1],o=n[2];return n[0]=r*e[0]+i*e[1]+o*e[2]+e[3],n[1]=r*e[4]+i*e[5]+o*e[6]+e[7],n[2]=r*e[8]+i*e[9]+o*e[10]+e[11],n},mult:function(t,n){var e=t.m,r=n.m,i=e[0],o=r[0],s=e[4],a=r[4],u=e[8],l=r[8],c=e[1],f=r[1],h=e[5],d=r[5],p=e[9],v=r[9],m=e[2],y=r[2],x=e[6],g=r[6],M=e[10],w=r[10],A=e[3],z=r[3],Y=e[7],X=r[7],Z=e[11],V=r[11];return e[0]=i*o+c*a+m*l,e[1]=i*f+c*d+m*v,e[2]=i*y+c*g+m*w,e[3]=i*z+c*X+m*V+A,e[4]=s*o+h*a+x*l,e[5]=s*f+h*d+x*v,e[6]=s*y+h*g+x*w,e[7]=s*z+h*X+x*V+Y,e[8]=u*o+p*a+M*l,e[9]=u*f+p*d+M*v,e[10]=u*y+p*g+M*w,e[11]=u*z+p*X+M*V+Z,t}},constructor:function s(t,e,r,o,a,u,l,c,f,h,d,p,v,m,y,x){var g=this;return g instanceof s?void(g.m=new i([t===n?1:t,e===n?0:e,r===n?0:r,o===n?0:o,a===n?0:a,u===n?1:u,l===n?0:l,c===n?0:c,f===n?0:f,h===n?0:h,d===n?1:d,p===n?0:p,v===n?0:v,m===n?0:m,y===n?0:y,x===n?1:x])):new s(t,e,r,o,a,u,l,c,f,h,d,p,v,m,y,x)},name:"Matrix4",m:null,dispose:function(){return this.m=null,this},reset:function(){var t=this.m;return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this},translate:function(t,n,e,r){var i=this.m;return!0===r&&(i[0]=1,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=1,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=1,i[11]=0,i[12]=0,i[13]=0,i[14]=0,i[15]=1),i[3]=t,i[7]=n,i[11]=e,this},scale:function(t,n,e,r){var i=this.m;return!0===r&&(i[0]=1,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=1,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=1,i[11]=0,i[12]=0,i[13]=0,i[14]=0,i[15]=1),i[0]=t,i[5]=n,i[10]=e,this},rotate:function(t,n,i,o,s){var a=this.m,u=r(o),l=e(o),c=1-u,f=t*n*c,h=n*i*c,d=t*i*c,p=l*i,v=l*n,m=l*t;return!0===s&&(a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1),a[0]=u+t*t*c,a[1]=-p+f,a[2]=v+d,a[3]=0,a[4]=p+f,a[5]=u+n*n*c,a[6]=-m+h,a[7]=0,a[8]=-v+d,a[9]=m+h,a[10]=u+i*i*c,a[11]=0,this},translateFromVector:function(t,n){return this.translate(t.xyz[0],t.xyz[1],t.xyz[2],n)},scaleFromVector:function(t,n){return this.scale(t.xyz[0],t.xyz[1],t.xyz[2],n)},rotateFromVector:function(t,n,e){return this.rotate(t.xyz[0],t.xyz[1],t.xyz[2],n,e)},multiply:function(t){return o.mult(this,t)},multiplyVector:function(t){return o.multXYZ(this,t.xyz),t}});o.prototype.translationMatrix=o.prototype.translate,o.prototype.scaleMatrix=o.prototype.scale,o.prototype.rotationMatrix=o.prototype.rotate,o.prototype.translationMatrixFromVector=o.prototype.translateFromVector,o.prototype.scaleMatrixFromVector=o.prototype.scaleFromVector,o.prototype.rotationMatrixFromVector=o.prototype.rotateFromVector}(n),!function(t,n){t.List={operate:function(t,n,e,r,i,o){var s=t.length;if(arguments.length<5&&(i=s-1),0>i&&(i+=s),arguments.length<4&&(r=0),r>i)return e;if(!0===o){var a,u,l=i-r+1,c=l-1,f=15&l,h=1&f,d=c-f,p=h?n(e,t[i],i):e;for(a=c-h;a>d;a-=2)u=r+a,p=n(n(p,t[u],u),t[u-1],u-1);for(a=d;a>=0;a-=16)u=r+a,p=n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(p,t[u],u),t[u-1],u-1),t[u-2],u-2),t[u-3],u-3),t[u-4],u-4),t[u-5],u-5),t[u-6],u-6),t[u-7],u-7),t[u-8],u-8),t[u-9],u-9),t[u-10],u-10),t[u-11],u-11),t[u-12],u-12),t[u-13],u-13),t[u-14],u-14),t[u-15],u-15)}else{var a,u,l=i-r+1,f=15&l,h=1&f,p=h?n(e,t[r],r):e;for(a=h;f>a;a+=2)u=r+a,p=n(n(p,t[u],u),t[u+1],u+1);for(a=f;l>a;a+=16)u=r+a,p=n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(n(p,t[u],u),t[u+1],u+1),t[u+2],u+2),t[u+3],u+3),t[u+4],u+4),t[u+5],u+5),t[u+6],u+6),t[u+7],u+7),t[u+8],u+8),t[u+9],u+9),t[u+10],u+10),t[u+11],u+11),t[u+12],u+12),t[u+13],u+13),t[u+14],u+14),t[u+15],u+15)}return p},each:function(t,n,e,r,i){if(null==t||!t.length)return t;var o=t.length;if(arguments.length<4&&(r=o-1),0>r&&(r+=o),arguments.length<3&&(e=0),e>r)return t;var s,a,u,l,c,f,h=r-e+1;if(!0===i){for(u=h-1,c=15&h,f=1&c,l=u-c,f&&n(t[r]),s=u-f;s>l;s-=2)a=e+s,n(t[a]),n(t[a-1]);for(s=l;s>=0;s-=16)a=e+s,n(t[a]),n(t[a-1]),n(t[a-2]),n(t[a-3]),n(t[a-4]),n(t[a-5]),n(t[a-6]),n(t[a-7]),n(t[a-8]),n(t[a-9]),n(t[a-10]),n(t[a-11]),n(t[a-12]),n(t[a-13]),n(t[a-14]),n(t[a-15])}else{for(c=15&h,f=1&c,f&&n(t[e]),s=f;c>s;s+=2)a=e+s,n(t[a]),n(t[a+1]);for(s=c;h>s;s+=16)a=e+s,n(t[a]),n(t[a+1]),n(t[a+2]),n(t[a+3]),n(t[a+4]),n(t[a+5]),n(t[a+6]),n(t[a+7]),n(t[a+8]),n(t[a+9]),n(t[a+10]),n(t[a+11]),n(t[a+12]),n(t[a+13]),n(t[a+14]),n(t[a+15])}return t}}}(n),!function(t,n){var e,r,i,o,s=t.ModConstant,a=s.X,u=s.Y,l=s.Z,c=t.XYZi,f=(t.Vector3,t.VecArray),h=Math.min,d=Math.max,p=t.List.each,v=function(t){t.dispose()},m=function(t){t.reset()},y=function(t){t.collapse()};e=t.FaceProxy=t.Class({constructor:function(){this.vertices=[]},name:"FaceProxy",vertices:null,dispose:function(){var t=this;return t.vertices=null,t},addVertex:function(t){this.vertices.push(t)},getVertices:function(){return this.vertices}}),r=t.VertexProxy=t.Class({constructor:function(t,n){var e=this;e.mesh=n||null,e.original=new f([0,0,0]),e.ratio=new f([0,0,0]),null!=t&&e.setVertex(t)},name:"VertexProxy",mesh:null,vertex:null,original:null,ratio:null,dispose:function(){var t=this;return t.mesh=null,t.vertex=null,t.original=null,t.ratio=null,t},setVertex:function(t){var n=this;return n.vertex=t,n},getRatioVector:function(){var t=this.ratio,n=new f(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},getRatio:function(t){return this.ratio[c[t]]||0},setRatios:function(t,e,r){var i=this.ratio;return i[0]=t===n?0:t,i[1]=e===n?0:e,i[2]=r===n?0:r,this},getOriginalValue:function(t){return this.original[c[t]]||0},setOriginalPosition:function(t,e,r){var i=this.original;return i[0]=t===n?0:t,i[1]=e===n?0:e,i[2]=r===n?0:r,this},getXYZ:function(){return new f([0,0,0])},getX:function(){return 0},getY:function(){return 0},getZ:function(){return 0},getValue:function(t){var n=this;return a===t?n.getX():u===t?n.getY():l===t?n.getZ():0},setXYZ:function(t){return this},setX:function(t){return this},setY:function(t){return this},setZ:function(t){return this},setValue:function(t,n){var e=this;return a===t?e.setX(n):u===t?e.setY(n):l===t&&e.setZ(n),e},reset:function(){var t=this;return t.setXYZ(t.original),t},collapse:function(){var t=this,n=t.getXYZ(),e=t.original;return e[0]=n[0],e[1]=n[1],e[2]=n[2],t}}),i=t.MeshProxy=t.Class({constructor:function(t){var n=this;n.maxX=0,n.maxY=0,n.maxZ=0,n.minX=0,n.minY=0,n.minZ=0,n.maxAxis=0,n.midAxis=0,n.minAxis=0,n.width=0,n.height=0,n.depth=0,n.vertices=null,n.faces=null,n.mesh=null,null!=t&&n.setMesh(t)},name:"MeshProxy",maxX:0,maxY:0,maxZ:0,minX:0,minY:0,minZ:0,maxAxis:0,midAxis:0,minAxis:0,width:0,height:0,depth:0,vertices:null,faces:null,mesh:null,v:null,dispose:function(){var t=this;return t.maxX=null,t.maxY=null,t.maxZ=null,t.minX=null,t.minY=null,t.minZ=null,t.maxAxis=null,t.midAxis=null,t.minAxis=null,t.width=null,t.height=null,t.depth=null,t.disposeFaces(),t.disposeVertices(),t.mesh=null,t.v=null,t},disposeVertices:function(){var t=this;return p(t.vertices,v),t.vertices=null,t},disposeFaces:function(){var t=this;return p(t.faces,v),t.faces=null,t},init:function(t){var n=this;return n.mesh=t,n},setMesh:function(t){return this.init(t).preApply().analyzeGeometry().postApply()},getVertices:function(){return this.vertices},getFaces:function(){return this.faces},applyModifiers:function(t){var n,e,r=this;for(e=0,n=t.length;n>e;e++)t[e].enabled&&t[e].apply(r);return r},analyzeGeometry:function(){var t,n,e,r=this,i=r.vertices,o=0,s=0,c=0,f=0,v=0,m=0,y=0,x=0,g=0;return i&&i.length?(e=i[0].getXYZ(),o=e[0],s=e[1],c=e[2],f=e[0],v=e[1],m=e[2],p(i,function(t){var n=t.getXYZ(),e=n[0],r=n[1],i=n[2];o=h(o,e),s=h(s,r),c=h(c,i),f=d(f,e),v=d(v,r),m=d(m,i),t.setOriginalPosition(e,r,i)}),y=f-o,x=v-s,g=m-c,r.width=y,r.height=x,r.depth=g,r.minX=o,r.maxX=f,r.minY=s,r.maxY=v,r.minZ=c,r.maxZ=m,t=d(y,x,g),n=h(y,x,g),t===y&&n===x?(r.minAxis=u,r.midAxis=l,r.maxAxis=a):t===y&&n===g?(r.minAxis=l,r.midAxis=u,r.maxAxis=a):t===x&&n===y?(r.minAxis=a,r.midAxis=l,r.maxAxis=u):t===x&&n===g?(r.minAxis=l,r.midAxis=a,r.maxAxis=u):t===g&&n===y?(r.minAxis=a,r.midAxis=u,r.maxAxis=l):t===g&&n===x&&(r.minAxis=u,r.midAxis=a,r.maxAxis=l),p(i,function(t){var n=t.getXYZ();t.setRatios(y>0?(n[0]-o)/y:0,x>0?(n[1]-s)/x:0,g>0?(n[2]-c)/g:0)}),r):r},resetGeometry:function(){var t=this;return p(t.vertices,m),t},collapseGeometry:function(){var t=this;return p(t.vertices,y),t.analyzeGeometry()},getMin:function(t){var n=this;return a===t?n.minX:u===t?n.minY:l===t?n.minZ:-1},getMax:function(t){var n=this;return a===t?n.maxX:u===t?n.maxY:l===t?n.maxZ:-1},getSize:function(t){var n=this;return a===t?n.width:u===t?n.height:l===t?n.depth:-1},update:function(){return this},preApply:function(){return this},postApply:function(){return this},updateMeshPosition:function(t){return this}}),t.Library3d={id:"Library3d",Mesh:i,Vertex:r},o=t.Factory=t.StaticClass({getLibrary:function(n){return n&&n.library&&t[n.library]?t[n.library]:t.Library3d},getMeshProxy:function(t){return arguments.length&&t.Mesh?new t.Mesh:null},getModifier:function(n){return n&&n.modifier&&t[n.modifier]?new t[n.modifier]:null}})}(n),!function(t,n){var e,r,i=0,o=t.ModConstant.NONE,s=t.Factory.getMeshProxy;e=t.Modifier=t.Class({constructor:function(){var t=this;t.id=++i,t.name="Modifier",t.axes=o,t.constraint=o,t.enabled=!0},id:null,name:"Modifier",axes:null,constraint:null,enabled:!0,dispose:function(){var t=this;return t.name=null,t.axes=null,t.constraint=null,t},enable:function(t){return arguments.length?(this.enabled=!!t,this):this.enabled},constraintAxes:function(t){return this.axes=t||o,this},setConstraint:function(t){return this.constraint=t||o,this},apply:function(t){return this},toString:function(){return"[Modifier "+this.name+"]"}}),r=t.ModifierStack=t.Class({constructor:function a(t,n){var e=this;return e instanceof a?(e.stack=[],void e.setModifiable(s(t),n)):new a(t,n)},name:"ModifierStack",modifiable:null,stack:null,dispose:function(t){var n=this;if(t&&n.stack)for(;n.stack.length;)n.stack.pop().dispose();return n.modifiable&&n.modifiable.dispose(),n.stack=null,n.modifiable=null,n},getModifiable:function(){return this.modifiable},setModifiable:function(t,n){var e=this;return e.modifiable=t,n&&e.modifiable.setMesh(n),e},add:function(t){var n=this;return t&&n.stack.push(t),n},apply:function(){var t=this,n=t.modifiable,e=t.stack;return n&&e&&e.length&&n.preApply().resetGeometry().applyModifiers(e).postApply().update(),t},collapse:function(){var t=this,n=t.modifiable;return n&&t.stack&&t.stack.length&&(n.preApply().resetGeometry().applyModifiers(t.stack).collapseGeometry().postApply().update(),t.stack.length=0),t},clear:function(){var t=this;return t.stack&&(t.stack.length=0),t}}),r.prototype.getMeshInfo=r.prototype.getModifiable,r.prototype.addModifier=r.prototype.add}(n),!function(t,n){var e=t.Vector3,r=t.List.each,i=e.add;t.Pivot=t.Class(t.Modifier,{constructor:function o(t,n,r){var i=this;return i instanceof o?(i.$super("constructor"),i.name="Pivot",void(i.vector=new e(t||0,n||0,r||0))):new o(t,n,r)},vector:null,dispose:function(){var t=this;return t.vector.dispose(),t.vector=null,t.$super("dispose"),t},setMeshCenter:function(t){var n=this;return n.vector=new e(-(t.minX+.5*t.width),-(t.minY+.5*t.height),-(t.minZ+.5*t.depth)),n},apply:function(t){var n=this,e=n.vector,o=e.xyz;return r(t.vertices,function(t){t.setXYZ(i(t.getXYZ(),o))}),t.updateMeshPosition(e.negate()),n}})}(n),!function(t,n){var e=t.ModConstant.NONE,r=t.ModConstant.LEFT,i=t.ModConstant.RIGHT,o=t.XYZi,s=t.Matrix,a=(Math.atan,Math.atan2,Math.sin),u=Math.cos,l=t.Constants.PI,c=t.Constants.halfPI,f=t.Constants.doublePI,h=Math.max,d=Math.min,p=t.List.each,v=s.transform;t.Bend=t.Class(t.Modifier,{constructor:function m(t,n,r){var i=this;return i instanceof m?(i.$super("constructor"),i.name="Bend",i.constraint=e,i.switchAxes=!1,i.force=t||0,i.offset=n||0,void(i.angle=r||0)):new m(t,n,r)},force:0,offset:0,angle:0,switchAxes:!1,dispose:function(){var t=this;return t.force=null,t.offset=null,t.angle=null,t.switchAxes=null,t.$super("dispose"),t},apply:function(t){var n=this;if(0==n.force)return n;var e=n.constraint,m=n.switchAxes,y=n.force,x=d(1,h(0,n.offset)),g=n.angle,M=m?t.midAxis:t.maxAxis,w=t.minAxis,A=m?t.maxAxis:t.midAxis,z=t.getSize(M),Y=(t.getSize(A),t.getMin(M)),X=(new s).rotate(g),Z=(new s).rotate(-g),V=Y+z*x,C=z/l/y,b=f*(z/(C*f));return p(t.vertices,function(t){var n,s,l,f,h,d=t.getXYZ(),p=d[o[M]],m=d[o[A]],y=d[o[w]],g=v(X,[p,m]);p=g[0],m=g[1],n=(p-Y)/z,r===e&&x>=n||i===e&&n>=x||(s=c-b*x+b*n,l=a(s)*(C+y),f=u(s)*(C+y),y=l-C,p=V-f),h=v(Z,[p,m]),p=h[0],m=h[1],d[o[M]]=p,d[o[A]]=m,d[o[w]]=y,t.setXYZ(d)}),n}})}(n),!function(t,n){var e=t.Vector3,r=Math.max,i=Math.exp,o=t.List.each,s=e.add,a=e.sub,u=e.muls,l=e.mod,c=e.norm;t.Bloat=t.Class(t.Modifier,{constructor:function f(t,n,r){var i=this;return i instanceof f?(i.$super("constructor"),i.name="Bloat",i.radius=t||0,i.a=null==n?.01:n,void(i.center=r||e.ZERO())):new f(t,n,r)},radius:0,a:.01,center:null,dispose:function(){var t=this;return t.center.dispose(),t.center=null,t.radius=null,t.a=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.center.xyz,f=r(0,n.radius),h=r(0,n.a);return o(t.vertices,function(t){var n=a(t.getXYZ(),e),r=l(n);u(c(n),r+f*i(-r*h)),t.setXYZ(s(n,e))}),n}})}(n),!function(t,n){var e=t.Vector3,r=(Math.sqrt,t.Matrix4),i=t.List.each,o=r.mult,s=e.dot,a=e.mod;t.Twist=t.Class(t.Modifier,{constructor:function u(t,n,r){var i=this;return i instanceof u?(i.$super("constructor"),i.name="Twist",i.angle=t||0,i.vector=n||e.Y(),void(i.center=r||e.ZERO())):new u(t,n,r)},angle:0,vector:null,center:null,dispose:function(){var t=this;return t.vector.dispose(),t.vector=null,t.angle=null,t.center.dispose(),t.center=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.vector.normalizeSelf().xyz,u=n.angle,l=n.center.xyz,c=a([.5*t.maxX,.5*t.maxY,.5*t.maxZ]),f=-s(e,l),h=new r,d=new r;return i(t.vertices,function(t){var n=t.getXYZ(),r=(s(n,e)+f)*u/c,i=o(d.rotate(e[0],e[1],e[2],r,!0),h.translate(n[0],n[1],n[2],!0));t.setXYZ([i.m[3],i.m[7],i.m[11]])}),n}})}(n),!function(t,n){var e=Math.abs,r=Math.pow,i=Math.max,o=Math.min,s=t.ModConstant,a=s.NONE,u=s.LEFT,l=s.RIGHT,c=s.X,f=s.Y,h=s.Z,d=t.List.each;t.Skew=t.Class(t.Modifier,{constructor:function p(t,e,r,i){var o=this;return o instanceof p?(o.$super("constructor"),o.name="Skew",o.constraint=a,o.force=t!==n?t:0,o.offset=e!==n?e:.5,o.power=r!==n?r:1,o.falloff=i!==n?i:1,o.inverseFalloff=!1,o.oneSide=!1,o.swapAxes=!1,void(o.skewAxis=0)):new p(t,e,r,i)},force:0,skewAxis:0,offset:.5,power:1,falloff:1,inverseFalloff:!1,oneSide:!1,swapAxes:!1,dispose:function(){var t=this;return t.force=null,t.skewAxis=null,t.offset=null,t.power=null,t.falloff=null,t.inverseFalloff=null,t.oneSide=null,t.swapAxes=null,t.$super("dispose"),t},apply:function(t){var n=this,s=n.constraint,a=n.skewAxis||t.maxAxis,p=n.swapAxes,v=o(1,i(0,n.offset)),m=n.oneSide,y=!!n.inverseFalloff,x=o(1,i(0,n.falloff)),g=1-x,M=n.power,w=n.force,A=c===a?p?h:f:f===a?p?h:c:h===a?p?f:c:0;return d(t.vertices,function(t){var n,i,o,c,f;f=t.getRatio(a),u===s&&v>=f||l===s&&f>v||(n=f-v,m&&0>n&&(n=-n),i=t.getRatio(A),y&&(i=1-i),o=x+i*g,c=(0>n?-1:1)*r(e(n),M),t.setValue(A,t.getValue(A)+w*c*o))}),n}})}(n),!function(t,n){var e=t.Vector3,r=t.Matrix4,i=Math.pow,o=e.mul,s=e.mod,a=t.List.each,u=r.multXYZ;t.Taper=t.Class(t.Modifier,{constructor:function l(t,r,i,o){var s=this;return s instanceof l?(s.$super("constructor"),s.name="Taper",s.force=t!==n?t:0,s.power=r!==n?r:1,s.vector=i||e.Y(!1),void(s.vector2=o||e.Y())):new l(t,r,i,o)},force:0,power:1,vector:null,vector2:null,dispose:function(){var t=this;return t.vector.dispose(),t.vector2.dispose(),t.vector=null,t.vector2=null,t.force=null,t.power=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.vector.xyz,l=n.vector2.xyz,c=n.force,f=n.power,h=new r;return a(t.vertices,1!=f?function(t){var n=s(o(t.getRatioVector(),l)),r=c*i(n,f);t.setXYZ(u(h.scale(1+r*e[0],1+r*e[1],1+r*e[2]),t.getXYZ()))}:function(t){var n=s(o(t.getRatioVector(),l)),r=c*n;t.setXYZ(u(h.scale(1+r*e[0],1+r*e[1],1+r*e[2]),t.getXYZ()))}),n}})}(n),!function(t,n){var e=(t.Constants.invPI,t.Constants.doublePI,t.Vector3),r=t.Matrix4,i=t.List.each,o=r.multXYZ;t.Wheel=t.Class(t.Modifier,{constructor:function s(t,n,r,i,o){var a=this;return a instanceof s?(a.$super("constructor"),a.name="Wheel",a.speed=t||0,a.turn=n||0,a.roll=r||0,a.steerVector=i||e.Y(),void(a.rollVector=o||e.Z())):new s(t,n,r,i,o)},speed:0,turn:0,roll:0,steerVector:null,rollVector:null,dispose:function(){var t=this;return t.speed=null,t.turn=null,t.roll=null,t.steerVector.dispose(),t.rollVector.dispose(),t.steerVector=null,t.rollVector=null,t.$super("dispose"),t},apply:function(t){var n=this,e=n.steerVector.normalizeSelf(),s=n.rollVector.normalizeSelf(),a=n.turn,u=n.roll,l=null,c=null;return n.roll+=n.speed,a?(c=(new r).rotateFromVector(e,a),l=(new r).rotateFromVector(c.multiplyVector(s.clone()),u)):l=(new r).rotateFromVector(s,u),i(t.vertices,c?function(t){t.setXYZ(o(l,o(c,t.getXYZ())))}:function(t){t.setXYZ(o(l,t.getXYZ()))}),n}})}(n),!function(t,n){var e=t.Vector3,r=t.Range,i=t.Matrix4,o=Math.max,s=Math.min,a=t.List.each,u=i.multXYZ;t.Break=t.Class(t.Modifier,{constructor:function l(t,n,i){var o=this;return o instanceof l?(o.$super("constructor"),o.name="Break",o.offset=t||0,o.angle=n||0,o.vector=i||e.Y(),void(o.range=new r(0,1))):new l(t,n,i)},offset:0,angle:0,vector:null,range:null,dispose:function(){var t=this;return t.vector.dispose(),t.range.dispose(),t.vector=null,t.range=null,t.offset=null,t.angle=null,t.$super("dispose"),t},apply:function(t){var n,e,r=this,l=s(1,o(0,r.offset)),c=r.range,f=r.angle,h=r.vector.normalizeSelf().xyz;return n=t.minZ+t.depth*l,e=(new i).rotate(h[0],h[1],h[2],f),a(t.vertices,function(t){var r=t.getXYZ();r[2]-=n,0<=r[2]&&c.isIn(t.ratio[1])&&u(e,r),r[2]+=n,t.setXYZ(r)}),r}})}(n),!function(t,n){var e=(t.ModConstant.NONE,t.ModConstant.X),r=t.ModConstant.Y,i=t.ModConstant.Z,o=Math.random,s=t.List.each;t.Noise=t.Class(t.Modifier,{constructor:function a(t){var n=this;return n instanceof a?(n.$super("constructor"),n.name="Noise",n.force=t||0,n.start=0,n.end=1,void(n.axes=e|r|i)):new a(t)},force:0,start:0,end:1,dispose:function(){var t=this;return t.force=null,t.start=null,t.end=null,t.$super("dispose"),t},setFalloff:function(t,e){var r=this;return r.start=t!==n?t:0,r.end=e!==n?e:1,r},apply:function(t){var n=this,a=n.axes,u=n.start,l=n.end,c=n.force,f=.5*c,h=t.maxAxis;return 0==a||0==c?n:(s(t.vertices,function(t){var n,s,d=o()*c-f,p=t.getRatio(h);l>u?u>p?p=0:p>l&&(p=1):u>l?(p=1-p,p>u?p=0:l>p&&(p=1)):p=1,n=d*p,s=t.getXYZ(),t.setXYZ([s[0]+(a&e?n:0),s[1]+(a&r?n:0),s[2]+(a&i?n:0)])}),n)}})}(n),!function(t,n){var e=t.ModConstant,r=(e.NONE,e.X),i=e.Y,o=e.Z,s=t.List.each;t.DisplaceMap=t.Class(t.Modifier,{constructor:function a(t,n,e){var s=this;return s instanceof a?(s.$super("constructor"),s.name="DisplaceMap",+t==t?(s.force=t||1,s.offset=null==n?127:n):(s.setBitmap(t),s.force=n||1,s.offset=null==e?127:e),void(s.axes=r|i|o)):new a(t,n,e)},width:null,height:null,bmpData:null,force:1,offset:127,dispose:function(){var t=this;return t.bmpData=null,t.width=null,t.height=null,t.force=null,t.offset=null,t.$super("dispose"),t},setBitmap:function(t){var n=this;return n.bmpData=t?t.data:null,n.width=t?t.width:0,n.height=t?t.height:0,n},apply:function(t){var n=this,e=n.axes,a=n.width,u=n.height,l=n.bmpData,c=n.force,f=n.offset;return e&&l?(s(t.vertices,function(t){var n,s,h,d=t.getXYZ();s=~~((a-1)*t.ratio[0]),h=~~((u-1)*t.ratio[2]),n=h*a+s<<2,t.setXYZ([d[0]+(e&r?((255&l[n])-f)*c:0),d[1]+(e&i?((255&l[n+1])-f)*c:0),d[2]+(e&o?((255&l[n+2])-f)*c:0)])}),n):n}})}(n),!function(t,n){function e(t,n,e,i,o){var s,a,u,l,c,f=n*e,h=new r(f);for(0>i&&(i+=n),0>o&&(o+=e),i=~~i,o=~~o,s=0,a=0,c=0;f>c;c++,s++)s>=n&&(s=0,a++),u=(s+i)%n,l=(a+o)%e,h[c]=t[u+l*n];return h}var r=(t.Vector3,Math.round,t.VecArray),i=t.ModConstant,o=(i.NONE,i.X),s=i.Y,a=i.Z,u=t.List.each;t.Perlin=t.Class(t.Modifier,{constructor:function l(t,e,r){var i=this;return i instanceof l?(i.$super("constructor"),i.name="Perlin",i.force=n!==t?t:1,i.perlin=e,i.autoRun=n!==r?!!r:!0,void(i.axes=o|s|a)):new l(t,e,r)},speedX:1,speedY:1,perlin:null,force:1,offset:0,autoRun:!0,dispose:function(){var t=this;return t.perlin=null,t.speedX=null,t.speedY=null,t.force=null,t.offset=null,t.autoRun=null,t.$super("dispose"),t},setSpeed:function(t,n){var e=this;return e.speedX=t,e.speedY=n,e},apply:function(t){var n=this,r=n.axes,i=n.force,l=n.offset,c=n.perlin,f=c.width,h=c.height;return r&&c?(n.autoRun&&(c=n.perlin=e(c,f,h,n.speedX,n.speedY),c.width=f,c.height=h),u(t.vertices,function(t){var n=t.getXYZ(),e=~~((f-1)*t.ratio[0]),u=~~((h-1)*t.ratio[2]),d=e+u*f;t.setXYZ([n[0]+(r&o?(c[d]-l)*i:0),n[1]+(r&s?(c[d]-l)*i:0),n[2]+(r&a?(c[d]-l)*i:0)])}),n):n}})}(n),n}); diff --git a/build/mod3.js b/build/mod3.js new file mode 100644 index 0000000..b758dd9 --- /dev/null +++ b/build/mod3.js @@ -0,0 +1,2514 @@ +/** +* MOD3 3D Modifier Library for JavaScript +* port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/) +* +* @version 1.0.0 (2023-01-03 16:08:34) +* https://github.com/foo123/MOD3 +* +**//** +* MOD3 3D Modifier Library for JavaScript +* port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/) +* +* @version 1.0.0 (2023-01-03 16:08:34) +* https://github.com/foo123/MOD3 +* +**/ +!function(root, name, factory) { +"use strict"; +if (('object' === typeof module) && module.exports) /* CommonJS */ + (module.$deps = module.$deps||{}) && (module.exports = module.$deps[name] = factory.call(root)); +else if (('function' === typeof define) && define.amd && ('function' === typeof require) && ('function' === typeof require.specified) && require.specified(name) /*&& !require.defined(name)*/) /* AMD */ + define(name, ['module'], function(module) {factory.moduleUri = module.uri; return factory.call(root);}); +else if (!(name in root)) /* Browser/WebWorker/.. */ + (root[name] = factory.call(root)||1) && ('function' === typeof(define)) && define.amd && define(function() {return root[name];}); +}( /* current root */ 'undefined' !== typeof self ? self : this, + /* module name */ "MOD3", + /* module factory */ function ModuleFactory__MOD3(undef) { +"use strict"; + +var HAS = Object.prototype.hasOwnProperty, + toString = Object.prototype.toString, + def = Object.defineProperty, + stdMath = Math, PI = stdMath.PI, + TWO_PI = 2*PI, HALF_PI = PI/2, INV_PI = 1/PI, + EMPTY_ARR = [], EMPTY_OBJ = {}, NOP = function() {}, + isNode = ("undefined" !== typeof global) && ("[object global]" === toString.call(global)), + isBrowser = ("undefined" !== typeof window) && ("[object Window]" === toString.call(window)) +; + +// basic backwards-compatible "class" construction +function makeSuper(superklass) +{ + var called = {}; + return function $super(method, args) { + var self = this, m = ':'+method, ret; + if (1 === called[m]) return (superklass.prototype.$super || NOP).call(self, method, args); + called[m] = 1; + ret = ('constructor' === method ? superklass : (superklass.prototype[method] || NOP)).apply(self, args || []); + called[m] = 0; + return ret; + }; +} +function makeClass(superklass, klass, statik) +{ + if (arguments.length < 2) + { + klass = superklass; + superklass = null; + } + var C = HAS.call(klass, 'constructor') ? klass.constructor : function() {}, p; + if (superklass) + { + C.prototype = Object.create(superklass.prototype); + C.prototype.$super = makeSuper(superklass); + } + else + { + C.prototype.$super = NOP; + } + C.prototype.constructor = C; + for (p in klass) + { + if (HAS.call(klass, p) && ('constructor' !== p)) + { + C.prototype[p] = klass[p]; + } + } + if (statik) + { + for (p in statik) + { + if (HAS.call(statik, p)) + { + C[p] = statik[p]; + } + } + } + return C; +} +var MOD3 = { + VERSION: "1.0.0", + Class: makeClass +}; +/** +* MOD3 Constants and Auxilliary methods +**/ +MOD3.Constants = { + // cache math constants for reference and optimization + PI: PI, + invPI: INV_PI, + halfPI: HALF_PI, + doublePI: TWO_PI, + toRad: PI/180, + toDeg: 180/PI +}; +MOD3.ModConstant = { + NONE: 0, + LEFT: -1, + RIGHT: 1, + + X: 1, + Y: 2, + Z: 4, + + Xi: 0, + Yi: 1, + Zi: 2 +}; +MOD3.XYZi = [ + null, + 0, + 1, + null, + 2 +]; +MOD3.iXYZ = [ + 1, + 2, + 4 +]; +MOD3.xyz = [ + "x", + "y", + "z" +]; +MOD3.XYZ = [ + "X", + "Y", + "Z" +]; + +// Typed Arrays Substitutes +MOD3.Array32F = typeof Float32Array !== "undefined" ? Float32Array : Array; +MOD3.Array64F = typeof Float64Array !== "undefined" ? Float64Array : Array; +MOD3.Array8I = typeof Int8Array !== "undefined" ? Int8Array : Array; +MOD3.Array16I = typeof Int16Array !== "undefined" ? Int16Array : Array; +MOD3.Array32I = typeof Int32Array !== "undefined" ? Int32Array : Array; +MOD3.Array8U = typeof Uint8Array !== "undefined" ? Uint8Array : Array; +MOD3.Array16U = typeof Uint16Array !== "undefined" ? Uint16Array : Array; +MOD3.Array32U = typeof Uint32Array !== "undefined" ? Uint32Array : Array; +// vector typed-array +MOD3.VecArray = MOD3.Array32F; +/** +* MOD3 Math Utilities Class +**/ +MOD3.XMath = { + normalize: function(start, end, val) { + var range = end - start; + return 0 === range ? 1 : MOD3.XMath.trim(0, 1, (val - start)/end); + }, + + toRange: function(start, end, normalized) { + var range = end - start; + return 0 === range ? 0 : (start + range*normalized); + }, + + inRange: function(start, end, value, excluding) { + return false !== excluding ? (value >= start && value <= end) : (value > start && value < end); + }, + + sign: function(val, ifZero) { + return 0 === val ? (ifZero || 0) : (val > 0 ? 1 : -1); + }, + + trim: function(start, end, value) { + return value < start ? start : (value > end ? end : value); + }, + + wrap: function(start, end, value) { + var r = end - start; + return value < start ? (value + r) : (value >= end ? value - r : value); + }, + + degToRad: function(deg) { + return deg/180*PI; + }, + + radToDeg: function(rad) { + return rad/PI*180; + }, + + presicion: function(number, precision) { + var r = stdMath.pow(10, precision); + return stdMath.round(number*r)/r; + }, + + uceil: function(val) { + return val < 0 ? stdMath.floor(val) : stdMath.ceil(val); + } +}; +// alias +MOD3.XMath.clamp = MOD3.XMath.trim; +/** +* MOD3 Range Auxilliary Class +**/ +MOD3.Range = MOD3.Class({ + constructor: function Range(s, e) { + var self = this; + if (!(self instanceof Range)) return new Range(s, e); + self.start = null != s ? s : 0; + self.end = null != e ? e : 1; + }, + + name: "Range", + start: 0, + end: 1, + + dispose: function() { + var self = this; + self.start = null; + self.end = null; + return self; + }, + + getSize: function() { + return this.end - this.start; + }, + + move: function(amount) { + this.start += amount; + this.end += amount; + }, + + isIn: function(n) { + return (n >= this.start && n <= this.end); + }, + + normalize: function(n) { + return MOD3.XMath.normalize(this.start, this.end, n); + }, + + toRange: function(n) { + return MOD3.XMath.toRange(this.start, this.end, n); + }, + + trim: function(n) { + return MOD3.XMath.trim(this.start, this.end, n); + }, + + interpolate: function(n, r) { + return MOD3.XMath.toRange(this.start, this.end, r.normalize(n)); + }, + + toString: function() { + return "[" + this.start + " - " + this.end + "]"; + } +}); +/** +* MOD3 Phase Auxilliary Class +**/ +MOD3.Phase = MOD3.Class({ + constructor: function Phase(v) { + var self = this; + if (!(self instanceof Phase)) return new Phase(v); + self.value = v || 0; + }, + + name: "Phase", + value: 0, + + dispose: function() { + this.value = null; + return this; + }, + + getPhasedValue: function() { + return stdMath.sin(this.value); + }, + + getAbsPhasedValue: function() { + return stdMath.abs(stdMath.sin(this.value)); + }, + + getNormValue: function() { + return (stdMath.sin(this.value) + 1)*0.5; + } +}); +/** +* MOD3 2D Point Class +**/ +MOD3.Point = MOD3.Class({ + constructor: function Point(x, y) { + var self = this; + if (!(self instanceof Point)) return new Point(x, y); + self.x = x || 0; + self.y = y || 0; + }, + + name: "Point", + x: 0, + y: 0, + + dispose: function() { + var self = this; + self.x = null; + self.y = null; + return self; + }, + + clone: function() { + return new MOD3.Point(this.x, this.y); + } +}); +/** +* MOD3 2D Transform Matrix Class +**/ +MOD3.Matrix = MOD3.Class(null, { + constructor: function Matrix(m11, m12, + m21, m22) + { + var self = this; + if (!(self instanceof Matrix)) return new Matrix(m11, m12, + m21, m22); + self.m = new MOD3.VecArray([ + m11 == null ? 1 : m11, + m12 == null ? 0 : m12, + m21 == null ? 0 : m21, + m22 == null ? 1 : m22 + ]); + }, + + name: "Matrix", + m: null, + + dispose: function() { + this.m = null; + return this; + }, + + reset: function() { + var m = this.m; + m[0] = 1; m[1] = 0; + m[2] = 0; m[3] = 1; + return this; + }, + + rotate: function(angle) { + var m = this.m, c = stdMath.cos(angle), s = stdMath.sin(angle); + m[0] = c; m[1] = -s; + m[2] = s; m[3] = c; + return this; + }, + + scale: function(sx, sy) { + var m = this.m; + m[0] = 1; m[1] = 0; + m[2] = 0; m[3] = 1; + if (sx != null) + { + m[0] = sx; + m[3] = sx; + } + if (sy != null) + { + m[3] = sy; + } + return this; + }, + + multiply: function(b) { + return MOD3.Matrix.mult(this, b); + }, + + transformPoint: function(p) { + var xy = MOD3.Matrix.transform(this, [p.x, p.y]); + return new MOD3.Point(xy[0], xy[1]); + }, + + transformPointSelf: function(p) { + var xy = MOD3.Matrix.transform(this, [p.x, p.y]); + p.x = xy[0]; p.y = xy[1]; + return p; + }, + + clone: function() { + var m = this.m; + return new MOD3.Matrix(m[0], m[1], + m[2], m[3]); + } +}, { + transform: function(m2, xy) { + var m = m2.m, x = xy[0], y = xy[1]; + xy[0] = m[0]*x + m[1]*y; + xy[1] = m[2]*x + m[3]*y; + return xy; + }, + + mult: function(m1, m2) { + var a = m1.m, b = m2.m, a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; + a[0] = a0*b[0] + a1*b[2]; + a[1] = a0*b[1] + a1*b[3]; + a[2] = a2*b[0] + a3*b[2]; + a[3] = a2*b[1] + a3*b[3]; + return m1; + } +}); +/** +* MOD3 Vector3 Class +**/ +MOD3.Vector3 = MOD3.Class(null, { + constructor: function Vector3(x, y, z) { + var self = this; + if (!(self instanceof Vector3)) return new Vector3(x, y, z); + + // use an internal typed-array for speed + var v = new MOD3.VecArray(3); + if (x && (3 === x.length)) + { + // array passed + v[0] = x[0] || 0; + v[1] = x[1] || 0; + v[2] = x[2] || 0; + } + else + { + // numbers passed + v[0] = x || 0; + v[1] = y || 0; + v[2] = z || 0; + } + self.xyz = v; + }, + + name: "Vector3", + xyz: null, + + dispose: function() { + this.xyz = null; + return this; + }, + + getXYZ: function() { + // copy it + return new MOD3.VecArray(this.xyz); + }, + + getXYZRef: function() { + return this.xyz; + }, + + setXYZ: function(w) { + var v = this.xyz; + v[0] = w[0]; + v[1] = w[1]; + v[2] = w[2]; + return this; + }, + + setXYZRef: function(xyz) { + this.xyz = xyz; + return this; + }, + + clone: function() { + return new MOD3.Vector3(this.xyz); + }, + + equalsSelf: function(b) { + var v = this.xyz, w = b.xyz; + return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]); + }, + + zeroSelf: function() { + var v = this.xyz; + v[0] = 0; v[1] = 0; v[2] = 0; + return this; + }, + + negate: function() { + var v = this.xyz; + return new MOD3.Vector3(-v[0], -v[1], -v[2]); + }, + + negateSelf: function() { + var v = this.xyz; + v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2]; + return this; + }, + + add: function(b) { + var v = this.xyz, w = b.xyz; + return new MOD3.Vector3(v[0] + w[0], v[1] + w[1], v[2] + w[2]); + }, + + addSelf: function(b) { + var v = this.xyz, w = b.xyz; + v[0] += w[0]; v[1] += w[1]; v[2] += w[2]; + return this; + }, + + subtract: function(b) { + var v = this.xyz, w = b.xyz; + return new MOD3.Vector3(v[0] - w[0], v[1] - w[1], v[2] - w[2]); + }, + + subtractSelf: function(b) { + var v = this.xyz, w = b.xyz; + v[0] -= w[0]; v[1] -= w[1]; v[2] -= w[2]; + return this; + }, + + multiplyScalar: function(s) { + var v = this.xyz; + return new MOD3.Vector3(v[0]*s, v[1]*s, v[2]*s); + }, + + multiplyScalarSelf: function(s) { + var v = this.xyz; + v[0] *= s; v[1] *= s; v[2] *= s; + return this; + }, + + multiply: function(b) { + var v = this.xyz, w = b.xyz; + return new MOD3.Vector3(v[0] * w[0], v[1] * w[1], v[2] * w[2]); + }, + + multiplySelf: function(b) { + var v = this.xyz, w = b.xyz; + v[0] *= w[0]; v[1] *= w[1]; v[2] *= w[2]; + return this; + }, + + divide: function(s) { + var v = this.xyz; + return new MOD3.Vector3(v[0] / s, v[1] / s, v[2] / s); + }, + + divideSelf: function(s) { + var v = this.xyz; + v[0] /= s; v[1] /= s; v[2] /= s; + return this; + }, + + normalize: function() { + var v = this.xyz, + x = v[0], y = v[1], z = v[2], + m = x * x + y * y + z * z, n; + if (0 < m) + { + n = stdMath.sqrt(m); + x /= n; + y /= n; + z /= n; + } + return new MOD3.Vector3(x, y, z); + }, + + normalizeSelf: function() { + var v = this.xyz, + x = v[0], y = v[1], z = v[2], + m = x * x + y * y + z * z, n; + if (0 < m) + { + n = stdMath.sqrt(m); + x /= n; + y /= n; + z /= n; + } + v[0] = x; v[1] = y; v[2] = z; + return this; + }, + + getMagnitude: function() { + var v = this.xyz, x = v[0], y = v[1], z = v[2]; + return stdMath.sqrt(x*x + y*y + z*z); + }, + + setMagnitude: function(m) { + this.normalizeSelf(); + var v = this.xyz; + v[0] *= m; v[1] *= m; v[2] *= m; + return this; + }, + + dot: function(b) { + var v = this.xyz, w = b.xyz; + return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; + }, + + cross: function(b) { + var v = this.xyz, w = b.xyz, + x1 = v[0], y1 = v[1], z1 = v[2], + x2 = w[0], y2 = w[1], z2 = w[2]; + return new MOD3.Vector3(y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2); + }, + + crossSelf: function(v) { + var v = this.xyz, w = b.xyz, + x1 = v[0], y1 = v[1], z1 = v[2], + x2 = w[0], y2 = w[1], z2 = w[2]; + v[0] = y1 * z2 - z1 * y2; + v[1] = z1 * x2 - x1 * z2; + v[2] = x1 * y2 - y1 * x2; + return this; + }, + + distance: function(b) { + var v = this.xyz, w = b.xyz, + dx = v[0] - w[0], + dy = v[1] - w[1], + dz = v[2] - w[2]; + return stdMath.sqrt(dx*dx + dy*dy + dz*dz); + }, + + toString: function() { + var v = this.xyz; + return "[" + v[0] + " , " + v[1] + " , " + v[2] + "]"; + } +}, { + ZERO: function() { + return new MOD3.Vector3(0, 0, 0); + }, + + X: function(direct_or_complement) { + return false === direct_or_complement ? new MOD3.Vector3(0, 1, 1) : new MOD3.Vector3(1, 0, 0); + }, + + Y: function(direct_or_complement) { + return false === direct_or_complement ? new MOD3.Vector3(1, 0, 1) : new MOD3.Vector3(0, 1, 0); + }, + + Z: function(direct_or_complement) { + return false === direct_or_complement ? new MOD3.Vector3(1, 1, 0) : new MOD3.Vector3(0, 0, 1); + }, + + dot: function(v, w) { + return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; + }, + + equals: function(v, w) { + return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]); + }, + + cross: function(v, w) { + var vw = new MOD3.VecArray(3); + vw[0] = v[1] * w[2] - v[2] * w[1]; + vw[1] = v[2] * w[0] - v[0] * w[2]; + vw[2] = v[0] * w[1] - v[1] * w[0]; + return vw; + }, + + mod: function(v) { + var x = v[0], y = v[1], z = v[2]; + return stdMath.sqrt(x*x + y*y + z*z); + }, + + dist: function(v, w) { + var dx = v[0] - w[0], + dy = v[1] - w[1], + dz = v[2] - w[2]; + return stdMath.sqrt(dx*dx + dy*dy + dz*dz); + }, + + add: function(v, w) { + v[0] += w[0]; + v[1] += w[1]; + v[2] += w[2]; + return v; + }, + + sub: function(v, w) { + v[0] -= w[0]; + v[1] -= w[1]; + v[2] -= w[2]; + return v; + }, + + mul: function(v, w) { + v[0] *= w[0]; + v[1] *= w[1]; + v[2] *= w[2]; + return v; + }, + + muls: function(v, m) { + v[0] *= m; + v[1] *= m; + v[2] *= m; + return v; + }, + + norm: function(v) { + var x = v[0], y = v[1], z = v[2], + m = x*x + y*y + z*z, n; + if (0 < m) + { + n = stdMath.sqrt(m); + x /= n; + y /= n; + z /= n; + } + v[0] = x; v[1] = y; v[2] = z; + return v; + } +}); +// alaises +MOD3.Vector3.modulo = MOD3.Vector3.mod; +MOD3.Vector3.distance = MOD3.Vector3.dist; +MOD3.Vector3.prototype.dotSelf = MOD3.Vector3.prototype.dot; +MOD3.Vector3.prototype.distanceSelf = MOD3.Vector3.prototype.distance; +/** +* MOD3 3D Transform Matrix Class +**/ +MOD3.Matrix4 = MOD3.Class(null, { + constructor: function Matrix4(n11, n12, n13, n14, + n21, n22, n23, n24, + n31, n32, n33, n34, + n41, n42, n43, n44) + { + var self = this; + if (!(self instanceof Matrix4)) return new Matrix4(n11, n12, n13, n14, + n21, n22, n23, n24, + n31, n32, n33, n34, + n41, n42, n43, n44); + self.m = new MOD3.VecArray([ + n11 == null ? 1 : n11, + n12 == null ? 0 : n12, + n13 == null ? 0 : n13, + n14 == null ? 0 : n14, + + n21 == null ? 0 : n21, + n22 == null ? 1 : n22, + n23 == null ? 0 : n23, + n24 == null ? 0 : n24, + + n31 == null ? 0 : n31, + n32 == null ? 0 : n32, + n33 == null ? 1 : n33, + n34 == null ? 0 : n34, + + n41 == null ? 0 : n41, + n42 == null ? 0 : n42, + n43 == null ? 0 : n43, + n44 == null ? 1 : n44 + ]); + }, + + name: "Matrix4", + m: null, + + dispose: function() { + this.m = null; + return this; + }, + + reset: function() { + var m = this.m; + m[0 ] = 1; m[1 ] = 0; m[2 ] = 0; m[3 ] = 0; + m[4 ] = 0; m[5 ] = 1; m[6 ] = 0; m[7 ] = 0; + m[8 ] = 0; m[9 ] = 0; m[10] = 1; m[11] = 0; + m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; + return this; + }, + + translate: function(tx, ty, tz, reset) { + var m = this.m; + if (true === reset) this.reset(); + m[3 ] = tx; + m[7 ] = ty; + m[11] = tz; + return this; + }, + + scale: function(sx, sy, sz, reset) { + var m = this.m; + if (true === reset) this.reset(); + m[0 ] = sx; + m[5 ] = sy; + m[10] = sz; + return this; + }, + + rotate: function(rx, ry, rz, theta, reset) { + var m = this.m, + nCos = stdMath.cos(theta), nSin = stdMath.sin(theta), scos = 1 - nCos, + sxy = rx*ry*scos, syz = ry*rz*scos, sxz = rx*rz*scos, + sz = nSin*rz, sy = nSin*ry, sx = nSin*rx + ; + if (true === reset) this.reset(); + m[0 ] = nCos + rx*rx*scos; + m[1 ] = -sz + sxy; + m[2 ] = sy + sxz; + m[3 ] = 0; + + m[4 ] = sz + sxy; + m[5 ] = nCos + ry*ry*scos; + m[6 ] = -sx + syz; + m[7 ] = 0; + + m[8 ] = -sy + sxz; + m[9 ] = sx + syz; + m[10] = nCos + rz*rz*scos; + m[11] = 0; + return this; + }, + + translateFromVector: function(v, reset) { + return this.translate(v.xyz[0], v.xyz[1], v.xyz[2], reset); + }, + + scaleFromVector: function(v, reset) { + return this.scale(v.xyz[0], v.xyz[1], v.xyz[2], reset); + }, + + rotateFromVector: function(v, theta, reset) { + return this.rotate(v.xyz[0], v.xyz[1], v.xyz[2], theta, reset); + }, + + multiply: function(b) { + return MOD3.Matrix4.mult(this, b); + }, + + multiplyVector: function(v) { + MOD3.Matrix4.multXYZ(this, v.xyz); + return v; + } +}, { + multXYZ: function(m4, v) { + var m = m4.m, x = v[0], y = v[1], z = v[2]; + v[0] = x*m[0 ] + y*m[1 ] + z*m[2 ] + m[3 ]; + v[1] = x*m[4 ] + y*m[5 ] + z*m[6 ] + m[7 ]; + v[2] = x*m[8 ] + y*m[9 ] + z*m[10] + m[11]; + return v; + }, + + mult: function(m1, m2) { + var a = m1.m, b = m2.m, + a11 = a[0 ], b11 = b[0 ], + a21 = a[4 ], b21 = b[4 ], + a31 = a[8 ], b31 = b[8 ], + a12 = a[1 ], b12 = b[1 ], + a22 = a[5 ], b22 = b[5 ], + a32 = a[9 ], b32 = b[9 ], + a13 = a[2 ], b13 = b[2 ], + a23 = a[6 ], b23 = b[6 ], + a33 = a[10], b33 = b[10], + a14 = a[3 ], b14 = b[3 ], + a24 = a[7 ], b24 = b[7 ], + a34 = a[11], b34 = b[11]; + + a[0 ] = a11*b11 + a12*b21 + a13*b31; + a[1 ] = a11*b12 + a12*b22 + a13*b32; + a[2 ] = a11*b13 + a12*b23 + a13*b33; + a[3 ] = a11*b14 + a12*b24 + a13*b34 + a14; + + a[4 ] = a21*b11 + a22*b21 + a23*b31; + a[5 ] = a21*b12 + a22*b22 + a23*b32; + a[6 ] = a21*b13 + a22*b23 + a23*b33; + a[7 ] = a21*b14 + a22*b24 + a23*b34 + a24; + + a[8 ] = a31*b11 + a32*b21 + a33*b31; + a[9 ] = a31*b12 + a32*b22 + a33*b32; + a[10] = a31*b13 + a32*b23 + a33*b33; + a[11] = a31*b14 + a32*b24 + a33*b34 + a34; + return m1; + } +}); +// aliases +MOD3.Matrix4.prototype.translationMatrix = MOD3.Matrix4.prototype.translate; +MOD3.Matrix4.prototype.scaleMatrix = MOD3.Matrix4.prototype.scale; +MOD3.Matrix4.prototype.rotationMatrix = MOD3.Matrix4.prototype.rotate; +MOD3.Matrix4.prototype.translationMatrixFromVector = MOD3.Matrix4.prototype.translateFromVector; +MOD3.Matrix4.prototype.scaleMatrixFromVector = MOD3.Matrix4.prototype.scaleFromVector; +MOD3.Matrix4.prototype.rotationMatrixFromVector = MOD3.Matrix4.prototype.rotateFromVector; +// fast list utilities +MOD3.List = { + operate: function operate(x, F, F0, i0, i1, reverse) { + var len = x.length; + if (arguments.length < 5) i1 = len-1; + if (0 > i1) i1 += len; + if (arguments.length < 4) i0 = 0; + if (i0 > i1) return F0; + if (true === reverse) + { + var i, k, l=i1-i0+1, l1=l-1, r=l&15, q=r&1, lr=l1-r, Fv=q?F(F0,x[i1],i1):F0; + for (i=l1-q; i>lr; i-=2) { k = i0+i; Fv = F(F(Fv,x[k],k),x[k-1],k-1); } + for (i=lr; i>=0; i-=16) { k = i0+i; Fv = F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(F(Fv,x[k],k),x[k-1],k-1),x[k-2],k-2),x[k-3],k-3),x[k-4],k-4),x[k-5],k-5),x[k-6],k-6),x[k-7],k-7),x[k-8],k-8),x[k-9],k-9),x[k-10],k-10),x[k-11],k-11),x[k-12],k-12),x[k-13],k-13),x[k-14],k-14),x[k-15],k-15); } + } + else + { + var i, k, l=i1-i0+1, r=l&15, q=r&1, Fv=q?F(F0,x[i0],i0):F0; + for (i=q; i i1) i1 += len; + if (arguments.length < 3) i0 = 0; + if (i0 > i1) return x; + var i, k, l=i1-i0+1, l1, lr, r, q; + if (true === reverse) + { + l1=l-1; r=l&15; q=r&1; lr=l1-r; + if (q) F(x[i1]); + for (i=l1-q; i>lr; i-=2) + { + k = i0+i; + F(x[k ]); + F(x[k-1]); + } + for (i=lr; i>=0; i-=16) + { + k = i0+i; + F(x[k ] ); + F(x[k-1] ); + F(x[k-2] ); + F(x[k-3] ); + F(x[k-4] ); + F(x[k-5] ); + F(x[k-6] ); + F(x[k-7] ); + F(x[k-8] ); + F(x[k-9] ); + F(x[k-10]); + F(x[k-11]); + F(x[k-12]); + F(x[k-13]); + F(x[k-14]); + F(x[k-15]); + } + } + else + { + r=l&15; q=r&1; + if (q) F(x[i0]); + for (i=q; i 0 ? (xyz[0] - minX) / width : 0, height > 0 ? (xyz[1] - minY) / height : 0, depth > 0 ? (xyz[2] - minZ) / depth : 0); + }); + return self; + }, + + resetGeometry: function() { + var self = this; + MOD3.List.each(self.vertices, reset); + return self; + }, + + collapseGeometry: function() { + var self = this; + MOD3.List.each(self.vertices, collapse); + self.analyzeGeometry(); + return self; + }, + + getMin: function(axis) { + var self = this; + return MOD3.ModConstant.X === axis + ? self.minX + : (MOD3.ModConstant.Y === axis + ? self.minY + : (MOD3.ModConstant.Z === axis + ? self.minZ + : -1)) + ; + }, + + getMax: function(axis) { + var self = this; + return MOD3.ModConstant.X === axis + ? self.maxX + : (MOD3.ModConstant.Y === axis + ? self.maxY + : (MOD3.ModConstant.Z === axis + ? self.maxZ + : -1)) + ; + }, + + getSize: function(axis) { + var self = this; + return MOD3.ModConstant.X === axis + ? self.width + : (MOD3.ModConstant.Y === axis + ? self.height + : (MOD3.ModConstant.Z === axis + ? self.depth + : -1)) + ; + }, + + update: function() { + // do nothing + return this; + }, + + preApply: function() { + // do nothing + return this; + }, + + postApply: function() { + // do nothing + return this; + }, + + updateMeshPosition: function(p) { + // do nothing + return this; + } +}); + +MOD3.Library3d = { + id : "Library3d", + Mesh : MOD3.MeshProxy, + Vertex : MOD3.VertexProxy +}; + +MOD3.Factory = { + getLibrary: function(json) { + if (json && json.library && MOD3[json.library]) return MOD3[json.library]; + // dummy, default + return MOD3.Library3d; + } + + ,getMeshProxy: function(lib3D) { + if (arguments.length) return lib3D.Mesh ? new lib3D.Mesh() : null; + return null; + } + + ,getModifier: function(json) { + if (json && json.modifier && MOD3[json.modifier]) return new MOD3[json.modifier](); + return null; + } + + /* + ,getMesh: function(json) { + if (json && json.mesh && MOD3[json.mesh] ) return new MOD3.MeshProxy().unserialize(json); + // dummy, default + return new MOD3.MeshProxy(); + } + + ,getVertex: function(json) { + if (json && json.vertex && MOD3[json.vertex]) return new MOD3.VertexProxy().unserialize(json); + // dummy, default + return new MOD3.VertexProxy(); + }*/ +}; +/** +* MOD3 Modifier & ModifierStack Classes +**/ +var _modCount = 0; + +MOD3.Modifier = MOD3.Class({ + constructor: function Modifier() { + var self = this; + self.id = ++_modCount; + self.name = 'Modifier'; + self.axes = MOD3.ModConstant.NONE; + self.constraint = MOD3.ModConstant.NONE; + self.enabled = true; + }, + + id: null, + name: 'Modifier', + axes: null, + constraint: null, + enabled: true, + + dispose: function() { + var self = this; + self.name = null; + self.axes = null; + self.constraint = null; + return self; + }, + + enable: function(enabled) { + if (arguments.length) + { + this.enabled = !!enabled; + return this; + } + return this.enabled; + }, + + constraintAxes: function(axes) { + this.axes = axes || MOD3.ModConstant.NONE; + return this; + }, + + setConstraint: function(c) { + this.constraint = c || MOD3.ModConstant.NONE; + return this; + }, + + // override + apply: function(modifiable) { + return this; + }, + + toString: function() { + return '[Modifier '+this.name+']'; + } +}); + +MOD3.ModifierStack = MOD3.Class({ + constructor: function ModifierStack(lib3d, mesh) { + var self = this; + if (!(self instanceof ModifierStack)) return new ModifierStack(lib3d, mesh); + self.stack = []; + self.setModifiable(MOD3.Factory.getMeshProxy(lib3d), mesh); + }, + + name: "ModifierStack", + modifiable: null, + stack: null, + + dispose: function(withModifiers) { + var self = this; + if (withModifiers && self.stack) while (self.stack.length) self.stack.pop().dispose(); + if (self.modifiable) self.modifiable.dispose(); + self.stack = null; + self.modifiable = null; + return self; + }, + + getModifiable: function() { + return this.modifiable; + }, + + setModifiable: function(modifiable, mesh) { + var self = this; + self.modifiable = modifiable; + if (mesh) self.modifiable.setMesh(mesh); + return self; + }, + + add: function(modifier) { + var self = this; + if (modifier) self.stack.push(modifier); + return self; + }, + + apply: function() { + var self = this, modifiable = self.modifiable, stack = self.stack; + if (modifiable && stack && stack.length) + modifiable + .preApply() + .resetGeometry() + .applyModifiers(stack) + .postApply() + .update() + ; + return self; + }, + + collapse: function() { + var self = this, modifiable = self.modifiable, stack = self.stack; + if (modifiable && stack && stack.length) + { + modifiable + .preApply() + .resetGeometry() + .applyModifiers(stack) + .collapseGeometry() + .postApply() + .update() + ; + stack.length = 0; + } + return self; + }, + + clear: function() { + var self = this; + if (self.stack) self.stack.length = 0; + return self; + } +}); +// aliases +MOD3.ModifierStack.prototype.getMeshInfo = MOD3.ModifierStack.prototype.getModifiable; +MOD3.ModifierStack.prototype.addModifier = MOD3.ModifierStack.prototype.add; +!function(MOD3) { +"use strict"; +/** +* MOD3 Pivot Modifier +**/ + +/**[DOC_MD] + * ### Pivot modifier + * + * Allows to move the pivot point of a 3D mesh. + * + * @author Bartek Drozdz + * +[/DOC_MD]**/ +MOD3.Pivot = MOD3.Class(MOD3.Modifier, { + constructor: function Pivot(x, y, z) { + var self = this; + if (!(self instanceof Pivot)) return new Pivot(x, y, z); + self.$super('constructor'); + self.name = 'Pivot'; + self.vector = new MOD3.Vector3(x||0, y||0, z||0); + }, + + vector: null, + + dispose: function() { + var self = this; + self.vector.dispose(); + self.vector = null; + self.$super('dispose'); + return self; + }, + + setMeshCenter: function(modifiable) { + var self = this; + self.vector = new MOD3.Vector3( + -(modifiable.minX + 0.5*modifiable.width), + -(modifiable.minY + 0.5*modifiable.height), + -(modifiable.minZ + 0.5*modifiable.depth) + ); + return self; + }, + + apply: function(modifiable) { + var self = this, pivot = self.vector, pv = pivot.xyz; + + MOD3.List.each(modifiable.vertices, function(v) { + v.setXYZ(MOD3.Vector3.add(v.getXYZ(), pv)); + }); + modifiable.updateMeshPosition(pivot.negate()); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Bend Modifier +**/ + +/**[DOC_MD] + * ### Bend modifier + * + * Bends an object along an axis. + * + * @author Bartek Drozdz + * +[/DOC_MD]**/ +var stdMath = Math, PI = stdMath.PI, + TWO_PI = 2*PI, HALF_PI = PI/2; + +MOD3.Bend = MOD3.Class(MOD3.Modifier, { + constructor: function Bend(force, offset, angle) { + var self = this; + if (!(self instanceof Bend)) return new Bend(force, offset, angle); + self.$super('constructor'); + self.name = 'Bend'; + self.constraint = MOD3.ModConstant.NONE; + self.switchAxes = false; + self.force = force || 0; + self.offset = offset || 0; + self.angle = angle || 0; + }, + + force: 0, + offset: 0, + angle: 0, + switchAxes: false, + + dispose: function() { + var self = this; + self.force = null; + self.offset = null; + self.angle = null; + self.switchAxes = null; + self.$super('dispose'); + return self; + }, + + apply: function(modifiable) { + var self = this; + + if (0 === self.force) return self; + + var constraint = self.constraint, switchAxes = self.switchAxes, + force = self.force, offset = stdMath.min(1, stdMath.max(0, self.offset)), a = self.angle, + max = switchAxes ? modifiable.midAxis : modifiable.maxAxis, + min = modifiable.minAxis, + mid = switchAxes ? modifiable.maxAxis : modifiable.midAxis, + width = modifiable.getSize(max), + height = modifiable.getSize(mid), + origin = modifiable.getMin(max), + //diagAngle = stdMath.atan2(height, width), + m1 = new MOD3.Matrix().rotate(a), + m2 = new MOD3.Matrix().rotate(-a), + distance = origin + width * offset, + radius = width / PI / force, + bendAngle = TWO_PI * (width / (radius * TWO_PI)) + ; + + MOD3.List.each(modifiable.vertices, function(v) { + var xyz = v.getXYZ(), + vmax = xyz[MOD3.XYZi[max]], + vmid = xyz[MOD3.XYZi[mid]], + vmin = xyz[MOD3.XYZi[min]], + np = MOD3.Matrix.transform(m1, [vmax, vmid]), + p, fa, op, ow, np2 + ; + vmax = np[0]; vmid = np[1]; + + p = (vmax - origin) / width; + + if ( + ((MOD3.ModConstant.LEFT === constraint) && (p <= offset)) || + ((MOD3.ModConstant.RIGHT === constraint) && (p >= offset)) + ) + { + /* do nothing */ + } + else + { + fa = (HALF_PI - bendAngle * offset) + (bendAngle * p); + op = stdMath.sin(fa) * (radius + vmin); + ow = stdMath.cos(fa) * (radius + vmin); + vmin = op - radius; + vmax = distance - ow; + } + + np2 = MOD3.Matrix.transform(m2, [vmax, vmid]); + vmax = np2[0]; vmid = np2[1]; + xyz[MOD3.XYZi[max]] = vmax; + xyz[MOD3.XYZi[mid]] = vmid; + xyz[MOD3.XYZi[min]] = vmin; + v.setXYZ(xyz); + }); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Bloat Modifier +**/ + +/**[DOC_MD] + * ### Bloat modifier + * + * Bloats a mesh by forcing vertices out of specified sphere + * + * @author makc + * +[/DOC_MD]**/ +var stdMath = Math; + +MOD3.Bloat = MOD3.Class(MOD3.Modifier, { + constructor: function Bloat(radius, a, center) { + var self = this; + if (!(self instanceof Bloat)) return new Bloat(radius, a, center); + self.$super('constructor'); + self.name = 'Bloat'; + self.radius = radius || 0; + self.a = null == a ? 0.01 : a; + self.center = center || MOD3.Vector3.ZERO(); + //self.u = MOD3.Vector3.ZERO(); + }, + + radius: 0, + a: 0.01, + center: null, + //u: null, + + dispose: function() { + var self = this; + self.center.dispose(); + self.center = null; + self.radius = null; + self.a = null; + self.$super('dispose'); + return self; + }, + + apply: function(modifiable) { + var self = this, center = self.center.xyz, + radius = stdMath.max(0, self.radius), a = stdMath.max(0, self.a); + + MOD3.List.each(modifiable.vertices, function(v) { + // get a vector towards vertex + // change norm to norm + r * exp (-a * norm) + var uu = MOD3.Vector3.sub(v.getXYZ(), center), magn = MOD3.Vector3.mod(uu); + MOD3.Vector3.muls(MOD3.Vector3.norm(uu), magn + radius * stdMath.exp(- magn * a)); + // move vertex accordingly + v.setXYZ(MOD3.Vector3.add(uu, center)); + // ?? needed?? + //self.u=uu; + }); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Twist Modifier +**/ + +/**[DOC_MD] + * ### Twist modifier + * + * Twist mesh along an axis + * Adapted from the Twist modifier for PV3D + * +[/DOC_MD]**/ +MOD3.Twist = MOD3.Class(MOD3.Modifier, { + constructor: function Twist(angle, vector, center) { + var self = this; + if (!(self instanceof Twist)) return new Twist(angle, vector, center); + self.$super('constructor'); + self.name = 'Twist'; + self.angle = angle || 0; + self.vector = vector || MOD3.Vector3.Y(); + self.center = center || MOD3.Vector3.ZERO(); + }, + + angle: 0, + vector: null, + center: null, + + dispose: function() { + var self = this; + self.vector.dispose(); + self.vector = null; + self.angle = null; + self.center.dispose(); + self.center = null; + self.$super('dispose'); + return self; + }, + + apply: function(modifiable) { + var self = this, + tvec = self.vector.normalizeSelf().xyz, angle = self.angle, center = self.center.xyz, + modulo = MOD3.Vector3.mod([0.5*modifiable.maxX, 0.5*modifiable.maxY, 0.5*modifiable.maxZ]), + d = -MOD3.Vector3.dot(tvec, center), + m1 = new MOD3.Matrix4(), m2 = new MOD3.Matrix4() + ; + + MOD3.List.each(modifiable.vertices, function(v) { + var xyz = v.getXYZ(), + a = (MOD3.Vector3.dot(xyz, tvec) + d) * angle / modulo, + m = MOD3.Matrix4.mult( + m2.rotate(tvec[0], tvec[1], tvec[2], a, true), + m1.translate(xyz[0], xyz[1], xyz[2], true) + ) + ; + v.setXYZ([m.m[3], m.m[7], m.m[11]]); + }); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Skew Modifier +**/ + +/**[DOC_MD] + * ### Skew modifier + * + * Skew mesh along an axis + * + * @author Bartek Drozdz + * +[/DOC_MD]**/ +var stdMath = Math; + +MOD3.Skew = MOD3.Class(MOD3.Modifier, { + constructor: function Skew(force, offset, power, falloff) { + var self = this; + if (!(self instanceof Skew)) return new Skew(force, offset, power, falloff); + self.$super('constructor'); + self.name = 'Skew'; + self.constraint = MOD3.ModConstant.NONE; + self.force = force != null ? force : 0; + self.offset = offset != null ? offset : 0.5; + self.power = power != null ? power : 1; + self.falloff = falloff != null ? falloff : 1; + self.inverseFalloff = false; + self.oneSide = false; + self.swapAxes = false; + self.skewAxis = 0; + }, + + force: 0, + skewAxis: 0, + offset: 0.5, + power: 1, + falloff: 1, + inverseFalloff: false, + oneSide: false, + swapAxes: false, + + dispose: function() { + var self = this; + self.force = null; + self.skewAxis = null; + self.offset = null; + self.power = null; + self.falloff = null; + self.inverseFalloff = null; + self.oneSide = null; + self.swapAxes = null; + self.$super('dispose'); + return self; + }, + + apply: function(modifiable) { + var self = this, + constraint = self.constraint, + skewAxis = self.skewAxis || modifiable.maxAxis, + swapAxes = self.swapAxes, + offset = stdMath.min(1, stdMath.max(0, self.offset)), + oneSide = self.oneSide, + inverseFalloff = !!self.inverseFalloff, + falloff = stdMath.min(1, stdMath.max(0, self.falloff)), + mirrorfalloff = 1-falloff, + power = self.power, + force = self.force, + displaceAxis = MOD3.ModConstant.X === skewAxis + ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.Y) + : (MOD3.ModConstant.Y === skewAxis + ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.X) + : (MOD3.ModConstant.Z === skewAxis + ? (swapAxes ? MOD3.ModConstant.Y : MOD3.ModConstant.X) + : 0)) + ; + + MOD3.List.each(modifiable.vertices, function(v) { + var r, dr, f, p, vRatio; + vRatio = v.getRatio(skewAxis); + if ((MOD3.ModConstant.LEFT === constraint) && (vRatio <= offset)) return; + if ((MOD3.ModConstant.RIGHT === constraint) && (vRatio > offset)) return; + + r = vRatio - offset; + if (oneSide && (0 > r)) r = -r; + + dr = v.getRatio(displaceAxis); + if (inverseFalloff) dr = 1 - dr; + + f = falloff + dr * mirrorfalloff; + p = (0 > r ? -1 : 1) * stdMath.pow(stdMath.abs(r), power); + v.setValue(displaceAxis, v.getValue(displaceAxis) + force * p * f); + }); + return self; + }, +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Taper Modifier +**/ + +/**[DOC_MD] + * ### Taper modifier + * + * The taper modifier displaces the vertices on two axes proportionally to their position on the third axis. + * + * @author Bartek Drozdz + * +[/DOC_MD]**/ +var stdMath = Math; + +MOD3.Taper = MOD3.Class(MOD3.Modifier, { + constructor: function Taper(force, power, v1, v2) { + var self = this; + if (!(self instanceof Taper)) return new Taper(force, power, v1, v2); + self.$super('constructor'); + self.name = 'Taper'; + /*self.start = 0; + self.end = 1;*/ + self.force = force != null ? force : 0; + self.power = power != null ? power : 1; + self.vector = v1 || MOD3.Vector3.Y(false); + self.vector2 = v2 || MOD3.Vector3.Y(); + }, + + force: 0, + power: 1, + /*start: 0, + end: 1,*/ + vector: null, + vector2: null, + + /*setFalloff : function(start, end) { + this.start = (start!==undef) ? start : 0; + this.end = (end!==undef) ? end : 1; + + return this; + },*/ + + dispose: function() { + var self = this; + self.vector.dispose(); + self.vector2.dispose(); + self.vector = null; + self.vector2 = null; + self.force = null; + self.power = null; + self.$super('dispose'); + return self; + }, + + apply: function(modifiable) { + var self = this, + vec = self.vector.xyz, vec2 = self.vector2.xyz, + force = self.force, power = self.power, m = new MOD3.Matrix4(); + + MOD3.List.each(modifiable.vertices, 1 !== power + ? function(v) { + var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * stdMath.pow(ar, power); + v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ())); + } + : function(v) { + var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * ar; + v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ())); + } + ); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Wheel Modifier +**/ + +/**[DOC_MD] + * ### Wheel modifier + * + * Use it with vehicle models for wheels. + * + * The usual problem with a 3d wheel in a vahicle is that it is + * supposed to turn (steer) and roll in the same time. + * So, this code: + * + * ```javascript + * wheel.rotationY = 10; // Steer 10deg to the left + * wheel.rotationZ += 5; // Roll with a speed of 5 + * ``` + * This will make the wheel roll incorectly. + * + * A usual way to solve this problem is to put the wheel in another DisplayObject3D/Mesh, + * turn the parent and roll the child, like that: + * ```javascript + * steer.rotationY = 10; // Steer 10deg to the left + * steer.wheel.rotationZ += 5; // Roll with a speed of 5 + * ``` + * That will make the wheel behave correctly. But it can be uncomfortanble to apply, especially + * to imported complex Collada models. + * + * The Wheel modifier elegantly solves this problem by doind the proper math in order to steer and roll + * a single mesh at the same time. The only thing you need to do is to specify a steer vector and + * roll vector - usually it will be 2 of the cardinal axes. The default value is: + * + * * steer - along the Y axis / new Vector3(0, 1, 0) + * * roll - along the Z axis / new Vector3(0, 0, 1) + * + * + * It should work with most car models imported from 3D editors as this is the natural position of a wheel. + * + * *Please note, that Papervision primitive cylinder, which may also be used as wheel, will require different axes + * (Y for roll and Z or X for steer).* + * + * @author Bartek Drozdz + * + [/DOC_MD]**/ +MOD3.Wheel = MOD3.Class(MOD3.Modifier, { + constructor: function Wheel(speed, turn, roll, steerVector, rollVector) { + var self = this; + if (!(self instanceof Wheel)) return new Wheel(speed, turn, roll, steerVector, rollVector); + self.$super('constructor'); + self.name = 'Wheel'; + self.speed = speed || 0; + self.turn = turn || 0; + self.roll = roll || 0; + self.steerVector = steerVector || MOD3.Vector3.Y(); + self.rollVector = rollVector || MOD3.Vector3.Z(); + }, + + speed: 0, + turn: 0, + roll: 0, + steerVector: null, + rollVector: null, + + dispose: function() { + var self = this; + self.speed = null; + self.turn = null; + self.roll = null; + self.steerVector.dispose(); + self.rollVector.dispose(); + self.steerVector = null; + self.rollVector = null; + self.$super('dispose'); + + return self; + }, + + apply: function(modifiable) { + var self = this, + steerVector = self.steerVector.normalizeSelf(), + rollVector = self.rollVector.normalizeSelf(), + turn = self.turn, roll = self.roll, + //radius = 0.5*modifiable.width, + //step = radius * self.speed / PI, + //perimeter = radius * TWO_PI, + ms = null, mt = null + ; + + self.roll += self.speed; + + if (turn) + { + mt = new MOD3.Matrix4().rotateFromVector(steerVector, turn); + ms = new MOD3.Matrix4().rotateFromVector(mt.multiplyVector(rollVector.clone()), roll); + } + else + { + ms = new MOD3.Matrix4().rotateFromVector(rollVector, roll); + } + + MOD3.List.each(modifiable.vertices, mt + ? function(v) { + v.setXYZ(MOD3.Matrix4.multXYZ(ms, MOD3.Matrix4.multXYZ(mt, v.getXYZ()))); + } + : function(v) { + v.setXYZ(MOD3.Matrix4.multXYZ(ms, v.getXYZ())); + } + ); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Break Modifier +**/ + +/**[DOC_MD] + * ### Break modifier + * + * Allow to break a mesh + * + * @author Bartek Drozdz + * +[/DOC_MD]**/ +var stdMath = Math; + +MOD3.Break = MOD3.Class(MOD3.Modifier, { + constructor: function Break(offset, angle, vector) { + var self = this; + if (!(self instanceof Break)) return new Break(offset, angle, vector); + self.$super('constructor'); + self.name = 'Break'; + self.offset = offset || 0; + self.angle = angle || 0; + self.vector = vector || MOD3.Vector3.Y(); + self.range = new MOD3.Range(0, 1); + }, + + offset: 0, + angle: 0, + vector: null, + range: null, + + dispose: function() { + var self = this; + self.vector.dispose(); + self.range.dispose(); + self.vector = null; + self.range = null; + self.offset = null; + self.angle = null; + self.$super('dispose'); + return self; + }, + + apply: function(modifiable) { + var self = this, + offset = stdMath.min(1, stdMath.max(0, self.offset)), range = self.range, angle = self.angle, + bv = self.vector.normalizeSelf().xyz, pv, rm; + + pv = modifiable.minZ + modifiable.depth*offset; + rm = new MOD3.Matrix4().rotate(bv[0], bv[1], bv[2], angle); + + MOD3.List.each(modifiable.vertices, function(v) { + var c = v.getXYZ(); + c[2] -= pv; + if ((0 <= c[2]) && range.isIn(v.ratio[1])) MOD3.Matrix4.multXYZ(rm, c); + c[2] += pv; + v.setXYZ(c); + }); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Noise Modifier +**/ + +/**[DOC_MD] + * ### Noise modifier + * + * Randomly displaces each vertex in all 3 axes + * + * +[/DOC_MD]**/ +var stdMath = Math; + +MOD3.Noise = MOD3.Class(MOD3.Modifier, { + constructor: function Noise(force) { + var self = this; + if (!(self instanceof Noise)) return new Noise(force); + self.$super('constructor'); + self.name = 'Noise'; + self.force = force || 0; + self.start = 0; + self.end = 1; + self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z; + }, + + force: 0, + start: 0, + end: 1, + + dispose: function() { + var self = this; + self.force = null; + self.start = null; + self.end = null; + self.$super('dispose'); + return self; + }, + + setFalloff: function(start, end) { + var self = this; + self.start = start != null ? start : 0; + self.end = end != null ? end : 1; + return self; + }, + + apply: function(modifiable) { + var self = this, + axes = self.axes, start = self.start, end = self.end, + force = self.force, halfforce = 0.5*force, + maxAxis = modifiable.maxAxis; + + if ((0 == axes) || (0 == force)) return self; + + MOD3.List.each(modifiable.vertices, function(v) { + var r = stdMath.random() * force - halfforce, + p = v.getRatio(maxAxis), rp, xyz; + if (start < end) + { + if (p < start) p = 0; + else if (p > end) p = 1; + } + else if (start > end) + { + p = 1 - p; + if (p > start) p = 0; + else if (p < end) p = 1; + } + else + { + p = 1; + } + + rp = r * p; + xyz = v.getXYZ(); + v.setXYZ([ + xyz[0] + (axes & MOD3.ModConstant.X ? rp : 0), + xyz[1] + (axes & MOD3.ModConstant.Y ? rp : 0), + xyz[2] + (axes & MOD3.ModConstant.Z ? rp : 0) + ]); + }); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 DisplaceMap (BitmapDisplacement) Modifier +**/ + +/**[DOC_MD] + * ### DisplaceMap (BitmapDisplacement) Modifier + * + * Displaces vertices based on RGB values of bitmapData pixels. + * + * BitmapDisplacement is inspired by both the AS3 built-in DisplacementMapFilter. It allows + * to use color values for each channels of a bitmap to modify the position of vertices in a mesh. + * + * The displacement takes place along the cardinal axes, and each axis is mapped to a + * channel in the bitmap: X for Red, Y for Green and Z for Blue. + * + * @author Bartek Drozdz + * +[/DOC_MD]**/ +MOD3.DisplaceMap = MOD3.Class(MOD3.Modifier, { + constructor: function DisplaceMap(bmp, force, offset) { + var self = this; + if (!(self instanceof DisplaceMap)) return new DisplaceMap(bmp, force, offset); + self.$super('constructor'); + self.name = 'DisplaceMap'; + if (+bmp === bmp) // number + { + self.force = bmp || 1; + self.offset = null == force ? 127 : force;// 0x7F; + } + else + { + self.setBitmap(bmp); + self.force = force || 1; + self.offset = null == offset ? 127 : offset;// 0x7F; + } + self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z; + }, + + width: null, + height: null, + bmpData: null, + force: 1, + offset: 127, + + dispose: function() { + var self = this; + self.bmpData = null; + self.width = null; + self.height = null; + self.force = null; + self.offset = null; + self.$super('dispose'); + return self; + }, + + setBitmap: function(bmpData) { + var self = this; + self.bmpData = bmpData ? bmpData.data : null; + self.width = bmpData ? bmpData.width : 0; + self.height = bmpData ? bmpData.height : 0; + return self; + }, + + apply: function(modifiable) { + var self = this, + axes = self.axes, + w = self.width, h = self.height, bmp = self.bmpData, + force = self.force, offset = self.offset; + + if (!axes || !bmp) return self; + + MOD3.List.each(modifiable.vertices, function(v) { + var uv, uu, vv, xyz = v.getXYZ(); + + uu = ~~((w - 1) * v.ratio[0]/* X */); + vv = ~~((h - 1) * v.ratio[2]/* Z */); + uv = (vv * w + uu) << 2; + + v.setXYZ([ + xyz[0] + (axes & MOD3.ModConstant.X ? ((bmp[uv] & 0xff) - offset) * force : 0), + xyz[1] + (axes & MOD3.ModConstant.Y ? ((bmp[uv+1] & 0xff) - offset) * force : 0), + xyz[2] + (axes & MOD3.ModConstant.Z ? ((bmp[uv+2] & 0xff) - offset) * force : 0) + ]); + }); + return self; + } +}); +}(MOD3);!function(MOD3) { +"use strict"; +/** +* MOD3 Perlin/Simplex Noise Modifier +**/ + +/**[DOC_MD] + * ### Perlin modifier + * + * Displaces vertices based on a perlin/simplex noise source. + * + * Accepts a perlin/simplex noise data (with width and height information) and displaces vertices + * based on the value of each point of the noise map. + * + * @author Bartek Drozdz + * + * @uses: https://github.com/josephg/noisejs for JavaScript + * +[/DOC_MD]**/ +function cyclic_shift(a, w, h, dX, dY) +{ + var size = w*h, b = new MOD3.VecArray(size), i, j, i2, j2, index; + if (dX < 0) dX += w; + if (dY < 0) dY += h; + dX = ~~dX; dY = ~~dY; + for (i=0,j=0,index=0; index= w) {i = 0; ++j;} + i2 = (i + dX) % w; j2 = (j + dY) % h; + b[index] = a[i2 + j2 * w]; + } + return b; +} +/*function generate2d(perlinNoise2d, w, h) +{ + var size = w*h, a = new MOD3.VecArray(size), i, j, index; + for (i=0,j=0,index=0; index= w) {i = 0; ++j;} + a[index] = perlinNoise2d(i/w, j/h); + } + return a; +}*/ +MOD3.Perlin = MOD3.Class(MOD3.Modifier, { + constructor: function Perlin(force, noise, autoRun) { + var self = this; + if (!(self instanceof Perlin)) return new Perlin(force, noise, autoRun); + self.$super('constructor'); + self.name = 'Perlin'; + self.force = null != force ? force : 1; + self.perlin = noise; + self.autoRun = null != autoRun ? !!autoRun : true; + self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z; + }, + + speedX: 1, + speedY: 1, + perlin: null, + force: 1, + offset: 0, + autoRun: true, + + dispose: function() { + var self = this; + self.perlin = null; + self.speedX = null; + self.speedY = null; + self.force = null; + self.offset = null; + self.autoRun = null; + self.$super('dispose'); + + return self; + }, + + setSpeed: function(dX, dY) { + var self = this; + self.speedX = dX; + self.speedY = dY; + return self; + }, + + apply: function(modifiable) { + var self = this, + axes = self.axes, force = self.force, + offset = self.offset, pn = self.perlin, + w, h; + + if (!axes || !pn) return self; + w = pn.width; h = pn.height; + if (self.autoRun) + { + pn = self.perlin = cyclic_shift(pn, w, h, self.speedX, self.speedY); + pn.width = w; pn.height = h; + } + + MOD3.List.each(modifiable.vertices, function(v) { + var xyz = v.getXYZ(), + uu = ~~((w - 1) * v.ratio[0]/* u */), + vv = ~~((h - 1) * v.ratio[2]/* v */), + uv = uu + vv * w; + + v.setXYZ([ + xyz[0] + (axes & MOD3.ModConstant.X ? (pn[uv] - offset) * force : 0), + xyz[1] + (axes & MOD3.ModConstant.Y ? (pn[uv/*+1*/] - offset) * force : 0), + xyz[2] + (axes & MOD3.ModConstant.Z ? (pn[uv/*+2*/] - offset) * force : 0) + ]); + }); + return self; + } +}); +}(MOD3);// export it +return MOD3; +}); diff --git a/examples/Copperlicht/Bend.html b/examples/Copperlicht/Bend.html index 59e705d..e4f26bc 100644 --- a/examples/Copperlicht/Bend.html +++ b/examples/Copperlicht/Bend.html @@ -2,7 +2,7 @@ - + Bend demo and copperlicht.js diff --git a/examples/Copperlicht/Bloat.html b/examples/Copperlicht/Bloat.html index 2911dfc..c223a69 100644 --- a/examples/Copperlicht/Bloat.html +++ b/examples/Copperlicht/Bloat.html @@ -2,7 +2,7 @@ - + Bloat demo and copperlicht.js diff --git a/examples/Copperlicht/Break.html b/examples/Copperlicht/Break.html index ddddddd..36b05fe 100644 --- a/examples/Copperlicht/Break.html +++ b/examples/Copperlicht/Break.html @@ -2,7 +2,7 @@ - + Break demo and copperlicht.js diff --git a/examples/Copperlicht/Noise.html b/examples/Copperlicht/Noise.html index 7b202d8..0e674d4 100644 --- a/examples/Copperlicht/Noise.html +++ b/examples/Copperlicht/Noise.html @@ -2,7 +2,7 @@ - + Noise demo and copperlicht.js diff --git a/examples/Copperlicht/Skew.html b/examples/Copperlicht/Skew.html index 949efe1..90cf2ab 100644 --- a/examples/Copperlicht/Skew.html +++ b/examples/Copperlicht/Skew.html @@ -2,7 +2,7 @@ - + Skew demo and copperlicht.js diff --git a/examples/Copperlicht/Taper.html b/examples/Copperlicht/Taper.html index 157a5c1..901c910 100644 --- a/examples/Copperlicht/Taper.html +++ b/examples/Copperlicht/Taper.html @@ -2,7 +2,7 @@ - + Taper demo and copperlicht.js diff --git a/examples/Copperlicht/Twist.html b/examples/Copperlicht/Twist.html index f8578a5..429fa3e 100644 --- a/examples/Copperlicht/Twist.html +++ b/examples/Copperlicht/Twist.html @@ -2,7 +2,7 @@ - + Twist demo and copperlicht.js diff --git a/examples/CubicVR/Bend.html b/examples/CubicVR/Bend.html index 1f07e5c..82fecdc 100644 --- a/examples/CubicVR/Bend.html +++ b/examples/CubicVR/Bend.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/CubicVR/Bloat.html b/examples/CubicVR/Bloat.html index ff42596..e8fc5bd 100644 --- a/examples/CubicVR/Bloat.html +++ b/examples/CubicVR/Bloat.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/CubicVR/Break.html b/examples/CubicVR/Break.html index c877e6a..75ccf92 100644 --- a/examples/CubicVR/Break.html +++ b/examples/CubicVR/Break.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/CubicVR/Noise.html b/examples/CubicVR/Noise.html index 13123cc..22d853e 100644 --- a/examples/CubicVR/Noise.html +++ b/examples/CubicVR/Noise.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/CubicVR/Perlin.html b/examples/CubicVR/Perlin.html index 145cd09..8de95e7 100644 --- a/examples/CubicVR/Perlin.html +++ b/examples/CubicVR/Perlin.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/CubicVR/Skew.html b/examples/CubicVR/Skew.html index 2bf0ef3..dd1f55c 100644 --- a/examples/CubicVR/Skew.html +++ b/examples/CubicVR/Skew.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/CubicVR/Taper.html b/examples/CubicVR/Taper.html index 87f38de..7fcaeda 100644 --- a/examples/CubicVR/Taper.html +++ b/examples/CubicVR/Taper.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/CubicVR/Twist.html b/examples/CubicVR/Twist.html index b8ee4e2..628f11d 100644 --- a/examples/CubicVR/Twist.html +++ b/examples/CubicVR/Twist.html @@ -11,7 +11,7 @@ } - + diff --git a/examples/J3D/Bend.html b/examples/J3D/Bend.html index 53f7bdd..c6bc2c5 100644 --- a/examples/J3D/Bend.html +++ b/examples/J3D/Bend.html @@ -10,7 +10,7 @@ - + diff --git a/examples/J3D/Noise.html b/examples/J3D/Noise.html index b2cb781..99a92e4 100644 --- a/examples/J3D/Noise.html +++ b/examples/J3D/Noise.html @@ -10,7 +10,7 @@ - + diff --git a/examples/J3D/Perlin.html b/examples/J3D/Perlin.html index c4c4aa2..723a759 100644 --- a/examples/J3D/Perlin.html +++ b/examples/J3D/Perlin.html @@ -10,7 +10,7 @@ - + diff --git a/examples/J3D/Skew.html b/examples/J3D/Skew.html index 054a01b..374754a 100644 --- a/examples/J3D/Skew.html +++ b/examples/J3D/Skew.html @@ -10,7 +10,7 @@ - + diff --git a/examples/J3D/Taper.html b/examples/J3D/Taper.html index bbf8f4b..ffeb106 100644 --- a/examples/J3D/Taper.html +++ b/examples/J3D/Taper.html @@ -10,7 +10,7 @@ - + diff --git a/examples/J3D/Twist.html b/examples/J3D/Twist.html index 4ac6f80..94369fd 100644 --- a/examples/J3D/Twist.html +++ b/examples/J3D/Twist.html @@ -10,7 +10,7 @@ - + diff --git a/examples/OSG/Bend.html b/examples/OSG/Bend.html index 7a05aba..d6d3e15 100644 --- a/examples/OSG/Bend.html +++ b/examples/OSG/Bend.html @@ -11,7 +11,7 @@ - + diff --git a/examples/OSG/Bloat.html b/examples/OSG/Bloat.html index 7c36258..bc33f3c 100644 --- a/examples/OSG/Bloat.html +++ b/examples/OSG/Bloat.html @@ -11,7 +11,7 @@ - + diff --git a/examples/OSG/Perlin.html b/examples/OSG/Perlin.html index 8f13bec..45ba520 100644 --- a/examples/OSG/Perlin.html +++ b/examples/OSG/Perlin.html @@ -11,7 +11,7 @@ - + diff --git a/examples/OSG/Skew.html b/examples/OSG/Skew.html index e2f8a63..be75c15 100644 --- a/examples/OSG/Skew.html +++ b/examples/OSG/Skew.html @@ -11,7 +11,7 @@ - + diff --git a/examples/OSG/Taper.html b/examples/OSG/Taper.html index fd1a33e..9a1df7e 100644 --- a/examples/OSG/Taper.html +++ b/examples/OSG/Taper.html @@ -11,7 +11,7 @@ - + diff --git a/examples/OSG/Twist.html b/examples/OSG/Twist.html index 46d3536..ec6e7f8 100644 --- a/examples/OSG/Twist.html +++ b/examples/OSG/Twist.html @@ -11,7 +11,7 @@ - + diff --git a/examples/Pre3D/Bend.html b/examples/Pre3D/Bend.html index 3af279f..334fe5c 100644 --- a/examples/Pre3D/Bend.html +++ b/examples/Pre3D/Bend.html @@ -14,7 +14,7 @@ - + diff --git a/examples/Pre3D/Twist.html b/examples/Pre3D/Twist.html index 1adc4c4..1e1645e 100644 --- a/examples/Pre3D/Twist.html +++ b/examples/Pre3D/Twist.html @@ -14,7 +14,7 @@ - + diff --git a/examples/Three/Bend.html b/examples/Three/Bend.html index b33750b..7cdc4f3 100644 --- a/examples/Three/Bend.html +++ b/examples/Three/Bend.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/Bloat.html b/examples/Three/Bloat.html index f38f046..4487df3 100644 --- a/examples/Three/Bloat.html +++ b/examples/Three/Bloat.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/Break.html b/examples/Three/Break.html index 9b4e986..82b4190 100644 --- a/examples/Three/Break.html +++ b/examples/Three/Break.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/DisplaceMap.html b/examples/Three/DisplaceMap.html index 163620d..75df162 100644 --- a/examples/Three/DisplaceMap.html +++ b/examples/Three/DisplaceMap.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/Noise.html b/examples/Three/Noise.html index ca27a6e..46e27d6 100644 --- a/examples/Three/Noise.html +++ b/examples/Three/Noise.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/Perlin.html b/examples/Three/Perlin.html index 705329d..3d5c38e 100644 --- a/examples/Three/Perlin.html +++ b/examples/Three/Perlin.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/Skew.html b/examples/Three/Skew.html index 7991544..bbf0465 100644 --- a/examples/Three/Skew.html +++ b/examples/Three/Skew.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/Taper.html b/examples/Three/Taper.html index ad3c631..b3d167e 100644 --- a/examples/Three/Taper.html +++ b/examples/Three/Taper.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/Twist.html b/examples/Three/Twist.html index 36e0794..67eb0b0 100644 --- a/examples/Three/Twist.html +++ b/examples/Three/Twist.html @@ -13,7 +13,7 @@ - + diff --git a/examples/Three/flipbook3/FlipBook3D.js b/examples/Three/flipbook3/FlipBook3D.js index 83b1f37..9364d23 100644 --- a/examples/Three/flipbook3/FlipBook3D.js +++ b/examples/Three/flipbook3/FlipBook3D.js @@ -6,21 +6,18 @@ **/ // 3D Flip Book ------------------------------------------------------------------------------------------- -var self = { }, - Class = root.Classy.Class, - THREE = root.THREE, - TWEEN = root.TWEEN, +var self = {}, MOD3 = root.MOD3, + THREE = root.THREE, + TWEEN = root.TWEEN, Book, Page, Abs = Math.abs, PI = Math.PI ; -var Abs = Math.abs, PI = Math.PI; - // Book Class------------------------------------------------------------------------------------------- -Book = self.Book = Class(THREE.Object3D, { - constructor: function( ){ +Book = self.Book = MOD3.Class(THREE.Object3D, { + constructor: function() { var self = this; self.$super("constructor"); self.pages = null; @@ -30,8 +27,8 @@ Book = self.Book = Class(THREE.Object3D, { self.flippedleft = 0; self.flippedright = 0; self.duration = 1; - self.centerContainer = new THREE.Object3D( ); - self.add( self.centerContainer ); + self.centerContainer = new THREE.Object3D(); + self.add(self.centerContainer); self.pages = []; }, @@ -44,27 +41,27 @@ Book = self.Book = Class(THREE.Object3D, { duration: 1, centerContainer: null, - getNumPages: function( ){ + getNumPages: function() { return this.pages.length; }, - addPage: function( pf, pb, hardness, pageColor ){ + addPage: function(pf, pb, hardness, pageColor) { var self = this, hardn = 0.5, pagecol = 0x555555; - if ( "undefined" !== typeof hardness ) hardn = hardness; - if ( "undefined" !== typeof pageColor ) pagecol = pageColor; + if ("undefined" !== typeof hardness) hardn = hardness; + if ("undefined" !== typeof pageColor) pagecol = pageColor; var i = self.pages.length, page = new Page(self, i, pf, pb, hardn, pagecol); - self.pages.push( page ); - self.centerContainer.add( page ); + self.pages.push(page); + self.centerContainer.add(page); return self; } }); // Page Class ------------------------------------------------------------------------------------------- -Page = self.Page = Class(THREE.Mesh, { - constructor: function( book, i, matf, matb, hard, col ) { +Page = self.Page = MOD3.Class(THREE.Mesh, { + constructor: function(book, i, matf, matb, hard, col) { var self = this; self.book = book; self.matFront = matf; @@ -89,47 +86,47 @@ Page = self.Page = Class(THREE.Mesh, { self.pageColor = col; self.sides = {bottom:3, top:2, right:0, left:1, front:4, back:5}; - self.book.flippedright++; + ++self.book.flippedright; // align flipBook center container - if ( 0 === self.index ) + if (0 === self.index) self.book.centerContainer.position.x = -self.book.pageWidth*0.5; // add page flip interaction TO DO.. - for (var mii=0;mii<6;mii++) + for (var mii=0; mii<6; ++mii) { // add front - back page images - if ( mii === self.sides.front ) + if (mii === self.sides.front) { - self.mats[self.sides.front] = new THREE.MeshBasicMaterial( { map: self.matFront, overdraw: true } ); + self.mats[self.sides.front] = new THREE.MeshBasicMaterial({map: self.matFront, overdraw: true}); self.mats[self.sides.front].name = "front"; } - else if ( mii === self.sides.back ) + else if (mii === self.sides.back) { - self.mats[self.sides.back] = new THREE.MeshBasicMaterial( { map: self.matBack, overdraw: true } ); + self.mats[self.sides.back] = new THREE.MeshBasicMaterial({map: self.matBack, overdraw: true}); self.mats[self.sides.back].name = "back"; } else { - self.mats[mii] = new THREE.MeshBasicMaterial( { color: self.pageColor } ); + self.mats[mii] = new THREE.MeshBasicMaterial({color: self.pageColor}); self.mats[mii].name = 'edge'; } } // call super // Three.js has made materials added to FaceMaterial instead of CubeGeometry - self.$super("constructor", new THREE.CubeGeometry( book.pageWidth, book.pageHeight, 1, self.nfacesw, self.nfacesh, 1 ), new THREE.MeshFaceMaterial(self.mats)); + self.$super("constructor", [new THREE.CubeGeometry(book.pageWidth, book.pageHeight, 1, self.nfacesw, self.nfacesh, 1), new THREE.MeshFaceMaterial(self.mats)]); self.overdraw = true; self.position.x = book.pageWidth * 0.5; self.position.z = -self.zz * self.index; // flip modifiers - self.mod = new MOD3.ModifierStack( MOD3.LibraryThree, self ); - self.mod.addModifier( new MOD3.Pivot( self.position.x, 0, 0 ) ).collapse( ); - self.bend = new MOD3.Bend( 0, 0, 0 ); + self.mod = new MOD3.ModifierStack(MOD3.LibraryThree, self); + self.mod.addModifier(new MOD3.Pivot(self.position.x, 0, 0)).collapse(); + self.bend = new MOD3.Bend(0, 0, 0); self.bend.constraint = MOD3.ModConstant.LEFT; self.bend.switchAxes = book.pageHeight > book.pageWidth ? true : false; - self.mod.addModifier( self.bend ); + self.mod.addModifier(self.bend); }, book : null, @@ -154,89 +151,89 @@ Page = self.Page = Class(THREE.Mesh, { pageColor : null, sides : null, - flipLeft: function( pt ) { + flipLeft: function(pt) { var self = this; if ( - !self.isFlippedLeft && - !self.flippingLeft && - !self.flippingRight && + !self.isFlippedLeft && + !self.flippingLeft && + !self.flippingRight && (self.index === self.book.flippedleft) ) { - if ( null != pt ) + if (null != pt) { //this.flipPt=pt;//e.localY/this.book.pageHeight; } self.flippingLeft = true; self.bend.angle = (2*self.flipPt-1)*self.angle; - new TWEEN.Tween( self.to={ angle: self.rotation.y, t: -1, xx: 0, page: self } ) + new TWEEN.Tween(self.to={angle: self.rotation.y, t: -1, xx: 0, page: self}) .to({angle:-Math.PI, xx:1, t:1}, self.book.duration*1000) - .onUpdate( self.renderFlip ) - .onComplete( self.flipFinished ) - .start( ) + .onUpdate(self.renderFlip) + .onComplete(self.flipFinished) + .start() ; - self.book.flippedleft++; - self.book.flippedright--; + ++self.book.flippedleft; + --self.book.flippedright; self.position.z = 1; } return self; }, - flipRight: function( pt ) { + flipRight: function(pt) { var self = this; if ( - !self.isFlippedRight && - !self.flippingRight && - !self.flippingLeft && + !self.isFlippedRight && + !self.flippingRight && + !self.flippingLeft && (self.index === self.book.getNumPages()-self.book.flippedright-1) ) { - if ( null != pt ) + if (null != pt) { //this.flipPt=pt;//e.localY/this.book.pageHeight; } self.flippingRight = true; self.bend.angle = (2*self.flipPt-1)*self.angle; - new TWEEN.Tween( self.to = { angle: self.rotation.y, t: -1, xx: 0, page: self } ) + new TWEEN.Tween(self.to={angle: self.rotation.y, t: -1, xx: 0, page: self}) .to({angle:0, xx:1, t:1}, self.book.duration*1000) - .onUpdate( self.renderFlip ) - .onComplete( self.flipFinished ) - .start( ) + .onUpdate(self.renderFlip) + .onComplete(self.flipFinished) + .start() ; - self.book.flippedleft--; - self.book.flippedright++; + --self.book.flippedleft; + ++self.book.flippedright; self.position.z = 1; } return self; }, - renderFlip: function( ) { + renderFlip: function() { var t = this, self = t.page, book = self.book, p2 = Math.PI*0.5, tt; // align flipBook to center - if ( self.flippingLeft && 0 === self.index && book.getNumPages() > 1 ) - book.centerContainer.position.x = (1-t.xx) * book.centerContainer.position.x; - else if ( self.flippingLeft && self.index+1 === book.getNumPages() ) - book.centerContainer.position.x = (1-t.xx)*book.centerContainer.position.x+t.xx*book.pageWidth*0.5; - else if ( self.flippingRight && 0 === self.index ) - book.centerContainer.position.x = (1-t.xx)*book.centerContainer.position.x-t.xx*book.pageWidth*0.5; - else if ( self.flippingRight && self.index+1 === book.getNumPages() ) - book.centerContainer.position.x = (1-t.xx)*book.centerContainer.position.x; + if (self.flippingLeft && 0 === self.index && book.getNumPages() > 1) + book.centerContainer.position.x = (1 - t.xx) * book.centerContainer.position.x; + else if (self.flippingLeft && self.index+1 === book.getNumPages()) + book.centerContainer.position.x = (1 - t.xx)*book.centerContainer.position.x + t.xx*book.pageWidth*0.5; + else if (self.flippingRight && 0 === self.index) + book.centerContainer.position.x = (1 - t.xx)*book.centerContainer.position.x - t.xx*book.pageWidth*0.5; + else if (self.flippingRight && self.index+1 === book.getNumPages()) + book.centerContainer.position.x = (1 - t.xx) * book.centerContainer.position.x; // flip page - tt=(1-Abs(t.t)); + tt = 1 - Abs(t.t); self.rotation.y = t.angle; self.bend.force = ((Abs(t.angle)-p2)/p2)*tt*self.force*(1-self.pageHardness); - self.bend.offset = (1-tt)*0.6+tt*0.5; - self.mod.apply( ); + self.bend.offset = (1 - tt)*0.6 + tt*0.5; + self.mod.apply(); }, - flipFinished: function( ) { + flipFinished: function() { var t = this, self = t.page; - if ( self.flippingLeft ) + if (self.flippingLeft) { self.flippingLeft = false; self.isFlippedLeft = true; @@ -244,7 +241,7 @@ Page = self.Page = Class(THREE.Mesh, { self.isFlippedRight = false; self.position.z = -self.zz*(self.book.getNumPages()-self.index); } - else if ( self.flippingRight ) + else if (self.flippingRight) { self.flippingLeft = false; self.isFlippedRight = true; diff --git a/examples/Three/flipbook3/FlipBook3DApplication.js b/examples/Three/flipbook3/FlipBook3DApplication.js index cd00f11..603f94a 100644 --- a/examples/Three/flipbook3/FlipBook3DApplication.js +++ b/examples/Three/flipbook3/FlipBook3DApplication.js @@ -4,9 +4,9 @@ * http://paulirish.com/2011/requestanimationframe-for-smart-animating/ */ -if ( !window.requestAnimationFrame ) { +if (!window.requestAnimationFrame) { - window.requestAnimationFrame = ( function() { + window.requestAnimationFrame = (function() { return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || @@ -18,7 +18,7 @@ if ( !window.requestAnimationFrame ) { }; - } )(); + })(); } @@ -26,7 +26,7 @@ var multx = 0.5*Math.PI, multy = -Math.PI, Sin = Math.sin, Cos = Math.cos, - + container, camera, scene, renderer, projector, targetRotationY = 0, targetRotationOnMouseDownY = 0, targetRotationX = 0, targetRotationOnMouseDownX = 0, rad=700, mouse={x:0,y:0}, mouseX = 0, mouseXOnMouseDown = 0, mouseY = 0, mouseYOnMouseDown = 0, @@ -37,20 +37,20 @@ var multx = 0.5*Math.PI, fl,fr ; -function onDocumentMouseDown( event ) +function onDocumentMouseDown(event) { event.preventDefault(); - mouseX = ( event.clientX / w ) * 2 - 1; + mouseX = (event.clientX / w) * 2 - 1; targetRotationY = mouseX; - mouseY = ( event.clientY / h ) * 2 - 1; - targetRotationX=mouseY; + mouseY = (event.clientY / h) * 2 - 1; + targetRotationX = mouseY; - container.addEventListener( 'mousemove', onDocumentMouseMove, false ); - container.addEventListener( 'mouseup', onDocumentMouseUp, false ); - container.addEventListener( 'mouseout', onDocumentMouseOut, false ); + container.addEventListener('mousemove', onDocumentMouseMove, false); + container.addEventListener('mouseup', onDocumentMouseUp, false); + container.addEventListener('mouseout', onDocumentMouseOut, false); } -function onDocumentMouseMove( event ) +function onDocumentMouseMove(event) { /*mouseX = event.clientX - w2; mouseY = event.clientY - h2; @@ -60,99 +60,99 @@ function onDocumentMouseMove( event ) //var target= //mouse_path.push(e.seenas.ray); - mouseX = ( event.clientX / w ) * 2 - 1; + mouseX = (event.clientX / w) * 2 - 1; targetRotationY = mouseX; - mouseY = ( event.clientY / h ) * 2 - 1; + mouseY = (event.clientY / h) * 2 - 1; targetRotationX = mouseY; } -function onDocumentMouseUp( event ) +function onDocumentMouseUp(event) { - container.removeEventListener( 'mousemove', onDocumentMouseMove, false ); - container.removeEventListener( 'mouseup', onDocumentMouseUp, false ); - container.removeEventListener( 'mouseout', onDocumentMouseOut, false ); + container.removeEventListener('mousemove', onDocumentMouseMove, false); + container.removeEventListener('mouseup', onDocumentMouseUp, false); + container.removeEventListener('mouseout', onDocumentMouseOut, false); } -function onDocumentMouseOut( event ) +function onDocumentMouseOut(event) { - container.removeEventListener( 'mousemove', onDocumentMouseMove, false ); - container.removeEventListener( 'mouseup', onDocumentMouseUp, false ); - container.removeEventListener( 'mouseout', onDocumentMouseOut, false ); + container.removeEventListener('mousemove', onDocumentMouseMove, false); + container.removeEventListener('mouseup', onDocumentMouseUp, false); + container.removeEventListener('mouseout', onDocumentMouseOut, false); } -function animate( ) +function animate() { // use spherical coordinatess // for mouse control viewing - camera.position.x = rad * Sin( targetRotationY * multy ) * Cos( targetRotationX * multx ); - camera.position.y = rad * Sin( targetRotationX * multx ); - camera.position.z = rad * Cos( targetRotationY * multy ) * Cos( targetRotationX * multx ); - camera.lookAt( scene.position ); + camera.position.x = rad * Sin(targetRotationY * multy) * Cos(targetRotationX * multx); + camera.position.y = rad * Sin(targetRotationX * multx); + camera.position.z = rad * Cos(targetRotationY * multy) * Cos(targetRotationX * multx); + camera.lookAt(scene.position); // render - TWEEN.update( ); - renderer.render( scene, camera ); - + TWEEN.update(); + renderer.render(scene, camera); + // setup next animation - requestAnimationFrame( animate ); + requestAnimationFrame(animate); } var self = { - init: function( images ) { + init: function(images) { // setup the scene container = document.getElementById('container'); w = window.innerWidth; h = window.innerHeight; w2 = w/2; h2 = h/2; - container.style.width = w+"px"; - container.style.height = h+"px"; - container.style.marginTop = 0.5*(window.innerHeight-h)+'px'; + container.style.width = String(w)+"px"; + container.style.height = String(h)+"px"; + container.style.marginTop = String(0.5*(window.innerHeight-h))+'px'; - scene = new THREE.Scene( ); + scene = new THREE.Scene(); projector = new THREE.Projector(); - camera = new THREE.PerspectiveCamera( 50, w / h, 1, 1000 ); + camera = new THREE.PerspectiveCamera(50, w / h, 1, 1000); camera.position.z = rad; - scene.add( camera ); + scene.add(camera); // webgl renderer gives better rendering without problems - renderer = new THREE.WebGLRenderer( ); - renderer.setSize( w, h ); + renderer = new THREE.WebGLRenderer(); + renderer.setSize(w, h); - container.appendChild( renderer.domElement ); - container.addEventListener( 'mousedown', onDocumentMouseDown, false ); + container.appendChild(renderer.domElement); + container.addEventListener('mousedown', onDocumentMouseDown, false); // create book - book = new FlipBook3D.Book( ); + book = new FlipBook3D.Book(); book.pageWidth = pagew; book.pageHeight = pageh; - scene.add( book ); + scene.add(book); // create pages - for (var i=0;i= 0 && pindex < plen ) book.pages[pindex].flipLeft( ); + if (pindex >= 0 && pindex < plen) book.pages[pindex].flipLeft(); }); fr = document.getElementById('flipright'); - fr.addEventListener('click',function( ){ + fr.addEventListener('click', function() { var plen = book.pages.length, pindex = book.flippedleft-1 ; - if ( pindex >= 0 && pindex < plen ) book.pages[pindex].flipRight( ); + if (pindex >= 0 && pindex < plen) book.pages[pindex].flipRight(); }); // start rendering - animate( ); + animate(); }, animate : animate diff --git a/examples/Three/flipbook3/index.html b/examples/Three/flipbook3/index.html index 704873a..17286d4 100644 --- a/examples/Three/flipbook3/index.html +++ b/examples/Three/flipbook3/index.html @@ -72,7 +72,7 @@ - + diff --git a/readme.md b/readme.md index 7a34d79..4378fc3 100644 --- a/readme.md +++ b/readme.md @@ -1,30 +1,18 @@ -# MOD3 - +# MOD3 **3D Modifier Library for JavaScript** -This is a port of the [AS3dMod Modifier Library for ActionScript 3](http://code.google.com/p/as3dmod/) to JavaScript. - -**supports:** *Three.js* , *Pre3d* , *J3D* , *Copperlicht* , *CubicVR.js*, *OSG.js* - - - -**IMPORTANT: Further development on this project has stopped! If anyone is interested in taking over this project for further development, send me a message through github.** +This is a port of the [AS3dMod Modifier Library for ActionScript 3](http://code.google.com/p/as3dmod/) to JavaScript. +**version: 1.0.0** +**supports: Three.js, CubicVR.js, OSG.js, J3D, Copperlicht, Pre3d [![MOD3.js](/flipbook2.png)](https://foo123.github.io/examples/flipbook3/) - -It is named *MOD3* to signify that it has support for [Three.js](https://github.com/mrdoob/three.js/) - - -It is a (almost) complete port. All Modifiers found in AS3DMod are scheduled to be ported. +It is an almost complete port. All Modifiers found in AS3DMod are scheduled to be ported. Also the API architecture is setup for more modifiers to be added (even custom ones). -The library has a dependency on [Classy.js](https://github.com/foo123/classy.js) micro Object-Oriented framework. - - ### Contents @@ -40,10 +28,7 @@ The library has a dependency on [Classy.js](https://github.com/foo123/classy.js) ### Source Code License -This code uses the [MIT Open Source License](http://opensource.org/licenses/mit-license.php), per requests to use the license of the original [AS3dMod Modifier Library for ActionScript 3](http://code.google.com/p/as3dmod/) code. - -Feel free to share, modify, contribute etc.. - +[MIT Open Source License](http://opensource.org/licenses/mit-license.php) like the original [AS3dMod Modifier Library for ActionScript 3](http://code.google.com/p/as3dmod/). ### Live Examples @@ -55,15 +40,15 @@ Feel free to share, modify, contribute etc.. * [Three.js](https://github.com/mrdoob/three.js/) with examples (r78) * [OSG.js](https://github.com/cedricpinson/osgjs) with examples (0.2.5) +* [CubicVR](https://github.com/cjcliffe/CubicVR.js/) with examples * [J3D](https://github.com/drojdjou/J3D) with examples (Build 51) * [Copperlicht](https://github.com/Sebmaster/copperlicht) with examples -* [CubicVR](https://github.com/cjcliffe/CubicVR.js/) with examples -* [Pre3d](https://github.com/deanm/pre3d) with examples (my pre3d examples are a little blurry but you'll get the picture) +* [Pre3d](https://github.com/deanm/pre3d) with examples (pre3d examples are a little blurry but you'll get the picture) -### Modifiers supported (up to present) -* Pivot (note: Pivot does not work with Pre3d) +### Modifiers supported (up to present) +* Pivot (note: Pivot does not work with Pre3d) * Bend * Twist * Taper @@ -72,8 +57,8 @@ Feel free to share, modify, contribute etc.. * Wheel * Bloat * Break -* Perlin ( MOD3 v.0.3.4 ) -* DisplaceMap ( MOD3 v.0.3.5 ) +* Perlin +* DisplaceMap ### TODO @@ -91,6 +76,7 @@ Feel free to share, modify, contribute etc.. ### Changelog +* 1.0.0 refactor, simplify and minify code, remove classy dependency * 0.6.0 3d engine plugins have been removed from the final build to make packaged code lighter, include the appropriate 3D plugin **manualy in your application** after the main **mod3** script (see examples), modifiers are independent of the underlying modifiable mesh (it is a parameter), and this enables them to be shared (if the exact same modifier is needed) across multiple different modifierStacks for different underlying meshes, support for OSG.js, further refactoring and optimisations, some method changes * 0.5.0 parallel processing through workers is dropped, add support for OSG.js (in progress), update support for Three.js r78, some refactoring and optimisations * 0.4 support parallel modifiers with web workers transparently, code refactor, optimizations, examples updates @@ -125,6 +111,7 @@ Feel free to share, modify, contribute etc.. * [Carousel3](https://github.com/foo123/Carousel3) HTML5 Photo Carousel using Three.js * [Rubik3](https://github.com/foo123/Rubik3) intuitive 3D Rubik Cube with Three.js * [MOD3](https://github.com/foo123/MOD3) JavaScript port of AS3DMod ActionScript 3D Modifier Library +* [Geometrize](https://github.com/foo123/Geometrize) Computational Geometry and Rendering Library for JavaScript * [RT](https://github.com/foo123/RT) unified client-side real-time communication for JavaScript using XHR polling / BOSH / WebSockets / WebRTC * [AjaxListener.js](https://github.com/foo123/AjaxListener.js): Listen to any AJAX event on page with JavaScript, even by other scripts * [asynchronous.js](https://github.com/foo123/asynchronous.js) simple manager for asynchronous, linear, parallel, sequential and interleaved tasks for JavaScript diff --git a/src/MOD3.js b/src/MOD3.js index 84229f9..0a015fa 100644 --- a/src/MOD3.js +++ b/src/MOD3.js @@ -1,16 +1,4 @@ -/** -* -* MOD3.js -* @version: @@VERSION@@ -* @dependencies: Classy.js -* -* MOD3 3D Modifier Library for JavaScript -* port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/) -* https://github.com/foo123/MOD3 -* -**/ -@@USE_STRICT@@ -var MOD3 = { - VERSION: "@@VERSION@@", - Class: Classy.Class, StaticClass: function( classdef ){ return Classy.Class(Classy.STATIC, classdef); } +var MOD3 = { + VERSION: "@@VERSION@@", + Class: makeClass }; diff --git a/src/core/Mesh.js b/src/core/Mesh.js index f6300e8..518a13e 100644 --- a/src/core/Mesh.js +++ b/src/core/Mesh.js @@ -1,67 +1,60 @@ /** -* * MOD3 MeshProxy Super Class -* -* **/ -!function(MOD3, undef){ -@@USE_STRICT@@ - -var ModConstant = MOD3.ModConstant, - X = ModConstant.X, Y = ModConstant.Y, Z = ModConstant.Z, - XYZ = MOD3.XYZi, Vector3 = MOD3.Vector3, V = MOD3.VecArray, - Min = Math.min, Max = Math.max, each = MOD3.List.each, - dispose = function( o ) { o.dispose( ); }, - reset = function( o ) { o.reset( ); }, - collapse = function( o ) { o.collapse( ); }, - FaceProxy, VertexProxy, MeshProxy, Factory -; - -FaceProxy = MOD3.FaceProxy = MOD3.Class({ - - constructor: function FaceProxy( ) { - this.vertices = [ ]; - }, - +function dispose(o) +{ + o.dispose(); +} +function reset(o) +{ + o.reset(); +} +function collapse(o) +{ + o.collapse(); +} + +MOD3.FaceProxy = MOD3.Class(null, { + constructor: function FaceProxy() { + this.vertices = []; + }, + name: "FaceProxy", - vertices: null, - dispose: function( ) { + dispose: function() { var self = this; self.vertices = null; return self; }, - - addVertex: function( v ) { - this.vertices.push( v ); + + addVertex: function(v) { + this.vertices.push(v); }, - getVertices: function( ) { + getVertices: function() { return this.vertices; } }); -VertexProxy = MOD3.VertexProxy = MOD3.Class({ - - constructor: function VertexProxy( vertex, mesh ) { +MOD3.VertexProxy = MOD3.Class(null, { + constructor: function VertexProxy(vertex, mesh) { var self = this; self.mesh = mesh || null; // use internal typed-arrays for speed - self.original = new V( [0,0,0] ); - self.ratio = new V( [0,0,0] ); + self.original = new MOD3.VecArray([0,0,0]); + self.ratio = new MOD3.VecArray([0,0,0]); // vertex can be zero - if ( null != vertex ) self.setVertex( vertex ); + if (null != vertex) self.setVertex(vertex); }, - + name: "VertexProxy", - mesh: null, vertex: null, original: null, ratio: null, - - dispose: function( ) { + + dispose: function() { var self = this; self.mesh = null; self.vertex = null; @@ -69,171 +62,170 @@ VertexProxy = MOD3.VertexProxy = MOD3.Class({ self.ratio = null; return self; }, - - setVertex: function( vt ) { + + setVertex: function(vt) { // override var self = this; self.vertex = vt; return self; }, - - getRatioVector: function( ) { - var r = this.ratio, rv = new V(3); + + getRatioVector: function() { + var r = this.ratio, rv = new MOD3.VecArray(3); rv[0] = r[0]; rv[1] = r[1]; rv[2] = r[2]; return rv; }, - getRatio: function( axis ) { - return this.ratio[ XYZ[axis] ] || 0; + getRatio: function(axis) { + return this.ratio[MOD3.XYZi[axis]] || 0; }, - setRatios: function( rx, ry, rz ) { + setRatios: function(rx, ry, rz) { var r = this.ratio; - r[0] = rx===undef ? 0 : rx; - r[1] = ry===undef ? 0 : ry; - r[2] = rz===undef ? 0 : rz; + r[0] = rx || 0; + r[1] = ry || 0; + r[2] = rz || 0; return this; }, - getOriginalValue: function( axis ) { - return this.original[ XYZ[axis] ] || 0; + getOriginalValue: function(axis) { + return this.original[MOD3.XYZi[axis]] || 0; }, - setOriginalPosition: function( ox, oy, oz ) { + setOriginalPosition: function(ox, oy, oz) { var o = this.original; - o[0] = ox===undef ? 0 : ox; - o[1] = oy===undef ? 0 : oy; - o[2] = oz===undef ? 0 : oz; + o[0] = ox || 0; + o[1] = oy || 0; + o[2] = oz || 0; return this; }, - getXYZ: function( ) { + getXYZ: function() { // override - return new V( [0,0,0] ); + return new MOD3.VecArray([0,0,0]); }, - - getX: function( ) { + + getX: function() { // override return 0; }, - getY: function( ) { + getY: function() { // override return 0; }, - getZ: function( ) { + getZ: function() { // override return 0; }, - getValue: function( axis ) { + getValue: function(axis) { var self = this; // override - return X === axis - ? self.getX( ) - : (Y === axis - ? self.getY( ) - : (Z === axis - ? self.getZ( ) + return MOD3.ModConstant.X === axis + ? self.getX() + : (MOD3.ModConstant.Y === axis + ? self.getY() + : (MOD3.ModConstant.Z === axis + ? self.getZ() : 0)) ; }, - setXYZ: function( xyz ) { + setXYZ: function(xyz) { // override return this; }, - - setX: function( vo ) { + + setX: function(vo) { // override return this; }, - setY: function( vo ) { + setY: function(vo) { // override return this; }, - setZ: function( vo ) { + setZ: function(vo) { // override return this; }, - setValue: function( axis, vo ) { + setValue: function(axis, vo) { var self = this; // override - if ( X === axis ) self.setX( vo ); - else if ( Y === axis ) self.setY( vo ); - else if ( Z === axis ) self.setZ( vo ); + if (MOD3.ModConstant.X === axis) self.setX(vo); + else if (MOD3.ModConstant.Y === axis) self.setY(vo); + else if (MOD3.ModConstant.Z === axis) self.setZ(vo); return self; }, - reset: function( ) { + reset: function() { // override var self = this; - self.setXYZ( self.original ); + self.setXYZ(self.original); return self; }, - collapse: function( ) { + collapse: function() { // override - var self = this, xyz = self.getXYZ( ), o = self.original; + var self = this, xyz = self.getXYZ(), o = self.original; o[0] = xyz[0]; o[1] = xyz[1]; o[2] = xyz[2]; return self; } }); -MeshProxy = MOD3.MeshProxy = MOD3.Class({ - - constructor: function MeshProxy( mesh ) { +MOD3.MeshProxy = MOD3.Class(null, { + constructor: function MeshProxy(mesh) { var self = this; self.maxX = 0; self.maxY = 0; self.maxZ = 0; - + self.minX = 0; self.minY = 0; self.minZ = 0; - + self.maxAxis = 0; self.midAxis = 0; self.minAxis = 0; - + self.width = 0; self.height = 0; self.depth = 0; - + self.vertices = null; self.faces = null; self.mesh = null; - - if ( null != mesh ) self.setMesh( mesh ); + + if (null != mesh) self.setMesh(mesh); }, - + name: "MeshProxy", - + maxX: 0, maxY: 0, maxZ: 0, minX: 0, minY: 0, minZ: 0, - + maxAxis: 0, midAxis: 0, minAxis: 0, - + width: 0, height: 0, depth: 0, - + vertices : null, faces : null, mesh : null, v: null, - - dispose: function( ) { + + dispose: function() { var self = this; self.maxX = null; self.maxY = null; @@ -241,98 +233,106 @@ MeshProxy = MOD3.MeshProxy = MOD3.Class({ self.minX = null; self.minY = null; self.minZ = null; - + self.maxAxis = null; self.midAxis = null; self.minAxis = null; - + self.width = null; self.height = null; self.depth = null; - - self.disposeFaces( ); - self.disposeVertices( ); + + self.disposeFaces(); + self.disposeVertices(); self.mesh = null; self.v = null; return self; }, - - disposeVertices: function( ) { + + disposeVertices: function() { var self = this; - each( self.vertices, dispose ); + if (self.vertices) MOD3.List.each(self.vertices, dispose); self.vertices = null; return self; }, - - disposeFaces: function( ) { + + disposeFaces: function() { var self = this; - each( self.faces, dispose ); + if (self.faces) MOD3.List.each(self.faces, dispose); self.faces = null; return self; }, - - init: function( mesh ) { + + init: function(mesh) { var self = this; self.mesh = mesh; - //self.vertices = [ ]; + //self.vertices = []; // not used //self.faces = []; return self; }, - setMesh: function( mesh ) { - return this.init( mesh ).preApply( ).analyzeGeometry( ).postApply( ); + setMesh: function(mesh) { + var self = this; + self.init(mesh); + self.preApply(); + self.analyzeGeometry() + self.postApply(); + return self; }, - getVertices: function( ) { + getVertices: function() { return this.vertices; }, - getFaces: function( ) { + getFaces: function() { return this.faces; }, - applyModifiers: function( modStack ) { + applyModifiers: function(modStack) { var self = this, sl, i; - for (i=0,sl=modStack.length; i 0 ? (xyz[ 0 ] - minX) / width : 0, height > 0 ? (xyz[ 1 ] - minY) / height : 0, depth > 0 ? (xyz[ 2 ] - minZ) / depth : 0); + MOD3.List.each(vertices, function(v) { + var xyz = v.getXYZ(); + v.setRatios(width > 0 ? (xyz[0] - minX) / width : 0, height > 0 ? (xyz[1] - minY) / height : 0, depth > 0 ? (xyz[2] - minZ) / depth : 0); }); return self; }, - resetGeometry: function( ) { + resetGeometry: function() { var self = this; - each( self.vertices, reset ); + MOD3.List.each(self.vertices, reset); return self; }, - collapseGeometry: function( ) { + collapseGeometry: function() { var self = this; - each( self.vertices, collapse ); - return self.analyzeGeometry( ); + MOD3.List.each(self.vertices, collapse); + self.analyzeGeometry(); + return self; }, - getMin: function( axis ) { + getMin: function(axis) { var self = this; - return X === axis + return MOD3.ModConstant.X === axis ? self.minX - : (Y === axis + : (MOD3.ModConstant.Y === axis ? self.minY - : (Z === axis + : (MOD3.ModConstant.Z === axis ? self.minZ : -1)) ; }, - getMax: function( axis ) { + getMax: function(axis) { var self = this; - return X === axis + return MOD3.ModConstant.X === axis ? self.maxX - : (Y === axis + : (MOD3.ModConstant.Y === axis ? self.maxY - : (Z === axis + : (MOD3.ModConstant.Z === axis ? self.maxZ : -1)) ; }, - getSize: function( axis ) { + getSize: function(axis) { var self = this; - return X === axis + return MOD3.ModConstant.X === axis ? self.width - : (Y === axis + : (MOD3.ModConstant.Y === axis ? self.height - : (Z === axis + : (MOD3.ModConstant.Z === axis ? self.depth : -1)) ; }, - update: function( ) { + update: function() { // do nothing return this; }, - preApply: function( ) { + preApply: function() { // do nothing return this; }, - postApply: function( ) { + postApply: function() { // do nothing return this; }, - updateMeshPosition: function( p ) { + updateMeshPosition: function(p) { // do nothing return this; } @@ -461,40 +462,37 @@ MeshProxy = MOD3.MeshProxy = MOD3.Class({ MOD3.Library3d = { id : "Library3d", - Mesh : MeshProxy, - Vertex : VertexProxy + Mesh : MOD3.MeshProxy, + Vertex : MOD3.VertexProxy }; -Factory = MOD3.Factory = MOD3.StaticClass({ - - getLibrary: function( json ) { - if ( json && json.library && MOD3[ json.library ] ) return MOD3[ json.library ]; +MOD3.Factory = { + getLibrary: function(json) { + if (json && json.library && MOD3[json.library]) return MOD3[json.library]; // dummy, default return MOD3.Library3d; } - - ,getMeshProxy: function( lib3D ) { - if ( arguments.length ) return lib3D.Mesh ? new lib3D.Mesh( ) : null; + + ,getMeshProxy: function(lib3D) { + if (arguments.length) return lib3D.Mesh ? new lib3D.Mesh() : null; return null; } - - ,getModifier: function( json ) { - if ( json && json.modifier && MOD3[ json.modifier ] ) return new MOD3[ json.modifier ]( ); + + ,getModifier: function(json) { + if (json && json.modifier && MOD3[json.modifier]) return new MOD3[json.modifier](); return null; } - + /* - ,getMesh: function( json ) { - if ( json && json.mesh && MOD3[ json.mesh ] ) return new MOD3.MeshProxy( ).unserialize( json ); + ,getMesh: function(json) { + if (json && json.mesh && MOD3[json.mesh] ) return new MOD3.MeshProxy().unserialize(json); // dummy, default - return new MOD3.MeshProxy( ); + return new MOD3.MeshProxy(); } - - ,getVertex: function( json ) { - if ( json && json.vertex && MOD3[ json.vertex ] ) return new MOD3.VertexProxy( ).unserialize( json ); + + ,getVertex: function(json) { + if (json && json.vertex && MOD3[json.vertex]) return new MOD3.VertexProxy().unserialize(json); // dummy, default - return new MOD3.VertexProxy( ); + return new MOD3.VertexProxy(); }*/ -}); - -}(MOD3); \ No newline at end of file +}; diff --git a/src/core/ModifierStack.js b/src/core/ModifierStack.js index 4d48ad9..ed10ba9 100644 --- a/src/core/ModifierStack.js +++ b/src/core/ModifierStack.js @@ -1,147 +1,135 @@ /** -* * MOD3 Modifier & ModifierStack Classes -* -* **/ -!function(MOD3, undef){ -@@USE_STRICT@@ +var _modCount = 0; -var _modCount = 0, NONE = MOD3.ModConstant.NONE, - getMeshProxy = MOD3.Factory.getMeshProxy, - Modifier, ModifierStack; - -Modifier = MOD3.Modifier = MOD3.Class({ - - constructor: function Modifier( ) { +MOD3.Modifier = MOD3.Class({ + constructor: function Modifier() { var self = this; self.id = ++_modCount; self.name = 'Modifier'; - self.axes = NONE; - self.constraint = NONE; + self.axes = MOD3.ModConstant.NONE; + self.constraint = MOD3.ModConstant.NONE; self.enabled = true; }, - + id: null, name: 'Modifier', axes: null, constraint: null, enabled: true, - dispose: function( ) { + dispose: function() { var self = this; self.name = null; self.axes = null; self.constraint = null; return self; }, - - enable: function( enabled ) { - if ( arguments.length ) + + enable: function(enabled) { + if (arguments.length) { this.enabled = !!enabled; return this; } return this.enabled; }, - - constraintAxes: function( axes ) { - this.axes = axes || NONE; + + constraintAxes: function(axes) { + this.axes = axes || MOD3.ModConstant.NONE; return this; }, - - setConstraint: function( c ) { - this.constraint = c || NONE; + + setConstraint: function(c) { + this.constraint = c || MOD3.ModConstant.NONE; return this; }, - + // override - apply: function( modifiable ) { + apply: function(modifiable) { return this; }, - - toString: function( ) { + + toString: function() { return '[Modifier '+this.name+']'; } }); -ModifierStack = MOD3.ModifierStack = MOD3.Class({ - - constructor: function ModifierStack( lib3d, mesh ) { +MOD3.ModifierStack = MOD3.Class({ + constructor: function ModifierStack(lib3d, mesh) { var self = this; - if ( !(self instanceof ModifierStack) ) return new ModifierStack(lib3d, mesh); - self.stack = [ ]; - self.setModifiable( getMeshProxy( lib3d ), mesh ); + if (!(self instanceof ModifierStack)) return new ModifierStack(lib3d, mesh); + self.stack = []; + self.setModifiable(MOD3.Factory.getMeshProxy(lib3d), mesh); }, name: "ModifierStack", modifiable: null, stack: null, - dispose: function( withModifiers ) { + dispose: function(withModifiers) { var self = this; - if ( withModifiers && self.stack ) while ( self.stack.length ) self.stack.pop( ).dispose( ); - if ( self.modifiable ) self.modifiable.dispose( ); + if (withModifiers && self.stack) while (self.stack.length) self.stack.pop().dispose(); + if (self.modifiable) self.modifiable.dispose(); self.stack = null; self.modifiable = null; return self; }, - - getModifiable: function( ) { + + getModifiable: function() { return this.modifiable; }, - setModifiable: function( modifiable, mesh ) { + setModifiable: function(modifiable, mesh) { var self = this; self.modifiable = modifiable; - if ( mesh ) self.modifiable.setMesh( mesh ); + if (mesh) self.modifiable.setMesh(mesh); return self; }, - add: function( modifier ) { + add: function(modifier) { var self = this; - if ( modifier ) self.stack.push( modifier ); + if (modifier) self.stack.push(modifier); return self; }, - apply: function( ) { + apply: function() { var self = this, modifiable = self.modifiable, stack = self.stack; - if ( modifiable && stack && stack.length ) + if (modifiable && stack && stack.length) modifiable - .preApply( ) - .resetGeometry( ) - .applyModifiers( stack ) - .postApply( ) - .update( ) + .preApply() + .resetGeometry() + .applyModifiers(stack) + .postApply() + .update() ; return self; }, - collapse: function( ) { - var self = this, modifiable = self.modifiable; - if ( modifiable && self.stack && self.stack.length ) + collapse: function() { + var self = this, modifiable = self.modifiable, stack = self.stack; + if (modifiable && stack && stack.length) { modifiable - .preApply( ) - .resetGeometry( ) - .applyModifiers( self.stack ) - .collapseGeometry( ) - .postApply( ) - .update( ) + .preApply() + .resetGeometry() + .applyModifiers(stack) + .collapseGeometry() + .postApply() + .update() ; - self.stack.length = 0; + stack.length = 0; } return self; }, - clear: function( ) { + clear: function() { var self = this; - if ( self.stack ) self.stack.length = 0; + if (self.stack) self.stack.length = 0; return self; } }); // aliases -ModifierStack.prototype.getMeshInfo = ModifierStack.prototype.getModifiable; -ModifierStack.prototype.addModifier = ModifierStack.prototype.add; - -}(MOD3); \ No newline at end of file +MOD3.ModifierStack.prototype.getMeshInfo = MOD3.ModifierStack.prototype.getModifiable; +MOD3.ModifierStack.prototype.addModifier = MOD3.ModifierStack.prototype.add; diff --git a/src/footer.js b/src/footer.js new file mode 100644 index 0000000..dab487f --- /dev/null +++ b/src/footer.js @@ -0,0 +1,3 @@ +// export it +return MOD3; +}); diff --git a/src/header.js b/src/header.js new file mode 100644 index 0000000..60f3823 --- /dev/null +++ b/src/header.js @@ -0,0 +1,81 @@ +/** +* MOD3 3D Modifier Library for JavaScript +* port of AS3DMod ActionScript3 library (http://code.google.com/p/as3dmod/) +* +* @version @@VERSION@@ (@@DATE@@) +* https://github.com/foo123/MOD3 +* +**/ +!function(root, name, factory) { +"use strict"; +if (('object' === typeof module) && module.exports) /* CommonJS */ + (module.$deps = module.$deps||{}) && (module.exports = module.$deps[name] = factory.call(root)); +else if (('function' === typeof define) && define.amd && ('function' === typeof require) && ('function' === typeof require.specified) && require.specified(name) /*&& !require.defined(name)*/) /* AMD */ + define(name, ['module'], function(module) {factory.moduleUri = module.uri; return factory.call(root);}); +else if (!(name in root)) /* Browser/WebWorker/.. */ + (root[name] = factory.call(root)||1) && ('function' === typeof(define)) && define.amd && define(function() {return root[name];}); +}( /* current root */ 'undefined' !== typeof self ? self : this, + /* module name */ "MOD3", + /* module factory */ function ModuleFactory__MOD3(undef) { +"use strict"; + +var HAS = Object.prototype.hasOwnProperty, + toString = Object.prototype.toString, + def = Object.defineProperty, + stdMath = Math, PI = stdMath.PI, + TWO_PI = 2*PI, HALF_PI = PI/2, INV_PI = 1/PI, + EMPTY_ARR = [], EMPTY_OBJ = {}, NOP = function() {}, + isNode = ("undefined" !== typeof global) && ("[object global]" === toString.call(global)), + isBrowser = ("undefined" !== typeof window) && ("[object Window]" === toString.call(window)) +; + +// basic backwards-compatible "class" construction +function makeSuper(superklass) +{ + var called = {}; + return function $super(method, args) { + var self = this, m = ':'+method, ret; + if (1 === called[m]) return (superklass.prototype.$super || NOP).call(self, method, args); + called[m] = 1; + ret = ('constructor' === method ? superklass : (superklass.prototype[method] || NOP)).apply(self, args || []); + called[m] = 0; + return ret; + }; +} +function makeClass(superklass, klass, statik) +{ + if (arguments.length < 2) + { + klass = superklass; + superklass = null; + } + var C = HAS.call(klass, 'constructor') ? klass.constructor : function() {}, p; + if (superklass) + { + C.prototype = Object.create(superklass.prototype); + C.prototype.$super = makeSuper(superklass); + } + else + { + C.prototype.$super = NOP; + } + C.prototype.constructor = C; + for (p in klass) + { + if (HAS.call(klass, p) && ('constructor' !== p)) + { + C.prototype[p] = klass[p]; + } + } + if (statik) + { + for (p in statik) + { + if (HAS.call(statik, p)) + { + C[p] = statik[p]; + } + } + } + return C; +} diff --git a/src/math/List.js b/src/math/List.js index 99371e3..49bb845 100644 --- a/src/math/List.js +++ b/src/math/List.js @@ -1,22 +1,12 @@ -/** -* -* MOD3 Vector3 Class -* -* -**/ -!function(MOD3, undef){ -@@USE_STRICT@@ - // fast list utilities MOD3.List = { - - operate: function operate( x, F, F0, i0, i1, reverse ) { + operate: function operate(x, F, F0, i0, i1, reverse) { var len = x.length; - if ( arguments.length < 5 ) i1 = len-1; - if ( 0 > i1 ) i1 += len; - if ( arguments.length < 4 ) i0 = 0; - if ( i0 > i1 ) return F0; - if ( true === reverse ) + if (arguments.length < 5) i1 = len-1; + if (0 > i1) i1 += len; + if (arguments.length < 4) i0 = 0; + if (i0 > i1) return F0; + if (true === reverse) { var i, k, l=i1-i0+1, l1=l-1, r=l&15, q=r&1, lr=l1-r, Fv=q?F(F0,x[i1],i1):F0; for (i=l1-q; i>lr; i-=2) { k = i0+i; Fv = F(F(Fv,x[k],k),x[k-1],k-1); } @@ -30,79 +20,77 @@ MOD3.List = { } return Fv; } - - ,each: function each( x, F, i0, i1, reverse ) { - if ( null == x || !x.length ) return x; + + ,each: function each(x, F, i0, i1, reverse) { + if (null == x || !x.length) return x; var len = x.length; - if ( arguments.length < 4 ) i1 = len-1; - if ( 0 > i1 ) i1 += len; - if ( arguments.length < 3 ) i0 = 0; - if ( i0 > i1 ) return x; + if (arguments.length < 4) i1 = len-1; + if (0 > i1) i1 += len; + if (arguments.length < 3) i0 = 0; + if (i0 > i1) return x; var i, k, l=i1-i0+1, l1, lr, r, q; - if ( true === reverse ) + if (true === reverse) { l1=l-1; r=l&15; q=r&1; lr=l1-r; - if ( q ) F( x[i1] ); + if (q) F(x[i1]); for (i=l1-q; i>lr; i-=2) - { + { k = i0+i; - F( x[k ] ); - F( x[k-1] ); + F(x[k ]); + F(x[k-1]); } for (i=lr; i>=0; i-=16) { k = i0+i; - F( x[k ] ); - F( x[k-1] ); - F( x[k-2] ); - F( x[k-3] ); - F( x[k-4] ); - F( x[k-5] ); - F( x[k-6] ); - F( x[k-7] ); - F( x[k-8] ); - F( x[k-9] ); - F( x[k-10] ); - F( x[k-11] ); - F( x[k-12] ); - F( x[k-13] ); - F( x[k-14] ); - F( x[k-15] ); + F(x[k ] ); + F(x[k-1] ); + F(x[k-2] ); + F(x[k-3] ); + F(x[k-4] ); + F(x[k-5] ); + F(x[k-6] ); + F(x[k-7] ); + F(x[k-8] ); + F(x[k-9] ); + F(x[k-10]); + F(x[k-11]); + F(x[k-12]); + F(x[k-13]); + F(x[k-14]); + F(x[k-15]); } } else { r=l&15; q=r&1; - if ( q ) F( x[i0] ); + if (q) F(x[i0]); for (i=q; i= this.start && n <= this.end); }, - normalize: function( n ) { - return normalize( this.start, this.end, n ); + normalize: function(n) { + return MOD3.XMath.normalize(this.start, this.end, n); }, - toRange: function( n ) { - return toRange( this.start, this.end, n ); + toRange: function(n) { + return MOD3.XMath.toRange(this.start, this.end, n); }, - trim: function( n ) { - return trim( this.start, this.end, n ); + trim: function(n) { + return MOD3.XMath.trim(this.start, this.end, n); }, - interpolate: function( n, r ) { - return toRange( this.start, this.end, r.normalize( n ) ); + interpolate: function(n, r) { + return MOD3.XMath.toRange(this.start, this.end, r.normalize(n)); }, - toString: function( ) { + toString: function() { return "[" + this.start + " - " + this.end + "]"; } }); - -}(MOD3); \ No newline at end of file diff --git a/src/math/Vector3.js b/src/math/Vector3.js index d5309e1..6275914 100644 --- a/src/math/Vector3.js +++ b/src/math/Vector3.js @@ -1,113 +1,14 @@ /** -* * MOD3 Vector3 Class -* -* **/ -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Sqrt = Math.sqrt, V = MOD3.VecArray; - -var Vector3 = MOD3.Vector3 = MOD3.Class({ - - // static - __static__: { - - ZERO: function( ) { - return new Vector3( 0, 0, 0 ); - }, - - X: function( direct_or_complement ) { - return false === direct_or_complement ? new Vector3( 0, 1, 1 ) : new Vector3( 1, 0, 0 ); - }, - - Y: function( direct_or_complement ) { - return false === direct_or_complement ? new Vector3( 1, 0, 1 ) : new Vector3( 0, 1, 0 ); - }, - - Z: function( direct_or_complement ) { - return false === direct_or_complement ? new Vector3( 1, 1, 0 ) : new Vector3( 0, 0, 1 ); - }, - - dot: function( v, w ) { - return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; - }, - - equals: function( v, w ) { - return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]); - }, - - cross: function( v, w ) { - var vw = new V(3); - vw[0] = v[1] * w[2] - v[2] * w[1]; - vw[1] = v[2] * w[0] - v[0] * w[2]; - vw[2] = v[0] * w[1] - v[1] * w[0]; - return vw; - }, - - mod: function( v ) { - var x = v[0], y = v[1], z = v[2]; - return Sqrt(x*x + y*y + z*z); - }, - - dist: function( v, w ) { - var dx = v[0] - w[0], - dy = v[1] - w[1], - dz = v[2] - w[2]; - return Sqrt(dx*dx + dy*dy + dz*dz); - }, - - add: function( v, w ) { - v[0] += w[0]; - v[1] += w[1]; - v[2] += w[2]; - return v; - }, - - sub: function( v, w ) { - v[0] -= w[0]; - v[1] -= w[1]; - v[2] -= w[2]; - return v; - }, - - mul: function( v, w ) { - v[0] *= w[0]; - v[1] *= w[1]; - v[2] *= w[2]; - return v; - }, - - muls: function( v, m ) { - v[0] *= m; - v[1] *= m; - v[2] *= m; - return v; - }, - - norm: function( v ) { - var x = v[0], y = v[1], z = v[2], - m = x*x + y*y + z*z, n; - if ( 0 < m ) - { - n = Sqrt(m); - x /= n; - y /= n; - z /= n; - } - v[0] = x; v[1] = y; v[2] = z; - return v; - } - }, - - constructor: function Vector3( x, y, z ) { +MOD3.Vector3 = MOD3.Class(null, { + constructor: function Vector3(x, y, z) { var self = this; - if ( !(self instanceof Vector3) ) return new Vector3( x, y, z ); - + if (!(self instanceof Vector3)) return new Vector3(x, y, z); + // use an internal typed-array for speed - var v = new V(3); - if ( x && (3 === x.length) ) + var v = new MOD3.VecArray(3); + if (x && (3 === x.length)) { // array passed v[0] = x[0] || 0; @@ -123,139 +24,139 @@ var Vector3 = MOD3.Vector3 = MOD3.Class({ } self.xyz = v; }, - + name: "Vector3", xyz: null, - - dispose: function( ) { + + dispose: function() { this.xyz = null; return this; }, - - getXYZ: function( ) { + + getXYZ: function() { // copy it - return new V( this.xyz ); + return new MOD3.VecArray(this.xyz); }, - - getXYZRef: function( ) { + + getXYZRef: function() { return this.xyz; }, - - setXYZ: function( w ) { + + setXYZ: function(w) { var v = this.xyz; v[0] = w[0]; v[1] = w[1]; v[2] = w[2]; return this; }, - - setXYZRef: function( xyz ) { + + setXYZRef: function(xyz) { this.xyz = xyz; return this; }, - - clone: function( ) { - return new Vector3( this.xyz ); + + clone: function() { + return new MOD3.Vector3(this.xyz); }, - equalsSelf: function( b ) { + equalsSelf: function(b) { var v = this.xyz, w = b.xyz; return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]); }, - zeroSelf: function( ) { + zeroSelf: function() { var v = this.xyz; v[0] = 0; v[1] = 0; v[2] = 0; return this; }, - negate: function( ) { + negate: function() { var v = this.xyz; - return new Vector3( -v[0], -v[1], -v[2] ); + return new MOD3.Vector3(-v[0], -v[1], -v[2]); }, - negateSelf: function( ) { + negateSelf: function() { var v = this.xyz; v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2]; return this; }, - add: function( b ) { + add: function(b) { var v = this.xyz, w = b.xyz; - return new Vector3( v[0] + w[0], v[1] + w[1], v[2] + w[2] ); + return new MOD3.Vector3(v[0] + w[0], v[1] + w[1], v[2] + w[2]); }, - addSelf: function( b ) { + addSelf: function(b) { var v = this.xyz, w = b.xyz; v[0] += w[0]; v[1] += w[1]; v[2] += w[2]; return this; }, - subtract: function( b ) { + subtract: function(b) { var v = this.xyz, w = b.xyz; - return new Vector3( v[0] - w[0], v[1] - w[1], v[2] - w[2] ); + return new MOD3.Vector3(v[0] - w[0], v[1] - w[1], v[2] - w[2]); }, - subtractSelf: function( b ) { + subtractSelf: function(b) { var v = this.xyz, w = b.xyz; v[0] -= w[0]; v[1] -= w[1]; v[2] -= w[2]; return this; }, - multiplyScalar: function( s ) { + multiplyScalar: function(s) { var v = this.xyz; - return new Vector3( v[0] * s, v[1] * s, v[2] * s ); + return new MOD3.Vector3(v[0]*s, v[1]*s, v[2]*s); }, - multiplyScalarSelf: function( s ) { + multiplyScalarSelf: function(s) { var v = this.xyz; v[0] *= s; v[1] *= s; v[2] *= s; return this; }, - multiply: function( b ) { + multiply: function(b) { var v = this.xyz, w = b.xyz; - return new Vector3( v[0] * w[0], v[1] * w[1], v[2] * w[2] ); + return new MOD3.Vector3(v[0] * w[0], v[1] * w[1], v[2] * w[2]); }, - multiplySelf: function( b ) { + multiplySelf: function(b) { var v = this.xyz, w = b.xyz; v[0] *= w[0]; v[1] *= w[1]; v[2] *= w[2]; return this; }, - divide: function( s ) { + divide: function(s) { var v = this.xyz; - return new Vector3( v[0] / s, v[1] / s, v[2] / s ); + return new MOD3.Vector3(v[0] / s, v[1] / s, v[2] / s); }, - divideSelf: function( s ) { + divideSelf: function(s) { var v = this.xyz; v[0] /= s; v[1] /= s; v[2] /= s; return this; }, - normalize: function( ) { + normalize: function() { var v = this.xyz, x = v[0], y = v[1], z = v[2], m = x * x + y * y + z * z, n; - if ( 0 < m ) + if (0 < m) { - n = Sqrt(m); + n = stdMath.sqrt(m); x /= n; y /= n; z /= n; } - return new Vector3( x, y, z ); + return new MOD3.Vector3(x, y, z); }, - normalizeSelf: function( ) { + normalizeSelf: function() { var v = this.xyz, x = v[0], y = v[1], z = v[2], m = x * x + y * y + z * z, n; - if ( 0 < m ) + if (0 < m) { - n = Sqrt(m); + n = stdMath.sqrt(m); x /= n; y /= n; z /= n; @@ -264,57 +165,141 @@ var Vector3 = MOD3.Vector3 = MOD3.Class({ return this; }, - getMagnitude: function( ) { + getMagnitude: function() { var v = this.xyz, x = v[0], y = v[1], z = v[2]; - return Sqrt(x*x + y*y + z*z); + return stdMath.sqrt(x*x + y*y + z*z); }, - setMagnitude: function( m ) { - this.normalizeSelf( ); + setMagnitude: function(m) { + this.normalizeSelf(); var v = this.xyz; v[0] *= m; v[1] *= m; v[2] *= m; return this; }, - dot: function( b ) { + dot: function(b) { var v = this.xyz, w = b.xyz; return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; }, - cross: function( b ) { + cross: function(b) { var v = this.xyz, w = b.xyz, - x1 = v[0], y1 = v[1], z1 = v[2], + x1 = v[0], y1 = v[1], z1 = v[2], x2 = w[0], y2 = w[1], z2 = w[2]; - return new Vector3( y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2 ); + return new MOD3.Vector3(y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2); }, - crossSelf: function( v ) { + crossSelf: function(v) { var v = this.xyz, w = b.xyz, - x1 = v[0], y1 = v[1], z1 = v[2], + x1 = v[0], y1 = v[1], z1 = v[2], x2 = w[0], y2 = w[1], z2 = w[2]; - v[0] = y1 * z2 - z1 * y2; - v[1] = z1 * x2 - x1 * z2; + v[0] = y1 * z2 - z1 * y2; + v[1] = z1 * x2 - x1 * z2; v[2] = x1 * y2 - y1 * x2; return this; }, - distance: function( b ) { + distance: function(b) { var v = this.xyz, w = b.xyz, dx = v[0] - w[0], dy = v[1] - w[1], dz = v[2] - w[2]; - return Sqrt(dx*dx + dy*dy + dz*dz); + return stdMath.sqrt(dx*dx + dy*dy + dz*dz); }, - toString: function( ) { + toString: function() { var v = this.xyz; return "[" + v[0] + " , " + v[1] + " , " + v[2] + "]"; } +}, { + ZERO: function() { + return new MOD3.Vector3(0, 0, 0); + }, + + X: function(direct_or_complement) { + return false === direct_or_complement ? new MOD3.Vector3(0, 1, 1) : new MOD3.Vector3(1, 0, 0); + }, + + Y: function(direct_or_complement) { + return false === direct_or_complement ? new MOD3.Vector3(1, 0, 1) : new MOD3.Vector3(0, 1, 0); + }, + + Z: function(direct_or_complement) { + return false === direct_or_complement ? new MOD3.Vector3(1, 1, 0) : new MOD3.Vector3(0, 0, 1); + }, + + dot: function(v, w) { + return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]; + }, + + equals: function(v, w) { + return (v[0] === w[0]) && (v[1] === w[1]) && (v[2] === w[2]); + }, + + cross: function(v, w) { + var vw = new MOD3.VecArray(3); + vw[0] = v[1] * w[2] - v[2] * w[1]; + vw[1] = v[2] * w[0] - v[0] * w[2]; + vw[2] = v[0] * w[1] - v[1] * w[0]; + return vw; + }, + + mod: function(v) { + var x = v[0], y = v[1], z = v[2]; + return stdMath.sqrt(x*x + y*y + z*z); + }, + + dist: function(v, w) { + var dx = v[0] - w[0], + dy = v[1] - w[1], + dz = v[2] - w[2]; + return stdMath.sqrt(dx*dx + dy*dy + dz*dz); + }, + + add: function(v, w) { + v[0] += w[0]; + v[1] += w[1]; + v[2] += w[2]; + return v; + }, + + sub: function(v, w) { + v[0] -= w[0]; + v[1] -= w[1]; + v[2] -= w[2]; + return v; + }, + + mul: function(v, w) { + v[0] *= w[0]; + v[1] *= w[1]; + v[2] *= w[2]; + return v; + }, + + muls: function(v, m) { + v[0] *= m; + v[1] *= m; + v[2] *= m; + return v; + }, + + norm: function(v) { + var x = v[0], y = v[1], z = v[2], + m = x*x + y*y + z*z, n; + if (0 < m) + { + n = stdMath.sqrt(m); + x /= n; + y /= n; + z /= n; + } + v[0] = x; v[1] = y; v[2] = z; + return v; + } }); // alaises -Vector3.modulo = Vector3.mod; -Vector3.distance = Vector3.dist; -Vector3.prototype.dotSelf = Vector3.prototype.dot; -Vector3.prototype.distanceSelf = Vector3.prototype.distance; - -}(MOD3); \ No newline at end of file +MOD3.Vector3.modulo = MOD3.Vector3.mod; +MOD3.Vector3.distance = MOD3.Vector3.dist; +MOD3.Vector3.prototype.dotSelf = MOD3.Vector3.prototype.dot; +MOD3.Vector3.prototype.distanceSelf = MOD3.Vector3.prototype.distance; diff --git a/src/math/XMath.js b/src/math/XMath.js index 80124d3..0e99ca1 100644 --- a/src/math/XMath.js +++ b/src/math/XMath.js @@ -1,67 +1,50 @@ /** -* * MOD3 Math Utilities Class -* -* **/ -!function(MOD3, undef){ -@@USE_STRICT@@ - -// cache constants -var - toRad = MOD3.Constants.toRad, toDeg = MOD3.Constants.toDeg, - Min = Math.min, Max = Math.max, - Pow = Math.pow, Round = Math.round, - Floor = Math.floor, Ceil = Math.ceil, Trim -; - -var XMath = MOD3.XMath = MOD3.StaticClass({ - - normalize: function( start, end, val ) { +MOD3.XMath = { + normalize: function(start, end, val) { var range = end - start; - return 0 === range ? 1 : Trim(0, 1, (val - start) / end); + return 0 === range ? 1 : MOD3.XMath.trim(0, 1, (val - start)/end); }, - toRange: function( start, end, normalized ) { + toRange: function(start, end, normalized) { var range = end - start; - return 0 === range ? 0 : start + range * normalized; + return 0 === range ? 0 : (start + range*normalized); }, - inRange: function( start, end, value, excluding ) { + inRange: function(start, end, value, excluding) { return false !== excluding ? (value >= start && value <= end) : (value > start && value < end); }, - sign: function( val, ifZero ) { - return 0 == val ? ifZero||0 : (val > 0 ? 1 : -1); + sign: function(val, ifZero) { + return 0 === val ? (ifZero || 0) : (val > 0 ? 1 : -1); }, - trim: function( start, end, value ) { + trim: function(start, end, value) { return value < start ? start : (value > end ? end : value); }, - wrap: function( start, end, value ) { - var r = end-start; - return value < start ? value + r : (value >= end ? value - r : value); + wrap: function(start, end, value) { + var r = end - start; + return value < start ? (value + r) : (value >= end ? value - r : value); }, - degToRad: function( deg ) { - return deg * toRad; + degToRad: function(deg) { + return deg/180*PI; }, - radToDeg: function( rad ) { - return rad * toDeg; + radToDeg: function(rad) { + return rad/PI*180; }, - presicion: function( number, precision ) { - var r = Pow( 10, precision ); - return Round( number * r ) / r; + presicion: function(number, precision) { + var r = stdMath.pow(10, precision); + return stdMath.round(number*r)/r; }, - uceil: function( val ) { - return (val < 0) ? Floor(val) : Ceil(val); + uceil: function(val) { + return val < 0 ? stdMath.floor(val) : stdMath.ceil(val); } -}); +}; // alias -Trim = XMath.clamp = XMath.trim; - -}(MOD3); \ No newline at end of file +MOD3.XMath.clamp = MOD3.XMath.trim; diff --git a/src/modifiers/Bend.js b/src/modifiers/Bend.js index b82391c..7c50920 100644 --- a/src/modifiers/Bend.js +++ b/src/modifiers/Bend.js @@ -1,36 +1,27 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Bend Modifier -* -* **/ /**[DOC_MD] - * ###Bend modifier + * ### Bend modifier * * Bends an object along an axis. * * @author Bartek Drozdz * [/DOC_MD]**/ +var stdMath = Math, PI = stdMath.PI, + TWO_PI = 2*PI, HALF_PI = PI/2; -!function(MOD3, undef){ -@@USE_STRICT@@ - -var NONE = MOD3.ModConstant.NONE, LEFT = MOD3.ModConstant.LEFT, RIGHT = MOD3.ModConstant.RIGHT, XYZ = MOD3.XYZi, - Matrix = MOD3.Matrix, Atan = Math.atan, Atan2 = Math.atan2, Sin = Math.sin, Cos = Math.cos, - PI = MOD3.Constants.PI, halfPI = MOD3.Constants.halfPI, doublePI = MOD3.Constants.doublePI, - Max = Math.max, Min = Math.min, each = MOD3.List.each, trans2 = Matrix.transform -; - -var Bend = MOD3.Bend = MOD3.Class ( MOD3.Modifier, { - - constructor: function Bend( force, offset, angle ) { +MOD3.Bend = MOD3.Class(MOD3.Modifier, { + constructor: function Bend(force, offset, angle) { var self = this; - if ( !(self instanceof Bend) ) return new Bend( force, offset, angle ); + if (!(self instanceof Bend)) return new Bend(force, offset, angle); self.$super('constructor'); self.name = 'Bend'; - self.constraint = NONE; + self.constraint = MOD3.ModConstant.NONE; self.switchAxes = false; self.force = force || 0; self.offset = offset || 0; @@ -42,7 +33,7 @@ var Bend = MOD3.Bend = MOD3.Class ( MOD3.Modifier, { angle: 0, switchAxes: false, - dispose: function( ) { + dispose: function() { var self = this; self.force = null; self.offset = null; @@ -52,33 +43,33 @@ var Bend = MOD3.Bend = MOD3.Class ( MOD3.Modifier, { return self; }, - apply: function( modifiable ) { + apply: function(modifiable) { var self = this; - if ( 0 == self.force ) return self; + if (0 === self.force) return self; - var constraint = self.constraint, switchAxes = self.switchAxes, - force = self.force, offset = Min(1, Max(0, self.offset)), a = self.angle, + var constraint = self.constraint, switchAxes = self.switchAxes, + force = self.force, offset = stdMath.min(1, stdMath.max(0, self.offset)), a = self.angle, max = switchAxes ? modifiable.midAxis : modifiable.maxAxis, min = modifiable.minAxis, mid = switchAxes ? modifiable.maxAxis : modifiable.midAxis, - width = modifiable.getSize( max ), - height = modifiable.getSize( mid ), - origin = modifiable.getMin( max ), - //diagAngle = Atan( width / height ), - m1 = new Matrix( ).rotate( a ), - m2 = new Matrix( ).rotate( -a ), + width = modifiable.getSize(max), + height = modifiable.getSize(mid), + origin = modifiable.getMin(max), + //diagAngle = stdMath.atan2(height, width), + m1 = new MOD3.Matrix().rotate(a), + m2 = new MOD3.Matrix().rotate(-a), distance = origin + width * offset, radius = width / PI / force, - bendAngle = doublePI * (width / (radius * doublePI)) + bendAngle = TWO_PI * (width / (radius * TWO_PI)) ; - each(modifiable.vertices, function( v ){ - var xyz = v.getXYZ( ), - vmax = xyz[ XYZ[max] ], - vmid = xyz[ XYZ[mid] ], - vmin = xyz[ XYZ[min] ], - np = trans2( m1, [vmax, vmid] ), + MOD3.List.each(modifiable.vertices, function(v) { + var xyz = v.getXYZ(), + vmax = xyz[MOD3.XYZi[max]], + vmid = xyz[MOD3.XYZi[mid]], + vmin = xyz[MOD3.XYZi[min]], + np = MOD3.Matrix.transform(m1, [vmax, vmid]), p, fa, op, ow, np2 ; vmax = np[0]; vmid = np[1]; @@ -86,30 +77,29 @@ var Bend = MOD3.Bend = MOD3.Class ( MOD3.Modifier, { p = (vmax - origin) / width; if ( - ( (LEFT === constraint) && (p <= offset) ) || - ( (RIGHT === constraint) && (p >= offset) ) + ((MOD3.ModConstant.LEFT === constraint) && (p <= offset)) || + ((MOD3.ModConstant.RIGHT === constraint) && (p >= offset)) ) { /* do nothing */ } else { - fa = (halfPI - bendAngle * offset) + (bendAngle * p); - op = Sin(fa) * (radius + vmin); - ow = Cos(fa) * (radius + vmin); + fa = (HALF_PI - bendAngle * offset) + (bendAngle * p); + op = stdMath.sin(fa) * (radius + vmin); + ow = stdMath.cos(fa) * (radius + vmin); vmin = op - radius; vmax = distance - ow; } - np2 = trans2( m2, [vmax, vmid] ); + np2 = MOD3.Matrix.transform(m2, [vmax, vmid]); vmax = np2[0]; vmid = np2[1]; - xyz[ XYZ[max] ] = vmax; - xyz[ XYZ[mid] ] = vmid; - xyz[ XYZ[min] ] = vmin; - v.setXYZ( xyz ); + xyz[MOD3.XYZi[max]] = vmax; + xyz[MOD3.XYZi[mid]] = vmid; + xyz[MOD3.XYZi[min]] = vmin; + v.setXYZ(xyz); }); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Bloat.js b/src/modifiers/Bloat.js index 4839e44..3cc4950 100644 --- a/src/modifiers/Bloat.js +++ b/src/modifiers/Bloat.js @@ -1,68 +1,61 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Bloat Modifier -* -* **/ /**[DOC_MD] - * ###Bloat modifier + * ### Bloat modifier * * Bloats a mesh by forcing vertices out of specified sphere * * @author makc - * + * [/DOC_MD]**/ +var stdMath = Math; -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Vector3 = MOD3.Vector3, Max = Math.max, Exp = Math.exp, each = MOD3.List.each, - add = Vector3.add, sub = Vector3.sub, mul = Vector3.muls, mod = Vector3.mod, norm = Vector3.norm; - -var Bloat = MOD3.Bloat = MOD3.Class ( MOD3.Modifier, { - - constructor: function Bloat( radius, a, center ) { +MOD3.Bloat = MOD3.Class(MOD3.Modifier, { + constructor: function Bloat(radius, a, center) { var self = this; - if ( !(self instanceof Bloat) ) return new Bloat( radius, a, center ); + if (!(self instanceof Bloat)) return new Bloat(radius, a, center); self.$super('constructor'); self.name = 'Bloat'; self.radius = radius || 0; self.a = null == a ? 0.01 : a; - self.center = center || Vector3.ZERO( ); - //self.u = Vector3.ZERO(); + self.center = center || MOD3.Vector3.ZERO(); + //self.u = MOD3.Vector3.ZERO(); }, - + radius: 0, a: 0.01, center: null, //u: null, - - dispose: function( ) { + + dispose: function() { var self = this; - self.center.dispose( ); + self.center.dispose(); self.center = null; self.radius = null; self.a = null; self.$super('dispose'); return self; }, - - apply: function( modifiable ) { - var self = this, center = self.center.xyz, radius = Max( 0, self.radius ), a = Max( 0, self.a ); - each(modifiable.vertices, function( v ){ + apply: function(modifiable) { + var self = this, center = self.center.xyz, + radius = stdMath.max(0, self.radius), a = stdMath.max(0, self.a); + + MOD3.List.each(modifiable.vertices, function(v) { // get a vector towards vertex // change norm to norm + r * exp (-a * norm) - var uu = sub( v.getXYZ( ), center ), magn = mod( uu ); - mul( norm( uu ), magn + radius * Exp ( - magn * a ) ); + var uu = MOD3.Vector3.sub(v.getXYZ(), center), magn = MOD3.Vector3.mod(uu); + MOD3.Vector3.muls(MOD3.Vector3.norm(uu), magn + radius * stdMath.exp(- magn * a)); // move vertex accordingly - v.setXYZ( add( uu, center ) ); + v.setXYZ(MOD3.Vector3.add(uu, center)); // ?? needed?? //self.u=uu; }); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Break.js b/src/modifiers/Break.js index a154628..c3131f9 100644 --- a/src/modifiers/Break.js +++ b/src/modifiers/Break.js @@ -1,47 +1,40 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Break Modifier -* -* **/ /**[DOC_MD] - * ###Break modifier + * ### Break modifier * * Allow to break a mesh * * @author Bartek Drozdz - * + * [/DOC_MD]**/ +var stdMath = Math; -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Vector3 = MOD3.Vector3, Range = MOD3.Range, Matrix4 = MOD3.Matrix4, - Max = Math.max, Min = Math.min, each = MOD3.List.each, mult4XYZ = Matrix4.multXYZ; - -var Break = MOD3.Break = MOD3.Class ( MOD3.Modifier, { - - constructor: function Break( offset, angle, vector ) { +MOD3.Break = MOD3.Class(MOD3.Modifier, { + constructor: function Break(offset, angle, vector) { var self = this; - if ( !(self instanceof Break) ) return new Break( offset, angle, vector ); + if (!(self instanceof Break)) return new Break(offset, angle, vector); self.$super('constructor'); self.name = 'Break'; self.offset = offset || 0; self.angle = angle || 0; - self.vector = vector || Vector3.Y( ); - self.range = new Range( 0, 1 ); + self.vector = vector || MOD3.Vector3.Y(); + self.range = new MOD3.Range(0, 1); }, - + offset: 0, angle: 0, vector: null, range: null, - - dispose: function( ) { + + dispose: function() { var self = this; - self.vector.dispose( ); - self.range.dispose( ); + self.vector.dispose(); + self.range.dispose(); self.vector = null; self.range = null; self.offset = null; @@ -49,24 +42,23 @@ var Break = MOD3.Break = MOD3.Class ( MOD3.Modifier, { self.$super('dispose'); return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, - offset = Min(1, Max(0, self.offset)), range = self.range, angle = self.angle, - bv = self.vector.normalizeSelf( ).xyz, pv, rm; + offset = stdMath.min(1, stdMath.max(0, self.offset)), range = self.range, angle = self.angle, + bv = self.vector.normalizeSelf().xyz, pv, rm; pv = modifiable.minZ + modifiable.depth*offset; - rm = new Matrix4( ).rotate( bv[ 0 ], bv[ 1 ], bv[ 2 ], angle ); + rm = new MOD3.Matrix4().rotate(bv[0], bv[1], bv[2], angle); - each(modifiable.vertices, function( v ) { - var c = v.getXYZ( ); - c[ 2 ] -= pv; - if ( (0 <= c[ 2 ]) && range.isIn( v.ratio[ 1 ] ) ) mult4XYZ( rm, c ); - c[ 2 ] += pv; - v.setXYZ( c ); + MOD3.List.each(modifiable.vertices, function(v) { + var c = v.getXYZ(); + c[2] -= pv; + if ((0 <= c[2]) && range.isIn(v.ratio[1])) MOD3.Matrix4.multXYZ(rm, c); + c[2] += pv; + v.setXYZ(c); }); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/DisplaceMap.js b/src/modifiers/DisplaceMap.js index 635a01b..191523e 100644 --- a/src/modifiers/DisplaceMap.js +++ b/src/modifiers/DisplaceMap.js @@ -1,61 +1,50 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 DisplaceMap (BitmapDisplacement) Modifier -* -* **/ /**[DOC_MD] - * ###DisplaceMap (BitmapDisplacement) Modifier + * ### DisplaceMap (BitmapDisplacement) Modifier + * + * Displaces vertices based on RGB values of bitmapData pixels. * - * Displaces vertices based on RGB values of bitmapData pixels. - * * BitmapDisplacement is inspired by both the AS3 built-in DisplacementMapFilter. It allows * to use color values for each channels of a bitmap to modify the position of vertices in a mesh. - * - * The displacement takes place along the cardinal axes, and each axis is mapped to a + * + * The displacement takes place along the cardinal axes, and each axis is mapped to a * channel in the bitmap: X for Red, Y for Green and Z for Blue. - * + * * @author Bartek Drozdz - * + * [/DOC_MD]**/ - -!function(MOD3, undef){ -@@USE_STRICT@@ - -var ModConstant = MOD3.ModConstant, NONE = ModConstant.NONE, - X = ModConstant.X, Y = ModConstant.Y, Z = ModConstant.Z, - each = MOD3.List.each -; - -var DisplaceMap = MOD3.DisplaceMap = MOD3.Class ( MOD3.Modifier, { - - constructor: function DisplaceMap( bmp, force, offset ) { +MOD3.DisplaceMap = MOD3.Class(MOD3.Modifier, { + constructor: function DisplaceMap(bmp, force, offset) { var self = this; - if ( !(self instanceof DisplaceMap) ) return new DisplaceMap( bmp, force, offset ); + if (!(self instanceof DisplaceMap)) return new DisplaceMap(bmp, force, offset); self.$super('constructor'); self.name = 'DisplaceMap'; - if ( +bmp == bmp ) // number + if (+bmp === bmp) // number { self.force = bmp || 1; self.offset = null == force ? 127 : force;// 0x7F; } else { - self.setBitmap( bmp ); + self.setBitmap(bmp); self.force = force || 1; self.offset = null == offset ? 127 : offset;// 0x7F; } - self.axes = X | Y | Z; + self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z; }, - + width: null, height: null, bmpData: null, force: 1, offset: 127, - - dispose: function( ) { + + dispose: function() { var self = this; self.bmpData = null; self.width = null; @@ -65,38 +54,37 @@ var DisplaceMap = MOD3.DisplaceMap = MOD3.Class ( MOD3.Modifier, { self.$super('dispose'); return self; }, - - setBitmap: function( bmpData ) { + + setBitmap: function(bmpData) { var self = this; self.bmpData = bmpData ? bmpData.data : null; self.width = bmpData ? bmpData.width : 0; self.height = bmpData ? bmpData.height : 0; return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, axes = self.axes, w = self.width, h = self.height, bmp = self.bmpData, force = self.force, offset = self.offset; - if ( !axes || !bmp ) return self; - - each(modifiable.vertices, function( v ){ - var uv, uu, vv, xyz = v.getXYZ( ); - - uu = ~~( (w - 1) * v.ratio[ 0 ]/* X */ ); - vv = ~~( (h - 1) * v.ratio[ 2 ]/* Z */ ); - uv = ( vv * w + uu ) << 2; - + if (!axes || !bmp) return self; + + MOD3.List.each(modifiable.vertices, function(v) { + var uv, uu, vv, xyz = v.getXYZ(); + + uu = ~~((w - 1) * v.ratio[0]/* X */); + vv = ~~((h - 1) * v.ratio[2]/* Z */); + uv = (vv * w + uu) << 2; + v.setXYZ([ - xyz[ 0 ] + (axes & X ? ((bmp[ uv ] & 0xff) - offset) * force : 0), - xyz[ 1 ] + (axes & Y ? ((bmp[ uv+1 ] & 0xff) - offset) * force : 0), - xyz[ 2 ] + (axes & Z ? ((bmp[ uv+2 ] & 0xff) - offset) * force : 0) + xyz[0] + (axes & MOD3.ModConstant.X ? ((bmp[uv] & 0xff) - offset) * force : 0), + xyz[1] + (axes & MOD3.ModConstant.Y ? ((bmp[uv+1] & 0xff) - offset) * force : 0), + xyz[2] + (axes & MOD3.ModConstant.Z ? ((bmp[uv+2] & 0xff) - offset) * force : 0) ]); }); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Noise.js b/src/modifiers/Noise.js index a26822a..dfcc3a0 100644 --- a/src/modifiers/Noise.js +++ b/src/modifiers/Noise.js @@ -1,44 +1,35 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Noise Modifier -* -* **/ /**[DOC_MD] - * ###Noise modifier + * ### Noise modifier * * Randomly displaces each vertex in all 3 axes * - * + * [/DOC_MD]**/ +var stdMath = Math; -!function(MOD3, undef){ -@@USE_STRICT@@ - -var NONE = MOD3.ModConstant.NONE, - X = MOD3.ModConstant.X, Y = MOD3.ModConstant.Y, Z = MOD3.ModConstant.Z, - Rand = Math.random, each = MOD3.List.each -; - -var Noise = MOD3.Noise = MOD3.Class ( MOD3.Modifier, { - - constructor: function Noise( force ) { +MOD3.Noise = MOD3.Class(MOD3.Modifier, { + constructor: function Noise(force) { var self = this; - if ( !(self instanceof Noise) ) return new Noise( force ); + if (!(self instanceof Noise)) return new Noise(force); self.$super('constructor'); self.name = 'Noise'; self.force = force || 0; self.start = 0; self.end = 1; - self.axes = X | Y | Z; + self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z; }, - + force: 0, start: 0, end: 1, - - dispose: function( ) { + + dispose: function() { var self = this; self.force = null; self.start = null; @@ -46,51 +37,50 @@ var Noise = MOD3.Noise = MOD3.Class ( MOD3.Modifier, { self.$super('dispose'); return self; }, - - setFalloff: function( start, end ) { + + setFalloff: function(start, end) { var self = this; - self.start = start !== undef ? start : 0; - self.end = end !== undef ? end : 1; + self.start = start != null ? start : 0; + self.end = end != null ? end : 1; return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, - axes = self.axes, start = self.start, end = self.end, + axes = self.axes, start = self.start, end = self.end, force = self.force, halfforce = 0.5*force, maxAxis = modifiable.maxAxis; - if ( (0 == axes) || (0 == force) ) return self; - - each( modifiable.vertices, function( v ){ - var r = Rand( ) * force - halfforce, - p = v.getRatio( maxAxis ), rp, xyz; - if ( start < end ) + if ((0 == axes) || (0 == force)) return self; + + MOD3.List.each(modifiable.vertices, function(v) { + var r = stdMath.random() * force - halfforce, + p = v.getRatio(maxAxis), rp, xyz; + if (start < end) { - if ( p < start ) p = 0; - else if ( p > end ) p = 1; - } - else if ( start > end ) + if (p < start) p = 0; + else if (p > end) p = 1; + } + else if (start > end) { p = 1 - p; - if ( p > start ) p = 0; - else if ( p < end ) p = 1; - } - else + if (p > start) p = 0; + else if (p < end) p = 1; + } + else { p = 1; } rp = r * p; - xyz = v.getXYZ( ); - v.setXYZ([ - xyz[ 0 ] + (axes & X ? rp : 0), - xyz[ 1 ] + (axes & Y ? rp : 0), - xyz[ 2 ] + (axes & Z ? rp : 0) + xyz = v.getXYZ(); + v.setXYZ([ + xyz[0] + (axes & MOD3.ModConstant.X ? rp : 0), + xyz[1] + (axes & MOD3.ModConstant.Y ? rp : 0), + xyz[2] + (axes & MOD3.ModConstant.Z ? rp : 0) ]); }); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Perlin.js b/src/modifiers/Perlin.js index 84e98bd..6598fad 100644 --- a/src/modifiers/Perlin.js +++ b/src/modifiers/Perlin.js @@ -1,81 +1,66 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Perlin/Simplex Noise Modifier -* -* **/ /**[DOC_MD] - * ###Perlin modifier + * ### Perlin modifier * * Displaces vertices based on a perlin/simplex noise source. - * + * * Accepts a perlin/simplex noise data (with width and height information) and displaces vertices * based on the value of each point of the noise map. - * + * * @author Bartek Drozdz * * @uses: https://github.com/josephg/noisejs for JavaScript - * + * [/DOC_MD]**/ - -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Vector3 = MOD3.Vector3, round = Math.round, - A = MOD3.VecArray, - ModConstant = MOD3.ModConstant, NONE = ModConstant.NONE, - X = ModConstant.X, Y = ModConstant.Y, Z = ModConstant.Z, - each = MOD3.List.each -; - -function cyclic_shift( a, w, h, dX, dY ) +function cyclic_shift(a, w, h, dX, dY) { - var size = w*h, b = new A( size ), - i, j, i2, j2, index; - if ( dX < 0 ) dX += w; - if ( dY < 0 ) dY += h; + var size = w*h, b = new MOD3.VecArray(size), i, j, i2, j2, index; + if (dX < 0) dX += w; + if (dY < 0) dY += h; dX = ~~dX; dY = ~~dY; - for (i=0,j=0,index=0; index= w ) { i = 0; j++; } + if (i >= w) {i = 0; ++j;} i2 = (i + dX) % w; j2 = (j + dY) % h; - b[ index ] = a[ i2 + j2 * w ]; + b[index] = a[i2 + j2 * w]; } return b; } -/*function generate2d( perlinNoise2d, w, h ) +/*function generate2d(perlinNoise2d, w, h) { - var size = w*h, a = new A( size ), i, j, index; - for (i=0,j=0,index=0; index= w ) { i = 0; j++; } - a[ index ] = perlinNoise2d( i/w, j/h ); + if (i >= w) {i = 0; ++j;} + a[index] = perlinNoise2d(i/w, j/h); } return a; }*/ - -var Perlin = MOD3.Perlin = MOD3.Class ( MOD3.Modifier, { - - constructor: function Perlin( force, noise, autoRun ) { +MOD3.Perlin = MOD3.Class(MOD3.Modifier, { + constructor: function Perlin(force, noise, autoRun) { var self = this; - if ( !(self instanceof Perlin) ) return new Perlin( force, noise, autoRun ); + if (!(self instanceof Perlin)) return new Perlin(force, noise, autoRun); self.$super('constructor'); self.name = 'Perlin'; - self.force = undef!==force ? force : 1; + self.force = null != force ? force : 1; self.perlin = noise; - self.autoRun = undef!==autoRun ? !!autoRun : true; - self.axes = X | Y | Z; + self.autoRun = null != autoRun ? !!autoRun : true; + self.axes = MOD3.ModConstant.X | MOD3.ModConstant.Y | MOD3.ModConstant.Z; }, - + speedX: 1, speedY: 1, perlin: null, force: 1, offset: 0, autoRun: true, - - dispose: function( ) { + + dispose: function() { var self = this; self.perlin = null; self.speedX = null; @@ -84,44 +69,44 @@ var Perlin = MOD3.Perlin = MOD3.Class ( MOD3.Modifier, { self.offset = null; self.autoRun = null; self.$super('dispose'); - + return self; }, - - setSpeed: function( dX, dY ) { + + setSpeed: function(dX, dY) { var self = this; self.speedX = dX; self.speedY = dY; return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, axes = self.axes, force = self.force, offset = self.offset, pn = self.perlin, - w = pn.width, h = pn.height; + w, h; - if ( !axes || !pn ) return self; - if ( self.autoRun ) + if (!axes || !pn) return self; + w = pn.width; h = pn.height; + if (self.autoRun) { - pn = self.perlin = cyclic_shift( pn, w, h, self.speedX, self.speedY ); + pn = self.perlin = cyclic_shift(pn, w, h, self.speedX, self.speedY); pn.width = w; pn.height = h; } - - each(modifiable.vertices, function( v ){ - var xyz = v.getXYZ( ), - uu = ~~( (w - 1) * v.ratio[ 0 ]/* u */ ), - vv = ~~( (h - 1) * v.ratio[ 2 ]/* v */ ), + + MOD3.List.each(modifiable.vertices, function(v) { + var xyz = v.getXYZ(), + uu = ~~((w - 1) * v.ratio[0]/* u */), + vv = ~~((h - 1) * v.ratio[2]/* v */), uv = uu + vv * w; - + v.setXYZ([ - xyz[ 0 ] + (axes & X ? (pn[ uv ] - offset) * force : 0), - xyz[ 1 ] + (axes & Y ? (pn[ uv/*+1*/ ] - offset) * force : 0), - xyz[ 2 ] + (axes & Z ? (pn[ uv/*+2*/ ] - offset) * force : 0) + xyz[0] + (axes & MOD3.ModConstant.X ? (pn[uv] - offset) * force : 0), + xyz[1] + (axes & MOD3.ModConstant.Y ? (pn[uv/*+1*/] - offset) * force : 0), + xyz[2] + (axes & MOD3.ModConstant.Z ? (pn[uv/*+2*/] - offset) * force : 0) ]); }); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Pivot.js b/src/modifiers/Pivot.js index 775fc93..803540b 100644 --- a/src/modifiers/Pivot.js +++ b/src/modifiers/Pivot.js @@ -1,63 +1,54 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Pivot Modifier -* -* **/ /**[DOC_MD] - * ###Pivot modifier + * ### Pivot modifier * * Allows to move the pivot point of a 3D mesh. * * @author Bartek Drozdz - * + * [/DOC_MD]**/ - -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Vector3 = MOD3.Vector3, each = MOD3.List.each, add = Vector3.add; - -var Pivot = MOD3.Pivot = MOD3.Class ( MOD3.Modifier, { - - constructor: function Pivot( x, y, z ) { +MOD3.Pivot = MOD3.Class(MOD3.Modifier, { + constructor: function Pivot(x, y, z) { var self = this; - if ( !(self instanceof Pivot) ) return new Pivot( x, y, z ); + if (!(self instanceof Pivot)) return new Pivot(x, y, z); self.$super('constructor'); self.name = 'Pivot'; - self.vector = new Vector3( x||0, y||0, z||0 ); + self.vector = new MOD3.Vector3(x||0, y||0, z||0); }, - + vector: null, - - dispose: function( ) { + + dispose: function() { var self = this; - self.vector.dispose( ); + self.vector.dispose(); self.vector = null; self.$super('dispose'); return self; }, - - setMeshCenter: function( modifiable ) { + + setMeshCenter: function(modifiable) { var self = this; - self.vector = new Vector3( - -(modifiable.minX + 0.5*modifiable.width), - -(modifiable.minY + 0.5*modifiable.height), + self.vector = new MOD3.Vector3( + -(modifiable.minX + 0.5*modifiable.width), + -(modifiable.minY + 0.5*modifiable.height), -(modifiable.minZ + 0.5*modifiable.depth) ); return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, pivot = self.vector, pv = pivot.xyz; - each(modifiable.vertices, function( v ){ - v.setXYZ( add( v.getXYZ( ), pv ) ); + MOD3.List.each(modifiable.vertices, function(v) { + v.setXYZ(MOD3.Vector3.add(v.getXYZ(), pv)); }); - modifiable.updateMeshPosition( pivot.negate( ) ); + modifiable.updateMeshPosition(pivot.negate()); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Skew.js b/src/modifiers/Skew.js index 0952e8c..99ed2b9 100644 --- a/src/modifiers/Skew.js +++ b/src/modifiers/Skew.js @@ -1,47 +1,36 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Skew Modifier -* -* **/ /**[DOC_MD] - * ###Skew modifier + * ### Skew modifier * * Skew mesh along an axis * * @author Bartek Drozdz - * + * [/DOC_MD]**/ +var stdMath = Math; -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Abs = Math.abs, Pow = Math.pow, Max = Math.max, Min = Math.min, - ModConstant = MOD3.ModConstant, - NONE = ModConstant.NONE, LEFT = ModConstant.LEFT, RIGHT = ModConstant.RIGHT, - X = ModConstant.X, Y = ModConstant.Y, Z = ModConstant.Z, - each = MOD3.List.each -; - -var Skew = MOD3.Skew = MOD3.Class ( MOD3.Modifier, { - - constructor: function Skew( force, offset, power, falloff ) { +MOD3.Skew = MOD3.Class(MOD3.Modifier, { + constructor: function Skew(force, offset, power, falloff) { var self = this; - if ( !(self instanceof Skew) ) return new Skew( force, offset, power, falloff ); + if (!(self instanceof Skew)) return new Skew(force, offset, power, falloff); self.$super('constructor'); self.name = 'Skew'; - self.constraint = NONE; - self.force = force!==undef ? force : 0; - self.offset = offset!==undef ? offset : 0.5; - self.power = power!==undef ? power : 1; - self.falloff = falloff!==undef ? falloff : 1; + self.constraint = MOD3.ModConstant.NONE; + self.force = force != null ? force : 0; + self.offset = offset != null ? offset : 0.5; + self.power = power != null ? power : 1; + self.falloff = falloff != null ? falloff : 1; self.inverseFalloff = false; self.oneSide = false; self.swapAxes = false; self.skewAxis = 0; }, - + force: 0, skewAxis: 0, offset: 0.5, @@ -50,8 +39,8 @@ var Skew = MOD3.Skew = MOD3.Class ( MOD3.Modifier, { inverseFalloff: false, oneSide: false, swapAxes: false, - - dispose: function( ) { + + dispose: function() { var self = this; self.force = null; self.skewAxis = null; @@ -64,46 +53,45 @@ var Skew = MOD3.Skew = MOD3.Class ( MOD3.Modifier, { self.$super('dispose'); return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, - constraint = self.constraint, - skewAxis = self.skewAxis || modifiable.maxAxis, - swapAxes = self.swapAxes, - offset = Min(1, Max(0, self.offset)), - oneSide = self.oneSide, - inverseFalloff = !!self.inverseFalloff, - falloff = Min(1, Max(0, self.falloff)), + constraint = self.constraint, + skewAxis = self.skewAxis || modifiable.maxAxis, + swapAxes = self.swapAxes, + offset = stdMath.min(1, stdMath.max(0, self.offset)), + oneSide = self.oneSide, + inverseFalloff = !!self.inverseFalloff, + falloff = stdMath.min(1, stdMath.max(0, self.falloff)), mirrorfalloff = 1-falloff, - power = self.power, - force = self.force, - displaceAxis = X === skewAxis - ? (swapAxes ? Z : Y) - : (Y === skewAxis - ? (swapAxes ? Z : X) - : (Z === skewAxis - ? (swapAxes ? Y : X) + power = self.power, + force = self.force, + displaceAxis = MOD3.ModConstant.X === skewAxis + ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.Y) + : (MOD3.ModConstant.Y === skewAxis + ? (swapAxes ? MOD3.ModConstant.Z : MOD3.ModConstant.X) + : (MOD3.ModConstant.Z === skewAxis + ? (swapAxes ? MOD3.ModConstant.Y : MOD3.ModConstant.X) : 0)) ; - each(modifiable.vertices, function( v ){ + MOD3.List.each(modifiable.vertices, function(v) { var r, dr, f, p, vRatio; - vRatio = v.getRatio( skewAxis ); - if ( (LEFT === constraint) && (vRatio <= offset) ) return; - if ( (RIGHT === constraint) && (vRatio > offset) ) return; + vRatio = v.getRatio(skewAxis); + if ((MOD3.ModConstant.LEFT === constraint) && (vRatio <= offset)) return; + if ((MOD3.ModConstant.RIGHT === constraint) && (vRatio > offset)) return; r = vRatio - offset; - if ( oneSide && (0 > r) ) r = -r; + if (oneSide && (0 > r)) r = -r; - dr = v.getRatio( displaceAxis ); - if ( inverseFalloff ) dr = 1 - dr; + dr = v.getRatio(displaceAxis); + if (inverseFalloff) dr = 1 - dr; f = falloff + dr * mirrorfalloff; - p = (0 > r ? -1 : 1) * Pow( Abs( r ), power ); - v.setValue( displaceAxis, v.getValue( displaceAxis ) + force * p * f ); + p = (0 > r ? -1 : 1) * stdMath.pow(stdMath.abs(r), power); + v.setValue(displaceAxis, v.getValue(displaceAxis) + force * p * f); }); return self; }, }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Taper.js b/src/modifiers/Taper.js index 19706e4..ba91a86 100644 --- a/src/modifiers/Taper.js +++ b/src/modifiers/Taper.js @@ -1,58 +1,51 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Taper Modifier -* -* **/ /**[DOC_MD] - * ###Taper modifier + * ### Taper modifier * * The taper modifier displaces the vertices on two axes proportionally to their position on the third axis. * * @author Bartek Drozdz - * + * [/DOC_MD]**/ +var stdMath = Math; -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Vector3 = MOD3.Vector3, Matrix4 = MOD3.Matrix4, Pow = Math.pow, - mult = Vector3.mul, mod = Vector3.mod, each = MOD3.List.each, mult4XYZ = Matrix4.multXYZ; - -var Taper = MOD3.Taper = MOD3.Class ( MOD3.Modifier, { - - constructor: function Taper( force, power, v1, v2 ) { +MOD3.Taper = MOD3.Class(MOD3.Modifier, { + constructor: function Taper(force, power, v1, v2) { var self = this; - if ( !(self instanceof Taper) ) return new Taper( force, power, v1, v2 ); + if (!(self instanceof Taper)) return new Taper(force, power, v1, v2); self.$super('constructor'); self.name = 'Taper'; /*self.start = 0; self.end = 1;*/ - self.force = force !== undef ? force : 0; - self.power = power !== undef ? power : 1; - self.vector = v1 || Vector3.Y( false ); - self.vector2 = v2 || Vector3.Y( ); + self.force = force != null ? force : 0; + self.power = power != null ? power : 1; + self.vector = v1 || MOD3.Vector3.Y(false); + self.vector2 = v2 || MOD3.Vector3.Y(); }, - + force: 0, power: 1, /*start: 0, end: 1,*/ vector: null, vector2: null, - + /*setFalloff : function(start, end) { this.start = (start!==undef) ? start : 0; this.end = (end!==undef) ? end : 1; - + return this; },*/ - - dispose: function( ) { + + dispose: function() { var self = this; - self.vector.dispose( ); - self.vector2.dispose( ); + self.vector.dispose(); + self.vector2.dispose(); self.vector = null; self.vector2 = null; self.force = null; @@ -60,24 +53,23 @@ var Taper = MOD3.Taper = MOD3.Class ( MOD3.Modifier, { self.$super('dispose'); return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, vec = self.vector.xyz, vec2 = self.vector2.xyz, - force = self.force, power = self.power, m = new Matrix4( ); - - each(modifiable.vertices, 1 != power - ? function( v ){ - var ar = mod( mult( v.getRatioVector( ), vec2 ) ), sc = force * Pow( ar, power ); - v.setXYZ( mult4XYZ( m.scale( 1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2] ), v.getXYZ( ) ) ); + force = self.force, power = self.power, m = new MOD3.Matrix4(); + + MOD3.List.each(modifiable.vertices, 1 !== power + ? function(v) { + var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * stdMath.pow(ar, power); + v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ())); } - : function( v ){ - var ar = mod( mult( v.getRatioVector( ), vec2 ) ), sc = force * ar; - v.setXYZ( mult4XYZ( m.scale( 1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2] ), v.getXYZ( ) ) ); + : function(v) { + var ar = MOD3.Vector3.mod(MOD3.Vector3.mul(v.getRatioVector(), vec2)), sc = force * ar; + v.setXYZ(MOD3.Matrix4.multXYZ(m.scale(1 + sc * vec[0], 1 + sc * vec[1], 1 + sc * vec[2]), v.getXYZ())); } ); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Twist.js b/src/modifiers/Twist.js index b097e2c..a22bb43 100644 --- a/src/modifiers/Twist.js +++ b/src/modifiers/Twist.js @@ -1,71 +1,61 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Twist Modifier -* -* **/ /**[DOC_MD] - * ###Twist modifier + * ### Twist modifier * * Twist mesh along an axis * Adapted from the Twist modifier for PV3D - * + * [/DOC_MD]**/ - -!function(MOD3, undef){ -@@USE_STRICT@@ - -var Vector3 = MOD3.Vector3, Sqrt = Math.sqrt, Matrix4 = MOD3.Matrix4, - each = MOD3.List.each, mult4 = Matrix4.mult, dotp = Vector3.dot, mod = Vector3.mod; - -var Twist = MOD3.Twist = MOD3.Class ( MOD3.Modifier, { - - constructor: function Twist( angle, vector, center ) { +MOD3.Twist = MOD3.Class(MOD3.Modifier, { + constructor: function Twist(angle, vector, center) { var self = this; - if ( !(self instanceof Twist) ) return new Twist( angle, vector, center ); + if (!(self instanceof Twist)) return new Twist(angle, vector, center); self.$super('constructor'); self.name = 'Twist'; self.angle = angle || 0; - self.vector = vector || Vector3.Y( ); - self.center = center || Vector3.ZERO( ); + self.vector = vector || MOD3.Vector3.Y(); + self.center = center || MOD3.Vector3.ZERO(); }, - + angle: 0, vector: null, center: null, - - dispose: function( ) { + + dispose: function() { var self = this; - self.vector.dispose( ); + self.vector.dispose(); self.vector = null; self.angle = null; - self.center.dispose( ); + self.center.dispose(); self.center = null; self.$super('dispose'); return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, - tvec = self.vector.normalizeSelf( ).xyz, angle = self.angle, center = self.center.xyz, - modulo = mod([0.5*modifiable.maxX, 0.5*modifiable.maxY, 0.5*modifiable.maxZ]), - d = -dotp( tvec, center ), - m1 = new Matrix4( ), m2 = new Matrix4( ) + tvec = self.vector.normalizeSelf().xyz, angle = self.angle, center = self.center.xyz, + modulo = MOD3.Vector3.mod([0.5*modifiable.maxX, 0.5*modifiable.maxY, 0.5*modifiable.maxZ]), + d = -MOD3.Vector3.dot(tvec, center), + m1 = new MOD3.Matrix4(), m2 = new MOD3.Matrix4() ; - each(modifiable.vertices, function( v ){ - var xyz = v.getXYZ( ), - a = (dotp( xyz, tvec ) + d) * angle / modulo, - m = mult4( - m2.rotate( tvec[0], tvec[1], tvec[2], a, true ), - m1.translate( xyz[0], xyz[1], xyz[2], true ) + MOD3.List.each(modifiable.vertices, function(v) { + var xyz = v.getXYZ(), + a = (MOD3.Vector3.dot(xyz, tvec) + d) * angle / modulo, + m = MOD3.Matrix4.mult( + m2.rotate(tvec[0], tvec[1], tvec[2], a, true), + m1.translate(xyz[0], xyz[1], xyz[2], true) ) - ; - v.setXYZ([ m.m[3], m.m[7], m.m[11] ]); + ; + v.setXYZ([m.m[3], m.m[7], m.m[11]]); }); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/modifiers/Wheel.js b/src/modifiers/Wheel.js index 893aada..216a19c 100644 --- a/src/modifiers/Wheel.js +++ b/src/modifiers/Wheel.js @@ -1,127 +1,114 @@ +!function(MOD3) { +"use strict"; /** -* * MOD3 Wheel Modifier -* -* **/ /**[DOC_MD] - * ###Wheel modifier + * ### Wheel modifier * * Use it with vehicle models for wheels. * - * The usual problem with a 3d wheel in a vahicle is that it is - * supposed to turn (steer) and roll in the same time. + * The usual problem with a 3d wheel in a vahicle is that it is + * supposed to turn (steer) and roll in the same time. * So, this code: - * + * * ```javascript * wheel.rotationY = 10; // Steer 10deg to the left - * wheel.rotationZ +- 5; // Roll with a speed of 5 + * wheel.rotationZ += 5; // Roll with a speed of 5 * ``` * This will make the wheel roll incorectly. - * - * A usual way to solve this problem is to put the wheel in another DisplayObject3D/Mesh, + * + * A usual way to solve this problem is to put the wheel in another DisplayObject3D/Mesh, * turn the parent and roll the child, like that: * ```javascript * steer.rotationY = 10; // Steer 10deg to the left - * steer.wheel.rotationZ +- 5; // Roll with a speed of 5 + * steer.wheel.rotationZ += 5; // Roll with a speed of 5 * ``` * That will make the wheel behave correctly. But it can be uncomfortanble to apply, especially * to imported complex Collada models. - * - * The Wheel modifier elegantly solves this problem by doind the proper math in order to steer and roll - * a single mesh at the same time. The only thing you need to do is to specify a steer vector and + * + * The Wheel modifier elegantly solves this problem by doind the proper math in order to steer and roll + * a single mesh at the same time. The only thing you need to do is to specify a steer vector and * roll vector - usually it will be 2 of the cardinal axes. The default value is: - * - * * steer - along the Y axis / new Vector3(0, 1, 0) - * * roll - along the Z axis / new Vector3(0, 0, 1) - * - * + * + * * steer - along the Y axis / new Vector3(0, 1, 0) + * * roll - along the Z axis / new Vector3(0, 0, 1) + * + * * It should work with most car models imported from 3D editors as this is the natural position of a wheel. - * - * Please note, that Papervision primitive cylinder, which may also be used as wheel, will require different axes - * (Y for roll and Z or X for steer). - * + * + * *Please note, that Papervision primitive cylinder, which may also be used as wheel, will require different axes + * (Y for roll and Z or X for steer).* + * * @author Bartek Drozdz * [/DOC_MD]**/ - -!function(MOD3, undef){ -@@USE_STRICT@@ - -var invPI = MOD3.Constants.invPI, - doublePI = MOD3.Constants.doublePI, - Vector3 = MOD3.Vector3, Matrix4 = MOD3.Matrix4, each = MOD3.List.each, - mult4XYZ = Matrix4.multXYZ -; - -var Wheel = MOD3.Wheel = MOD3.Class( MOD3.Modifier, { - - constructor: function Wheel( speed, turn, roll, steerVector, rollVector ) { +MOD3.Wheel = MOD3.Class(MOD3.Modifier, { + constructor: function Wheel(speed, turn, roll, steerVector, rollVector) { var self = this; - if ( !(self instanceof Wheel) ) return new Wheel( speed, turn, roll, steerVector, rollVector ); + if (!(self instanceof Wheel)) return new Wheel(speed, turn, roll, steerVector, rollVector); self.$super('constructor'); self.name = 'Wheel'; self.speed = speed || 0; self.turn = turn || 0; self.roll = roll || 0; - self.steerVector = steerVector || Vector3.Y( ); - self.rollVector = rollVector || Vector3.Z( ); + self.steerVector = steerVector || MOD3.Vector3.Y(); + self.rollVector = rollVector || MOD3.Vector3.Z(); }, - + speed: 0, turn: 0, roll: 0, steerVector: null, rollVector: null, - - dispose: function( ) { + + dispose: function() { var self = this; self.speed = null; self.turn = null; self.roll = null; - self.steerVector.dispose( ); - self.rollVector.dispose( ); + self.steerVector.dispose(); + self.rollVector.dispose(); self.steerVector = null; self.rollVector = null; self.$super('dispose'); - + return self; }, - - apply: function( modifiable ) { + + apply: function(modifiable) { var self = this, - steerVector = self.steerVector.normalizeSelf(), - rollVector = self.rollVector.normalizeSelf(), + steerVector = self.steerVector.normalizeSelf(), + rollVector = self.rollVector.normalizeSelf(), turn = self.turn, roll = self.roll, //radius = 0.5*modifiable.width, - //step = radius * self.speed * invPI, - //perimeter = radius * doublePI, + //step = radius * self.speed / PI, + //perimeter = radius * TWO_PI, ms = null, mt = null ; - + self.roll += self.speed; - - if ( turn ) + + if (turn) { - mt = new Matrix4( ).rotateFromVector( steerVector, turn ); - ms = new Matrix4( ).rotateFromVector( mt.multiplyVector( rollVector.clone( ) ), roll ); - } - else + mt = new MOD3.Matrix4().rotateFromVector(steerVector, turn); + ms = new MOD3.Matrix4().rotateFromVector(mt.multiplyVector(rollVector.clone()), roll); + } + else { - ms = new Matrix4( ).rotateFromVector( rollVector, roll ); + ms = new MOD3.Matrix4().rotateFromVector(rollVector, roll); } - each(modifiable.vertices, mt - ? function( v ){ - v.setXYZ( mult4XYZ( ms, mult4XYZ( mt, v.getXYZ( ) ) ) ); + MOD3.List.each(modifiable.vertices, mt + ? function(v) { + v.setXYZ(MOD3.Matrix4.multXYZ(ms, MOD3.Matrix4.multXYZ(mt, v.getXYZ()))); } - : function( v ){ - v.setXYZ( mult4XYZ( ms, v.getXYZ( ) ) ); + : function(v) { + v.setXYZ(MOD3.Matrix4.multXYZ(ms, v.getXYZ())); } ); return self; } }); - }(MOD3); \ No newline at end of file diff --git a/src/plugins/Copperlicht/Copperlicht.js b/src/plugins/Copperlicht/Copperlicht.js index dbc0071..8cb56e3 100644 --- a/src/plugins/Copperlicht/Copperlicht.js +++ b/src/plugins/Copperlicht/Copperlicht.js @@ -11,118 +11,119 @@ var ModConstant = MOD3.ModConstant, X = ModConstant.X, Y = ModConstant.Y, Z = ModConstant.Z, XYZ = MOD3.XYZ, XYZi = MOD3.XYZi, V = MOD3.VecArray, each = MOD3.List.each, - VertexCopperlicht, MeshCopperlicht -; + VertexCopperlicht, MeshCopperlicht; -VertexCopperlicht = MOD3.VertexCopperlicht = MOD3.Class( MOD3.VertexProxy, { - - constructor: function VertexCopperlicht( vertex, mesh ) { +VertexCopperlicht = MOD3.Class(MOD3.VertexProxy, { + constructor: function VertexCopperlicht(vertex, mesh) { var self = this; - self.$super('constructor', vertex, mesh); + self.$super('constructor', [vertex, mesh]); self.name = "VertexCopperlicht"; }, - - setVertex: function( vt ) { + + setVertex: function(vt) { var self = this; self.vertex = vt; - self.original = new V( [vt.X, vt.Y, vt.Z] ); + self.original = new V([vt.X, vt.Y, vt.Z]); return self; }, - - getXYZ: function( ) { + + getXYZ: function() { var vt = this.vertex, xyz = new V(3); xyz[0] = vt.X; xyz[1] = vt.Y; xyz[2] = vt.Z; return xyz; }, - - getX: function( ) { + + getX: function() { return this.vertex.X; }, - - getY: function( ) { + + getY: function() { return this.vertex.Y; }, - - getZ: function( ) { + + getZ: function() { return this.vertex.Z; }, - - getValue: function( axis ) { - return this.vertex[ XYZ[XYZi[axis]] ] || 0; + + getValue: function(axis) { + return this.vertex[XYZ[XYZi[axis]]] || 0; }, - setXYZ: function( xyz ) { + setXYZ: function(xyz) { var vt = this.vertex; vt.X = xyz[0]; vt.Y = xyz[1]; vt.Z = xyz[2]; return self; }, - - setX: function( vo ) { + + setX: function(vo) { this.vertex.X = vo; return this; }, - - setY: function( vo ) { + + setY: function(vo) { this.vertex.Y = vo; return this; }, - - setZ: function( vo ) { + + setZ: function(vo) { this.vertex.Z = vo; return this; }, - setValue: function( axis, vo ) { - this.vertex[ XYZ[XYZi[axis]] ] = vo; + setValue: function(axis, vo) { + this.vertex[XYZ[XYZi[axis]]] = vo; return this; }, - - reset: function( ) { + + reset: function() { var self = this, vt = self.vertex, o = self.original; vt.X = o[0]; vt.Y = o[1]; vt.Z = o[2]; return self; }, - collapse: function( ) { + collapse: function() { var self = this, vt = self.vertex, o = self.original; o[0] = vt.X; o[1] = vt.Y; o[2] = vt.Z; return self; } }); -MeshCopperlicht = MOD3.MeshCopperlicht = MOD3.Class( MOD3.MeshProxy, { - - constructor: function MeshCopperlicht( mesh ) { +MeshCopperlicht = MOD3.Class(MOD3.MeshProxy, { + constructor: function MeshCopperlicht(mesh) { var self = this; - self.$super('constructor', mesh); + self.$super('constructor', [mesh]); self.name = "MeshCopperlicht"; }, - - init: function( mesh ) { + + init: function(mesh) { var self = this; - self.$super('init', mesh); - + self.$super('init', [mesh]); + var i, b, bl, buffers = self.mesh.getMesh().GetMeshBuffers(), vertices, vs, vc, nv; - + self.faces = null; self.vertices = vertices = []; - for (b=0,bl=buffers.length; bi;i++)for(n=0,o=c[i].Vertices,h=o.length;h>n;n++)u.push(new r(o[n].Pos,e));return e},update:function(){var t=this;return h(t.mesh.getMesh().GetMeshBuffers(),function(t){t.update(!0)}),t},updateMeshPosition:function(t){var e=this,r=e.mesh.Pos,n=t.xyz;return r.X+=n[0],r.Y+=n[1],r.Z+=n[2],e}}),t.LibraryCopperlicht={id:"Copperlicht",Mesh:n,Vertex:r}}(MOD3); \ No newline at end of file +!function(t){"use strict";var e=t.ModConstant,r=(e.X,e.Y,e.Z,t.XYZ),n=t.XYZi,s=t.VecArray,i=t.List.each,c=t.Class(t.VertexProxy,{constructor:function(t,e){this.$super("constructor",[t,e]),this.name="VertexCopperlicht"},setVertex:function(t){var e=this;return e.vertex=t,e.original=new s([t.X,t.Y,t.Z]),e},getXYZ:function(){var t=this.vertex,e=new s(3);return e[0]=t.X,e[1]=t.Y,e[2]=t.Z,e},getX:function(){return this.vertex.X},getY:function(){return this.vertex.Y},getZ:function(){return this.vertex.Z},getValue:function(t){return this.vertex[r[n[t]]]||0},setXYZ:function(t){var e=this.vertex;return e.X=t[0],e.Y=t[1],e.Z=t[2],self},setX:function(t){return this.vertex.X=t,this},setY:function(t){return this.vertex.Y=t,this},setZ:function(t){return this.vertex.Z=t,this},setValue:function(t,e){return this.vertex[r[n[t]]]=e,this},reset:function(){var t=this,e=t.vertex,r=t.original;return e.X=r[0],e.Y=r[1],e.Z=r[2],t},collapse:function(){var t=this,e=t.vertex,r=t.original;return r[0]=e.X,r[1]=e.Y,r[2]=e.Z,t}}),e=t.Class(t.MeshProxy,{constructor:function(t){this.$super("constructor",[t]),this.name="MeshCopperlicht"},init:function(t){var e=this;e.$super("init",[t]);var r,n,s,i,u,o,h=e.mesh.getMesh().GetMeshBuffers();for(e.faces=null,e.vertices=i=[],n=0,s=h.length;ni;i++)n[i]=new r(s[i],e);return e},update:function(){var t=this;return t.mesh.dirty=!0,t},updateMeshPosition:function(t){var e=this,r=e.mesh.position,n=t.xyz;return r[0]+=n[0],r[1]+=n[1],r[2]+=n[2],e}}),t.LibraryCubicVR={id:"CubicVR",Mesh:n,Vertex:r}}(MOD3); \ No newline at end of file +!function(t){"use strict";var e=t.ModConstant,r=(e.X,e.Y,e.Z,t.XYZi),n=t.VecArray,u=t.Class(t.VertexProxy,{constructor:function(t,e){this.$super("constructor",[t,e]),this.name="VertexCubicVR"},setVertex:function(t){var e=this;return e.vertex=t,e.original=new n([t[0],t[1],t[2]]),e},getXYZ:function(){var t=this.vertex,e=new n(3);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e},getX:function(){return this.vertex[0]},getY:function(){return this.vertex[1]},getZ:function(){return this.vertex[2]},getValue:function(t){return this.vertex[r[t]]||0},setXYZ:function(t){var e=this.vertex;return e[0]=t[0],e[1]=t[1],e[2]=t[2],this},setX:function(t){return this.vertex[0]=t,this},setY:function(t){return this.vertex[1]=t,this},setZ:function(t){return this.vertex[2]=t,this},setValue:function(t,e){return this.vertex[r[t]]=e,this},reset:function(){var t=this,e=t.vertex,r=t.original;return e[0]=r[0],e[1]=r[1],e[2]=r[2],t},collapse:function(){var t=this,e=t.vertex,r=t.original;return r[0]=e[0],r[1]=e[1],r[2]=e[2],t}}),e=t.Class(t.MeshProxy,{constructor:function(t){this.$super("constructor",[t]),this.name="MeshCubicVR"},init:function(t){var e=this;e.$super("init",[t]);var r,n,i=t.obj.points,s=i.length;for(e.faces=null,e.vertices=r=new Array(s),n=0;ns;s+=c)i[n++]=new r(s,t);return t},update:function(){var e=this,t=e.mesh.geometry,r=t.arraysByName[J3D.Mesh.VERTEX_POSITION],s=r.data;return t.replaceArray(r,s),e},preApply:function(){var e=this;return e.v=e.mesh.geometry.arraysByName[J3D.Mesh.VERTEX_POSITION].data,e},postApply:function(){var e=this;return e.v=null,e}}),e.LibraryJ3D={id:"J3D",Mesh:s,Vertex:r}}(MOD3); \ No newline at end of file +!function(t){"use strict";var e=t.ModConstant,r=(e.X,e.Y,e.Z,t.XYZi),s=t.VecArray,u=Math.ceil,a=t.Class(t.VertexProxy,{constructor:function(t,e){this.$super("constructor",[t,e]),this.name="VertexJ3D"},setVertex:function(t){var e=this,r=e.mesh.mesh.geometry.arraysByName[J3D.Mesh.VERTEX_POSITION].data;return e.vertex=t,e.original=new s([r[t],r[t+1],r[t+2]]),e},getXYZ:function(){var t=this.vertex,e=this.mesh.v,r=new s(3);return r[0]=e[t],r[1]=e[t+1],r[2]=e[t+2],r},getX:function(){return this.mesh.v[this.vertex]},getY:function(){return this.mesh.v[this.vertex+1]},getZ:function(){return this.mesh.v[this.vertex+2]},getValue:function(t){return this.mesh.v[this.vertex+r[t]]||0},setXYZ:function(t){var e=this,r=e.vertex,s=e.mesh.v;return s[r]=t[0],s[r+1]=t[1],s[r+2]=t[2],e},setX:function(t){return this.mesh.v[this.vertex]=t,this},setY:function(t){return this.mesh.v[this.vertex+1]=t,this},setZ:function(t){return this.mesh.v[this.vertex+2]=t,this},setValue:function(t,e){return this.mesh.v[this.vertex+r[t]]=e,this},reset:function(){var t=this,e=t.vertex,r=t.mesh.v,s=t.original;return r[e]=s[0],r[e+1]=s[1],r[e+2]=s[2],t},collapse:function(){var t=this,e=t.vertex,r=t.mesh.v,s=t.original;return s[0]=r[e],s[1]=r[e+1],s[2]=r[e+2],t}}),e=t.Class(t.MeshProxy,{constructor:function(t){this.$super("constructor",[t]),this.name="MeshJ3D"},init:function(t){var e=this;e.$super("init",[t]);var r,s,n,t=t.geometry.arraysByName[J3D.Mesh.VERTEX_POSITION],i=t.data.length,h=t.itemSize;for(e.faces=null,e.vertices=n=new Array(u(i/h)),r=s=0;r 0 && ii > 2 ) + if (vc > 0 && ii > 2) { - self.vertices = vertices = new Array( ceil(vc/ii) ); - for (j=0,i=0; i0&&c>2)for(e.vertices=s=new Array(u(o/c)),i=0,n=0;o>n;n+=c)s[i++]=new r(n,e);else e.vertices=[];return e},update:function(){var t=this;return t.mesh.getVertexAttributeList().Vertex.dirty(),t.mesh.dirtyBound(),t},preApply:function(){var t=this;return t.v=t.mesh.getVertexAttributeList().Vertex.getElements(),t},postApply:function(){var t=this;return t.v=null,t}}),t.LibraryOSG={id:"OSG",Mesh:s,Vertex:r}}(MOD3); \ No newline at end of file +!function(t){"use strict";var e=t.ModConstant,r=(e.X,e.Y,e.Z,t.XYZi),s=t.VecArray,u=Math.ceil,o=t.Class(t.VertexProxy,{constructor:function(t,e){this.$super("constructor",[t,e]),this.name="VertexOSG"},setVertex:function(t){var e=this,r=e.mesh.mesh.getVertexAttributeList().Vertex.getElements();return e.vertex=t,e.original=new s([r[t],r[t+1],r[t+2]]),e},getXYZ:function(){var t=this.vertex,e=this.mesh.v,r=new s(3);return r[0]=e[t],r[1]=e[t+1],r[2]=e[t+2],r},getX:function(){return this.mesh.v[this.vertex]},getY:function(){return this.mesh.v[this.vertex+1]},getZ:function(){return this.mesh.v[this.vertex+2]},getValue:function(t){return this.mesh.v[this.vertex+r[t]]||0},setXYZ:function(t){var e=this,r=e.vertex,s=e.mesh.v;return s[r]=t[0],s[r+1]=t[1],s[r+2]=t[2],e},setX:function(t){return this.mesh.v[this.vertex]=t,this},setY:function(t){return this.mesh.v[this.vertex+1]=t,this},setZ:function(t){return this.mesh.v[this.vertex+2]=t,this},setValue:function(t,e){return this.mesh.v[this.vertex+r[t]]=e,this},reset:function(){var t=this,e=t.vertex,r=t.mesh.v,s=t.original;return r[e]=s[0],r[e+1]=s[1],r[e+2]=s[2],t},collapse:function(){var t=this,e=t.vertex,r=t.mesh.v,s=t.original;return s[0]=r[e],s[1]=r[e+1],s[2]=r[e+2],t}}),e=t.Class(t.MeshProxy,{constructor:function(t){this.$super("constructor",[t]),this.name="MeshOSG"},init:function(t){var e=this;e.$super("init",[t]);var r,s,i,t=(t=e.mesh).getVertexAttributeList().Vertex,n=(t&&t.getElements()||[]).length,h=t?t.getItemSize():0;if(e.faces=null,0i;i++)n[i]=new r(s[i],e);return e}}),t.LibraryPre3D={id:"Pre3D",Mesh:n,Vertex:r}}(MOD3); \ No newline at end of file +!function(t){"use strict";var e=t.ModConstant,r=(e.X,e.Y,e.Z,t.xyz),n=t.XYZi,i=t.VecArray,u=t.Class(t.VertexProxy,{constructor:function(t,e){this.$super("constructor",[t,e]),this.name="VertexPre3D"},setVertex:function(t){var e=this;return e.vertex=t,e.original=new i([t.x,t.y,t.z]),e},getXYZ:function(){var t=this.vertex,e=new i(3);return e[0]=t.x,e[1]=t.y,e[2]=t.z,e},getX:function(){return this.vertex.x},getY:function(){return this.vertex.y},getZ:function(){return this.vertex.z},getValue:function(t){return this.vertex[r[n[t]]]||0},setXYZ:function(t){var e=this.vertex;return e.x=t[0],e.y=t[1],e.z=t[2],this},setX:function(t){return this.vertex.x=t,this},setY:function(t){return this.vertex.y=t,this},setZ:function(t){return this.vertex.z=t,this},setValue:function(t,e){return this.vertex[r[n[t]]]=e,self},reset:function(){var t=this,e=t.vertex,r=t.original;return e.x=r[0],e.y=r[1],e.z=r[2],t},collapse:function(){var t=this,e=t.vertex,r=t.original;return r[0]=e.x,r[1]=e.y,r[2]=e.z,t}}),e=t.Class(t.MeshProxy,{constructor:function(t){this.$super("constructor",[t]),this.name="MeshPre3D"},init:function(t){var e=this;e.$super("init",[t]);var r,n,i=e.mesh.vertices,s=i.length;for(e.faces=null,e.vertices=r=new Array(s),n=0;ns;s++)n[s]=new r(i[s],t);return t},update:function(){var e=this,t=e.mesh.geometry;return t.verticesNeedUpdate=!0,t.elementsNeedUpdate=!0,t.uvsNeedUpdate=!0,t.normalsNeedUpdate=!0,t.colorsNeedUpdate=!0,t.lineDistancesNeedUpdate=!0,t.groupsNeedUpdate=!0,t.buffersNeedUpdate=!0,t.dynamic=!0,e},updateMeshPosition:function(e){var t=this,r=t.mesh.position,n=e.xyz;return r.x+=n[0],r.y+=n[1],r.z+=n[2],t}}),e.LibraryThree={id:"Three",Mesh:n,Vertex:r}}(MOD3); \ No newline at end of file +!function(e){"use strict";var t=e.ModConstant,r=(t.X,t.Y,t.Z,e.xyz),n=e.XYZi,i=e.VecArray,u=e.Class(e.VertexProxy,{constructor:function(e,t){this.$super("constructor",[e,t]),this.name="VertexThree"},setVertex:function(e){var t=this;return t.vertex=e,t.original=new i([e.x,e.y,e.z]),t},getXYZ:function(){var e=this.vertex,t=new i(3);return t[0]=e.x,t[1]=e.y,t[2]=e.z,t},getX:function(){return this.vertex.x},getY:function(){return this.vertex.y},getZ:function(){return this.vertex.z},getValue:function(e){return this.vertex[r[n[e]]]||0},setXYZ:function(e){var t=this.vertex;return t.x=e[0],t.y=e[1],t.z=e[2],this},setX:function(e){return this.vertex.x=e,this},setY:function(e){return this.vertex.y=e,this},setZ:function(e){return this.vertex.z=e,this},setValue:function(e,t){return this.vertex[r[n[e]]]=t,this},reset:function(){var e=this,t=e.vertex,r=e.original;return t.x=r[0],t.y=r[1],t.z=r[2],e},collapse:function(){var e=this,t=e.vertex,r=e.original;return r[0]=t.x,r[1]=t.y,r[2]=t.z,e}}),t=e.Class(e.MeshProxy,{constructor:function(e){this.$super("constructor",[e]),this.name="MeshThree"},init:function(e){var t=this;t.$super("init",[e]);var r,n,i=(e=t.mesh).geometry.vertices,s=i.length;for(t.faces=null,t.vertices=r=new Array(s),n=0;n