| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| !function(root, name, factory) { |
| "use strict"; |
| if (('object' === typeof module) && module.exports) |
| (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) ) |
| define(name, ['module'], function(module) {factory.moduleUri = module.uri; return factory.call(root);}); |
| else if (!(name in root)) |
| (root[name] = factory.call(root)||1) && ('function' === typeof(define)) && define.amd && define(function() {return root[name];}); |
| }( 'undefined' !== typeof self ? self : this, |
| "MOD3", |
| 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)) |
| ; |
|
|
| |
| 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 = { |
| |
| 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" |
| ]; |
|
|
| |
| 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; |
| |
| MOD3.VecArray = MOD3.Array32F; |
| |
| |
| |
| 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); |
| } |
| }; |
| |
| MOD3.XMath.clamp = MOD3.XMath.trim; |
| |
| |
| |
| 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 = 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.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.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 = MOD3.Class(null, { |
| constructor: function Vector3(x, y, z) { |
| var self = this; |
| if (!(self instanceof Vector3)) return new Vector3(x, y, z); |
|
|
| |
| var v = new MOD3.VecArray(3); |
| if (x && (3 === x.length)) |
| { |
| |
| v[0] = x[0] || 0; |
| v[1] = x[1] || 0; |
| v[2] = x[2] || 0; |
| } |
| else |
| { |
| |
| 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() { |
| |
| 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; |
| } |
| }); |
| |
| 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.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; |
| } |
| }); |
| |
| 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; |
| |
| 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<r; i+=2) { k = i0+i; Fv = F(F(Fv,x[k],k),x[k+1],k+1); } |
| for (i=r; i<l; 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); } |
| } |
| return Fv; |
| } |
|
|
| ,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; |
| 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<r; i+=2) |
| { |
| k = i0+i; |
| F(x[k ]); |
| F(x[k+1]); |
| } |
| for (i=r; i<l; 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]); |
| } |
| } |
| return x; |
| } |
| }; |
| |
| |
| |
| 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() { |
| var self = this; |
| self.vertices = null; |
| return self; |
| }, |
|
|
| addVertex: function(v) { |
| this.vertices.push(v); |
| }, |
|
|
| getVertices: function() { |
| return this.vertices; |
| } |
| }); |
|
|
| MOD3.VertexProxy = MOD3.Class(null, { |
| constructor: function VertexProxy(vertex, mesh) { |
| var self = this; |
| self.mesh = mesh || null; |
| |
| self.original = new MOD3.VecArray([0,0,0]); |
| self.ratio = new MOD3.VecArray([0,0,0]); |
| |
| if (null != vertex) self.setVertex(vertex); |
| }, |
|
|
| name: "VertexProxy", |
| mesh: null, |
| vertex: null, |
| original: null, |
| ratio: null, |
|
|
| dispose: function() { |
| var self = this; |
| self.mesh = null; |
| self.vertex = null; |
| self.original = null; |
| self.ratio = null; |
| return self; |
| }, |
|
|
| setVertex: function(vt) { |
| |
| var self = this; |
| self.vertex = vt; |
| return self; |
| }, |
|
|
| 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[MOD3.XYZi[axis]] || 0; |
| }, |
|
|
| setRatios: function(rx, ry, rz) { |
| var r = this.ratio; |
| r[0] = rx || 0; |
| r[1] = ry || 0; |
| r[2] = rz || 0; |
| return this; |
| }, |
|
|
| getOriginalValue: function(axis) { |
| return this.original[MOD3.XYZi[axis]] || 0; |
| }, |
|
|
| setOriginalPosition: function(ox, oy, oz) { |
| var o = this.original; |
| o[0] = ox || 0; |
| o[1] = oy || 0; |
| o[2] = oz || 0; |
| return this; |
| }, |
|
|
| getXYZ: function() { |
| |
| return new MOD3.VecArray([0,0,0]); |
| }, |
|
|
| getX: function() { |
| |
| return 0; |
| }, |
|
|
| getY: function() { |
| |
| return 0; |
| }, |
|
|
| getZ: function() { |
| |
| return 0; |
| }, |
|
|
| getValue: function(axis) { |
| var self = this; |
| |
| return MOD3.ModConstant.X === axis |
| ? self.getX() |
| : (MOD3.ModConstant.Y === axis |
| ? self.getY() |
| : (MOD3.ModConstant.Z === axis |
| ? self.getZ() |
| : 0)) |
| ; |
| }, |
|
|
| setXYZ: function(xyz) { |
| |
| return this; |
| }, |
|
|
| setX: function(vo) { |
| |
| return this; |
| }, |
|
|
| setY: function(vo) { |
| |
| return this; |
| }, |
|
|
| setZ: function(vo) { |
| |
| return this; |
| }, |
|
|
| setValue: function(axis, vo) { |
| var self = this; |
| |
| 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() { |
| |
| var self = this; |
| self.setXYZ(self.original); |
| return self; |
| }, |
|
|
| collapse: function() { |
| |
| var self = this, xyz = self.getXYZ(), o = self.original; |
| o[0] = xyz[0]; o[1] = xyz[1]; o[2] = xyz[2]; |
| return self; |
| } |
| }); |
|
|
| 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); |
| }, |
|
|
| 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 self = this; |
| self.maxX = null; |
| self.maxY = null; |
| self.maxZ = null; |
| 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.mesh = null; |
| self.v = null; |
| return self; |
| }, |
|
|
| disposeVertices: function() { |
| var self = this; |
| if (self.vertices) MOD3.List.each(self.vertices, dispose); |
| self.vertices = null; |
| return self; |
| }, |
|
|
| disposeFaces: function() { |
| var self = this; |
| if (self.faces) MOD3.List.each(self.faces, dispose); |
| self.faces = null; |
| return self; |
| }, |
|
|
| init: function(mesh) { |
| var self = this; |
| self.mesh = mesh; |
| |
| |
| |
| return self; |
| }, |
|
|
| setMesh: function(mesh) { |
| var self = this; |
| self.init(mesh); |
| self.preApply(); |
| self.analyzeGeometry() |
| self.postApply(); |
| return self; |
| }, |
|
|
| getVertices: function() { |
| return this.vertices; |
| }, |
|
|
| getFaces: function() { |
| return this.faces; |
| }, |
|
|
| applyModifiers: function(modStack) { |
| var self = this, sl, i; |
| for (i=0,sl=modStack.length; i<sl; ++i) |
| { |
| modStack[i].enabled && modStack[i].apply(self); |
| } |
| return self; |
| }, |
|
|
| analyzeGeometry: function() { |
| var self = this, |
| vertices = self.vertices, |
| minX = 0, minY = 0, minZ = 0, |
| maxX = 0, maxY = 0, maxZ = 0, |
| width = 0, height = 0, depth = 0, |
| maxe, mine, w |
| ; |
| if (!vertices || !vertices.length) return self; |
|
|
| w = vertices[0].getXYZ(); |
| minX = w[0]; |
| minY = w[1]; |
| minZ = w[2]; |
|
|
| maxX = w[0]; |
| maxY = w[1]; |
| maxZ = w[2]; |
|
|
| MOD3.List.each(vertices, function(v) { |
| var xyz = v.getXYZ(), x = xyz[0], y = xyz[1], z = xyz[2]; |
| minX = stdMath.min(minX, x); |
| minY = stdMath.min(minY, y); |
| minZ = stdMath.min(minZ, z); |
|
|
| maxX = stdMath.max(maxX, x); |
| maxY = stdMath.max(maxY, y); |
| maxZ = stdMath.max(maxZ, z); |
| v.setOriginalPosition(x, y, z); |
| }); |
|
|
| width = maxX - minX; |
| height = maxY - minY; |
| depth = maxZ - minZ; |
|
|
| self.width = width; |
| self.height = height; |
| self.depth = depth; |
| self.minX = minX; |
| self.maxX = maxX; |
| self.minY = minY; |
| self.maxY = maxY; |
| self.minZ = minZ; |
| self.maxZ = maxZ; |
|
|
| maxe = stdMath.max(width, height, depth); |
| mine = stdMath.min(width, height, depth); |
|
|
| if ((maxe === width) && (mine === height)) |
| { |
| self.minAxis = MOD3.ModConstant.Y; |
| self.midAxis = MOD3.ModConstant.Z; |
| self.maxAxis = MOD3.ModConstant.X; |
| } |
| else if ((maxe === width) && (mine === depth)) |
| { |
| self.minAxis = MOD3.ModConstant.Z; |
| self.midAxis = MOD3.ModConstant.Y; |
| self.maxAxis = MOD3.ModConstant.X; |
| } |
| else if ((maxe === height) && (mine === width)) |
| { |
| self.minAxis = MOD3.ModConstant.X; |
| self.midAxis = MOD3.ModConstant.Z; |
| self.maxAxis = MOD3.ModConstant.Y; |
| } |
| else if ((maxe === height) && (mine === depth)) |
| { |
| self.minAxis = MOD3.ModConstant.Z; |
| self.midAxis = MOD3.ModConstant.X; |
| self.maxAxis = MOD3.ModConstant.Y; |
| } |
| else if ((maxe === depth) && (mine === width)) |
| { |
| self.minAxis = MOD3.ModConstant.X; |
| self.midAxis = MOD3.ModConstant.Y; |
| self.maxAxis = MOD3.ModConstant.Z; |
| } |
| else if ((maxe === depth) && (mine === height)) |
| { |
| self.minAxis = MOD3.ModConstant.Y; |
| self.midAxis = MOD3.ModConstant.X; |
| self.maxAxis = MOD3.ModConstant.Z; |
| } |
|
|
| 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() { |
| 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() { |
| |
| return this; |
| }, |
|
|
| preApply: function() { |
| |
| return this; |
| }, |
|
|
| postApply: function() { |
| |
| return this; |
| }, |
|
|
| updateMeshPosition: function(p) { |
| |
| 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]; |
| |
| 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; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| }; |
| |
| |
| |
| 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; |
| }, |
|
|
| |
| 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; |
| } |
| }); |
| |
| MOD3.ModifierStack.prototype.getMeshInfo = MOD3.ModifierStack.prototype.getModifiable; |
| MOD3.ModifierStack.prototype.addModifier = MOD3.ModifierStack.prototype.add; |
| !function(MOD3) { |
| "use strict"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| 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"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| 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), |
| |
| 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)) |
| ) |
| { |
| |
| } |
| 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"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| 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(); |
| |
| }, |
|
|
| radius: 0, |
| a: 0.01, |
| center: 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) { |
| |
| |
| 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)); |
| |
| v.setXYZ(MOD3.Vector3.add(uu, center)); |
| |
| |
| }); |
| return self; |
| } |
| }); |
| }(MOD3);!function(MOD3) { |
| "use strict"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| 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"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| 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"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| 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.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, |
| |
| |
| vector: null, |
| vector2: null, |
|
|
| |
| |
| |
| |
| |
| |
|
|
| 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 = 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, |
| |
| |
| |
| 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"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| 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"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| 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 = 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) |
| { |
| self.force = bmp || 1; |
| self.offset = null == force ? 127 : force; |
| } |
| else |
| { |
| self.setBitmap(bmp); |
| self.force = force || 1; |
| self.offset = null == offset ? 127 : offset; |
| } |
| 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]); |
| vv = ~~((h - 1) * v.ratio[2]); |
| 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"; |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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<size; ++index,++i) |
| { |
| if (i >= w) {i = 0; ++j;} |
| i2 = (i + dX) % w; j2 = (j + dY) % h; |
| b[index] = a[i2 + j2 * w]; |
| } |
| return b; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| 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]), |
| vv = ~~((h - 1) * v.ratio[2]), |
| 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] - offset) * force : 0), |
| xyz[2] + (axes & MOD3.ModConstant.Z ? (pn[uv] - offset) * force : 0) |
| ]); |
| }); |
| return self; |
| } |
| }); |
| }(MOD3); |
| return MOD3; |
| }); |
|
|