| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | !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; |
| | }); |
| |
|