From e36b9c45a3f3c4c5b5498d7ae6d8a6059ac87762 Mon Sep 17 00:00:00 2001 From: Mr F Date: Fri, 12 Jun 2015 23:43:37 +0300 Subject: [PATCH] removed unused files --- build/output/playcanvas-latest.js | 20547 ---------------- package.json | 15 - .../chunks/generated_shaderchunks.js | 149 - 3 files changed, 20711 deletions(-) delete mode 100644 build/output/playcanvas-latest.js delete mode 100644 package.json delete mode 100644 src/graphics/programlib/chunks/generated_shaderchunks.js diff --git a/build/output/playcanvas-latest.js b/build/output/playcanvas-latest.js deleted file mode 100644 index 845abdff420..00000000000 --- a/build/output/playcanvas-latest.js +++ /dev/null @@ -1,20547 +0,0 @@ -/* - PlayCanvas Engine v0.169.0-dev - revision - - http://playcanvas.com - Copyright 2011-2014 PlayCanvas Ltd. All rights reserved. - Do not distribute. - Contains: https://github.com/tildeio/rsvp.js - see page for license information -*/ -var pc = {config:{}, common:{}, apps:{}, data:{}, unpack:function() { - console.warn("pc.unpack has been deprecated and will be removed shortly. Please update your code.") -}, makeArray:function(arr) { - var i, ret = [], length = arr.length; - for(i = 0;i < length;++i) { - ret.push(arr[i]) - } - return ret -}, type:function(obj) { - if(obj === null) { - return"null" - } - var type = typeof obj; - if(type == "undefined" || type == "number" || type == "string" || type == "boolean") { - return type - } - return _typeLookup[Object.prototype.toString.call(obj)] -}, extend:function(target, ex) { - var prop, copy; - for(prop in ex) { - copy = ex[prop]; - if(pc.type(copy) == "object") { - target[prop] = pc.extend({}, copy) - }else { - if(pc.type(copy) == "array") { - target[prop] = pc.extend([], copy) - }else { - target[prop] = copy - } - } - } - return target -}, isDefined:function(o) { - var a; - return o !== a -}}; -var _typeLookup = function() { - var result = {}, index, names = ["Array", "Object", "Function", "Date", "RegExp", "Float32Array"]; - for(index = 0;index < names.length;++index) { - result["[object " + names[index] + "]"] = names[index].toLowerCase() - } - return result -}(); -if(typeof exports !== "undefined") { - exports.pc = pc -} -;(function() { - if(typeof document === "undefined") { - return - } - var fullscreenchange = function() { - var e = document.createEvent("CustomEvent"); - e.initCustomEvent("fullscreenchange", true, false, null); - document.dispatchEvent(e) - }; - var fullscreenerror = function() { - var e = document.createEvent("CustomEvent"); - e.initCustomEvent("fullscreenerror", true, false, null); - document.dispatchEvent(e) - }; - document.addEventListener("webkitfullscreenchange", fullscreenchange, false); - document.addEventListener("mozfullscreenchange", fullscreenchange, false); - document.addEventListener("MSFullscreenChange", fullscreenchange, false); - document.addEventListener("webkitfullscreenerror", fullscreenerror, false); - document.addEventListener("mozfullscreenerror", fullscreenerror, false); - document.addEventListener("MSFullscreenError", fullscreenerror, false); - if(Element.prototype.mozRequestFullScreen) { - Element.prototype.requestFullscreen = function() { - this.mozRequestFullScreen() - } - }else { - Element.prototype.requestFullscreen = Element.prototype.requestFullscreen || Element.prototype.webkitRequestFullscreen || Element.prototype.msRequestFullscreen || function() { - } - } - document.exitFullscreen = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen; - if(!document.hasOwnProperty("fullscreenElement")) { - Object.defineProperty(document, "fullscreenElement", {enumerable:true, configurable:false, get:function() { - return document.webkitCurrentFullScreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement - }}) - } - if(!document.hasOwnProperty("fullscreenEnabled")) { - Object.defineProperty(document, "fullscreenEnabled", {enumerable:true, configurable:false, get:function() { - return document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled - }}) - } -})(); -pc.extend(pc, function() { - var Color = function() { - this.data = new Float32Array(4); - if(arguments.length >= 3) { - this.data[0] = arguments[0]; - this.data[1] = arguments[1]; - this.data[2] = arguments[2]; - this.data[3] = arguments.length >= 4 ? arguments[3] : 1 - }else { - this.data[0] = 0; - this.data[1] = 0; - this.data[2] = 0; - this.data[3] = 1 - } - }; - Color.prototype = {clone:function() { - return new pc.Color(this.r, this.g, this.b, this.a) - }, copy:function(rhs) { - var a = this.data; - var b = rhs.data; - a[0] = b[0]; - a[1] = b[1]; - a[2] = b[2]; - a[3] = b[3]; - return this - }, set:function(r, g, b, a) { - var c = this.data; - c[0] = r; - c[1] = g; - c[2] = b; - c[3] = a === undefined ? 1 : a; - return this - }, fromString:function(hex) { - var i = parseInt(hex.replace("#", "0x")); - var bytes; - if(hex.length > 7) { - bytes = pc.math.intToBytes32(i) - }else { - bytes = pc.math.intToBytes24(i); - bytes[3] = 255 - } - this.set(bytes[0] / 255, bytes[1] / 255, bytes[2] / 255, bytes[3] / 255); - return this - }, toString:function(alpha) { - var s = "#" + ((1 << 24) + (parseInt(this.r * 255) << 16) + (parseInt(this.g * 255) << 8) + parseInt(this.b * 255)).toString(16).slice(1); - if(alpha === true) { - var a = parseInt(this.a * 255).toString(16); - if(this.a < 16 / 255) { - s += "0" + a - }else { - s += a - } - } - return s - }}; - Object.defineProperty(Color.prototype, "r", {get:function() { - return this.data[0] - }, set:function(value) { - this.data[0] = value - }}); - Object.defineProperty(Color.prototype, "g", {get:function() { - return this.data[1] - }, set:function(value) { - this.data[1] = value - }}); - Object.defineProperty(Color.prototype, "b", {get:function() { - return this.data[2] - }, set:function(value) { - this.data[2] = value - }}); - Object.defineProperty(Color.prototype, "a", {get:function() { - return this.data[3] - }, set:function(value) { - this.data[3] = value - }}); - return{Color:Color} -}()); -pc.guid = function() { - return{create:function() { - return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - var r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; - return v.toString(16) - }) - }} -}(); -pc.extend(pc, function() { - var Timer = function Timer() { - this._isRunning = false; - this._a = 0; - this._b = 0 - }; - Timer.prototype = {start:function() { - this._isRunning = true; - this._a = (new Date).getTime() - }, stop:function() { - this._isRunning = false; - this._b = (new Date).getTime() - }, getMilliseconds:function() { - return this._b - this._a - }}; - return{Timer:Timer, now:function() { - return(new Date).getTime() - }} -}()); -pc.extend(pc, function() { - return{createURI:function(options) { - var s = ""; - if((options.authority || options.scheme) && (options.host || options.hostpath)) { - throw new Error("Can't have 'scheme' or 'authority' and 'host' or 'hostpath' option"); - } - if(options.host && options.hostpath) { - throw new Error("Can't have 'host' and 'hostpath' option"); - } - if(options.path && options.hostpath) { - throw new Error("Can't have 'path' and 'hostpath' option"); - } - if(options.scheme) { - s += options.scheme + ":" - } - if(options.authority) { - s += "//" + options.authority - } - if(options.host) { - s += options.host - } - if(options.path) { - s += options.path - } - if(options.hostpath) { - s += options.hostpath - } - if(options.query) { - s += "?" + options.query - } - if(options.fragment) { - s += "#" + options.fragment - } - return s - }, URI:function(uri) { - var re = /^(([^:\/?\#]+):)?(\/\/([^\/?\#]*))?([^?\#]*)(\?([^\#]*))?(\#(.*))?/, result = uri.match(re); - this.scheme = result[2]; - this.authority = result[4]; - this.path = result[5]; - this.query = result[7]; - this.fragment = result[9]; - this.toString = function() { - var s = ""; - if(this.scheme) { - s += this.scheme + ":" - } - if(this.authority) { - s += "//" + this.authority - } - s += this.path; - if(this.query) { - s += "?" + this.query - } - if(this.fragment) { - s += "#" + this.fragment - } - return s - }; - this.getQuery = function() { - var vars; - var pair; - var result = {}; - if(this.query) { - vars = decodeURIComponent(this.query).split("&"); - vars.forEach(function(item, index, arr) { - pair = item.split("="); - result[pair[0]] = pair[1] - }, this) - } - return result - }; - this.setQuery = function(params) { - q = ""; - for(var key in params) { - if(params.hasOwnProperty(key)) { - if(q !== "") { - q += "&" - } - q += encodeURIComponent(key) + "=" + encodeURIComponent(params[key]) - } - } - this.query = q - } - }} -}()); -pc.extend(pc, function() { - var log = {write:function(text) { - console.log(text) - }, open:function(text) { - pc.log.write(Date()) - }, info:function(text) { - console.info("INFO: " + text) - }, debug:function(text) { - console.debug("DEBUG: " + text) - }, error:function(text) { - console.error("ERROR: " + text) - }, warning:function(text) { - console.warn("WARNING: " + text) - }, alert:function(text) { - pc.log.write("ALERT: " + text); - alert(text) - }, assert:function(condition, text) { - if(condition === false) { - pc.log.write("ASSERT: " + text); - alert("ASSERT failed: " + text) - } - }}; - return{log:log} -}()); -var logINFO = pc.log.info; -var logDEBUG = pc.log.debug; -var logWARNING = pc.log.warning; -var logERROR = pc.log.error; -var logALERT = pc.log.alert; -var logASSERT = pc.log.assert; -Function.prototype.extendsFrom = function(Super) { - var Self; - var Func; - var Temp = function() { - }; - Self = this; - Func = function() { - Super.apply(this, arguments); - Self.apply(this, arguments); - this.constructor = Self - }; - Func._super = Super.prototype; - Temp.prototype = Super.prototype; - Func.prototype = new Temp; - return Func -}; -pc.extend(pc, function() { - return{inherits:function(Self, Super) { - var Temp = function() { - }; - var Func = function() { - Super.apply(this, arguments); - Self.apply(this, arguments) - }; - Func._super = Super.prototype; - Temp.prototype = Super.prototype; - Func.prototype = new Temp; - return Func - }} -}()); -if(!Function.prototype.bind) { - Function.prototype.bind = function(oThis) { - if(typeof this !== "function") { - throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable"); - } - var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function() { - }, fBound = function() { - return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments))) - }; - fNOP.prototype = this.prototype; - fBound.prototype = new fNOP; - return fBound - } -} -;pc.path = function() { - return{delimiter:"/", join:function() { - var index; - var num = arguments.length; - var result = arguments[0]; - for(index = 0;index < num - 1;++index) { - var one = arguments[index]; - var two = arguments[index + 1]; - if(!pc.isDefined(one) || !pc.isDefined(two)) { - throw new Error("undefined argument to pc.path.join"); - } - if(two[0] === pc.path.delimiter) { - result = two; - continue - } - if(one && two && one[one.length - 1] !== pc.path.delimiter && two[0] !== pc.path.delimiter) { - result += pc.path.delimiter + two - }else { - result += two - } - } - return result - }, split:function(path) { - var parts = path.split(pc.path.delimiter); - var tail = parts.slice(parts.length - 1)[0]; - var head = parts.slice(0, parts.length - 1).join(pc.path.delimiter); - return[head, tail] - }, getBasename:function(path) { - return pc.path.split(path)[1] - }, getDirectory:function(path) { - var parts = path.split(pc.path.delimiter); - return parts.slice(0, parts.length - 1).join(pc.path.delimiter) - }, getExtension:function(path) { - var ext = path.split(".").pop(); - if(ext !== path) { - return"." + ext - }else { - return"" - } - }, isRelativePath:function(s) { - return s.charAt(0) !== "/" && s.match(/:\/\//) === null - }, extractPath:function(s) { - var path = ".", parts = s.split("/"), i = 0; - if(parts.length > 1) { - if(pc.path.isRelativePath(s) === false) { - path = "" - } - for(i = 0;i < parts.length - 1;++i) { - path += "/" + parts[i] - } - } - return path - }} -}(); -pc.string = function() { - return{ASCII_LOWERCASE:"abcdefghijklmnopqrstuvwxyz", ASCII_UPPERCASE:"ABCDEFGHIJKLMNOPQRSTUVWXYZ", ASCII_LETTERS:this.ASCII_LOWERCASE + this.ASCII_UPPERCASE, format:function(s) { - var i = 0, regexp, args = pc.makeArray(arguments); - args.shift(); - for(i = 0;i < args.length;i++) { - regexp = new RegExp("\\{" + i + "\\}", "gi"); - s = s.replace(regexp, args[i]) - } - return s - }, startsWith:function(s, subs) { - return s.indexOf(subs) === 0 - }, endsWith:function(s, subs) { - return s.lastIndexOf(subs, s.length - subs.length) !== -1 - }, toBool:function(s, strict) { - if(s === "true") { - return true - } - if(strict) { - if(s === "false") { - return false - } - throw new Error("Not a boolean string"); - } - return false - }} -}(); -pc.extend(pc, function() { - var json = {parse:function(value, reviver) { - return JSON.parse(value, reviver) - }, stringify:function(value, replacer, space) { - return JSON.stringify(value, function(key, value) { - if(this[key] instanceof Float32Array) { - value = pc.makeArray(this[key]) - } - return replacer ? replacer(key, value) : value - }, space) - }}; - return{json:json} -}()); -pc.cookie = function() { - return{set:function(name, value, options) { - options = options || {}; - var cookie = name + "=" + value; - if(options.path) { - cookie += ";path=" + options.path - } - if(options.domain) { - cookie += ";domain=" + options.domain - } - if(options.path) { - cookie += ";path=" + options.path - } - if(options.secure) { - cookie += ";secure" - } - if(options.lifetime) { - cookie += ";max-age=" + options.lifetime * 24 * 60 * 60 - }else { - cookie += ";max-age=" + 1 * 24 * 60 * 60 - } - document.cookie = cookie - }, get:function(name) { - var cookie, cookies = document.cookie.split(";"); - var i, len = cookies.length; - for(i = 0;i < len;i++) { - cookie = cookies[i].trim(); - if(pc.string.startsWith(cookie, name)) { - return cookie.split("=")[1] - } - } - }, remove:function(name, options) { - options.lifetime = 0; - pc.cookie.set(name, "", options) - }} -}(); -pc.debug = function() { - var table = null; - var row = null; - var title = null; - var field = null; - return{display:function(data) { - function init() { - table = document.createElement("table"); - row = document.createElement("tr"); - title = document.createElement("td"); - field = document.createElement("td"); - table.style.cssText = "position:absolute;font-family:sans-serif;font-size:12px;color:#cccccc"; - table.style.top = "0px"; - table.style.left = "0px"; - table.style.border = "thin solid #cccccc"; - document.body.appendChild(table) - } - if(!table) { - init() - } - table.innerHTML = ""; - for(var key in data) { - var r = row.cloneNode(); - var t = title.cloneNode(); - var f = field.cloneNode(); - t.textContent = key; - f.textContent = data[key]; - r.appendChild(t); - r.appendChild(f); - table.appendChild(r) - } - }} -}(); -pc.extend(pc, function() { - var ObjectPool = function(constructor, options) { - this.objects = []; - this.ctor = constructor; - this.name = options.name; - this.useNew = options.useNew === undefined || options.useNew; - this.metrics = options.metrics; - if(options.metrics) { - this.total = 0; - this.used = 0 - } - }; - ObjectPool.prototype = {_construct:function(constructor, args) { - function F() { - return constructor.apply(this, args) - } - F.prototype = constructor.prototype; - return new F - }, allocate:function() { - var object; - if(this.objects.length) { - object = this.objects.pop(); - this.ctor.apply(object, arguments); - if(this.metrics) { - this.used++ - } - }else { - if(this.useNew) { - object = this._construct(this.ctor, arguments) - }else { - object = this.ctor.apply(this, arguments) - } - if(this.metrics) { - this.total++; - this.used++ - } - } - return object - }, free:function(object) { - this.objects.push(object); - if(this.metrics) { - this.used-- - } - if(object.onFree) { - object.onFree() - } - }, usage:function() { - return pc.string.format("{0} - total: {1}, used: {2}", this.name, this.total, this.used) - }}; - var AllocatePool = function(constructor, size) { - this._constructor = constructor; - this._pool = []; - this._count = 0; - this._resize(size) - }; - AllocatePool.prototype = {_resize:function(size) { - if(size > this._pool.length) { - for(var i = this._pool.length;i < size;i++) { - this._pool[i] = new this._constructor - } - } - }, allocate:function() { - if(this._count >= this._pool.length) { - this._resize(this._pool.length * 2) - } - return this._pool[this._count++] - }, freeAll:function() { - this._count = 0 - }}; - return{AllocatePool:AllocatePool, ObjectPool:ObjectPool} -}()); -pc.events = function() { - var Events = {attach:function(target) { - var ev = pc.events; - target.on = ev.on; - target.off = ev.off; - target.fire = ev.fire; - target.once = ev.once; - target.hasEvent = ev.hasEvent; - target.bind = ev.on; - target.unbind = ev.off; - return target - }, on:function(name, callback, scope) { - if(pc.type(name) != "string") { - throw new TypeError("Event name must be a string"); - } - var callbacks = this._callbacks || (this._callbacks = {}); - var events = callbacks[name] || (callbacks[name] = []); - events.push({callback:callback, scope:scope || this}); - return this - }, off:function(name, callback, scope) { - var callbacks = this._callbacks; - var events; - var index; - if(!callbacks) { - return - } - if(!callback) { - callbacks[name] = [] - }else { - events = callbacks[name]; - if(!events) { - return this - } - for(index = 0;index < events.length;index++) { - if(events[index].callback === callback) { - if(!scope || scope === events[index].scope) { - events.splice(index, 1); - index-- - } - } - } - } - return this - }, fire:function(name) { - var index; - var length; - var args; - var callbacks; - if(this._callbacks && this._callbacks[name]) { - length = this._callbacks[name].length; - if(length) { - args = pc.makeArray(arguments); - args.shift(); - callbacks = this._callbacks[name].slice(); - for(index = 0;index < length;++index) { - var scope = callbacks[index].scope; - callbacks[index].callback.apply(scope, args) - } - } - } - return this - }, once:function(name, callback, scope) { - var fn; - this.on(name, fn = function() { - this.off(name, fn, scope); - callback.apply(scope, arguments) - }, scope) - }, hasEvent:function(name) { - return this._callbacks !== undefined && this._callbacks[name] !== undefined && this._callbacks[name].length > 0 - }}; - Events.bind = Events.on; - Events.unbind = Events.off; - return Events -}(); -pc.dom = function() { - return{getWidth:function(element) { - return element.offsetWidth - }, getHeight:function(element) { - return element.offsetHeight - }, setText:function(element, text) { - if(element.textContent) { - element.textContent = text - }else { - if(element.innerText) { - element.innerText = text - } - } - }, getText:function(element) { - return element.textContent || element.innerText - }} -}(); -pc.math = {DEG_TO_RAD:Math.PI / 180, RAD_TO_DEG:180 / Math.PI, INV_LOG2:1 / Math.log(2), clamp:function(value, min, max) { - if(value >= max) { - return max - } - if(value <= min) { - return min - } - return value -}, intToBytes24:function(i) { - var r, g, b; - r = i >> 16 & 255; - g = i >> 8 & 255; - b = i & 255; - return[r, g, b] -}, intToBytes32:function(i) { - var r, g, b, a; - r = i >> 24 & 255; - g = i >> 16 & 255; - b = i >> 8 & 255; - a = i & 255; - return[r, g, b, a] -}, bytesToInt24:function(r, g, b) { - if(r.length) { - b = r[2]; - g = r[1]; - r = r[0] - } - return r << 16 | g << 8 | b -}, bytesToInt32:function(r, g, b, a) { - if(r.length) { - a = r[3]; - b = r[2]; - g = r[1]; - r = r[0] - } - return(r << 24 | g << 16 | b << 8 | a) >>> 32 -}, lerp:function(a, b, alpha) { - return a + (b - a) * pc.math.clamp(alpha, 0, 1) -}, lerpAngle:function(a, b, alpha) { - if(b - a > 180) { - b -= 360 - } - if(b - a < -180) { - b += 360 - } - return pc.math.lerp(a, b, pc.math.clamp(alpha, 0, 1)) -}, powerOfTwo:function(x) { - return x !== 0 && !(x & x - 1) -}, nextPowerOfTwo:function(val) { - val--; - val = val >> 1 | val; - val = val >> 2 | val; - val = val >> 4 | val; - val = val >> 8 | val; - val = val >> 16 | val; - val++; - return val -}, random:function(min, max) { - var diff = max - min; - return Math.random() * diff + min -}, smoothstep:function(min, max, x) { - if(x <= min) { - return 0 - } - if(x >= max) { - return 1 - } - x = (x - min) / (max - min); - return x * x * (3 - 2 * x) -}, smootherstep:function(min, max, x) { - if(x <= min) { - return 0 - } - if(x >= max) { - return 1 - } - x = (x - min) / (max - min); - return x * x * x * (x * (x * 6 - 15) + 10) -}}; -pc.math.intToBytes = pc.math.intToBytes32; -pc.math.bytesToInt = pc.math.bytesToInt32; -if(!Math.log2) { - Math.log2 = function(x) { - return Math.log(x) * pc.math.INV_LOG2 - } -} -;pc.extend(pc, function() { - var Vec2 = function() { - this.data = new Float32Array(2); - if(arguments.length === 2) { - this.data.set(arguments) - }else { - this.data[0] = 0; - this.data[1] = 0 - } - }; - Vec2.prototype = {add:function(rhs) { - var a = this.data, b = rhs.data; - a[0] += b[0]; - a[1] += b[1]; - return this - }, add2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - return this - }, clone:function() { - return(new Vec2).copy(this) - }, copy:function(rhs) { - var a = this.data, b = rhs.data; - a[0] = b[0]; - a[1] = b[1]; - return this - }, dot:function(rhs) { - var a = this.data, b = rhs.data; - return a[0] * b[0] + a[1] * b[1] - }, equals:function(rhs) { - var a = this.data, b = rhs.data; - return a[0] === b[0] && a[1] === b[1] - }, length:function() { - var v = this.data; - return Math.sqrt(v[0] * v[0] + v[1] * v[1]) - }, lengthSq:function() { - var v = this.data; - return v[0] * v[0] + v[1] * v[1] - }, lerp:function(lhs, rhs, alpha) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] + alpha * (b[0] - a[0]); - r[1] = a[1] + alpha * (b[1] - a[1]); - return this - }, mul:function(rhs) { - var a = this.data, b = rhs.data; - a[0] *= b[0]; - a[1] *= b[1]; - return this - }, mul2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] * b[0]; - r[1] = a[1] * b[1]; - return this - }, normalize:function() { - return this.scale(1 / this.length()) - }, scale:function(scalar) { - var v = this.data; - v[0] *= scalar; - v[1] *= scalar; - return this - }, set:function(x, y) { - var v = this.data; - v[0] = x; - v[1] = y; - return this - }, sub:function(rhs) { - var a = this.data, b = rhs.data; - a[0] -= b[0]; - a[1] -= b[1]; - return this - }, sub2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - return this - }, toString:function() { - return"[" + this.data[0] + ", " + this.data[1] + "]" - }}; - Object.defineProperty(Vec2.prototype, "x", {get:function() { - return this.data[0] - }, set:function(value) { - this.data[0] = value - }}); - Object.defineProperty(Vec2.prototype, "y", {get:function() { - return this.data[1] - }, set:function(value) { - this.data[1] = value - }}); - Object.defineProperty(Vec2, "ONE", {get:function() { - var one = new Vec2(1, 1); - return function() { - return one - } - }()}); - Object.defineProperty(Vec2, "RIGHT", {get:function() { - var right = new Vec2(1, 0); - return function() { - return right - } - }()}); - Object.defineProperty(Vec2, "UP", {get:function() { - var down = new Vec2(0, 1); - return function() { - return down - } - }()}); - Object.defineProperty(Vec2, "ZERO", {get:function() { - var zero = new Vec2(0, 0); - return function() { - return zero - } - }()}); - return{Vec2:Vec2} -}()); -pc.extend(pc, function() { - var Vec3 = function() { - this.data = new Float32Array(3); - if(arguments.length === 3) { - this.data.set(arguments) - }else { - this.data[0] = 0; - this.data[1] = 0; - this.data[2] = 0 - } - }; - Vec3.prototype = {add:function(rhs) { - var a = this.data, b = rhs.data; - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - return this - }, add2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - r[2] = a[2] + b[2]; - return this - }, clone:function() { - return(new Vec3).copy(this) - }, copy:function(rhs) { - var a = this.data, b = rhs.data; - a[0] = b[0]; - a[1] = b[1]; - a[2] = b[2]; - return this - }, cross:function(lhs, rhs) { - var a, b, r, ax, ay, az, bx, by, bz; - a = lhs.data; - b = rhs.data; - r = this.data; - ax = a[0]; - ay = a[1]; - az = a[2]; - bx = b[0]; - by = b[1]; - bz = b[2]; - r[0] = ay * bz - by * az; - r[1] = az * bx - bz * ax; - r[2] = ax * by - bx * ay; - return this - }, dot:function(rhs) { - var a = this.data, b = rhs.data; - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] - }, equals:function(rhs) { - var a = this.data, b = rhs.data; - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] - }, length:function() { - var v = this.data; - return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) - }, lengthSq:function() { - var v = this.data; - return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] - }, lerp:function(lhs, rhs, alpha) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] + alpha * (b[0] - a[0]); - r[1] = a[1] + alpha * (b[1] - a[1]); - r[2] = a[2] + alpha * (b[2] - a[2]); - return this - }, mul:function(rhs) { - var a = this.data, b = rhs.data; - a[0] *= b[0]; - a[1] *= b[1]; - a[2] *= b[2]; - return this - }, mul2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] * b[0]; - r[1] = a[1] * b[1]; - r[2] = a[2] * b[2]; - return this - }, normalize:function() { - return this.scale(1 / this.length()) - }, project:function(rhs) { - var a = this.data; - var b = rhs.data; - var a_dot_b = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; - var b_dot_b = b[0] * b[0] + b[1] * b[1] + b[2] * b[2]; - var s = a_dot_b / b_dot_b; - a[0] = b[0] * s; - a[1] = b[1] * s; - a[2] = b[2] * s; - return this - }, scale:function(scalar) { - var v = this.data; - v[0] *= scalar; - v[1] *= scalar; - v[2] *= scalar; - return this - }, set:function(x, y, z) { - var v = this.data; - v[0] = x; - v[1] = y; - v[2] = z; - return this - }, sub:function(rhs) { - var a = this.data, b = rhs.data; - a[0] -= b[0]; - a[1] -= b[1]; - a[2] -= b[2]; - return this - }, sub2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - r[2] = a[2] - b[2]; - return this - }, toString:function() { - return"[" + this.data[0] + ", " + this.data[1] + ", " + this.data[2] + "]" - }}; - Object.defineProperty(Vec3.prototype, "x", {get:function() { - return this.data[0] - }, set:function(value) { - this.data[0] = value - }}); - Object.defineProperty(Vec3.prototype, "y", {get:function() { - return this.data[1] - }, set:function(value) { - this.data[1] = value - }}); - Object.defineProperty(Vec3.prototype, "z", {get:function() { - return this.data[2] - }, set:function(value) { - this.data[2] = value - }}); - Object.defineProperty(Vec3, "BACK", {get:function() { - var back = new Vec3(0, 0, 1); - return function() { - return back - } - }()}); - Object.defineProperty(Vec3, "DOWN", {get:function() { - var down = new Vec3(0, -1, 0); - return function() { - return down - } - }()}); - Object.defineProperty(Vec3, "FORWARD", {get:function() { - var forward = new Vec3(0, 0, -1); - return function() { - return forward - } - }()}); - Object.defineProperty(Vec3, "LEFT", {get:function() { - var left = new Vec3(-1, 0, 0); - return function() { - return left - } - }()}); - Object.defineProperty(Vec3, "ONE", {get:function() { - var one = new Vec3(1, 1, 1); - return function() { - return one - } - }()}); - Object.defineProperty(Vec3, "RIGHT", {get:function() { - var right = new Vec3(1, 0, 0); - return function() { - return right - } - }()}); - Object.defineProperty(Vec3, "UP", {get:function() { - var down = new Vec3(0, 1, 0); - return function() { - return down - } - }()}); - Object.defineProperty(Vec3, "ZERO", {get:function() { - var zero = new Vec3(0, 0, 0); - return function() { - return zero - } - }()}); - return{Vec3:Vec3} -}()); -pc.extend(pc, function() { - var Vec4 = function() { - this.data = new Float32Array(4); - if(arguments.length === 4) { - this.data.set(arguments) - }else { - this.data[0] = 0; - this.data[1] = 0; - this.data[2] = 0; - this.data[3] = 0 - } - }; - Vec4.prototype = {add:function(rhs) { - var a = this.data, b = rhs.data; - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; - a[3] += b[3]; - return this - }, add2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - r[2] = a[2] + b[2]; - r[3] = a[3] + b[3]; - return this - }, clone:function() { - return(new Vec4).copy(this) - }, copy:function(rhs) { - var a = this.data, b = rhs.data; - a[0] = b[0]; - a[1] = b[1]; - a[2] = b[2]; - a[3] = b[3]; - return this - }, dot:function(rhs) { - var a = this.data, b = rhs.data; - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3] - }, equals:function(rhs) { - var a = this.data, b = rhs.data; - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] - }, length:function() { - var v = this.data; - return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]) - }, lengthSq:function() { - var v = this.data; - return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3] - }, lerp:function(lhs, rhs, alpha) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] + alpha * (b[0] - a[0]); - r[1] = a[1] + alpha * (b[1] - a[1]); - r[2] = a[2] + alpha * (b[2] - a[2]); - r[3] = a[3] + alpha * (b[3] - a[3]); - return this - }, mul:function(rhs) { - var a = this.data, b = rhs.data; - a[0] *= b[0]; - a[1] *= b[1]; - a[2] *= b[2]; - a[3] *= b[3]; - return this - }, mul2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] * b[0]; - r[1] = a[1] * b[1]; - r[2] = a[2] * b[2]; - r[3] = a[3] * b[3]; - return this - }, normalize:function() { - return this.scale(1 / this.length()) - }, scale:function(scalar) { - var v = this.data; - v[0] *= scalar; - v[1] *= scalar; - v[2] *= scalar; - v[3] *= scalar; - return this - }, set:function(x, y, z, w) { - var v = this.data; - v[0] = x; - v[1] = y; - v[2] = z; - v[3] = w; - return this - }, sub:function(rhs) { - var a = this.data, b = rhs.data; - a[0] -= b[0]; - a[1] -= b[1]; - a[2] -= b[2]; - a[3] -= b[3]; - return this - }, sub2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] - b[0]; - r[1] = a[1] - b[1]; - r[2] = a[2] - b[2]; - r[3] = a[3] - b[3]; - return this - }, toString:function() { - return"[" + this.data[0] + ", " + this.data[1] + ", " + this.data[2] + ", " + this.data[3] + "]" - }}; - Object.defineProperty(Vec4.prototype, "x", {get:function() { - return this.data[0] - }, set:function(value) { - this.data[0] = value - }}); - Object.defineProperty(Vec4.prototype, "y", {get:function() { - return this.data[1] - }, set:function(value) { - this.data[1] = value - }}); - Object.defineProperty(Vec4.prototype, "z", {get:function() { - return this.data[2] - }, set:function(value) { - this.data[2] = value - }}); - Object.defineProperty(Vec4.prototype, "w", {get:function() { - return this.data[3] - }, set:function(value) { - this.data[3] = value - }}); - Object.defineProperty(Vec4, "ONE", {get:function() { - var one = new Vec4(1, 1, 1, 1); - return function() { - return one - } - }()}); - Object.defineProperty(Vec4, "ZERO", {get:function() { - var zero = new Vec4(0, 0, 0, 0); - return function() { - return zero - } - }()}); - return{Vec4:Vec4} -}()); -pc.extend(pc, function() { - var Mat3 = function() { - this.data = new Float32Array(9); - if(arguments.length === 9) { - this.data.set(arguments) - }else { - this.setIdentity() - } - }; - Mat3.prototype = {clone:function() { - return(new pc.Mat3).copy(this) - }, copy:function(rhs) { - var src = rhs.data; - var dst = this.data; - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - dst[4] = src[4]; - dst[5] = src[5]; - dst[6] = src[6]; - dst[7] = src[7]; - dst[8] = src[8]; - return this - }, equals:function(rhs) { - var l = this.data; - var r = rhs.data; - return l[0] === r[0] && l[1] === r[1] && l[2] === r[2] && l[3] === r[3] && l[4] === r[4] && l[5] === r[5] && l[6] === r[6] && l[7] === r[7] && l[8] === r[8] - }, isIdentity:function() { - var m = this.data; - return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 0 && m[4] === 1 && m[5] === 0 && m[6] === 0 && m[7] === 0 && m[8] === 1 - }, setIdentity:function() { - var m = this.data; - m[0] = 1; - m[1] = 0; - m[2] = 0; - m[3] = 0; - m[4] = 1; - m[5] = 0; - m[6] = 0; - m[7] = 0; - m[8] = 1; - return this - }, toString:function() { - var t = "["; - for(var i = 0;i < 9;i++) { - t += this.data[i]; - t += i !== 9 ? ", " : "" - } - t += "]"; - return t - }, transpose:function() { - var m = this.data; - var tmp; - tmp = m[1]; - m[1] = m[3]; - m[3] = tmp; - tmp = m[2]; - m[2] = m[6]; - m[6] = tmp; - tmp = m[5]; - m[5] = m[7]; - m[7] = tmp; - return this - }}; - Object.defineProperty(Mat3, "IDENTITY", {get:function() { - var identity = new Mat3; - return function() { - return identity - } - }()}); - Object.defineProperty(Mat3, "ZERO", {get:function() { - var zero = new Mat3(0, 0, 0, 0, 0, 0, 0, 0, 0); - return function() { - return zero - } - }()}); - return{Mat3:Mat3} -}()); -pc.extend(pc, function() { - var Mat4 = function() { - this.data = new Float32Array(16); - if(arguments.length === 16) { - this.data.set(arguments) - }else { - this.setIdentity() - } - }; - Mat4.prototype = {add2:function(lhs, rhs) { - var a = lhs.data, b = rhs.data, r = this.data; - r[0] = a[0] + b[0]; - r[1] = a[1] + b[1]; - r[2] = a[2] + b[2]; - r[3] = a[3] + b[3]; - r[4] = a[4] + b[4]; - r[5] = a[5] + b[5]; - r[6] = a[6] + b[6]; - r[7] = a[7] + b[7]; - r[8] = a[8] + b[8]; - r[9] = a[9] + b[9]; - r[10] = a[10] + b[10]; - r[11] = a[11] + b[11]; - r[12] = a[12] + b[12]; - r[13] = a[13] + b[13]; - r[14] = a[14] + b[14]; - r[15] = a[15] + b[15]; - return this - }, add:function(rhs) { - return this.add2(this, rhs) - }, clone:function() { - return(new pc.Mat4).copy(this) - }, copy:function(rhs) { - var src = rhs.data, dst = this.data; - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - dst[4] = src[4]; - dst[5] = src[5]; - dst[6] = src[6]; - dst[7] = src[7]; - dst[8] = src[8]; - dst[9] = src[9]; - dst[10] = src[10]; - dst[11] = src[11]; - dst[12] = src[12]; - dst[13] = src[13]; - dst[14] = src[14]; - dst[15] = src[15]; - return this - }, equals:function(rhs) { - var l = this.data, r = rhs.data; - return l[0] === r[0] && l[1] === r[1] && l[2] === r[2] && l[3] === r[3] && l[4] === r[4] && l[5] === r[5] && l[6] === r[6] && l[7] === r[7] && l[8] === r[8] && l[9] === r[9] && l[10] === r[10] && l[11] === r[11] && l[12] === r[12] && l[13] === r[13] && l[14] === r[14] && l[15] === r[15] - }, isIdentity:function() { - var m = this.data; - return 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 - }, mul2:function(lhs, rhs) { - var a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, a30, a31, a32, a33, b0, b1, b2, b3, a = lhs.data, b = rhs.data, r = this.data; - a00 = a[0]; - a01 = a[1]; - a02 = a[2]; - a03 = a[3]; - a10 = a[4]; - a11 = a[5]; - a12 = a[6]; - a13 = a[7]; - a20 = a[8]; - a21 = a[9]; - a22 = a[10]; - a23 = a[11]; - a30 = a[12]; - a31 = a[13]; - a32 = a[14]; - a33 = a[15]; - b0 = b[0]; - b1 = b[1]; - b2 = b[2]; - b3 = b[3]; - r[0] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3; - r[1] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3; - r[2] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3; - r[3] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3; - b0 = b[4]; - b1 = b[5]; - b2 = b[6]; - b3 = b[7]; - r[4] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3; - r[5] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3; - r[6] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3; - r[7] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3; - b0 = b[8]; - b1 = b[9]; - b2 = b[10]; - b3 = b[11]; - r[8] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3; - r[9] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3; - r[10] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3; - r[11] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3; - b0 = b[12]; - b1 = b[13]; - b2 = b[14]; - b3 = b[15]; - r[12] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3; - r[13] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3; - r[14] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3; - r[15] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3; - return this - }, mul:function(rhs) { - return this.mul2(this, rhs) - }, transformPoint:function(vec, res) { - var x, y, z, m = this.data, v = vec.data; - res = res === undefined ? new pc.Vec3 : res; - x = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + m[12]; - y = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + m[13]; - z = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + m[14]; - return res.set(x, y, z) - }, transformVector:function(vec, res) { - var x, y, z, m = this.data, v = vec.data; - res = res === undefined ? new pc.Vec3 : res; - x = v[0] * m[0] + v[1] * m[4] + v[2] * m[8]; - y = v[0] * m[1] + v[1] * m[5] + v[2] * m[9]; - z = v[0] * m[2] + v[1] * m[6] + v[2] * m[10]; - return res.set(x, y, z) - }, setLookAt:function() { - var x, y, z; - x = new pc.Vec3; - y = new pc.Vec3; - z = new pc.Vec3; - return function(position, target, up) { - z.sub2(position, target).normalize(); - y.copy(up).normalize(); - x.cross(y, z).normalize(); - y.cross(z, x); - var r = this.data; - r[0] = x.x; - r[1] = x.y; - r[2] = x.z; - r[3] = 0; - r[4] = y.x; - r[5] = y.y; - r[6] = y.z; - r[7] = 0; - r[8] = z.x; - r[9] = z.y; - r[10] = z.z; - r[11] = 0; - r[12] = position.x; - r[13] = position.y; - r[14] = position.z; - r[15] = 1; - return this - } - }(), setFrustum:function(left, right, bottom, top, znear, zfar) { - var temp1, temp2, temp3, temp4, r; - temp1 = 2 * znear; - temp2 = right - left; - temp3 = top - bottom; - temp4 = zfar - znear; - r = this.data; - r[0] = temp1 / temp2; - r[1] = 0; - r[2] = 0; - r[3] = 0; - r[4] = 0; - r[5] = temp1 / temp3; - r[6] = 0; - r[7] = 0; - r[8] = (right + left) / temp2; - r[9] = (top + bottom) / temp3; - r[10] = (-zfar - znear) / temp4; - r[11] = -1; - r[12] = 0; - r[13] = 0; - r[14] = -temp1 * zfar / temp4; - r[15] = 0; - return this - }, setPerspective:function(fovy, aspect, znear, zfar) { - var xmax, ymax; - ymax = znear * Math.tan(fovy * Math.PI / 360); - xmax = ymax * aspect; - return this.setFrustum(-xmax, xmax, -ymax, ymax, znear, zfar) - }, setOrtho:function(left, right, bottom, top, near, far) { - var r = this.data; - r[0] = 2 / (right - left); - r[1] = 0; - r[2] = 0; - r[3] = 0; - r[4] = 0; - r[5] = 2 / (top - bottom); - r[6] = 0; - r[7] = 0; - r[8] = 0; - r[9] = 0; - r[10] = -2 / (far - near); - r[11] = 0; - r[12] = -(right + left) / (right - left); - r[13] = -(top + bottom) / (top - bottom); - r[14] = -(far + near) / (far - near); - r[15] = 1; - return this - }, setFromAxisAngle:function(axis, angle) { - var x, y, z, c, s, t, tx, ty, m; - angle *= pc.math.DEG_TO_RAD; - x = axis.x; - y = axis.y; - z = axis.z; - c = Math.cos(angle); - s = Math.sin(angle); - t = 1 - c; - tx = t * x; - ty = t * y; - m = this.data; - m[0] = tx * x + c; - m[1] = tx * y + s * z; - m[2] = tx * z - s * y; - m[3] = 0; - m[4] = tx * y - s * z; - m[5] = ty * y + c; - m[6] = ty * z + s * x; - m[7] = 0; - m[8] = tx * z + s * y; - m[9] = ty * z - x * s; - m[10] = t * z * z + c; - m[11] = 0; - m[12] = 0; - m[13] = 0; - m[14] = 0; - m[15] = 1; - return this - }, setTranslate:function(tx, ty, tz) { - var m = this.data; - 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] = tx; - m[13] = ty; - m[14] = tz; - m[15] = 1; - return this - }, setScale:function(sx, sy, sz) { - var m = this.data; - m[0] = sx; - m[1] = 0; - m[2] = 0; - m[3] = 0; - m[4] = 0; - m[5] = sy; - m[6] = 0; - m[7] = 0; - m[8] = 0; - m[9] = 0; - m[10] = sz; - m[11] = 0; - m[12] = 0; - m[13] = 0; - m[14] = 0; - m[15] = 1; - return this - }, invert:function() { - var a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, a30, a31, a32, a33, b00, b01, b02, b03, b04, b05, b06, b07, b08, b09, b10, b11, invDet, m; - m = this.data; - a00 = m[0]; - a01 = m[1]; - a02 = m[2]; - a03 = m[3]; - a10 = m[4]; - a11 = m[5]; - a12 = m[6]; - a13 = m[7]; - a20 = m[8]; - a21 = m[9]; - a22 = m[10]; - a23 = m[11]; - a30 = m[12]; - a31 = m[13]; - a32 = m[14]; - a33 = m[15]; - b00 = a00 * a11 - a01 * a10; - b01 = a00 * a12 - a02 * a10; - b02 = a00 * a13 - a03 * a10; - b03 = a01 * a12 - a02 * a11; - b04 = a01 * a13 - a03 * a11; - b05 = a02 * a13 - a03 * a12; - b06 = a20 * a31 - a21 * a30; - b07 = a20 * a32 - a22 * a30; - b08 = a20 * a33 - a23 * a30; - b09 = a21 * a32 - a22 * a31; - b10 = a21 * a33 - a23 * a31; - b11 = a22 * a33 - a23 * a32; - invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06); - m[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet; - m[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet; - m[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet; - m[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet; - m[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet; - m[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet; - m[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet; - m[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet; - m[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet; - m[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet; - m[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet; - m[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet; - m[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet; - m[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet; - m[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet; - m[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet; - return this - }, setIdentity:function() { - var m = this.data; - 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 - }, setTRS:function(t, r, s) { - var tx, ty, tz, qx, qy, qz, qw, sx, sy, sz, x2, y2, z2, xx, xy, xz, yy, yz, zz, wx, wy, wz, m; - tx = t.x; - ty = t.y; - tz = t.z; - qx = r.x; - qy = r.y; - qz = r.z; - qw = r.w; - sx = s.x; - sy = s.y; - sz = s.z; - x2 = qx + qx; - y2 = qy + qy; - z2 = qz + qz; - xx = qx * x2; - xy = qx * y2; - xz = qx * z2; - yy = qy * y2; - yz = qy * z2; - zz = qz * z2; - wx = qw * x2; - wy = qw * y2; - wz = qw * z2; - m = this.data; - m[0] = (1 - (yy + zz)) * sx; - m[1] = (xy + wz) * sx; - m[2] = (xz - wy) * sx; - m[3] = 0; - m[4] = (xy - wz) * sy; - m[5] = (1 - (xx + zz)) * sy; - m[6] = (yz + wx) * sy; - m[7] = 0; - m[8] = (xz + wy) * sz; - m[9] = (yz - wx) * sz; - m[10] = (1 - (xx + yy)) * sz; - m[11] = 0; - m[12] = tx; - m[13] = ty; - m[14] = tz; - m[15] = 1; - return this - }, transpose:function() { - var tmp, m = this.data; - tmp = m[1]; - m[1] = m[4]; - m[4] = tmp; - tmp = m[2]; - m[2] = m[8]; - m[8] = tmp; - tmp = m[3]; - m[3] = m[12]; - m[12] = tmp; - tmp = m[6]; - m[6] = m[9]; - m[9] = tmp; - tmp = m[7]; - m[7] = m[13]; - m[13] = tmp; - tmp = m[11]; - m[11] = m[14]; - m[14] = tmp; - return this - }, invertTo3x3:function(res) { - var a11, a21, a31, a12, a22, a32, a13, a23, a33, m, r, det, idet; - m = this.data; - r = res.data; - a11 = m[10] * m[5] - m[6] * m[9]; - a21 = -m[10] * m[1] + m[2] * m[9]; - a31 = m[6] * m[1] - m[2] * m[5]; - a12 = -m[10] * m[4] + m[6] * m[8]; - a22 = m[10] * m[0] - m[2] * m[8]; - a32 = -m[6] * m[0] + m[2] * m[4]; - a13 = m[9] * m[4] - m[5] * m[8]; - a23 = -m[9] * m[0] + m[1] * m[8]; - a33 = m[5] * m[0] - m[1] * m[4]; - det = m[0] * a11 + m[1] * a12 + m[2] * a13; - if(det === 0) { - console.warn("pc.Mat4#invertTo3x3: Matrix not invertible"); - return this - } - idet = 1 / det; - r[0] = idet * a11; - r[1] = idet * a21; - r[2] = idet * a31; - r[3] = idet * a12; - r[4] = idet * a22; - r[5] = idet * a32; - r[6] = idet * a13; - r[7] = idet * a23; - r[8] = idet * a33; - return this - }, getTranslation:function(t) { - t = t === undefined ? new pc.Vec3 : t; - return t.set(this.data[12], this.data[13], this.data[14]) - }, getX:function(x) { - x = x === undefined ? new pc.Vec3 : x; - return x.set(this.data[0], this.data[1], this.data[2]) - }, getY:function(y) { - y = y === undefined ? new pc.Vec3 : y; - return y.set(this.data[4], this.data[5], this.data[6]) - }, getZ:function(z) { - z = z === undefined ? new pc.Vec3 : z; - return z.set(this.data[8], this.data[9], this.data[10]) - }, getScale:function() { - var x, y, z; - x = new pc.Vec3; - y = new pc.Vec3; - z = new pc.Vec3; - return function(scale) { - scale = scale === undefined ? new pc.Vec3 : scale; - this.getX(x); - this.getY(y); - this.getZ(z); - scale.set(x.length(), y.length(), z.length()); - return scale - } - }(), setFromEulerAngles:function(ex, ey, ez) { - var s1, c1, s2, c2, s3, c3, m; - ex *= pc.math.DEG_TO_RAD; - ey *= pc.math.DEG_TO_RAD; - ez *= pc.math.DEG_TO_RAD; - s1 = Math.sin(-ex); - c1 = Math.cos(-ex); - s2 = Math.sin(-ey); - c2 = Math.cos(-ey); - s3 = Math.sin(-ez); - c3 = Math.cos(-ez); - m = this.data; - m[0] = c2 * c3; - m[1] = -c2 * s3; - m[2] = s2; - m[3] = 0; - m[4] = c1 * s3 + c3 * s1 * s2; - m[5] = c1 * c3 - s1 * s2 * s3; - m[6] = -c2 * s1; - m[7] = 0; - m[8] = s1 * s3 - c1 * c3 * s2; - m[9] = c3 * s1 + c1 * s2 * s3; - m[10] = c1 * c2; - m[11] = 0; - m[12] = 0; - m[13] = 0; - m[14] = 0; - m[15] = 1; - return this - }, getEulerAngles:function() { - var scale = new pc.Vec3; - return function(eulers) { - var x, y, z, sx, sy, sz, m, halfPi; - eulers = eulers === undefined ? new pc.Vec3 : eulers; - this.getScale(scale); - sx = scale.x; - sy = scale.y; - sz = scale.z; - m = this.data; - y = Math.asin(-m[2] / sx); - halfPi = Math.PI * 0.5; - if(y < halfPi) { - if(y > -halfPi) { - x = Math.atan2(m[6] / sy, m[10] / sz); - z = Math.atan2(m[1] / sx, m[0] / sx) - }else { - z = 0; - x = -Math.atan2(m[4] / sy, m[5] / sy) - } - }else { - z = 0; - x = Math.atan2(m[4] / sy, m[5] / sy) - } - return eulers.set(x, y, z).scale(pc.math.RAD_TO_DEG) - } - }(), toString:function() { - var i, t; - t = "["; - for(i = 0;i < 16;i += 1) { - t += this.data[i]; - t += i !== 15 ? ", " : "" - } - t += "]"; - return t - }}; - Object.defineProperty(Mat4, "IDENTITY", {get:function() { - var identity = new Mat4; - return function() { - return identity - } - }()}); - Object.defineProperty(Mat4, "ZERO", {get:function() { - var zero = new Mat4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - return function() { - return zero - } - }()}); - return{Mat4:Mat4} -}()); -pc.extend(pc, function() { - var Quat = function(x, y, z, w) { - this.x = x === undefined ? 0 : x; - this.y = y === undefined ? 0 : y; - this.z = z === undefined ? 0 : z; - this.w = w === undefined ? 1 : w - }; - Quat.prototype = {clone:function() { - return new pc.Quat(this.x, this.y, this.z, this.w) - }, conjugate:function() { - this.x *= -1; - this.y *= -1; - this.z *= -1; - return this - }, copy:function(rhs) { - this.x = rhs.x; - this.y = rhs.y; - this.z = rhs.z; - this.w = rhs.w; - return this - }, equals:function(that) { - return this.x === that.x && this.y === that.y && this.z === that.z && this.w === that.w - }, getEulerAngles:function(eulers) { - var x, y, z, qx, qy, qz, qw, a2; - eulers = eulers === undefined ? new pc.Vec3 : eulers; - qx = this.x; - qy = this.y; - qz = this.z; - qw = this.w; - a2 = 2 * (qw * qy - qx * qz); - if(a2 <= -0.99999) { - x = 2 * Math.atan2(qx, qw); - y = -Math.PI / 2; - z = 0 - }else { - if(a2 >= 0.99999) { - x = 2 * Math.atan2(qx, qw); - y = Math.PI / 2; - z = 0 - }else { - x = Math.atan2(2 * (qw * qx + qy * qz), 1 - 2 * (qx * qx + qy * qy)); - y = Math.asin(a2); - z = Math.atan2(2 * (qw * qz + qx * qy), 1 - 2 * (qy * qy + qz * qz)) - } - } - return eulers.set(x, y, z).scale(pc.math.RAD_TO_DEG) - }, invert:function() { - return this.conjugate().normalize() - }, length:function() { - var x, y, z, w; - x = this.x; - y = this.y; - z = this.z; - w = this.w; - return Math.sqrt(x * x + y * y + z * z + w * w) - }, lengthSq:function() { - var v = this.data; - return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] - }, mul:function(rhs) { - var q1x, q1y, q1z, q1w, q2x, q2y, q2z, q2w; - q1x = this.x; - q1y = this.y; - q1z = this.z; - q1w = this.w; - q2x = rhs.x; - q2y = rhs.y; - q2z = rhs.z; - q2w = rhs.w; - this.x = q1w * q2x + q1x * q2w + q1y * q2z - q1z * q2y; - this.y = q1w * q2y + q1y * q2w + q1z * q2x - q1x * q2z; - this.z = q1w * q2z + q1z * q2w + q1x * q2y - q1y * q2x; - this.w = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; - return this - }, mul2:function(lhs, rhs) { - var q1x, q1y, q1z, q1w, q2x, q2y, q2z, q2w; - q1x = lhs.x; - q1y = lhs.y; - q1z = lhs.z; - q1w = lhs.w; - q2x = rhs.x; - q2y = rhs.y; - q2z = rhs.z; - q2w = rhs.w; - this.x = q1w * q2x + q1x * q2w + q1y * q2z - q1z * q2y; - this.y = q1w * q2y + q1y * q2w + q1z * q2x - q1x * q2z; - this.z = q1w * q2z + q1z * q2w + q1x * q2y - q1y * q2x; - this.w = q1w * q2w - q1x * q2x - q1y * q2y - q1z * q2z; - return this - }, normalize:function() { - var len = this.length(); - if(len === 0) { - this.x = this.y = this.z = 0; - this.w = 1 - }else { - len = 1 / len; - this.x *= len; - this.y *= len; - this.z *= len; - this.w *= len - } - return this - }, set:function(x, y, z, w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - return this - }, setFromAxisAngle:function(axis, angle) { - var sa, ca; - angle *= 0.5 * pc.math.DEG_TO_RAD; - sa = Math.sin(angle); - ca = Math.cos(angle); - this.x = sa * axis.x; - this.y = sa * axis.y; - this.z = sa * axis.z; - this.w = ca; - return this - }, setFromEulerAngles:function(ex, ey, ez) { - var sx, cx, sy, cy, sz, cz, halfToRad; - halfToRad = 0.5 * pc.math.DEG_TO_RAD; - ex *= halfToRad; - ey *= halfToRad; - ez *= halfToRad; - sx = Math.sin(ex); - cx = Math.cos(ex); - sy = Math.sin(ey); - cy = Math.cos(ey); - sz = Math.sin(ez); - cz = Math.cos(ez); - this.x = sx * cy * cz - cx * sy * sz; - this.y = cx * sy * cz + sx * cy * sz; - this.z = cx * cy * sz - sx * sy * cz; - this.w = cx * cy * cz + sx * sy * sz; - return this - }, setFromMat4:function(m) { - var m00, m01, m02, m10, m11, m12, m20, m21, m22, tr, s, rs, lx, ly, lz; - m = m.data; - m00 = m[0]; - m01 = m[1]; - m02 = m[2]; - m10 = m[4]; - m11 = m[5]; - m12 = m[6]; - m20 = m[8]; - m21 = m[9]; - m22 = m[10]; - lx = 1 / Math.sqrt(m00 * m00 + m01 * m01 + m02 * m02); - ly = 1 / Math.sqrt(m10 * m10 + m11 * m11 + m12 * m12); - lz = 1 / Math.sqrt(m20 * m20 + m21 * m21 + m22 * m22); - m00 *= lx; - m01 *= lx; - m02 *= lx; - m10 *= ly; - m11 *= ly; - m12 *= ly; - m20 *= lz; - m21 *= lz; - m22 *= lz; - tr = m00 + m11 + m22; - if(tr >= 0) { - s = Math.sqrt(tr + 1); - this.w = s * 0.5; - s = 0.5 / s; - this.x = (m12 - m21) * s; - this.y = (m20 - m02) * s; - this.z = (m01 - m10) * s - }else { - if(m00 > m11) { - if(m00 > m22) { - rs = m00 - (m11 + m22) + 1; - rs = Math.sqrt(rs); - this.x = rs * 0.5; - rs = 0.5 / rs; - this.w = (m12 - m21) * rs; - this.y = (m01 + m10) * rs; - this.z = (m02 + m20) * rs - }else { - rs = m22 - (m00 + m11) + 1; - rs = Math.sqrt(rs); - this.z = rs * 0.5; - rs = 0.5 / rs; - this.w = (m01 - m10) * rs; - this.x = (m20 + m02) * rs; - this.y = (m21 + m12) * rs - } - }else { - if(m11 > m22) { - rs = m11 - (m22 + m00) + 1; - rs = Math.sqrt(rs); - this.y = rs * 0.5; - rs = 0.5 / rs; - this.w = (m20 - m02) * rs; - this.z = (m12 + m21) * rs; - this.x = (m10 + m01) * rs - }else { - rs = m22 - (m00 + m11) + 1; - rs = Math.sqrt(rs); - this.z = rs * 0.5; - rs = 0.5 / rs; - this.w = (m01 - m10) * rs; - this.x = (m20 + m02) * rs; - this.y = (m21 + m12) * rs - } - } - } - return this - }, slerp:function(lhs, rhs, alpha) { - var lx, ly, lz, lw, rx, ry, rz, rw; - lx = lhs.x; - ly = lhs.y; - lz = lhs.z; - lw = lhs.w; - rx = rhs.x; - ry = rhs.y; - rz = rhs.z; - rw = rhs.w; - var cosHalfTheta = lw * rw + lx * rx + ly * ry + lz * rz; - if(cosHalfTheta < 0) { - rw = -rw; - rx = -rx; - ry = -ry; - rz = -rz; - cosHalfTheta = -cosHalfTheta - } - if(Math.abs(cosHalfTheta) >= 1) { - this.w = lw; - this.x = lx; - this.y = ly; - this.z = lz; - return this - } - var halfTheta = Math.acos(cosHalfTheta); - var sinHalfTheta = Math.sqrt(1 - cosHalfTheta * cosHalfTheta); - if(Math.abs(sinHalfTheta) < 0.001) { - this.w = lw * 0.5 + rw * 0.5; - this.x = lx * 0.5 + rx * 0.5; - this.y = ly * 0.5 + ry * 0.5; - this.z = lz * 0.5 + rz * 0.5; - return this - } - var ratioA = Math.sin((1 - alpha) * halfTheta) / sinHalfTheta; - var ratioB = Math.sin(alpha * halfTheta) / sinHalfTheta; - this.w = lw * ratioA + rw * ratioB; - this.x = lx * ratioA + rx * ratioB; - this.y = ly * ratioA + ry * ratioB; - this.z = lz * ratioA + rz * ratioB; - return this - }, transformVector:function(vec, res) { - if(res === undefined) { - res = new pc.Vec3 - } - var x = vec.x, y = vec.y, z = vec.z; - var qx = this.x, qy = this.y, qz = this.z, qw = this.w; - var ix = qw * x + qy * z - qz * y; - var iy = qw * y + qz * x - qx * z; - var iz = qw * z + qx * y - qy * x; - var iw = -qx * x - qy * y - qz * z; - res.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; - res.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; - res.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; - return res - }, toString:function() { - return"[" + this.x + ", " + this.y + ", " + this.z + ", " + this.w + "]" - }}; - Object.defineProperty(Quat, "IDENTITY", {get:function() { - var identity = new Quat; - return function() { - return identity - } - }()}); - Object.defineProperty(Quat, "ZERO", {get:function() { - var zero = new Quat(0, 0, 0, 0); - return function() { - return zero - } - }()}); - return{Quat:Quat} -}()); -pc.extend(pc, function() { - var CURVE_LINEAR = 0; - var CURVE_SMOOTHSTEP = 1; - var CURVE_CATMULL = 2; - var CURVE_CARDINAL = 3; - var Curve = function(data) { - this.keys = []; - this.type = CURVE_SMOOTHSTEP; - this.tension = 0.5; - if(data) { - for(var i = 0;i < data.length - 1;i += 2) { - this.keys.push([data[i], data[i + 1]]) - } - } - this.sort() - }; - Curve.prototype = {add:function(time, value) { - var keys = this.keys; - var len = keys.length; - var i = 0; - for(;i < len;i++) { - if(keys[i][0] > time) { - break - } - } - var key = [time, value]; - this.keys.splice(i, 0, key); - return key - }, get:function(index) { - return this.keys[index] - }, sort:function() { - this.keys.sort(function(a, b) { - return a[0] - b[0] - }) - }, value:function(time) { - var keys = this.keys; - if(!keys.length) { - return 0 - } - if(time < keys[0][0]) { - return keys[0][1] - }else { - if(time > keys[keys.length - 1][0]) { - return keys[keys.length - 1][1] - } - } - var leftTime = 0; - var leftValue = keys.length ? keys[0][1] : 0; - var rightTime = 1; - var rightValue = 0; - for(var i = 0, len = keys.length;i < len;i++) { - if(keys[i][0] === time) { - return keys[i][1] - } - rightValue = keys[i][1]; - if(time < keys[i][0]) { - rightTime = keys[i][0]; - break - } - leftTime = keys[i][0]; - leftValue = keys[i][1] - } - var div = rightTime - leftTime; - var interpolation = div === 0 ? 0 : (time - leftTime) / div; - if(this.type === CURVE_SMOOTHSTEP) { - interpolation *= interpolation * (3 - 2 * interpolation) - }else { - if(this.type === CURVE_CATMULL || this.type === CURVE_CARDINAL) { - var p1 = leftValue; - var p2 = rightValue; - var p0 = p1 + (p1 - p2); - var p3 = p2 + (p2 - p1); - var dt1 = rightTime - leftTime; - var dt0 = dt1; - var dt2 = dt1; - if(i > 0) { - i = i - 1 - } - if(i > 0) { - p0 = keys[i - 1][1]; - dt0 = keys[i][0] - keys[i - 1][0] - } - if(keys.length > i + 1) { - dt1 = keys[i + 1][0] - keys[i][0] - } - if(keys.length > i + 2) { - dt2 = keys[i + 2][0] - keys[i + 1][0]; - p3 = keys[i + 2][1] - } - p0 = p1 + (p0 - p1) * dt1 / dt0; - p3 = p2 + (p3 - p2) * dt1 / dt2; - if(this.type === CURVE_CATMULL) { - return this._interpolateCatmullRom(p0, p1, p2, p3, interpolation) - }else { - return this._interpolateCardinal(p0, p1, p2, p3, interpolation, this.tension) - } - } - } - return pc.math.lerp(leftValue, rightValue, interpolation) - }, _interpolateHermite:function(p0, p1, t0, t1, s) { - var s2 = s * s; - var s3 = s * s * s; - var h0 = 2 * s3 - 3 * s2 + 1; - var h1 = -2 * s3 + 3 * s2; - var h2 = s3 - 2 * s2 + s; - var h3 = s3 - s2; - return p0 * h0 + p1 * h1 + t0 * h2 + t1 * h3 - }, _interpolateCardinal:function(p0, p1, p2, p3, s, t) { - var t0 = t * (p2 - p0); - var t1 = t * (p3 - p1); - return this._interpolateHermite(p1, p2, t0, t1, s) - }, _interpolateCatmullRom:function(p0, p1, p2, p3, s) { - return this._interpolateCardinal(p0, p1, p2, p3, s, 0.5) - }, closest:function(time) { - var keys = this.keys; - var length = keys.length; - var min = 2; - var result = null; - for(var i = 0;i < length;i++) { - var diff = Math.abs(time - keys[i][0]); - if(min >= diff) { - min = diff; - result = keys[i] - }else { - break - } - } - return result - }, clone:function() { - var result = new pc.Curve; - result.keys = pc.extend(result.keys, this.keys); - result.type = this.type; - return result - }, quantize:function(precision) { - precision = Math.max(precision, 2); - var values = new Float32Array(precision); - var step = 1 / (precision - 1); - for(var i = 0;i < precision;i++) { - var value = this.value(step * i); - values[i] = value - } - return values - }}; - Object.defineProperty(Curve.prototype, "length", {get:function() { - return this.keys.length - }}); - return{Curve:Curve, CURVE_LINEAR:CURVE_LINEAR, CURVE_SMOOTHSTEP:CURVE_SMOOTHSTEP, CURVE_CATMULL:CURVE_CATMULL, CURVE_CARDINAL:CURVE_CARDINAL} -}()); -pc.extend(pc, function() { - var CurveSet = function() { - var i; - this.curves = []; - this._type = pc.CURVE_SMOOTHSTEP; - if(arguments.length > 1) { - for(i = 0;i < arguments.length;i++) { - this.curves.push(new pc.Curve(arguments[i])) - } - }else { - if(arguments.length === 0) { - this.curves.push(new pc.Curve) - }else { - var arg = arguments[0]; - if(pc.type(arg) === "number") { - for(i = 0;i < arg;i++) { - this.curves.push(new pc.Curve) - } - }else { - for(i = 0;i < arg.length;i++) { - this.curves.push(new pc.Curve(arg[i])) - } - } - } - } - }; - CurveSet.prototype = {get:function(index) { - return this.curves[index] - }, value:function(time, result) { - var length = this.curves.length; - result = result || []; - result.length = length; - for(var i = 0;i < length;i++) { - result[i] = this.curves[i].value(time) - } - return result - }, clone:function() { - var result = new pc.CurveSet; - result.curves = []; - for(var i = 0;i < this.curves.length;i++) { - result.curves.push(this.curves[i].clone()) - } - result._type = this._type; - return result - }, quantize:function(precision) { - precision = Math.max(precision, 2); - var numCurves = this.curves.length; - var values = new Float32Array(precision * numCurves); - var step = 1 / (precision - 1); - var temp = []; - for(var i = 0;i < precision;i++) { - var value = this.value(step * i, temp); - if(numCurves == 1) { - values[i] = value[0] - }else { - for(var j = 0;j < numCurves;j++) { - values[i * numCurves + j] = value[j] - } - } - } - return values - }}; - Object.defineProperty(CurveSet.prototype, "length", {get:function() { - return this.curves.length - }}); - Object.defineProperty(CurveSet.prototype, "type", {get:function() { - return this._type - }, set:function(value) { - this._type = value; - for(var i = 0;i < this.curves.length;i++) { - this.curves[i].type = value - } - }}); - return{CurveSet:CurveSet} -}()); -pc.shape = function() { - var Shape = function Shape() { - }; - Shape.prototype = {containsPoint:function(point) { - throw new Error("Shape hasn't implemented containsPoint"); - }}; - return{Shape:Shape, Type:{CAPSULE:"Capsule", CONE:"Cone", CYLINDER:"Cylinder", CIRCLE:"Circle", RECT:"Rect"}} -}(); -pc.shape.intersection = function() { - return{aabbAabb:function(a, b) { - var aMax = a.getMax(); - var aMin = a.getMin(); - var bMax = b.getMax(); - var bMin = b.getMin(); - return aMin[0] <= bMax[0] && aMax[0] >= bMin[0] && aMin[1] <= bMax[1] && aMax[1] >= bMin[1] && aMin[2] <= bMax[2] && aMax[2] >= bMin[2] - }, rayAabb:function(rayOrigin, rayDir, aabb) { - var diff = new pc.Vec3, absDiff, absDir, cross = new pc.Vec3, prod = new pc.Vec3, i; - diff.sub2(rayOrigin, aabb.center); - absDiff = new pc.Vec3(Math.abs(diff.x), Math.abs(diff.y), Math.abs(diff.z)); - prod.mul2(diff, rayDir); - if(absDiff.x > aabb.halfExtents.x && prod.x >= 0) { - return false - } - if(absDiff.y > aabb.halfExtents.y && prod.y >= 0) { - return false - } - if(absDiff.z > aabb.halfExtents.z && prod.z >= 0) { - return false - } - absDir = new pc.Vec3(Math.abs(rayDir.x), Math.abs(rayDir.y), Math.abs(rayDir.z)); - cross.cross(rayDir, diff); - cross.set(Math.abs(cross.x), Math.abs(cross.y), Math.abs(cross.z)); - if(cross.x > aabb.halfExtents.y * absDir.z + aabb.halfExtents.z * absDir.y) { - return false - } - if(cross.y > aabb.halfExtents.x * absDir.z + aabb.halfExtents.z * absDir.x) { - return false - } - if(cross.z > aabb.halfExtents.x * absDir.y + aabb.halfExtents.y * absDir.x) { - return false - } - return true - }, raySphere:function(rayOrigin, rayDir, sphere, result) { - var diff = new pc.Vec3; - var a = 0; - var b = 0; - var c = 0; - var discr = 0; - result = result || {}; - diff.sub2(rayOrigin, sphere.center); - if(diff.dot(diff) < sphere.radius * sphere.radius) { - result.success = true; - result.t = 0; - return true - } - a = rayDir.dot(rayDir); - b = 2 * rayDir.dot(diff); - c = sphere.center.dot(sphere.center); - c += rayOrigin.dot(rayOrigin); - c -= 2 * sphere.center.dot(rayOrigin); - c -= sphere.radius * sphere.radius; - discr = b * b - 4 * a * c; - if(discr < 0) { - result.success = false; - result.t = 0; - return false - } - result.success = true; - result.t = (-b - Math.sqrt(discr)) / (2 * a); - return true - }, rayTriangle:function(rayOrigin, rayDir, t, intersection) { - var w0 = rayOrigin.clone().sub(t.v0); - var a = -t.n.dot(w0); - var b = t.n.dot(rayDir); - if(Math.fabs(b) < 1E-8) { - if(a === 0) { - return 2 - }else { - return 0 - } - } - var r = a / b; - if(r < 0) { - return 0 - } - var fromOrigin = rayDir.clone().scale(r); - intersection.add2(rayOrigin, fromOrigin); - var w = (new pc.Vec3).sub2(intersection, t.v0); - var wu = w.dot(t.u); - var wv = w.dot(t.v); - var s = (t.uv * wv - t.vv * wu) / t.d; - if(s < 0 || s > 1) { - return 0 - } - var t = (t.uv * wu - t.uu * wv) / t.d; - if(t < 0 || s + t > 1) { - return 0 - } - return 1 - }} -}(); -pc.extend(pc.shape, function() { - pc.shape.Type.AABB = "Aabb"; - var Aabb = function Aabb(center, halfExtents) { - this.center = center || new pc.Vec3(0, 0, 0); - this.halfExtents = halfExtents || new pc.Vec3(0.5, 0.5, 0.5); - this.type = pc.shape.Type.AABB - }; - Aabb = pc.inherits(Aabb, pc.shape.Shape); - Aabb.prototype.add = function(other) { - var tc = this.center; - var th = this.halfExtents; - var tminx = tc.x - th.x; - var tmaxx = tc.x + th.x; - var tminy = tc.y - th.y; - var tmaxy = tc.y + th.y; - var tminz = tc.z - th.z; - var tmaxz = tc.z + th.z; - var oc = other.center; - var oh = other.halfExtents; - var ominx = oc.x - oh.x; - var omaxx = oc.x + oh.x; - var ominy = oc.y - oh.y; - var omaxy = oc.y + oh.y; - var ominz = oc.z - oh.z; - var omaxz = oc.z + oh.z; - if(ominx < tminx) { - tminx = ominx - } - if(omaxx > tmaxx) { - tmaxx = omaxx - } - if(ominy < tminy) { - tminy = ominy - } - if(omaxy > tmaxy) { - tmaxy = omaxy - } - if(ominz < tminz) { - tminz = ominz - } - if(omaxz > tmaxz) { - tmaxz = omaxz - } - tc.set(tminx + tmaxx, tminy + tmaxy, tminz + tmaxz).scale(0.5); - th.set(tmaxx - tminx, tmaxy - tminy, tmaxz - tminz).scale(0.5) - }; - Aabb.prototype.copy = function(src) { - this.center.copy(src.center); - this.halfExtents.copy(src.halfExtents); - this.type = src.type - }; - Aabb.prototype.setMinMax = function(min, max) { - this.center.add2(max, min).scale(0.5); - this.halfExtents.sub2(max, min).scale(0.5) - }; - Aabb.prototype.getMin = function() { - return this.center.clone().sub(this.halfExtents) - }; - Aabb.prototype.getMax = function() { - return this.center.clone().add(this.halfExtents) - }; - Aabb.prototype.containsPoint = function(point) { - var min = this.getMin(), max = this.getMax(), i; - for(i = 0;i < 3;++i) { - if(point.data[i] < min.data[i] || point.data[i] > max.data[i]) { - return false - } - } - return true - }; - Aabb.prototype.setFromTransformedAabb = function(aabb, m) { - var bc = this.center; - var br = this.halfExtents; - var ac = aabb.center.data; - var ar = aabb.halfExtents.data; - m = m.data; - var mx0 = m[0]; - var mx1 = m[4]; - var mx2 = m[8]; - var my0 = m[1]; - var my1 = m[5]; - var my2 = m[9]; - var mz0 = m[2]; - var mz1 = m[6]; - var mz2 = m[10]; - var mx0a = Math.abs(mx0); - var mx1a = Math.abs(mx1); - var mx2a = Math.abs(mx2); - var my0a = Math.abs(my0); - var my1a = Math.abs(my1); - var my2a = Math.abs(my2); - var mz0a = Math.abs(mz0); - var mz1a = Math.abs(mz1); - var mz2a = Math.abs(mz2); - bc.set(m[12] + mx0 * ac[0] + mx1 * ac[1] + mx2 * ac[2], m[13] + my0 * ac[0] + my1 * ac[1] + my2 * ac[2], m[14] + mz0 * ac[0] + mz1 * ac[1] + mz2 * ac[2]); - br.set(mx0a * ar[0] + mx1a * ar[1] + mx2a * ar[2], my0a * ar[0] + my1a * ar[1] + my2a * ar[2], mz0a * ar[0] + mz1a * ar[1] + mz2a * ar[2]) - }; - Aabb.prototype.compute = function(vertices) { - var min = new pc.Vec3(vertices[0], vertices[1], vertices[2]); - var max = new pc.Vec3(vertices[0], vertices[1], vertices[2]); - var numVerts = vertices.length / 3; - for(var i = 1;i < numVerts;i++) { - var x = vertices[i * 3 + 0]; - var y = vertices[i * 3 + 1]; - var z = vertices[i * 3 + 2]; - if(x < min.x) { - min.x = x - } - if(y < min.y) { - min.y = y - } - if(z < min.z) { - min.z = z - } - if(x > max.x) { - max.x = x - } - if(y > max.y) { - max.y = y - } - if(z > max.z) { - max.z = z - } - } - this.setMinMax(min, max) - }; - return{Aabb:Aabb} -}()); -pc.extend(pc.shape, function() { - pc.shape.Type.BOX = "Box"; - var center = new pc.Vec3; - var p = new pc.Vec3; - var t = new pc.Mat4; - var scale = new pc.Mat4; - function Box(transform, halfExtents) { - this.transform = transform === undefined ? new pc.Mat4 : transform; - this.halfExtents = halfExtents === undefined ? new pc.Vec3(0.5, 0.5, 0.5) : halfExtents; - this.type = pc.shape.Type.BOX - } - Box = pc.inherits(Box, pc.shape.Shape); - Box.prototype.containsPoint = function(point) { - this.transform.getTranslation(center); - var extents = this.getHalfExtents(); - t.copy(this.transform); - p.copy(extents).scale(2); - scale.setTRS(pc.Vec3.ZERO, pc.Quat.IDENTITY, p); - t.mul(scale).invert(); - t.transformPoint(point, p); - var min = -0.5; - var max = 0.5; - if(p.x < min || p.x > max) { - return false - }else { - if(p.y < min || p.y > max) { - return false - }else { - if(p.z < min || p.z > max) { - return false - } - } - } - return true - }; - Box.prototype.getHalfExtents = function() { - return this.halfExtents - }; - return{Box:Box} -}()); -pc.extend(pc, function() { - var viewProj = new pc.Mat4; - var Frustum = function Frustum(projectionMatrix, viewMatrix) { - projectionMatrix = projectionMatrix || (new pc.Mat4).setPerspective(90, 16 / 9, 0.1, 1E3); - viewMatrix = viewMatrix || new pc.Mat4; - this.planes = []; - for(var i = 0;i < 6;i++) { - this.planes[i] = [] - } - this.update(projectionMatrix, viewMatrix) - }; - Frustum.prototype = {update:function(projectionMatrix, viewMatrix) { - viewProj.mul2(projectionMatrix, viewMatrix); - var vpm = viewProj.data; - this.planes[0][0] = vpm[3] - vpm[0]; - this.planes[0][1] = vpm[7] - vpm[4]; - this.planes[0][2] = vpm[11] - vpm[8]; - this.planes[0][3] = vpm[15] - vpm[12]; - t = Math.sqrt(this.planes[0][0] * this.planes[0][0] + this.planes[0][1] * this.planes[0][1] + this.planes[0][2] * this.planes[0][2]); - this.planes[0][0] /= t; - this.planes[0][1] /= t; - this.planes[0][2] /= t; - this.planes[0][3] /= t; - this.planes[1][0] = vpm[3] + vpm[0]; - this.planes[1][1] = vpm[7] + vpm[4]; - this.planes[1][2] = vpm[11] + vpm[8]; - this.planes[1][3] = vpm[15] + vpm[12]; - t = Math.sqrt(this.planes[1][0] * this.planes[1][0] + this.planes[1][1] * this.planes[1][1] + this.planes[1][2] * this.planes[1][2]); - this.planes[1][0] /= t; - this.planes[1][1] /= t; - this.planes[1][2] /= t; - this.planes[1][3] /= t; - this.planes[2][0] = vpm[3] + vpm[1]; - this.planes[2][1] = vpm[7] + vpm[5]; - this.planes[2][2] = vpm[11] + vpm[9]; - this.planes[2][3] = vpm[15] + vpm[13]; - t = Math.sqrt(this.planes[2][0] * this.planes[2][0] + this.planes[2][1] * this.planes[2][1] + this.planes[2][2] * this.planes[2][2]); - this.planes[2][0] /= t; - this.planes[2][1] /= t; - this.planes[2][2] /= t; - this.planes[2][3] /= t; - this.planes[3][0] = vpm[3] - vpm[1]; - this.planes[3][1] = vpm[7] - vpm[5]; - this.planes[3][2] = vpm[11] - vpm[9]; - this.planes[3][3] = vpm[15] - vpm[13]; - t = Math.sqrt(this.planes[3][0] * this.planes[3][0] + this.planes[3][1] * this.planes[3][1] + this.planes[3][2] * this.planes[3][2]); - this.planes[3][0] /= t; - this.planes[3][1] /= t; - this.planes[3][2] /= t; - this.planes[3][3] /= t; - this.planes[4][0] = vpm[3] - vpm[2]; - this.planes[4][1] = vpm[7] - vpm[6]; - this.planes[4][2] = vpm[11] - vpm[10]; - this.planes[4][3] = vpm[15] - vpm[14]; - t = Math.sqrt(this.planes[4][0] * this.planes[4][0] + this.planes[4][1] * this.planes[4][1] + this.planes[4][2] * this.planes[4][2]); - this.planes[4][0] /= t; - this.planes[4][1] /= t; - this.planes[4][2] /= t; - this.planes[4][3] /= t; - this.planes[5][0] = vpm[3] + vpm[2]; - this.planes[5][1] = vpm[7] + vpm[6]; - this.planes[5][2] = vpm[11] + vpm[10]; - this.planes[5][3] = vpm[15] + vpm[14]; - t = Math.sqrt(this.planes[5][0] * this.planes[5][0] + this.planes[5][1] * this.planes[5][1] + this.planes[5][2] * this.planes[5][2]); - this.planes[5][0] /= t; - this.planes[5][1] /= t; - this.planes[5][2] /= t; - this.planes[5][3] /= t - }, containsPoint:function(point) { - for(var p = 0;p < 6;p++) { - if(this.planes[p][0] * point.x + this.planes[p][1] * point.y + this.planes[p][2] * point.z + this.planes[p][3] <= 0) { - return false - } - } - return true - }, containsSphere:function(sphere) { - var c = 0; - var d; - for(p = 0;p < 6;p++) { - d = this.planes[p][0] * sphere.center.x + this.planes[p][1] * sphere.center.y + this.planes[p][2] * sphere.center.z + this.planes[p][3]; - if(d <= -sphere.radius) { - return 0 - } - if(d > sphere.radius) { - c++ - } - } - return c === 6 ? 2 : 1 - }}; - return{Frustum:Frustum} -}()); -pc.extend(pc.shape, function() { - pc.shape.Type.PLANE = "Plane"; - var Plane = function Plane(point, normal) { - this.normal = normal || new pc.Vec3(0, 0, 1); - this.point = point || new pc.Vec3(0, 0, 0); - this.d = -this.normal.dot(this.point); - this.type = pc.shape.Type.PLANE - }; - Plane = pc.inherits(Plane, pc.shape.Shape); - Plane.prototype.containsPoint = function(point) { - return false - }; - Plane.prototype.distance = function(pos) { - return this.normal.dot(pos) + this.d - }; - Plane.prototype.intersect = function(p0, p1) { - var d0 = this.distance(p0); - var d1 = this.distance(p1); - return d0 / (d0 - d1) - }; - Plane.prototype.intersectPosition = function(p0, p1) { - var t = this.intersect(p0, p1); - var r = new pc.Vec3; - r.lerp(p0, p1, t); - return r - }; - return{Plane:Plane} -}()); -pc.extend(pc.shape, function() { - pc.shape.Type.SPHERE = "Sphere"; - function Sphere(center, radius) { - this.center = center === undefined ? new pc.Vec3(0, 0, 0) : center; - this.radius = radius === undefined ? 1 : radius; - this.type = pc.shape.Type.SPHERE - } - Sphere = pc.inherits(Sphere, pc.shape.Shape); - Sphere.prototype.containsPoint = function() { - var centerToPoint = new pc.Vec3; - return function(point) { - var lenSq = centerToPoint.sub2(point, this.center).lengthSq(); - var r = this.radius; - return lenSq < r * r - } - }(); - Sphere.prototype.compute = function(vertices) { - var i; - var numVerts = vertices.length / 3; - var vertex = new pc.Vec3(0, 0, 0); - var avgVertex = new pc.Vec3(0, 0, 0); - var sum = new pc.Vec3(0, 0, 0); - for(i = 0;i < numVerts;i++) { - vertex.set(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]); - sum.addSelf(vertex); - if(i % 100 === 0) { - sum.scale(1 / numVerts); - avgVertex.add(sum); - sum.set(0, 0, 0) - } - } - sum.scale(1 / numVerts); - avgVertex.add(sum); - this.center.copy(avgVertex); - var maxDistSq = 0; - var centerToVert = new pc.Vec3(0, 0, 0); - for(i = 0;i < numVerts;i++) { - vertex.set(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]); - centerToVert.sub2(vertex, this.center); - maxDistSq = Math.max(centerToVert.lengthSq(), maxDistSq) - } - this.radius = Math.sqrt(maxDistSq) - }; - Sphere.prototype.intersectRay = function(start, direction) { - var m = start.clone().sub(this.center); - var b = m.dot(direction); - var c = m.dot(m) - this.radius * this.radius; - if(c > 0 && b > 0) { - return null - } - var discr = b * b - c; - if(discr < 0) { - return null - } - t = Math.abs(-b - Math.sqrt(discr)); - return direction.clone().scale(t).add(start) - }; - return{Sphere:Sphere} -}()); -pc.extend(pc.shape, function() { - pc.shape.Type.TORUS = "Torus"; - var Torus = function Torus(transform, iradius, oradius) { - this.transform = transform; - this.iradius = iradius; - this.oradius = oradius; - this.type = pc.shape.Type.TORUS - }; - Torus = pc.inherits(Torus, pc.shape.Shape); - Torus.prototype.containsPoint = function(point) { - throw new Error("Not implemented yet"); - }; - return{Torus:Torus} -}()); -(function() { - var enums = {ADDRESS_REPEAT:0, ADDRESS_CLAMP_TO_EDGE:1, ADDRESS_MIRRORED_REPEAT:2, BLENDMODE_ZERO:0, BLENDMODE_ONE:1, BLENDMODE_SRC_COLOR:2, BLENDMODE_ONE_MINUS_SRC_COLOR:3, BLENDMODE_DST_COLOR:4, BLENDMODE_ONE_MINUS_DST_COLOR:5, BLENDMODE_SRC_ALPHA:6, BLENDMODE_SRC_ALPHA_SATURATE:7, BLENDMODE_ONE_MINUS_SRC_ALPHA:8, BLENDMODE_DST_ALPHA:9, BLENDMODE_ONE_MINUS_DST_ALPHA:10, BLENDEQUATION_ADD:0, BLENDEQUATION_SUBTRACT:1, BLENDEQUATION_REVERSE_SUBTRACT:2, BUFFER_STATIC:0, BUFFER_DYNAMIC:1, BUFFER_STREAM:2, - CLEARFLAG_COLOR:1, CLEARFLAG_DEPTH:2, CLEARFLAG_STENCIL:4, CULLFACE_NONE:0, CULLFACE_BACK:1, CULLFACE_FRONT:2, CULLFACE_FRONTANDBACK:3, ELEMENTTYPE_INT8:0, ELEMENTTYPE_UINT8:1, ELEMENTTYPE_INT16:2, ELEMENTTYPE_UINT16:3, ELEMENTTYPE_INT32:4, ELEMENTTYPE_UINT32:5, ELEMENTTYPE_FLOAT32:6, FILTER_NEAREST:0, FILTER_LINEAR:1, FILTER_NEAREST_MIPMAP_NEAREST:2, FILTER_NEAREST_MIPMAP_LINEAR:3, FILTER_LINEAR_MIPMAP_NEAREST:4, FILTER_LINEAR_MIPMAP_LINEAR:5, INDEXFORMAT_UINT8:0, INDEXFORMAT_UINT16:1, INDEXFORMAT_UINT32:2, - PIXELFORMAT_A8:0, PIXELFORMAT_L8:1, PIXELFORMAT_L8_A8:2, PIXELFORMAT_R5_G6_B5:3, PIXELFORMAT_R5_G5_B5_A1:4, PIXELFORMAT_R4_G4_B4_A4:5, PIXELFORMAT_R8_G8_B8:6, PIXELFORMAT_R8_G8_B8_A8:7, PIXELFORMAT_DXT1:8, PIXELFORMAT_DXT3:9, PIXELFORMAT_DXT5:10, PIXELFORMAT_RGB16F:11, PIXELFORMAT_RGBA16F:12, PIXELFORMAT_RGB32F:13, PIXELFORMAT_RGBA32F:14, PIXELFORMAT_ETC1:15, PRIMITIVE_POINTS:0, PRIMITIVE_LINES:1, PRIMITIVE_LINELOOP:2, PRIMITIVE_LINESTRIP:3, PRIMITIVE_TRIANGLES:4, PRIMITIVE_TRISTRIP:5, PRIMITIVE_TRIFAN:6, - SEMANTIC_POSITION:"POSITION", SEMANTIC_NORMAL:"NORMAL", SEMANTIC_TANGENT:"TANGENT", SEMANTIC_BLENDWEIGHT:"BLENDWEIGHT", SEMANTIC_BLENDINDICES:"BLENDINDICES", SEMANTIC_COLOR:"COLOR", SEMANTIC_TEXCOORD0:"TEXCOORD0", SEMANTIC_TEXCOORD1:"TEXCOORD1", SEMANTIC_TEXCOORD2:"TEXCOORD2", SEMANTIC_TEXCOORD3:"TEXCOORD3", SEMANTIC_TEXCOORD4:"TEXCOORD4", SEMANTIC_TEXCOORD5:"TEXCOORD5", SEMANTIC_TEXCOORD6:"TEXCOORD6", SEMANTIC_TEXCOORD7:"TEXCOORD7", SEMANTIC_ATTR0:"ATTR0", SEMANTIC_ATTR1:"ATTR1", SEMANTIC_ATTR2:"ATTR2", - SEMANTIC_ATTR3:"ATTR3", SEMANTIC_ATTR4:"ATTR4", SEMANTIC_ATTR5:"ATTR5", SEMANTIC_ATTR6:"ATTR6", SEMANTIC_ATTR7:"ATTR7", SEMANTIC_ATTR8:"ATTR8", SEMANTIC_ATTR9:"ATTR9", SEMANTIC_ATTR10:"ATTR10", SEMANTIC_ATTR11:"ATTR11", SEMANTIC_ATTR12:"ATTR12", SEMANTIC_ATTR13:"ATTR13", SEMANTIC_ATTR14:"ATTR14", SEMANTIC_ATTR15:"ATTR15", TEXTURELOCK_READ:1, TEXTURELOCK_WRITE:2, UNIFORMTYPE_BOOL:0, UNIFORMTYPE_INT:1, UNIFORMTYPE_FLOAT:2, UNIFORMTYPE_VEC2:3, UNIFORMTYPE_VEC3:4, UNIFORMTYPE_VEC4:5, UNIFORMTYPE_IVEC2:6, - UNIFORMTYPE_IVEC3:7, UNIFORMTYPE_IVEC4:8, UNIFORMTYPE_BVEC2:9, UNIFORMTYPE_BVEC3:10, UNIFORMTYPE_BVEC4:11, UNIFORMTYPE_MAT2:12, UNIFORMTYPE_MAT3:13, UNIFORMTYPE_MAT4:14, UNIFORMTYPE_TEXTURE2D:15, UNIFORMTYPE_TEXTURECUBE:16}; - pc.extend(pc, enums); - pc.gfx = {}; - pc.extend(pc.gfx, enums) -})(); -pc.extend(pc, function() { - var ScopeId = function(name) { - this.name = name; - this.value = null; - this.versionObject = new pc.VersionedObject - }; - ScopeId.prototype = {setValue:function(value) { - this.value = value; - this.versionObject.increment() - }, getValue:function(value) { - return this.value - }}; - return{ScopeId:ScopeId} -}()); -pc.extend(pc, function() { - var ScopeSpace = function(name) { - this.name = name; - this.variables = {}; - this.namespaces = {} - }; - ScopeSpace.prototype = {resolve:function(name) { - if(this.variables.hasOwnProperty(name) === false) { - this.variables[name] = new pc.ScopeId(name) - } - return this.variables[name] - }, getSubSpace:function(name) { - if(this.namespaces.hasOwnProperty(name) === false) { - this.namespaces[name] = new pc.ScopeSpace(name); - logDEBUG("Added ScopeSpace: " + name) - } - return this.namespaces[name] - }}; - return{ScopeSpace:ScopeSpace} -}()); -pc.extend(pc, function() { - var Version = function() { - this.globalId = 0; - this.revision = 0 - }; - Version.prototype = {equals:function(other) { - return this.globalId === other.globalId && this.revision === other.revision - }, notequals:function(other) { - return this.globalId !== other.globalId || this.revision !== other.revision - }, copy:function(other) { - this.globalId = other.globalId; - this.revision = other.revision - }, reset:function() { - this.globalId = 0; - this.revision = 0 - }}; - return{Version:Version} -}()); -pc.extend(pc, function() { - var idCounter = 0; - var VersionedObject = function() { - idCounter++; - this.version = new pc.Version; - this.version.globalId = idCounter - }; - VersionedObject.prototype = {increment:function() { - this.version.revision++ - }}; - return{VersionedObject:VersionedObject} -}()); -pc.extend(pc, function() { - function VertexIteratorSetter(buffer, vertexElement) { - this.index = 0; - switch(vertexElement.dataType) { - case pc.ELEMENTTYPE_INT8: - this.array = new Int8Array(buffer, vertexElement.offset); - break; - case pc.ELEMENTTYPE_UINT8: - this.array = new Uint8Array(buffer, vertexElement.offset); - break; - case pc.ELEMENTTYPE_INT16: - this.array = new Int16Array(buffer, vertexElement.offset); - break; - case pc.ELEMENTTYPE_UINT16: - this.array = new Uint16Array(buffer, vertexElement.offset); - break; - case pc.ELEMENTTYPE_INT32: - this.array = new Int32Array(buffer, vertexElement.offset); - break; - case pc.ELEMENTTYPE_UINT32: - this.array = new Uint32Array(buffer, vertexElement.offset); - break; - case pc.ELEMENTTYPE_FLOAT32: - this.array = new Float32Array(buffer, vertexElement.offset); - break - } - switch(vertexElement.numComponents) { - case 1: - this.set = VertexIteratorSetter_set1; - break; - case 2: - this.set = VertexIteratorSetter_set2; - break; - case 3: - this.set = VertexIteratorSetter_set3; - break; - case 4: - this.set = VertexIteratorSetter_set4; - break - } - } - function VertexIteratorSetter_set1(a) { - this.array[this.index] = a - } - function VertexIteratorSetter_set2(a, b) { - this.array[this.index] = a; - this.array[this.index + 1] = b - } - function VertexIteratorSetter_set3(a, b, c) { - this.array[this.index] = a; - this.array[this.index + 1] = b; - this.array[this.index + 2] = c - } - function VertexIteratorSetter_set4(a, b, c, d) { - this.array[this.index] = a; - this.array[this.index + 1] = b; - this.array[this.index + 2] = c; - this.array[this.index + 3] = d - } - function VertexIterator(vertexBuffer) { - this.vertexBuffer = vertexBuffer; - this.buffer = this.vertexBuffer.lock(); - this.setters = []; - this.element = {}; - var vertexFormat = this.vertexBuffer.getFormat(); - for(var i = 0;i < vertexFormat.elements.length;i++) { - var vertexElement = vertexFormat.elements[i]; - this.setters[i] = new VertexIteratorSetter(this.buffer, vertexElement); - this.element[vertexElement.name] = this.setters[i] - } - } - VertexIterator.prototype = {next:function() { - var i = 0; - var setters = this.setters; - var numSetters = this.setters.length; - var vertexFormat = this.vertexBuffer.getFormat(); - while(i < numSetters) { - var setter = setters[i++]; - setter.index += vertexFormat.size / setter.array.constructor.BYTES_PER_ELEMENT - } - }, end:function() { - this.vertexBuffer.unlock() - }}; - return{VertexIterator:VertexIterator} -}()); -pc.extend(pc, function() { - var _typeSize = []; - _typeSize[pc.ELEMENTTYPE_INT8] = 1; - _typeSize[pc.ELEMENTTYPE_UINT8] = 1; - _typeSize[pc.ELEMENTTYPE_INT16] = 2; - _typeSize[pc.ELEMENTTYPE_UINT16] = 2; - _typeSize[pc.ELEMENTTYPE_INT32] = 4; - _typeSize[pc.ELEMENTTYPE_UINT32] = 4; - _typeSize[pc.ELEMENTTYPE_FLOAT32] = 4; - var VertexFormat = function(graphicsDevice, description) { - var i; - this.elements = []; - this.hasUv1 = false; - this.hasColor = false; - this.size = 0; - for(var i = 0, len = description.length;i < len;i++) { - var elementDesc = description[i]; - var element = {name:elementDesc.semantic, offset:0, stride:0, stream:-1, scopeId:graphicsDevice.scope.resolve(elementDesc.semantic), dataType:elementDesc.type, numComponents:elementDesc.components, normalize:elementDesc.normalize === undefined ? false : elementDesc.normalize, size:elementDesc.components * _typeSize[elementDesc.type]}; - this.elements.push(element); - this.size += element.size; - if(elementDesc.semantic === pc.SEMANTIC_TEXCOORD1) { - this.hasUv1 = true - }else { - if(elementDesc.semantic === pc.SEMANTIC_COLOR) { - this.hasColor = true - } - } - } - var offset = 0; - for(var i = 0, len = this.elements.length;i < len;i++) { - var element = this.elements[i]; - element.offset = offset; - element.stride = this.size; - offset += element.size - } - }; - return{VertexFormat:VertexFormat} -}()); -pc.extend(pc, function() { - var VertexBuffer = function(graphicsDevice, format, numVertices, usage, initialData) { - this.usage = usage || pc.BUFFER_STATIC; - this.format = format; - this.numVertices = numVertices; - this.numBytes = format.size * numVertices; - this.device = graphicsDevice; - var gl = this.device.gl; - this.bufferId = gl.createBuffer(); - if(initialData && this.setData(initialData)) { - return - }else { - this.storage = new ArrayBuffer(this.numBytes) - } - }; - VertexBuffer.prototype = {destroy:function() { - var gl = this.device.gl; - gl.deleteBuffer(this.bufferId) - }, getFormat:function() { - return this.format - }, getUsage:function() { - return this.usage - }, getNumVertices:function() { - return this.numVertices - }, lock:function() { - return this.storage - }, unlock:function() { - var gl = this.device.gl; - var glUsage; - switch(this.usage) { - case pc.BUFFER_STATIC: - glUsage = gl.STATIC_DRAW; - break; - case pc.BUFFER_DYNAMIC: - glUsage = gl.DYNAMIC_DRAW; - break; - case pc.BUFFER_STREAM: - glUsage = gl.STREAM_DRAW; - break - } - gl.bindBuffer(gl.ARRAY_BUFFER, this.bufferId); - gl.bufferData(gl.ARRAY_BUFFER, this.storage, glUsage) - }, setData:function(data) { - if(data.byteLength !== this.numBytes) { - console.error("VertexBuffer: wrong initial data size: expected " + this.numBytes + ", got " + data.byteLength); - return false - } - this.storage = data; - this.unlock(); - return true - }}; - return{VertexBuffer:VertexBuffer} -}()); -pc.extend(pc, function() { - var IndexBuffer = function(graphicsDevice, format, numIndices, usage) { - this.usage = usage || pc.BUFFER_STATIC; - this.format = format; - this.numIndices = numIndices; - this.device = graphicsDevice; - var gl = this.device.gl; - this.bufferId = gl.createBuffer(); - var bytesPerIndex; - if(format === pc.INDEXFORMAT_UINT8) { - bytesPerIndex = 1; - this.glFormat = gl.UNSIGNED_BYTE - }else { - if(format === pc.INDEXFORMAT_UINT16) { - bytesPerIndex = 2; - this.glFormat = gl.UNSIGNED_SHORT - }else { - if(format === pc.INDEXFORMAT_UINT32) { - bytesPerIndex = 4; - this.glFormat = gl.UNSIGNED_INT - } - } - } - var numBytes = this.numIndices * bytesPerIndex; - this.storage = new ArrayBuffer(numBytes) - }; - IndexBuffer.prototype = {destroy:function() { - var gl = this.device.gl; - gl.deleteBuffer(this.bufferId) - }, getFormat:function() { - return this.format - }, getNumIndices:function() { - return this.numIndices - }, lock:function() { - return this.storage - }, unlock:function() { - var gl = this.device.gl; - var glUsage; - switch(this.usage) { - case pc.BUFFER_STATIC: - glUsage = gl.STATIC_DRAW; - break; - case pc.BUFFER_DYNAMIC: - glUsage = gl.DYNAMIC_DRAW; - break; - case pc.BUFFER_STREAM: - glUsage = gl.STREAM_DRAW; - break - } - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufferId); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.storage, glUsage) - }}; - return{IndexBuffer:IndexBuffer} -}()); -pc.extend(pc, function() { - var Texture = function(graphicsDevice, options) { - this.device = graphicsDevice; - var width = 4; - var height = 4; - var format = pc.PIXELFORMAT_R8_G8_B8_A8; - var cubemap = false; - var autoMipmap = true; - var rgbm = false; - var fixCubemapSeams = false; - if(options !== undefined) { - width = options.width !== undefined ? options.width : width; - height = options.height !== undefined ? options.height : height; - format = options.format !== undefined ? options.format : format; - cubemap = options.cubemap !== undefined ? options.cubemap : cubemap; - autoMipmap = options.autoMipmap !== undefined ? options.autoMipmap : autoMipmap; - rgbm = options.rgbm !== undefined ? options.rgbm : rgbm; - fixCubemapSeams = options.fixCubemapSeams !== undefined ? options.fixCubemapSeams : fixCubemapSeams - } - this.name = null; - this.autoMipmap = autoMipmap; - this.rgbm = rgbm; - this.fixCubemapSeams = fixCubemapSeams; - this._cubemap = cubemap; - this._format = format; - this._compressed = format === pc.PIXELFORMAT_DXT1 || format === pc.PIXELFORMAT_DXT3 || format === pc.PIXELFORMAT_DXT5 || format === pc.PIXELFORMAT_ETC1; - this._width = width || 4; - this._height = height || 4; - this._addressU = pc.ADDRESS_REPEAT; - this._addressV = pc.ADDRESS_REPEAT; - if(pc.math.powerOfTwo(this._width) && pc.math.powerOfTwo(this._height)) { - this._minFilter = pc.FILTER_LINEAR_MIPMAP_LINEAR - }else { - this._minFilter = pc.FILTER_LINEAR - } - this._magFilter = pc.FILTER_LINEAR; - this._anisotropy = 1; - this._levels = cubemap ? [[null, null, null, null, null, null]] : [null]; - this._lockedLevel = -1; - this._needsUpload = true - }; - Object.defineProperty(Texture.prototype, "minFilter", {get:function() { - return this._minFilter - }, set:function(filter) { - if(!(pc.math.powerOfTwo(this._width) && pc.math.powerOfTwo(this._height))) { - if(!(filter === pc.FILTER_NEAREST || filter === pc.FILTER_LINEAR)) { - logWARNING("Invalid minification filter mode set on non power of two texture. Forcing linear addressing."); - filter = pc.FILTER_LINEAR - } - } - this._minFilter = filter - }}); - Object.defineProperty(Texture.prototype, "magFilter", {get:function() { - return this._magFilter - }, set:function(magFilter) { - if(!(magFilter === pc.FILTER_NEAREST || magFilter === pc.FILTER_LINEAR)) { - logWARNING("Invalid magnification filter mode. Must be set to FILTER_NEAREST or FILTER_LINEAR.") - } - this._magFilter = magFilter - }}); - Object.defineProperty(Texture.prototype, "addressU", {get:function() { - return this._addressU - }, set:function(addressU) { - if(!(pc.math.powerOfTwo(this._width) && pc.math.powerOfTwo(this._height))) { - if(addressU !== pc.ADDRESS_CLAMP_TO_EDGE) { - logWARNING("Invalid address mode in U set on non power of two texture. Forcing clamp to edge addressing."); - addressU = pc.ADDRESS_CLAMP_TO_EDGE - } - } - this._addressU = addressU - }}); - Object.defineProperty(Texture.prototype, "addressV", {get:function() { - return this._addressV - }, set:function(addressV) { - if(!(pc.math.powerOfTwo(this._width) && pc.math.powerOfTwo(this._height))) { - if(addressV !== pc.ADDRESS_CLAMP_TO_EDGE) { - logWARNING("Invalid address mode in V set on non power of two texture. Forcing clamp to edge addressing."); - addressV = pc.ADDRESS_CLAMP_TO_EDGE - } - } - this._addressV = addressV - }}); - Object.defineProperty(Texture.prototype, "anisotropy", {get:function() { - return this._anisotropy - }, set:function(anisotropy) { - this._anisotropy = pc.math.clamp(anisotropy, 1, this.device.maxAnisotropy) - }}); - Object.defineProperty(Texture.prototype, "width", {get:function() { - return this._width - }}); - Object.defineProperty(Texture.prototype, "height", {get:function() { - return this._height - }}); - Object.defineProperty(Texture.prototype, "format", {get:function() { - return this._format - }}); - Object.defineProperty(Texture.prototype, "cubemap", {get:function() { - return this._cubemap - }}); - pc.extend(Texture.prototype, {bind:function() { - }, destroy:function() { - if(this._glTextureId) { - var gl = this.device.gl; - gl.deleteTexture(this._glTextureId) - } - }, lock:function(options) { - options = options || {level:0, face:0, mode:pc.TEXTURELOCK_WRITE}; - if(options.level === undefined) { - options.level = 0 - } - if(options.face === undefined) { - options.face = 0 - } - if(options.mode === undefined) { - options.mode = pc.TEXTURELOCK_WRITE - } - this._lockedLevel = options.level; - if(this._levels[options.level] === null) { - switch(this._format) { - case pc.PIXELFORMAT_A8: - ; - case pc.PIXELFORMAT_L8: - this._levels[options.level] = new Uint8Array(this._width * this._height); - break; - case pc.PIXELFORMAT_L8_A8: - this._levels[options.level] = new Uint8Array(this._width * this._height * 2); - break; - case pc.PIXELFORMAT_R5_G6_B5: - ; - case pc.PIXELFORMAT_R5_G5_B5_A1: - ; - case pc.PIXELFORMAT_R4_G4_B4_A4: - this._levels[options.level] = new Uint16Array(this._width * this._height); - break; - case pc.PIXELFORMAT_R8_G8_B8: - this._levels[options.level] = new Uint8Array(this._width * this._height * 3); - break; - case pc.PIXELFORMAT_R8_G8_B8_A8: - this._levels[options.level] = new Uint8Array(this._width * this._height * 4); - break; - case pc.PIXELFORMAT_DXT1: - this._levels[options.level] = new Uint8Array(Math.floor((this._width + 3) / 4) * Math.floor((this._height + 3) / 4) * 8); - break; - case pc.PIXELFORMAT_DXT3: - ; - case pc.PIXELFORMAT_DXT5: - this._levels[options.level] = new Uint8Array(Math.floor((this._width + 3) / 4) * Math.floor((this._height + 3) / 4) * 16); - break; - case pc.PIXELFORMAT_RGB16F: - ; - case pc.PIXELFORMAT_RGB32F: - this._levels[options.level] = new Float32Array(this._width * this._height * 3); - break; - case pc.PIXELFORMAT_RGBA16F: - ; - case pc.PIXELFORMAT_RGBA32F: - this._levels[options.level] = new Float32Array(this._width * this._height * 4); - break - } - } - return this._levels[options.level] - }, recover:function() { - }, setSource:function(source) { - if(this._cubemap) { - if(source.length !== 6) { - return - } - var validTypes = 0; - var validDimensions = true; - var width = source[0].width; - var height = source[0].height; - for(var i = 0;i < 6;i++) { - if(source[i] instanceof HTMLCanvasElement || source[i] instanceof HTMLImageElement || source[i] instanceof HTMLVideoElement) { - validTypes++ - } - if(source[i].width !== width) { - validDimensions = false - } - if(source[i].height !== height) { - validDimensions = false - } - } - if(validTypes !== 6 || validDimensions === false) { - return - } - this._width = source[0].width; - this._height = source[0].height; - this._levels[0] = source - }else { - if(!(source instanceof HTMLCanvasElement || source instanceof HTMLImageElement || source instanceof HTMLVideoElement)) { - return - } - this._width = source.width; - this._height = source.height; - this._levels[0] = source - } - this.upload(); - this.minFilter = this._minFilter; - this.magFilter = this._magFilter; - this.addressu = this._addressu; - this.addressv = this._addressv - }, getSource:function() { - return this._levels[0] - }, unlock:function() { - logASSERT(this._lockedLevel !== -1, "Attempting to unlock a texture that is not locked"); - this.upload(); - this._lockedLevel = -1 - }, upload:function() { - this._needsUpload = true - }, getDds:function() { - if(this.format != pc.PIXELFORMAT_R8_G8_B8_A8) { - console.error("This format is not implemented yet") - } - var fsize = 128; - var i = 0; - var j; - var face; - while(this._levels[i]) { - if(!this.cubemap) { - var mipSize = this._levels[i].length; - if(!mipSize) { - console.error("No byte array for mip " + i); - return - } - fsize += mipSize - }else { - for(face = 0;face < 6;face++) { - var mipSize = this._levels[i][face].length; - if(!mipSize) { - console.error("No byte array for mip " + i + ", face " + face); - return - } - fsize += mipSize - } - } - var mipSize; - fsize += this._levels[i].length; - i++ - } - var buff = new ArrayBuffer(fsize); - var header = new Uint32Array(buff, 0, 128 / 4); - var DDS_MAGIC = 542327876; - var DDS_HEADER_SIZE = 124; - var DDS_FLAGS_REQUIRED = 1 | 2 | 4 | 4096 | 524288; - var DDS_FLAGS_MIPMAP = 131072; - var DDS_PIXELFORMAT_SIZE = 32; - var DDS_PIXELFLAGS_RGBA8 = 1 | 64; - var DDS_CAPS_REQUIRED = 4096; - var DDS_CAPS_MIPMAP = 4194304; - var DDS_CAPS_COMPLEX = 8; - var DDS_CAPS2_CUBEMAP = 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768; - var flags = DDS_FLAGS_REQUIRED; - if(this._levels.length > 1) { - flags |= DDS_FLAGS_MIPMAP - } - var caps = DDS_CAPS_REQUIRED; - if(this._levels.length > 1) { - caps |= DDS_CAPS_MIPMAP - } - if(this._levels.length > 1 || this.cubemap) { - caps |= DDS_CAPS_COMPLEX - } - var caps2 = this.cubemap ? DDS_CAPS2_CUBEMAP : 0; - header[0] = DDS_MAGIC; - header[1] = DDS_HEADER_SIZE; - header[2] = flags; - header[3] = this.height; - header[4] = this.width; - header[5] = this.width * this.height * 4; - header[6] = 0; - header[7] = this._levels.length; - for(i = 0;i < 11;i++) { - header[8 + i] = 0 - } - header[19] = DDS_PIXELFORMAT_SIZE; - header[20] = DDS_PIXELFLAGS_RGBA8; - header[21] = 0; - header[22] = 32; - header[23] = 16711680; - header[24] = 65280; - header[25] = 255; - header[26] = 4278190080; - header[27] = caps; - header[28] = caps2; - header[29] = 0; - header[30] = 0; - header[31] = 0; - var offset = 128; - if(!this.cubemap) { - for(i = 0;i < this._levels.length;i++) { - var level = this._levels[i]; - var mip = new Uint8Array(buff, offset, level.length); - for(j = 0;j < level.length;j++) { - mip[j] = level[j] - } - offset += level.length - } - }else { - for(face = 0;face < 6;face++) { - for(i = 0;i < this._levels.length;i++) { - var level = this._levels[i][face]; - var mip = new Uint8Array(buff, offset, level.length); - for(j = 0;j < level.length;j++) { - mip[j] = level[j] - } - offset += level.length - } - } - } - return buff - }}); - return{Texture:Texture} -}()); -pc.extend(pc, function() { - var defaultOptions = {depth:true, face:0}; - var RenderTarget = function(graphicsDevice, colorBuffer, options) { - this._device = graphicsDevice; - this._colorBuffer = colorBuffer; - options = options !== undefined ? options : defaultOptions; - this._face = options.face !== undefined ? options.face : 0; - this._depth = options.depth !== undefined ? options.depth : true - }; - RenderTarget.prototype = {bind:function() { - }, destroy:function() { - var gl = this._device.gl; - gl.deleteFramebuffer(this._frameBuffer); - if(this._depthBuffer) { - gl.deleteRenderbuffer(this._depthBuffer) - } - }, unbind:function() { - }}; - Object.defineProperty(RenderTarget.prototype, "colorBuffer", {get:function() { - return this._colorBuffer - }}); - Object.defineProperty(RenderTarget.prototype, "face", {get:function() { - return this._face - }}); - Object.defineProperty(RenderTarget.prototype, "width", {get:function() { - return this._colorBuffer.width - }}); - Object.defineProperty(RenderTarget.prototype, "height", {get:function() { - return this._colorBuffer.height - }}); - return{RenderTarget:RenderTarget} -}()); -pc.extend(pc, function() { - var ShaderInput = function(graphicsDevice, name, type, locationId) { - this.locationId = locationId; - this.scopeId = graphicsDevice.scope.resolve(name); - this.version = new pc.Version; - this.dataType = type; - this.array = [] - }; - return{ShaderInput:ShaderInput} -}()); -pc.extend(pc, function() { - function addLineNumbers(src) { - var chunks = src.split("\n"); - for(var i = 0, len = chunks.length;i < len;i++) { - chunks[i] = i + 1 + ":\t" + chunks[i] - } - return chunks.join("\n") - } - function createShader(gl, type, src) { - var shader = gl.createShader(type); - gl.shaderSource(shader, src); - gl.compileShader(shader); - var ok = gl.getShaderParameter(shader, gl.COMPILE_STATUS); - if(!ok) { - var error = gl.getShaderInfoLog(shader); - var typeName = type === gl.VERTEX_SHADER ? "vertex" : "fragment"; - logERROR("Failed to compile " + typeName + " shader:\n\n" + addLineNumbers(src) + "\n\n" + error) - } - return shader - } - function createProgram(gl, vertexShader, fragmentShader) { - var program = gl.createProgram(); - gl.attachShader(program, vertexShader); - gl.attachShader(program, fragmentShader); - gl.linkProgram(program); - var ok = gl.getProgramParameter(program, gl.LINK_STATUS); - if(!ok) { - var error = gl.getProgramInfoLog(program); - logERROR("Failed to link shader program. Error: " + error) - } - return program - } - var Shader = function(graphicsDevice, definition) { - this.device = graphicsDevice; - this.definition = definition; - var gl = this.device.gl; - var vertexShader = createShader(gl, gl.VERTEX_SHADER, definition.vshader); - var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, definition.fshader); - this.program = createProgram(gl, vertexShader, fragmentShader); - gl.deleteShader(vertexShader); - gl.deleteShader(fragmentShader); - this.attributes = []; - this.uniforms = []; - this.samplers = []; - var i = 0; - var info, location; - var _typeToPc = {}; - _typeToPc[gl.BOOL] = pc.UNIFORMTYPE_BOOL; - _typeToPc[gl.INT] = pc.UNIFORMTYPE_INT; - _typeToPc[gl.FLOAT] = pc.UNIFORMTYPE_FLOAT; - _typeToPc[gl.FLOAT_VEC2] = pc.UNIFORMTYPE_VEC2; - _typeToPc[gl.FLOAT_VEC3] = pc.UNIFORMTYPE_VEC3; - _typeToPc[gl.FLOAT_VEC4] = pc.UNIFORMTYPE_VEC4; - _typeToPc[gl.INT_VEC2] = pc.UNIFORMTYPE_IVEC2; - _typeToPc[gl.INT_VEC3] = pc.UNIFORMTYPE_IVEC3; - _typeToPc[gl.INT_VEC4] = pc.UNIFORMTYPE_IVEC4; - _typeToPc[gl.BOOL_VEC2] = pc.UNIFORMTYPE_BVEC2; - _typeToPc[gl.BOOL_VEC3] = pc.UNIFORMTYPE_BVEC3; - _typeToPc[gl.BOOL_VEC4] = pc.UNIFORMTYPE_BVEC4; - _typeToPc[gl.FLOAT_MAT2] = pc.UNIFORMTYPE_MAT2; - _typeToPc[gl.FLOAT_MAT3] = pc.UNIFORMTYPE_MAT3; - _typeToPc[gl.FLOAT_MAT4] = pc.UNIFORMTYPE_MAT4; - _typeToPc[gl.SAMPLER_2D] = pc.UNIFORMTYPE_TEXTURE2D; - _typeToPc[gl.SAMPLER_CUBE] = pc.UNIFORMTYPE_TEXTURECUBE; - var numAttributes = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES); - while(i < numAttributes) { - info = gl.getActiveAttrib(this.program, i++); - location = gl.getAttribLocation(this.program, info.name); - if(definition.attributes[info.name] === undefined) { - console.error('Vertex shader attribute "' + info.name + '" is not mapped to a semantic in shader definition.') - } - var attr = new pc.ShaderInput(graphicsDevice, definition.attributes[info.name], _typeToPc[info.type], location); - this.attributes.push(attr) - } - i = 0; - var numUniforms = gl.getProgramParameter(this.program, gl.ACTIVE_UNIFORMS); - while(i < numUniforms) { - info = gl.getActiveUniform(this.program, i++); - location = gl.getUniformLocation(this.program, info.name); - if(info.type === gl.SAMPLER_2D || info.type === gl.SAMPLER_CUBE) { - this.samplers.push(new pc.ShaderInput(graphicsDevice, info.name, _typeToPc[info.type], location)) - }else { - this.uniforms.push(new pc.ShaderInput(graphicsDevice, info.name, _typeToPc[info.type], location)) - } - } - }; - Shader.prototype = {destroy:function() { - var gl = this.device.gl; - gl.deleteProgram(this.program) - }}; - return{Shader:Shader} -}()); -pc.extend(pc, function() { - var ProgramLibrary = function(device) { - this._device = device; - this._cache = {}; - this._generators = {} - }; - ProgramLibrary.prototype.register = function(name, generator) { - if(!this.isRegistered(name)) { - this._generators[name] = generator - } - }; - ProgramLibrary.prototype.unregister = function(name) { - if(this.isRegistered(name)) { - delete this._generators[name] - } - }; - ProgramLibrary.prototype.isRegistered = function(name) { - var generator = this._generators[name]; - return generator !== undefined - }; - ProgramLibrary.prototype.getProgram = function(name, options) { - var generator = this._generators[name]; - if(generator === undefined) { - logERROR("No program library functions registered for: " + name); - return null - } - var key = generator.generateKey(gd, options); - var shader = this._cache[key]; - if(!shader) { - var gd = this._device; - var shaderDefinition = generator.createShaderDefinition(gd, options); - shader = this._cache[key] = new pc.Shader(gd, shaderDefinition) - } - return shader - }; - return{ProgramLibrary:ProgramLibrary} -}()); -pc.extend(pc, function() { - var EVENT_RESIZE = "resizecanvas"; - function UnsupportedBrowserError(message) { - this.name = "UnsupportedBrowserError"; - this.message = message || "" - } - UnsupportedBrowserError.prototype = Error.prototype; - function ContextCreationError(message) { - this.name = "ContextCreationError"; - this.message = message || "" - } - ContextCreationError.prototype = Error.prototype; - var _contextLostHandler = function() { - logWARNING("Context lost.") - }; - var _contextRestoredHandler = function() { - logINFO("Context restored.") - }; - var _createContext = function(canvas, options) { - var names = ["webgl", "experimental-webgl"]; - var context = null; - for(var i = 0;i < names.length;i++) { - try { - context = canvas.getContext(names[i], options) - }catch(e) { - } - if(context) { - break - } - } - return context - }; - var _downsampleImage = function(image, size) { - var srcW = image.width; - var srcH = image.height; - if(srcW > size || srcH > size) { - var scale = size / Math.max(srcW, srcH); - var dstW = Math.floor(srcW * scale); - var dstH = Math.floor(srcH * scale); - console.warn("Image dimensions larger than max supported texture size of " + size + ". " + "Resizing from " + srcW + ", " + srcH + " to " + dstW + ", " + dstH + "."); - var canvas = document.createElement("canvas"); - canvas.width = dstW; - canvas.height = dstH; - var context = canvas.getContext("2d"); - context.drawImage(image, 0, 0, srcW, srcH, 0, 0, dstW, dstH); - return canvas - } - return image - }; - function _isIE() { - var ua = window.navigator.userAgent; - var msie = ua.indexOf("MSIE "); - var trident = navigator.userAgent.match(/Trident.*rv\:11\./); - return msie > 0 || !!trident - } - var GraphicsDevice = function(canvas) { - this.gl = undefined; - this.canvas = canvas; - this.shader = null; - this.indexBuffer = null; - this.vertexBuffers = []; - this.precision = "highp"; - this.enableAutoInstancing = false; - this.autoInstancingMaxObjects = 16384; - this.attributesInvalidated = true; - this.boundBuffer = []; - this.instancedAttribs = {}; - this.enabledAttributes = {}; - this.textureUnits = []; - this.commitFunction = {}; - this._maxPixelRatio = 1; - this._width = 0; - this._height = 0; - if(!window.WebGLRenderingContext) { - throw new pc.UnsupportedBrowserError; - } - if(canvas) { - this.gl = _createContext(canvas) - } - if(!this.gl) { - throw new pc.ContextCreationError; - } - var gl = this.gl; - (function() { - canvas.addEventListener("webglcontextlost", _contextLostHandler, false); - canvas.addEventListener("webglcontextrestored", _contextRestoredHandler, false); - this.canvas = canvas; - this.shader = null; - this.indexBuffer = null; - this.vertexBuffers = []; - this.precision = "highp"; - this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); - this.maxCubeMapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE); - var vertexShaderPrecisionHighpFloat = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT); - var vertexShaderPrecisionMediumpFloat = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT); - var vertexShaderPrecisionLowpFloat = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_FLOAT); - var fragmentShaderPrecisionHighpFloat = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT); - var fragmentShaderPrecisionMediumpFloat = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT); - var fragmentShaderPrecisionLowpFloat = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_FLOAT); - var vertexShaderPrecisionHighpInt = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_INT); - var vertexShaderPrecisionMediumpInt = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_INT); - var vertexShaderPrecisionLowpInt = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.LOW_INT); - var fragmentShaderPrecisionHighpInt = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT); - var fragmentShaderPrecisionMediumpInt = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_INT); - var fragmentShaderPrecisionLowpInt = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.LOW_INT); - var highpAvailable = vertexShaderPrecisionHighpFloat.precision > 0 && fragmentShaderPrecisionHighpFloat.precision > 0; - var mediumpAvailable = vertexShaderPrecisionMediumpFloat.precision > 0 && fragmentShaderPrecisionMediumpFloat.precision > 0; - if(!highpAvailable) { - if(mediumpAvailable) { - this.precision = "mediump"; - console.warn("WARNING: highp not supported, using mediump") - }else { - this.precision = "lowp"; - console.warn("WARNING: highp and mediump not supported, using lowp") - } - } - this.maxPrecision = this.precision; - this.defaultClearOptions = {color:[0, 0, 0, 1], depth:1, flags:pc.CLEARFLAG_COLOR | pc.CLEARFLAG_DEPTH}; - this.glAddress = [gl.REPEAT, gl.CLAMP_TO_EDGE, gl.MIRRORED_REPEAT]; - this.glBlendEquation = [gl.FUNC_ADD, gl.FUNC_SUBTRACT, gl.FUNC_REVERSE_SUBTRACT]; - this.glBlendFunction = [gl.ZERO, gl.ONE, gl.SRC_COLOR, gl.ONE_MINUS_SRC_COLOR, gl.DST_COLOR, gl.ONE_MINUS_DST_COLOR, gl.SRC_ALPHA, gl.SRC_ALPHA_SATURATE, gl.ONE_MINUS_SRC_ALPHA, gl.DST_ALPHA, gl.ONE_MINUS_DST_ALPHA]; - this.glClearFlag = [0, gl.COLOR_BUFFER_BIT, gl.DEPTH_BUFFER_BIT, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.STENCIL_BUFFER_BIT, gl.STENCIL_BUFFER_BIT | gl.COLOR_BUFFER_BIT, gl.STENCIL_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.STENCIL_BUFFER_BIT | gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT]; - this.glFilter = [gl.NEAREST, gl.LINEAR, gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST_MIPMAP_LINEAR, gl.LINEAR_MIPMAP_NEAREST, gl.LINEAR_MIPMAP_LINEAR]; - this.glPrimitive = [gl.POINTS, gl.LINES, gl.LINE_LOOP, gl.LINE_STRIP, gl.TRIANGLES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN]; - this.glType = [gl.BYTE, gl.UNSIGNED_BYTE, gl.SHORT, gl.UNSIGNED_SHORT, gl.INT, gl.UNSIGNED_INT, gl.FLOAT]; - this.extTextureFloat = gl.getExtension("OES_texture_float"); - this.extTextureFloatLinear = gl.getExtension("OES_texture_float_linear"); - this.extTextureHalfFloat = gl.getExtension("OES_texture_half_float"); - this.maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); - this.supportsBoneTextures = this.extTextureFloat && this.maxVertexTextures > 0; - this.extTextureFloatRenderable = !!this.extTextureFloat; - if(this.extTextureFloat) { - var __texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, __texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - var __width = 2; - var __height = 2; - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, __width, __height, 0, gl.RGBA, gl.FLOAT, null); - var __fbo = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, __fbo); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, __texture, 0); - gl.bindTexture(gl.TEXTURE_2D, null); - if(gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { - this.extTextureFloatRenderable = false - } - } - this.extTextureLod = gl.getExtension("EXT_shader_texture_lod"); - this.fragmentUniformsCount = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); - this.samplerCount = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); - this.useTexCubeLod = true; - this.extDepthTexture = null; - this.extStandardDerivatives = gl.getExtension("OES_standard_derivatives"); - if(this.extStandardDerivatives) { - gl.hint(this.extStandardDerivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, gl.NICEST) - } - this.extTextureFilterAnisotropic = gl.getExtension("EXT_texture_filter_anisotropic"); - if(!this.extTextureFilterAnisotropic) { - this.extTextureFilterAnisotropic = gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic") - } - this.extCompressedTextureS3TC = gl.getExtension("WEBGL_compressed_texture_s3tc"); - if(!this.extCompressedTextureS3TC) { - this.extCompressedTextureS3TC = gl.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc") - } - if(this.extCompressedTextureS3TC) { - if(_isIE()) { - this.extCompressedTextureS3TC = false - } - } - if(this.extCompressedTextureS3TC) { - var formats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS); - for(var i = 0;i < formats.length;i++) { - switch(formats[i]) { - case this.extCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT: - break; - case this.extCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT: - break; - case this.extCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT: - break; - case this.extCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT: - break; - default: - break - } - } - } - this.extInstancing = gl.getExtension("ANGLE_instanced_arrays"); - if(this.enableAutoInstancing && !this.extInstancing) { - this.enableAutoInstancing = false - } - this.extCompressedTextureETC1 = gl.getExtension("WEBGL_compressed_texture_etc1"); - this.extDrawBuffers = gl.getExtension("EXT_draw_buffers"); - this.maxDrawBuffers = this.extDrawBuffers ? gl.getParameter(this.extDrawBuffers.MAX_DRAW_BUFFERS_EXT) : 1; - this.maxColorAttachments = this.extDrawBuffers ? gl.getParameter(this.extDrawBuffers.MAX_COLOR_ATTACHMENTS_EXT) : 1; - this.renderTarget = null; - this.scope = new pc.ScopeSpace("Device"); - this.commitFunction = {}; - this.commitFunction[pc.UNIFORMTYPE_BOOL] = function(locationId, value) { - gl.uniform1i(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_INT] = function(locationId, value) { - gl.uniform1i(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_FLOAT] = function(locationId, value) { - if(typeof value == "number") { - gl.uniform1f(locationId, value) - }else { - gl.uniform1fv(locationId, value) - } - }; - this.commitFunction[pc.UNIFORMTYPE_VEC2] = function(locationId, value) { - gl.uniform2fv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_VEC3] = function(locationId, value) { - gl.uniform3fv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_VEC4] = function(locationId, value) { - gl.uniform4fv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_IVEC2] = function(locationId, value) { - gl.uniform2iv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_BVEC2] = function(locationId, value) { - gl.uniform2iv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_IVEC3] = function(locationId, value) { - gl.uniform3iv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_BVEC3] = function(locationId, value) { - gl.uniform3iv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_IVEC4] = function(locationId, value) { - gl.uniform4iv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_BVEC4] = function(locationId, value) { - gl.uniform4iv(locationId, value) - }; - this.commitFunction[pc.UNIFORMTYPE_MAT2] = function(locationId, value) { - gl.uniformMatrix2fv(locationId, false, value) - }; - this.commitFunction[pc.UNIFORMTYPE_MAT3] = function(locationId, value) { - gl.uniformMatrix3fv(locationId, false, value) - }; - this.commitFunction[pc.UNIFORMTYPE_MAT4] = function(locationId, value) { - gl.uniformMatrix4fv(locationId, false, value) - }; - this.setBlending(false); - this.setBlendFunction(pc.BLENDMODE_ONE, pc.BLENDMODE_ZERO); - this.setBlendEquation(pc.BLENDEQUATION_ADD); - this.setColorWrite(true, true, true, true); - this.setCullMode(pc.CULLFACE_BACK); - this.setDepthTest(true); - this.setDepthWrite(true); - this.setClearDepth(1); - this.setClearColor(0, 0, 0, 0); - gl.enable(gl.SCISSOR_TEST); - this.programLib = new pc.ProgramLibrary(this); - for(var generator in pc.programlib) { - this.programLib.register(generator, pc.programlib[generator]) - } - var numUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); - numUniforms -= 4 * 4; - numUniforms -= 8; - numUniforms -= 1; - numUniforms -= 4 * 4; - this.boneLimit = Math.floor(numUniforms / 4); - if(this.boneLimit > 110) { - this.boneLimit = 110 - } - pc.events.attach(this); - this.boundBuffer = []; - this.instancedAttribs = {}; - this.textureUnits = []; - this.attributesInvalidated = true; - this.enabledAttributes = {}; - var bufferId = gl.createBuffer(); - var storage = new ArrayBuffer(16); - gl.bindBuffer(gl.ARRAY_BUFFER, bufferId); - gl.bufferData(gl.ARRAY_BUFFER, storage, gl.STATIC_DRAW); - gl.getError(); - gl.vertexAttribPointer(0, 4, gl.UNSIGNED_BYTE, false, 4, 0); - this.supportsUnsignedByte = gl.getError() === 0; - gl.deleteBuffer(bufferId) - }).call(this) - }; - GraphicsDevice.prototype = {setViewport:function(x, y, width, height) { - var gl = this.gl; - gl.viewport(x, y, width, height) - }, setScissor:function(x, y, width, height) { - var gl = this.gl; - gl.scissor(x, y, width, height) - }, getProgramLibrary:function() { - return this.programLib - }, setProgramLibrary:function(programLib) { - this.programLib = programLib - }, updateBegin:function() { - var gl = this.gl; - this.boundBuffer = []; - this.indexBuffer = null; - var target = this.renderTarget; - if(target) { - if(!target._glFrameBuffer) { - target._glFrameBuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, target._glFrameBuffer); - if(!target._colorBuffer._glTextureId) { - this.setTexture(target._colorBuffer, 0) - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target._colorBuffer._cubemap ? gl.TEXTURE_CUBE_MAP_POSITIVE_X + target._face : gl.TEXTURE_2D, target._colorBuffer._glTextureId, 0); - if(target._depth) { - if(!target._glDepthBuffer) { - target._glDepthBuffer = gl.createRenderbuffer() - } - gl.bindRenderbuffer(gl.RENDERBUFFER, target._glDepthBuffer); - gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, target.width, target.height); - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, target._glDepthBuffer) - } - var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); - switch(status) { - case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - console.error("ERROR: FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); - break; - case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - console.error("ERROR: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); - break; - case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - console.error("ERROR: FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); - break; - case gl.FRAMEBUFFER_UNSUPPORTED: - console.error("ERROR: FRAMEBUFFER_UNSUPPORTED"); - break; - case gl.FRAMEBUFFER_COMPLETE: - break; - default: - break - } - }else { - gl.bindFramebuffer(gl.FRAMEBUFFER, target._glFrameBuffer) - } - }else { - gl.bindFramebuffer(gl.FRAMEBUFFER, null) - } - for(var i = 0;i < 16;i++) { - this.textureUnits[i] = null - } - }, updateEnd:function() { - var gl = this.gl; - var target = this.renderTarget; - if(target) { - gl.bindFramebuffer(gl.FRAMEBUFFER, null) - } - }, initializeTexture:function(texture) { - var gl = this.gl; - texture._glTextureId = gl.createTexture(); - texture._glTarget = texture._cubemap ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D; - switch(texture._format) { - case pc.PIXELFORMAT_A8: - texture._glFormat = gl.ALPHA; - texture._glInternalFormat = gl.ALPHA; - texture._glPixelType = gl.UNSIGNED_BYTE; - break; - case pc.PIXELFORMAT_L8: - texture._glFormat = gl.LUMINANCE; - texture._glInternalFormat = gl.LUMINANCE; - texture._glPixelType = gl.UNSIGNED_BYTE; - break; - case pc.PIXELFORMAT_L8_A8: - texture._glFormat = gl.LUMINANCE_ALPHA; - texture._glInternalFormat = gl.LUMINANCE_ALPHA; - texture._glPixelType = gl.UNSIGNED_BYTE; - break; - case pc.PIXELFORMAT_R5_G6_B5: - texture._glFormat = gl.RGB; - texture._glInternalFormat = gl.RGB; - texture._glPixelType = gl.UNSIGNED_SHORT_5_6_5; - break; - case pc.PIXELFORMAT_R5_G5_B5_A1: - texture._glFormat = gl.RGBA; - texture._glInternalFormat = gl.RGBA; - texture._glPixelType = gl.UNSIGNED_SHORT_5_5_5_1; - break; - case pc.PIXELFORMAT_R4_G4_B4_A4: - texture._glFormat = gl.RGBA; - texture._glInternalFormat = gl.RGBA; - texture._glPixelType = gl.UNSIGNED_SHORT_4_4_4_4; - break; - case pc.PIXELFORMAT_R8_G8_B8: - texture._glFormat = gl.RGB; - texture._glInternalFormat = gl.RGB; - texture._glPixelType = gl.UNSIGNED_BYTE; - break; - case pc.PIXELFORMAT_R8_G8_B8_A8: - texture._glFormat = gl.RGBA; - texture._glInternalFormat = gl.RGBA; - texture._glPixelType = gl.UNSIGNED_BYTE; - break; - case pc.PIXELFORMAT_DXT1: - ext = this.extCompressedTextureS3TC; - texture._glFormat = gl.RGB; - texture._glInternalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; - break; - case pc.PIXELFORMAT_DXT3: - ext = this.extCompressedTextureS3TC; - texture._glFormat = gl.RGBA; - texture._glInternalFormat = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - case pc.PIXELFORMAT_DXT5: - ext = this.extCompressedTextureS3TC; - texture._glFormat = gl.RGBA; - texture._glInternalFormat = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - case pc.PIXELFORMAT_ETC1: - ext = this.extCompressedTextureETC1; - texture._glFormat = gl.RGB; - texture._glInternalFormat = ext.COMPRESSED_RGB_ETC1_WEBGL; - break; - case pc.PIXELFORMAT_RGB16F: - ext = this.extTextureHalfFloat; - texture._glFormat = gl.RGB; - texture._glInternalFormat = gl.RGB; - texture._glPixelType = ext.HALF_FLOAT_OES; - break; - case pc.PIXELFORMAT_RGBA16F: - ext = this.extTextureHalfFloat; - texture._glFormat = gl.RGBA; - texture._glInternalFormat = gl.RGBA; - texture._glPixelType = ext.HALF_FLOAT_OES; - break; - case pc.PIXELFORMAT_RGB32F: - texture._glFormat = gl.RGB; - texture._glInternalFormat = gl.RGB; - texture._glPixelType = gl.FLOAT; - break; - case pc.PIXELFORMAT_RGBA32F: - texture._glFormat = gl.RGBA; - texture._glInternalFormat = gl.RGBA; - texture._glPixelType = gl.FLOAT; - break - } - }, uploadTexture:function(texture) { - var gl = this.gl; - var mipLevel = 0; - var mipObject; - while(texture._levels[mipLevel] || mipLevel == 0) { - mipObject = texture._levels[mipLevel]; - if(mipLevel == 1 && !texture._compressed) { - gl.generateMipmap(texture._glTarget) - } - if(texture._cubemap) { - var face; - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); - if(mipObject[0] instanceof HTMLCanvasElement || mipObject[0] instanceof HTMLImageElement || mipObject[0] instanceof HTMLVideoElement) { - for(face = 0;face < 6;face++) { - var src = mipObject[face]; - if(src instanceof HTMLImageElement) { - if(src.width > this.maxCubeMapSize || src.height > this.maxCubeMapSize) { - src = _downsampleImage(src, this.maxCubeMapSize); - if(mipLevel === 0) { - texture.width = src.width; - texture.height = src.height - } - } - } - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, mipLevel, texture._glInternalFormat, texture._glFormat, texture._glPixelType, src) - } - }else { - var resMult = 1 / Math.pow(2, mipLevel); - for(face = 0;face < 6;face++) { - if(texture._compressed) { - gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, mipLevel, texture._glInternalFormat, Math.max(texture._width * resMult, 1), Math.max(texture._height * resMult, 1), 0, mipObject[face]) - }else { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, mipLevel, texture._glInternalFormat, Math.max(texture._width * resMult, 1), Math.max(texture._height * resMult, 1), 0, texture._glFormat, texture._glPixelType, mipObject[face]) - } - } - } - }else { - if(mipObject instanceof HTMLCanvasElement || mipObject instanceof HTMLImageElement || mipObject instanceof HTMLVideoElement) { - if(mipObject instanceof HTMLImageElement) { - if(mipObject.width > this.maxTextureSize || mipObject.height > this.maxTextureSize) { - mipObject = _downsampleImage(mipObject, this.maxTextureSize); - if(mipLevel === 0) { - texture.width = mipObject.width; - texture.height = mipObject.height - } - } - } - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); - gl.texImage2D(gl.TEXTURE_2D, mipLevel, texture._glInternalFormat, texture._glFormat, texture._glPixelType, mipObject) - }else { - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); - var resMult = 1 / Math.pow(2, mipLevel); - if(texture._compressed) { - gl.compressedTexImage2D(gl.TEXTURE_2D, mipLevel, texture._glInternalFormat, Math.max(texture._width * resMult, 1), Math.max(texture._height * resMult, 1), 0, mipObject) - }else { - gl.texImage2D(gl.TEXTURE_2D, mipLevel, texture._glInternalFormat, Math.max(texture._width * resMult, 1), Math.max(texture._height * resMult, 1), 0, texture._glFormat, texture._glPixelType, mipObject) - } - } - } - mipLevel++ - } - if(texture.autoMipmap && pc.math.powerOfTwo(texture._width) && pc.math.powerOfTwo(texture._height) && texture._levels.length === 1 && !texture._compressed) { - gl.generateMipmap(texture._glTarget) - } - }, setTexture:function(texture, textureUnit) { - var gl = this.gl; - if(!texture._glTextureId) { - this.initializeTexture(texture) - } - gl.activeTexture(gl.TEXTURE0 + textureUnit); - if(this.textureUnits[textureUnit] !== texture) { - gl.bindTexture(texture._glTarget, texture._glTextureId); - this.textureUnits[textureUnit] = texture - } - gl.texParameteri(texture._glTarget, gl.TEXTURE_MIN_FILTER, this.glFilter[texture._minFilter]); - gl.texParameteri(texture._glTarget, gl.TEXTURE_MAG_FILTER, this.glFilter[texture._magFilter]); - gl.texParameteri(texture._glTarget, gl.TEXTURE_WRAP_S, this.glAddress[texture._addressU]); - gl.texParameteri(texture._glTarget, gl.TEXTURE_WRAP_T, this.glAddress[texture._addressV]); - var ext = this.extTextureFilterAnisotropic; - if(ext) { - var maxAnisotropy = this.maxAnisotropy; - var anisotropy = texture.anisotropy; - anisotropy = Math.min(anisotropy, maxAnisotropy); - gl.texParameterf(texture._glTarget, ext.TEXTURE_MAX_ANISOTROPY_EXT, anisotropy) - } - if(texture._needsUpload) { - this.uploadTexture(texture); - texture._needsUpload = false - } - }, draw:function(primitive, numInstances) { - var gl = this.gl; - var i, j, len, sampler, samplerValue, texture, numTextures, uniform, scopeId, uniformVersion, programVersion; - var shader = this.shader; - var samplers = shader.samplers; - var uniforms = shader.uniforms; - if(numInstances > 1) { - this.boundBuffer = []; - this.attributesInvalidated = true - } - if(this.attributesInvalidated) { - var attribute, element, vertexBuffer; - var attributes = shader.attributes; - for(i = 0, len = attributes.length;i < len;i++) { - attribute = attributes[i]; - element = attribute.scopeId.value; - if(element !== null) { - vertexBuffer = this.vertexBuffers[element.stream]; - if(this.boundBuffer[element.stream] !== vertexBuffer.bufferId) { - gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.bufferId); - this.boundBuffer[element.stream] = vertexBuffer.bufferId - } - if(!this.enabledAttributes[attribute.locationId]) { - gl.enableVertexAttribArray(attribute.locationId); - this.enabledAttributes[attribute.locationId] = true - } - gl.vertexAttribPointer(attribute.locationId, element.numComponents, this.glType[element.dataType], element.normalize, element.stride, element.offset); - if(element.stream === 1 && numInstances > 1) { - if(!this.instancedAttribs[attribute.locationId]) { - this.extInstancing.vertexAttribDivisorANGLE(attribute.locationId, 1); - this.instancedAttribs = attribute.locationId - } - }else { - if(this.instancedAttribs[attribute.locationId]) { - this.extInstancing.vertexAttribDivisorANGLE(attribute.locationId, 0); - this.instancedAttribs[attribute.locationId] = false - } - } - } - } - this.attributesInvalidated = false - } - textureUnit = 0; - for(i = 0, len = samplers.length;i < len;i++) { - sampler = samplers[i]; - samplerValue = sampler.scopeId.value; - if(samplerValue instanceof pc.Texture) { - texture = samplerValue; - this.setTexture(texture, textureUnit); - if(sampler.slot !== textureUnit) { - gl.uniform1i(sampler.locationId, textureUnit); - sampler.slot = textureUnit - } - textureUnit++ - }else { - sampler.array.length = 0; - numTexures = samplerValue.length; - for(j = 0;j < numTexures;j++) { - texture = samplerValue[j]; - this.setTexture(texture, textureUnit); - sampler.array[j] = textureUnit; - textureUnit++ - } - gl.uniform1iv(sampler.locationId, sampler.array) - } - } - for(i = 0, len = uniforms.length;i < len;i++) { - uniform = uniforms[i]; - scopeId = uniform.scopeId; - uniformVersion = uniform.version; - programVersion = scopeId.versionObject.version; - if(uniformVersion.globalId !== programVersion.globalId || uniformVersion.revision !== programVersion.revision) { - uniformVersion.globalId = programVersion.globalId; - uniformVersion.revision = programVersion.revision; - if(scopeId.value !== null) { - this.commitFunction[uniform.dataType](uniform.locationId, scopeId.value) - } - } - } - if(primitive.indexed) { - if(numInstances > 1) { - this.extInstancing.drawElementsInstancedANGLE(this.glPrimitive[primitive.type], primitive.count, this.indexBuffer.glFormat, primitive.base * 2, numInstances); - this.boundBuffer = []; - this.attributesInvalidated = true - }else { - gl.drawElements(this.glPrimitive[primitive.type], primitive.count, this.indexBuffer.glFormat, primitive.base * 2) - } - }else { - if(numInstances > 1) { - this.extInstancing.drawArraysInstancedANGLE(this.glPrimitive[primitive.type], primitive.base, primitive.count, numInstances); - this.boundBuffer = []; - this.attributesInvalidated = true - }else { - gl.drawArrays(this.glPrimitive[primitive.type], primitive.base, primitive.count) - } - } - }, clear:function(options) { - var defaultOptions = this.defaultClearOptions; - options = options || defaultOptions; - var flags = options.flags === undefined ? defaultOptions.flags : options.flags; - if(flags !== 0) { - var gl = this.gl; - if(flags & pc.CLEARFLAG_COLOR) { - var color = options.color === undefined ? defaultOptions.color : options.color; - this.setClearColor(color[0], color[1], color[2], color[3]) - } - if(flags & pc.CLEARFLAG_DEPTH) { - var depth = options.depth === undefined ? defaultOptions.depth : options.depth; - this.setClearDepth(depth); - if(!this.depthWrite) { - gl.depthMask(true) - } - } - gl.clear(this.glClearFlag[flags]); - if(flags & pc.CLEARFLAG_DEPTH) { - if(!this.depthWrite) { - gl.depthMask(false) - } - } - } - }, readPixels:function(x, y, w, h, pixels) { - var gl = this.gl; - gl.readPixels(x, y, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels) - }, setClearDepth:function(depth) { - if(depth !== this.clearDepth) { - this.gl.clearDepth(depth); - this.clearDepth = depth - } - }, setClearColor:function(r, g, b, a) { - if(r !== this.clearRed || g !== this.clearGreen || b !== this.clearBlue || a !== this.clearAlpha) { - this.gl.clearColor(r, g, b, a); - this.clearRed = r; - this.clearGreen = g; - this.clearBlue = b; - this.clearAlpha = a - } - }, setRenderTarget:function(renderTarget) { - this.renderTarget = renderTarget - }, getRenderTarget:function() { - return this.renderTarget - }, getDepthTest:function() { - return this.depthTest - }, setDepthTest:function(depthTest) { - if(this.depthTest !== depthTest) { - var gl = this.gl; - if(depthTest) { - gl.enable(gl.DEPTH_TEST) - }else { - gl.disable(gl.DEPTH_TEST) - } - this.depthTest = depthTest - } - }, getDepthWrite:function() { - return this.depthWrite - }, setDepthWrite:function(writeDepth) { - if(this.depthWrite !== writeDepth) { - this.gl.depthMask(writeDepth); - this.depthWrite = writeDepth - } - }, setColorWrite:function(writeRed, writeGreen, writeBlue, writeAlpha) { - if(this.writeRed !== writeRed || this.writeGreen !== writeGreen || this.writeBlue !== writeBlue || this.writeAlpha !== writeAlpha) { - this.gl.colorMask(writeRed, writeGreen, writeBlue, writeAlpha); - this.writeRed = writeRed; - this.writeGreen = writeGreen; - this.writeBlue = writeBlue; - this.writeAlpha = writeAlpha - } - }, getBlending:function() { - return this.blending - }, setBlending:function(blending) { - if(this.blending !== blending) { - var gl = this.gl; - if(blending) { - gl.enable(gl.BLEND) - }else { - gl.disable(gl.BLEND) - } - this.blending = blending - } - }, setBlendFunction:function(blendSrc, blendDst) { - if(this.blendSrc !== blendSrc || this.blendDst !== blendDst) { - this.gl.blendFunc(this.glBlendFunction[blendSrc], this.glBlendFunction[blendDst]); - this.blendSrc = blendSrc; - this.blendDst = blendDst - } - }, setBlendEquation:function(blendEquation) { - if(this.blendEquation !== blendEquation) { - var gl = this.gl; - gl.blendEquation(this.glBlendEquation[blendEquation]); - this.blendEquation = blendEquation - } - }, setCullMode:function(cullMode) { - if(this.cullMode !== cullMode) { - var gl = this.gl; - switch(cullMode) { - case pc.CULLFACE_NONE: - gl.disable(gl.CULL_FACE); - break; - case pc.CULLFACE_FRONT: - gl.enable(gl.CULL_FACE); - gl.cullFace(gl.FRONT); - break; - case pc.CULLFACE_BACK: - gl.enable(gl.CULL_FACE); - gl.cullFace(gl.BACK); - break; - case pc.CULLFACE_FRONTANDBACK: - gl.enable(gl.CULL_FACE); - gl.cullFace(gl.FRONT_AND_BACK); - break - } - this.cullMode = cullMode - } - }, setIndexBuffer:function(indexBuffer) { - if(this.indexBuffer !== indexBuffer) { - this.indexBuffer = indexBuffer; - var gl = this.gl; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer ? indexBuffer.bufferId : null) - } - }, setVertexBuffer:function(vertexBuffer, stream) { - if(this.vertexBuffers[stream] !== vertexBuffer) { - this.vertexBuffers[stream] = vertexBuffer; - var vertexFormat = vertexBuffer.getFormat(); - var i = 0; - var elements = vertexFormat.elements; - var numElements = elements.length; - while(i < numElements) { - var vertexElement = elements[i++]; - vertexElement.stream = stream; - vertexElement.scopeId.setValue(vertexElement) - } - this.attributesInvalidated = true - } - }, setShader:function(shader) { - if(shader !== this.shader) { - this.shader = shader; - var gl = this.gl; - gl.useProgram(shader.program); - this.attributesInvalidated = true - } - }, getBoneLimit:function() { - return this.boneLimit - }, setBoneLimit:function(maxBones) { - this.boneLimit = maxBones - }, enableValidation:function(enable) { - console.warn("enableValidation: This function is deprecated and will be removed shortly.") - }, validate:function() { - console.warn("validate: This function is deprecated and will be removed shortly.") - }, resizeCanvas:function(width, height) { - this._width = width; - this._height = height; - var ratio = Math.min(this._maxPixelRatio, window.devicePixelRatio); - width *= ratio; - height *= ratio; - this.canvas.width = width; - this.canvas.height = height; - this.fire(EVENT_RESIZE, width, height) - }}; - Object.defineProperty(GraphicsDevice.prototype, "width", {get:function() { - return this.gl.drawingBufferWidth || this.canvas.width - }}); - Object.defineProperty(GraphicsDevice.prototype, "height", {get:function() { - return this.gl.drawingBufferHeight || this.canvas.height - }}); - Object.defineProperty(GraphicsDevice.prototype, "fullscreen", {get:function() { - return!!document.fullscreenElement - }, set:function(fullscreen) { - if(fullscreen) { - var canvas = this.gl.canvas; - canvas.requestFullscreen() - }else { - document.exitFullscreen() - } - }}); - Object.defineProperty(GraphicsDevice.prototype, "maxAnisotropy", {get:function() { - var maxAniso; - return function() { - if(maxAniso === undefined) { - maxAniso = 1; - var gl = this.gl; - var glExt = this.extTextureFilterAnisotropic; - if(glExt) { - maxAniso = gl.getParameter(glExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT) - } - } - return maxAniso - } - }()}); - Object.defineProperty(GraphicsDevice.prototype, "maxPixelRatio", {get:function() { - return this._maxPixelRatio - }, set:function(ratio) { - this._maxPixelRatio = ratio; - this.resizeCanvas(this._width, this._height) - }}); - return{UnsupportedBrowserError:UnsupportedBrowserError, ContextCreationError:ContextCreationError, GraphicsDevice:GraphicsDevice, precalculatedTangents:true} -}()); -pc.extend(pc, function() { - var shaderChunks = {}; - var shaderCache = {}; - shaderChunks.collectAttribs = function(vsCode) { - var attribs = {}; - var attrs = 0; - var found = vsCode.indexOf("attribute"); - while(found >= 0) { - var endOfLine = vsCode.indexOf(";", found); - var startOfAttribName = vsCode.lastIndexOf(" ", endOfLine); - var attribName = vsCode.substr(startOfAttribName + 1, endOfLine - (startOfAttribName + 1)); - if(attribName == "aPosition") { - attribs.aPosition = pc.SEMANTIC_POSITION - }else { - attribs[attribName] = "ATTR" + attrs; - attrs++ - } - found = vsCode.indexOf("attribute", found + 1) - } - return attribs - }; - shaderChunks.createShader = function(device, vsName, psName) { - var vsCode = shaderChunks[vsName]; - var psCode = pc.programlib.getSnippet(device, "fs_precision") + "\n" + shaderChunks[psName]; - attribs = this.collectAttribs(vsCode); - return new pc.Shader(device, {attributes:attribs, vshader:vsCode, fshader:psCode}) - }; - shaderChunks.createShaderFromCode = function(device, vsCode, psCode, uName) { - var cached = shaderCache[uName]; - if(cached != undefined) { - return cached - } - psCode = pc.programlib.getSnippet(device, "fs_precision") + "\n" + psCode; - attribs = this.collectAttribs(vsCode); - shaderCache[uName] = new pc.Shader(device, {attributes:attribs, vshader:vsCode, fshader:psCode}); - return shaderCache[uName] - }; - return{shaderChunks:shaderChunks} -}()); -pc.extend(pc, function() { - var _postEffectQuadVB = null; - function drawQuadWithShader(device, target, shader, rect) { - if(_postEffectQuadVB == null) { - var vertexFormat = new pc.VertexFormat(device, [{semantic:pc.SEMANTIC_POSITION, components:2, type:pc.ELEMENTTYPE_FLOAT32}]); - _postEffectQuadVB = new pc.VertexBuffer(device, vertexFormat, 4); - var iterator = new pc.VertexIterator(_postEffectQuadVB); - iterator.element[pc.SEMANTIC_POSITION].set(-1, -1); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(1, -1); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(-1, 1); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(1, 1); - iterator.end() - } - device.setRenderTarget(target); - device.updateBegin(); - var x, y, w, h; - if(!rect) { - w = target !== null ? target.width : device.width; - h = target !== null ? target.height : device.height; - x = 0; - y = 0 - }else { - x = rect.x; - y = rect.y; - w = rect.z; - h = rect.w - } - device.setViewport(x, y, w, h); - device.setScissor(x, y, w, h); - var oldDepthTest = device.getDepthTest(); - var oldDepthWrite = device.getDepthWrite(); - device.setDepthTest(false); - device.setDepthWrite(false); - device.setBlending(false); - device.setVertexBuffer(_postEffectQuadVB, 0); - device.setShader(shader); - device.draw({type:pc.PRIMITIVE_TRISTRIP, base:0, count:4, indexed:false}); - device.setDepthTest(oldDepthTest); - device.setDepthWrite(oldDepthWrite); - device.updateEnd() - } - return{drawQuadWithShader:drawQuadWithShader} -}()); -pc.extend(pc, function() { - function fixChrome() { - var endTime = Date.now() + 10; - while(Date.now() < endTime) { - } - } - function syncToCpu(device, targ, face) { - var tex = targ._colorBuffer; - if(tex.format != pc.PIXELFORMAT_R8_G8_B8_A8) { - return - } - var pixels = new Uint8Array(tex.width * tex.height * 4); - var gl = device.gl; - gl.bindFramebuffer(gl.FRAMEBUFFER, targ._glFrameBuffer); - gl.readPixels(0, 0, tex.width, tex.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - if(!tex._levels) { - tex._levels = [] - } - if(!tex._levels[0]) { - tex._levels[0] = [] - } - tex._levels[0][face] = pixels - } - function prefilterCubemap(options) { - var device = options.device; - var sourceCubemap = options.sourceCubemap; - var method = options.method; - var samples = options.samples; - var cpuSync = options.cpuSync; - var chromeFix = options.chromeFix; - if(cpuSync && !sourceCubemap._levels[0]) { - console.error("ERROR: prefilter: cubemap must have _levels"); - return - } - var chunks = pc.shaderChunks; - var shader = chunks.createShaderFromCode(device, chunks.fullscreenQuadVS, chunks.rgbmPS + chunks.prefilterCubemapPS.replace(/\$METHOD/g, method === 0 ? "cos" : "phong").replace(/\$NUMSAMPLES/g, samples), "prefilter" + method + "" + samples); - var shader2 = chunks.createShaderFromCode(device, chunks.fullscreenQuadVS, chunks.outputCubemapPS, "outputCubemap"); - var constantTexSource = device.scope.resolve("source"); - var constantParams = device.scope.resolve("params"); - var params = new pc.Vec4; - var size = sourceCubemap.width; - var rgbmSource = sourceCubemap.rgbm; - var format = sourceCubemap.format; - var cmapsList = [[], options.filteredFixed, options.filteredRgbm, options.filteredFixedRgbm]; - var gloss = method === 0 ? [0.9, 0.85, 0.7, 0.4, 0.25] : [512, 128, 32, 8, 2]; - var mipSize = [64, 32, 16, 8, 4]; - var mips = 5; - var targ; - var i, face, pass; - var rgbFormat = format === pc.PIXELFORMAT_R8_G8_B8; - var isImg = false; - if(cpuSync) { - isImg = sourceCubemap._levels[0][0] instanceof HTMLImageElement - } - if((rgbFormat || isImg) && cpuSync) { - format = pc.PIXELFORMAT_R8_G8_B8_A8; - var nextCubemap = new pc.gfx.Texture(device, {cubemap:true, rgbm:rgbmSource, format:format, width:size, height:size, autoMipmap:false}); - nextCubemap.minFilter = pc.FILTER_LINEAR; - nextCubemap.magFilter = pc.FILTER_LINEAR; - nextCubemap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - nextCubemap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - for(face = 0;face < 6;face++) { - targ = new pc.RenderTarget(device, nextCubemap, {face:face, depth:false}); - params.x = face; - params.y = 0; - constantTexSource.setValue(sourceCubemap); - constantParams.setValue(params.data); - if(chromeFix) { - fixChrome() - } - pc.drawQuadWithShader(device, targ, shader2); - syncToCpu(device, targ, face) - } - sourceCubemap = nextCubemap - } - if(size > 128) { - var log128 = Math.round(Math.log2(128)); - var logSize = Math.round(Math.log2(size)); - var steps = logSize - log128; - var nextCubemap; - for(i = 0;i < steps;i++) { - size = sourceCubemap.width * 0.5; - var sampleGloss = method === 0 ? 1 : Math.pow(2, Math.round(Math.log2(gloss[0]) + (steps - i) * 2)); - nextCubemap = new pc.gfx.Texture(device, {cubemap:true, rgbm:rgbmSource, format:format, width:size, height:size, autoMipmap:false}); - nextCubemap.minFilter = pc.FILTER_LINEAR; - nextCubemap.magFilter = pc.FILTER_LINEAR; - nextCubemap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - nextCubemap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - for(face = 0;face < 6;face++) { - targ = new pc.RenderTarget(device, nextCubemap, {face:face, depth:false}); - params.x = face; - params.y = sampleGloss; - params.z = size; - params.w = 0; - constantTexSource.setValue(sourceCubemap); - constantParams.setValue(params.data); - if(chromeFix) { - fixChrome() - } - pc.drawQuadWithShader(device, targ, shader2); - if(i === steps - 1 && cpuSync) { - syncToCpu(device, targ, face) - } - } - sourceCubemap = nextCubemap - } - } - options.sourceCubemap = sourceCubemap; - var sourceCubemapRgbm = null; - if(!rgbmSource && options.filteredFixedRgbm) { - var nextCubemap = new pc.gfx.Texture(device, {cubemap:true, rgbm:true, format:pc.PIXELFORMAT_R8_G8_B8_A8, width:size, height:size, autoMipmap:false}); - nextCubemap.minFilter = pc.FILTER_LINEAR; - nextCubemap.magFilter = pc.FILTER_LINEAR; - nextCubemap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - nextCubemap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - for(face = 0;face < 6;face++) { - targ = new pc.RenderTarget(device, nextCubemap, {face:face, depth:false}); - params.x = face; - params.w = 2; - constantTexSource.setValue(sourceCubemap); - constantParams.setValue(params.data); - if(chromeFix) { - fixChrome() - } - pc.drawQuadWithShader(device, targ, shader2); - syncToCpu(device, targ, face) - } - sourceCubemapRgbm = nextCubemap - } - var unblurredGloss = method === 0 ? 1 : 2048; - var startPass = method === 0 ? 0 : -1; - cmapsList[startPass] = []; - for(i = 0;i < mips;i++) { - for(pass = startPass;pass < cmapsList.length;pass++) { - if(cmapsList[pass] != null) { - cmapsList[pass][i] = new pc.gfx.Texture(device, {cubemap:true, rgbm:pass < 2 ? rgbmSource : true, format:pass < 2 ? format : pc.PIXELFORMAT_R8_G8_B8_A8, fixCubemapSeams:pass === 1 || pass === 3, width:mipSize[i], height:mipSize[i], autoMipmap:false}); - cmapsList[pass][i].minFilter = pc.FILTER_LINEAR; - cmapsList[pass][i].magFilter = pc.FILTER_LINEAR; - cmapsList[pass][i].addressU = pc.ADDRESS_CLAMP_TO_EDGE; - cmapsList[pass][i].addressV = pc.ADDRESS_CLAMP_TO_EDGE - } - } - } - for(pass = startPass;pass < cmapsList.length;pass++) { - if(cmapsList[pass] != null) { - if(pass > 1 && rgbmSource) { - cmapsList[pass] = cmapsList[pass - 2]; - continue - } - for(i = 0;i < mips;i++) { - for(face = 0;face < 6;face++) { - targ = new pc.RenderTarget(device, cmapsList[pass][i], {face:face, depth:false}); - params.x = face; - params.y = pass < 0 ? unblurredGloss : gloss[i]; - params.z = mipSize[i]; - params.w = pass; - constantTexSource.setValue(i === 0 ? sourceCubemap : method === 0 ? cmapsList[0][i - 1] : cmapsList[-1][i - 1]); - constantParams.setValue(params.data); - if(chromeFix) { - fixChrome() - } - pc.drawQuadWithShader(device, targ, shader); - if(cpuSync) { - syncToCpu(device, targ, face) - } - } - } - } - } - options.filtered = cmapsList[0]; - if(cpuSync && options.singleFilteredFixed) { - var mips = [sourceCubemap, options.filteredFixed[0], options.filteredFixed[1], options.filteredFixed[2], options.filteredFixed[3], options.filteredFixed[4], options.filteredFixed[5]]; - var cubemap = new pc.gfx.Texture(device, {cubemap:true, rgbm:rgbmSource, fixCubemapSeams:true, format:format, width:128, height:128, autoMipmap:false}); - for(i = 0;i < 6;i++) { - cubemap._levels[i] = mips[i]._levels[0] - } - cubemap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - cubemap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - cubemap.upload(); - cubemap.minFilter = pc.FILTER_LINEAR_MIPMAP_LINEAR; - cubemap.magFilter = pc.FILTER_LINEAR; - cubemap._prefilteredMips = true; - options.singleFilteredFixed = cubemap - } - if(cpuSync && options.singleFilteredFixedRgbm && options.filteredFixedRgbm) { - var mips = [sourceCubemapRgbm, options.filteredFixedRgbm[0], options.filteredFixedRgbm[1], options.filteredFixedRgbm[2], options.filteredFixedRgbm[3], options.filteredFixedRgbm[4], options.filteredFixedRgbm[5]]; - var cubemap = new pc.gfx.Texture(device, {cubemap:true, rgbm:true, fixCubemapSeams:true, format:pc.PIXELFORMAT_R8_G8_B8_A8, width:128, height:128, autoMipmap:false}); - for(i = 0;i < 6;i++) { - cubemap._levels[i] = mips[i]._levels[0] - } - cubemap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - cubemap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - cubemap.upload(); - cubemap.minFilter = pc.FILTER_LINEAR_MIPMAP_LINEAR; - cubemap.magFilter = pc.FILTER_LINEAR; - cubemap._prefilteredMips = true; - options.singleFilteredFixedRgbm = cubemap - } - } - function areaElement(x, y) { - return Math.atan2(x * y, Math.sqrt(x * x + y * y + 1)) - } - function texelCoordSolidAngle(u, v, size) { - var _u = 2 * (u + 0.5) / size - 1; - var _v = 2 * (v + 0.5) / size - 1; - _u *= 1 - 1 / size; - _v *= 1 - 1 / size; - var invResolution = 1 / size; - var x0 = _u - invResolution; - var y0 = _v - invResolution; - var x1 = _u + invResolution; - var y1 = _v + invResolution; - var solidAngle = areaElement(x0, y0) - areaElement(x0, y1) - areaElement(x1, y0) + areaElement(x1, y1); - if(u == 0 && v == 0 || u == size - 1 && v == 0 || u == 0 && v == size - 1 || u == size - 1 && v == size - 1) { - solidAngle /= 3 - }else { - if(u == 0 || v == 0 || u == size - 1 || v == size - 1) { - solidAngle *= 0.5 - } - } - return solidAngle - } - function shFromCubemap(source) { - var face; - var cubeSize = source.width; - if(source.format != pc.PIXELFORMAT_R8_G8_B8_A8) { - console.error("ERROR: SH: cubemap must be RGBA8"); - return - } - if(!source._levels[0]) { - console.error("ERROR: SH: cubemap must be synced to CPU"); - return - } - if(!source._levels[0][0].length) { - if(source._levels[0][0] instanceof HTMLImageElement) { - var device = pc.Application.getApplication().graphicsDevice; - var gl = device.gl; - var chunks = pc.shaderChunks; - var shader = chunks.createShaderFromCode(device, chunks.fullscreenQuadVS, chunks.fullscreenQuadPS, "fsQuadSimple"); - var constantTexSource = device.scope.resolve("source"); - for(face = 0;face < 6;face++) { - var img = source._levels[0][face]; - var tex = new pc.gfx.Texture(device, {cubemap:false, rgbm:false, format:source.format, width:cubeSize, height:cubeSize, autoMipmap:false}); - tex.minFilter = pc.FILTER_NEAREST; - tex.magFilter = pc.FILTER_NEAREST; - tex.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - tex.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - tex._levels[0] = img; - tex.upload(); - var tex2 = new pc.gfx.Texture(device, {cubemap:false, rgbm:false, format:source.format, width:cubeSize, height:cubeSize, autoMipmap:false}); - tex2.minFilter = pc.FILTER_NEAREST; - tex2.magFilter = pc.FILTER_NEAREST; - tex2.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - tex2.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - targ = new pc.RenderTarget(device, tex2, {depth:false}); - constantTexSource.setValue(tex); - pc.drawQuadWithShader(device, targ, shader); - var pixels = new Uint8Array(cubeSize * cubeSize * 4); - gl.bindFramebuffer(gl.FRAMEBUFFER, targ._glFrameBuffer); - gl.readPixels(0, 0, tex.width, tex.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - source._levels[0][face] = pixels - } - }else { - console.error("ERROR: SH: cubemap must be composed of arrays or images"); - return - } - } - var dirs = []; - for(y = 0;y < cubeSize;y++) { - for(x = 0;x < cubeSize;x++) { - var u = x / (cubeSize - 1) * 2 - 1; - var v = y / (cubeSize - 1) * 2 - 1; - dirs[y * cubeSize + x] = (new pc.Vec3(u, v, 1)).normalize() - } - } - var sh = new Float32Array(25 * 3); - var coef1 = 0; - var coef2 = 1 * 3; - var coef3 = 2 * 3; - var coef4 = 3 * 3; - var coef5 = 4 * 3; - var coef6 = 5 * 3; - var coef7 = 6 * 3; - var coef8 = 7 * 3; - var coef9 = 8 * 3; - var nx = 0; - var px = 1; - var ny = 2; - var py = 3; - var nz = 4; - var pz = 5; - var x, y, addr, c, a, value, weight, dir, dx, dy, dz; - var accum = 0; - for(face = 0;face < 6;face++) { - for(y = 0;y < cubeSize;y++) { - for(x = 0;x < cubeSize;x++) { - addr = y * cubeSize + x; - weight = texelCoordSolidAngle(x, y, cubeSize); - weight1 = weight * 4 / 17; - weight2 = weight * 8 / 17; - weight3 = weight * 15 / 17; - weight4 = weight * 5 / 68; - weight5 = weight * 15 / 68; - dir = dirs[addr]; - if(face == nx) { - dx = dir.z; - dy = -dir.y; - dz = -dir.x - }else { - if(face == px) { - dx = -dir.z; - dy = -dir.y; - dz = dir.x - }else { - if(face == ny) { - dx = dir.x; - dy = dir.z; - dz = dir.y - }else { - if(face == py) { - dx = dir.x; - dy = -dir.z; - dz = -dir.y - }else { - if(face == nz) { - dx = dir.x; - dy = -dir.y; - dz = dir.z - }else { - if(face == pz) { - dx = -dir.x; - dy = -dir.y; - dz = -dir.z - } - } - } - } - } - } - dx = -dx; - a = source._levels[0][face][addr * 4 + 3] / 255; - for(c = 0;c < 3;c++) { - value = source._levels[0][face][addr * 4 + c] / 255; - if(source.rgbm) { - value *= a * 8; - value *= value - } - sh[coef1 + c] += value * weight1; - sh[coef2 + c] += value * weight2 * dx; - sh[coef3 + c] += value * weight2 * dy; - sh[coef4 + c] += value * weight2 * dz; - sh[coef5 + c] += value * weight3 * dx * dz; - sh[coef6 + c] += value * weight3 * dz * dy; - sh[coef7 + c] += value * weight3 * dy * dx; - sh[coef8 + c] += value * weight4 * (3 * dz * dz - 1); - sh[coef9 + c] += value * weight5 * (dx * dx - dy * dy); - accum += weight - } - } - } - } - for(c = 0;c < sh.length;c++) { - sh[c] *= 4 * Math.PI / accum - } - return sh - } - return{prefilterCubemap:prefilterCubemap, shFromCubemap:shFromCubemap} -}()); -pc.extend(pc, function() { - var dpMult = 2; - function paraboloidFromCubemap(device, sourceCubemap, fixSeamsAmount) { - var chunks = pc.shaderChunks; - var shader = chunks.createShaderFromCode(device, chunks.fullscreenQuadVS, (sourceCubemap.fixCubemapSeams ? chunks.fixCubemapSeamsStretchPS : chunks.fixCubemapSeamsNonePS) + chunks.genParaboloidPS, "genParaboloid"); - var constantTexSource = device.scope.resolve("source"); - var constantParams = device.scope.resolve("params"); - var params = new pc.Vec4; - var size = sourceCubemap.width; - var rgbmSource = sourceCubemap.rgbm; - var format = sourceCubemap.format; - size = Math.max(size, 8) * dpMult; - var tex = new pc.gfx.Texture(device, {rgbm:rgbmSource, format:format, width:size * 2, height:size, autoMipmap:false}); - tex.minFilter = pc.FILTER_LINEAR; - tex.magFilter = pc.FILTER_LINEAR; - tex.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - tex.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - var targ = new pc.RenderTarget(device, tex, {depth:false}); - params.x = fixSeamsAmount; - params.y = 1 / tex.width; - params.z = 1 / tex.height; - constantTexSource.setValue(sourceCubemap); - constantParams.setValue(params.data); - pc.drawQuadWithShader(device, targ, shader); - return tex - } - function getDpAtlasRect(rect, mip) { - rect.x = pc.math.clamp(mip - 2, 0, 1) * 0.5; - var t = mip - rect.x * 6; - var i = 1 - rect.x; - rect.y = Math.min(t * 0.5, 0.75) * i + rect.x; - rect.z = (1 - pc.math.clamp(t, 0, 1) * 0.5) * i; - rect.w = rect.z * 0.5; - return 1 / rect.z - } - function generateDpAtlas(device, sixCubemaps) { - var dp, rect; - rect = new pc.Vec4; - var params = new pc.Vec4; - var size = sixCubemaps[0].width * 2 * dpMult; - var chunks = pc.shaderChunks; - var shader = chunks.createShaderFromCode(device, chunks.fullscreenQuadVS, chunks.dpAtlasQuadPS, "dpAtlasQuad"); - var constantTexSource = device.scope.resolve("source"); - var constantParams = device.scope.resolve("params"); - var tex = new pc.gfx.Texture(device, {rgbm:sixCubemaps[0].rgbm, format:sixCubemaps[0].format, width:size, height:size, autoMipmap:false}); - tex.minFilter = pc.FILTER_LINEAR; - tex.magFilter = pc.FILTER_LINEAR; - tex.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - tex.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - var targ = new pc.RenderTarget(device, tex, {depth:false}); - var borderSize = 2; - var mip0Width = size; - var scaleFactor = (mip0Width + borderSize) / mip0Width - 1; - var scaleAmount; - for(var i = 0;i < 6;i++) { - dp = pc.paraboloidFromCubemap(device, sixCubemaps[i], i); - constantTexSource.setValue(dp); - scaleAmount = getDpAtlasRect(rect, i); - params.x = scaleAmount * scaleFactor; - params.y = params.x * 2; - params.x += 1; - params.y += 1; - constantParams.setValue(params.data); - rect.x *= size; - rect.y *= size; - rect.z *= size; - rect.w *= size; - pc.drawQuadWithShader(device, targ, shader, rect) - } - return tex - } - return{paraboloidFromCubemap:paraboloidFromCubemap, generateDpAtlas:generateDpAtlas} -}()); -pc.shaderChunks.ambientConstantPS = "\nvoid addAmbient(inout psInternalData data) {\n data.diffuseLight = light_globalAmbient;\n}\n"; -pc.shaderChunks.ambientPrefilteredCubePS = "void addAmbient(inout psInternalData data) {\n vec3 fixedReflDir = fixSeamsStatic(data.normalW, 1.0 - 1.0 / 4.0);\n fixedReflDir.x *= -1.0;\n data.diffuseLight = processEnvironment($DECODE(textureCube(texture_prefilteredCubeMap4, fixedReflDir)).rgb);\n}\n\n"; -pc.shaderChunks.ambientPrefilteredCubeLodPS = "void addAmbient(inout psInternalData data) {\n vec3 fixedReflDir = fixSeamsStatic(data.normalW, 1.0 - 1.0 / 4.0);\n fixedReflDir.x *= -1.0;\n data.diffuseLight = processEnvironment($DECODE( textureCubeLodEXT(texture_prefilteredCubeMap128, fixedReflDir, 5.0) ).rgb);\n}\n\n"; -pc.shaderChunks.ambientSHPS = "uniform vec3 ambientSH[9];\nvoid addAmbient(inout psInternalData data) {\n vec3 n = data.normalW;\n\n data.diffuseLight =\n ambientSH[0] +\n ambientSH[1] * n.x +\n ambientSH[2] * n.y +\n ambientSH[3] * n.z +\n ambientSH[4] * n.x * n.z +\n ambientSH[5] * n.z * n.y +\n ambientSH[6] * n.y * n.x +\n ambientSH[7] * (3.0 * n.z * n.z - 1.0) +\n ambientSH[8] * (n.x * n.x - n.y * n.y);\n\n data.diffuseLight = processEnvironment(max(data.diffuseLight, vec3(0.0)));\n}\n\n"; -pc.shaderChunks.aoSpecOccPS = "uniform float material_occludeSpecularIntensity;\nvoid occludeSpecular(inout psInternalData data) {\n // approximated specular occlusion from AO\n float specPow = exp2(data.glossiness * 11.0);\n // http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx\n float specOcc = saturate(pow(dot(data.normalW, data.viewDirW) + data.ao, 0.01*specPow) - 1.0 + data.ao);\n specOcc = mix(1.0, specOcc, material_occludeSpecularIntensity);\n\n data.specularLight *= specOcc;\n data.reflection *= specOcc;\n}\n\n"; -pc.shaderChunks.aoSpecOccConstPS = "void occludeSpecular(inout psInternalData data) {\n // approximated specular occlusion from AO\n float specPow = exp2(data.glossiness * 11.0);\n // http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx\n float specOcc = saturate(pow(dot(data.normalW, data.viewDirW) + data.ao, 0.01*specPow) - 1.0 + data.ao);\n\n data.specularLight *= specOcc;\n data.reflection *= specOcc;\n}\n\n"; -pc.shaderChunks.aoTexPS = "uniform sampler2D texture_aoMap;\nvoid applyAO(inout psInternalData data) {\n data.ao = texture2D(texture_aoMap, $UV).$CH;\n data.diffuseLight *= data.ao;\n}\n\n"; -pc.shaderChunks.aoVertPS = "void applyAO(inout psInternalData data) {\n data.ao = saturate(vVertexColor.$CH);\n data.diffuseLight *= data.ao;\n}\n\n"; -pc.shaderChunks.basePS = "\nuniform vec3 view_position;\n\nuniform vec3 light_globalAmbient;\n\nstruct psInternalData {\n vec3 albedo;\n vec3 specularity;\n float glossiness;\n vec3 emission;\n vec3 normalW;\n mat3 TBN;\n vec3 viewDirW;\n vec3 reflDirW;\n vec3 diffuseLight;\n vec3 specularLight;\n vec4 reflection;\n float alpha;\n vec3 lightDirNormW;\n vec3 lightDirW;\n vec3 lightPosW;\n float atten;\n vec3 shadowCoord;\n vec2 uvOffset;\n vec3 normalMap;\n float ao;\n};\n\nvoid getViewDir(inout psInternalData data) {\n data.viewDirW = normalize(view_position - vPositionW);\n}\n\nvoid getReflDir(inout psInternalData data) {\n data.reflDirW = normalize(-reflect(data.viewDirW, data.normalW));\n}\n\nvoid getLightDirPoint(inout psInternalData data, vec3 lightPosW) {\n data.lightDirW = vPositionW - lightPosW;\n data.lightDirNormW = normalize(data.lightDirW);\n data.lightPosW = lightPosW;\n}\n\nfloat getFalloffLinear(inout psInternalData data, float lightRadius) {\n float d = length(data.lightDirW);\n return max(((lightRadius - d) / lightRadius), 0.0);\n}\n\nfloat square(float x) {\n return x*x;\n}\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 saturate(vec3 x) {\n return clamp(x, vec3(0.0), vec3(1.0));\n}\n\nfloat getFalloffInvSquared(inout psInternalData data, float lightRadius) {\n float sqrDist = dot(data.lightDirW, data.lightDirW);\n float falloff = 1.0 / (sqrDist + 1.0);\n float invRadius = 1.0 / lightRadius;\n\n falloff *= 16.0;\n falloff *= square( saturate( 1.0 - square( sqrDist * square(invRadius) ) ) );\n\n return falloff;\n}\n\nfloat getSpotEffect(inout psInternalData data, vec3 lightSpotDirW, float lightInnerConeAngle, float lightOuterConeAngle) {\n float cosAngle = dot(data.lightDirNormW, lightSpotDirW);\n return smoothstep(lightOuterConeAngle, lightInnerConeAngle, cosAngle);\n}\n\nvoid processMetalness(inout psInternalData data, float metalness) {\n const float dielectricF0 = 0.04;\n data.specularity = mix(vec3(dielectricF0), data.albedo, metalness);\n data.albedo *= 1.0 - metalness;\n}\n\n"; -pc.shaderChunks.baseVS = "\nattribute vec3 vertex_position;\nattribute vec3 vertex_normal;\nattribute vec4 vertex_tangent;\nattribute vec2 vertex_texCoord0;\nattribute vec2 vertex_texCoord1;\nattribute vec4 vertex_color;\n\nuniform mat4 matrix_viewProjection;\nuniform mat4 matrix_model;\nuniform mat3 matrix_normal;\n\nstruct vsInternalData {\n vec3 positionW;\n mat4 modelMatrix;\n mat3 normalMatrix;\n vec3 lightPosW;\n vec3 lightDirNormW;\n vec3 normalW;\n};\n\n"; -pc.shaderChunks.combineDiffusePS = "vec3 combineColor(inout psInternalData data) {\n return data.albedo * data.diffuseLight;\n}\n\n"; -pc.shaderChunks.combineDiffuseSpecularPS = "vec3 combineColor(inout psInternalData data) {\n return mix(data.albedo * data.diffuseLight, data.specularLight + data.reflection.rgb * data.reflection.a, data.specularity);\n}\n\n"; -pc.shaderChunks.combineDiffuseSpecularNoConservePS = "vec3 combineColor(inout psInternalData data) {\n return data.albedo * data.diffuseLight + (data.specularLight + data.reflection.rgb * data.reflection.a) * data.specularity;\n}\n\n"; -pc.shaderChunks.combineDiffuseSpecularNoReflPS = "vec3 combineColor(inout psInternalData data) {\n return data.albedo * data.diffuseLight + data.specularLight * data.specularity;\n}\n\n"; -pc.shaderChunks.combineDiffuseSpecularNoReflSeparateAmbientPS = "uniform vec3 material_ambient;\nvec3 combineColor(inout psInternalData data) {\n return (data.diffuseLight - light_globalAmbient) * data.albedo + data.specularLight * data.specularity + material_ambient * light_globalAmbient;\n}\n\n"; -pc.shaderChunks.combineDiffuseSpecularOldPS = "vec3 combineColor(inout psInternalData data) {\n return mix(data.albedo * data.diffuseLight + data.specularLight * data.specularity, data.reflection.rgb, data.reflection.a);\n}\n\n"; -pc.shaderChunks.cubeMapProjectBoxPS = "uniform vec3 envBoxMin, envBoxMax;\n\nvec3 cubeMapProject(vec3 nrdir) {\n vec3 rbmax = (envBoxMax - vPositionW) / nrdir;\n vec3 rbmin = (envBoxMin - vPositionW) / nrdir;\n\n vec3 rbminmax;\n rbminmax.x = nrdir.x>0.0? rbmax.x : rbmin.x;\n rbminmax.y = nrdir.y>0.0? rbmax.y : rbmin.y;\n rbminmax.z = nrdir.z>0.0? rbmax.z : rbmin.z;\n\n float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z);\n\n vec3 posonbox = vPositionW + nrdir * fa;\n vec3 envBoxPos = (envBoxMin + envBoxMax) * 0.5;\n return posonbox - envBoxPos;\n}\n\n"; -pc.shaderChunks.cubeMapProjectNonePS = "vec3 cubeMapProject(vec3 dir) {\n return dir;\n}\n\n"; -pc.shaderChunks.diffuseConstPS = "uniform vec3 material_diffuse;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = material_diffuse.rgb;\n}\n\n"; -pc.shaderChunks.diffuseTexPS = "uniform sampler2D texture_diffuseMap;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = texture2DSRGB(texture_diffuseMap, $UV).$CH;\n}\n\n"; -pc.shaderChunks.diffuseTexConstPS = "uniform sampler2D texture_diffuseMap;\nuniform vec3 material_diffuse;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = texture2DSRGB(texture_diffuseMap, $UV).$CH * material_diffuse;\n}\n\n"; -pc.shaderChunks.diffuseVertPS = "void getAlbedo(inout psInternalData data) {\n data.albedo = gammaCorrectInput(saturate(vVertexColor.$CH));\n}\n\n"; -pc.shaderChunks.diffuseVertConstPS = "uniform vec3 material_diffuse;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = gammaCorrectInput(saturate(vVertexColor.$CH)) * material_diffuse;\n}\n\n"; -pc.shaderChunks.dpAtlasQuadPS = "varying vec2 vUv0;\nuniform sampler2D source;\nuniform vec4 params;\n\nvoid main(void) {\n vec2 uv = vUv0;\n uv = uv * 2.0 - vec2(1.0);\n uv *= params.xy;\n uv = uv * 0.5 + 0.5;\n gl_FragColor = texture2D(source, uv);\n}\n"; -pc.shaderChunks.emissiveConstPS = "uniform vec3 material_emissive;\nvec3 getEmission(inout psInternalData data) {\n return material_emissive;\n}\n\n"; -pc.shaderChunks.emissiveTexPS = "uniform sampler2D texture_emissiveMap;\nvec3 getEmission(inout psInternalData data) {\n return $texture2DSAMPLE(texture_emissiveMap, $UV).$CH;\n}\n\n"; -pc.shaderChunks.emissiveTexConstPS = "uniform sampler2D texture_emissiveMap;\nuniform vec3 material_emissive;\nvec3 getEmission(inout psInternalData data) {\n return $texture2DSAMPLE(texture_emissiveMap, $UV).$CH * material_emissive;\n}\n\n"; -pc.shaderChunks.emissiveVertPS = "vec3 getEmission(inout psInternalData data) {\n return gammaCorrectInput(saturate(vVertexColor.$CH));\n}\n\n"; -pc.shaderChunks.emissiveVertConstPS = "uniform vec3 material_emissive;\nvec3 getEmission(inout psInternalData data) {\n return gammaCorrectInput(saturate(vVertexColor.$CH)) * material_emissive;\n}\n\n"; -pc.shaderChunks.endPS = " gl_FragColor.rgb = combineColor(data);\n gl_FragColor.rgb += getEmission(data);\n gl_FragColor.rgb = addFog(data, gl_FragColor.rgb);\n gl_FragColor.rgb = toneMap(gl_FragColor.rgb);\n gl_FragColor.rgb = gammaCorrectOutput(gl_FragColor.rgb);\n"; -pc.shaderChunks.envConstPS = "vec3 processEnvironment(vec3 color) {\n return color;\n}\n\n"; -pc.shaderChunks.envMultiplyPS = "uniform float skyboxIntensity;\nvec3 processEnvironment(vec3 color) {\n return color * skyboxIntensity;\n}\n\n"; -pc.shaderChunks.fixCubemapSeamsNonePS = "vec3 fixSeams(vec3 vec, float mipmapIndex) {\n return vec;\n}\n\nvec3 fixSeams(vec3 vec) {\n return vec;\n}\n\nvec3 fixSeamsStatic(vec3 vec, float invRecMipSize) {\n return vec;\n}\n"; -pc.shaderChunks.fixCubemapSeamsStretchPS = "vec3 fixSeams(vec3 vec, float mipmapIndex) {\n float scale = 1.0 - exp2(mipmapIndex) / 128.0;\n float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));\n if (abs(vec.x) != M) vec.x *= scale;\n if (abs(vec.y) != M) vec.y *= scale;\n if (abs(vec.z) != M) vec.z *= scale;\n return vec;\n}\n\nvec3 fixSeams(vec3 vec) {\n float scale = 1.0 - 1.0 / 128.0;\n float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));\n if (abs(vec.x) != M) vec.x *= scale;\n if (abs(vec.y) != M) vec.y *= scale;\n if (abs(vec.z) != M) vec.z *= scale;\n return vec;\n}\n\nvec3 fixSeamsStatic(vec3 vec, float invRecMipSize) {\n float scale = invRecMipSize;\n float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));\n if (abs(vec.x) != M) vec.x *= scale;\n if (abs(vec.y) != M) vec.y *= scale;\n if (abs(vec.z) != M) vec.z *= scale;\n return vec;\n}\n\n"; -pc.shaderChunks.fogExpPS = "uniform vec3 fog_color;\nuniform float fog_density;\nvec3 addFog(inout psInternalData data, vec3 color) {\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n float fogFactor = exp(-depth * fog_density);\n fogFactor = clamp(fogFactor, 0.0, 1.0);\n return mix(fog_color, color, fogFactor);\n}\n"; -pc.shaderChunks.fogExp2PS = "uniform vec3 fog_color;\nuniform float fog_density;\nvec3 addFog(inout psInternalData data, vec3 color) {\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n float fogFactor = exp(-depth * depth * fog_density * fog_density);\n fogFactor = clamp(fogFactor, 0.0, 1.0);\n return mix(fog_color, color, fogFactor);\n}\n"; -pc.shaderChunks.fogLinearPS = "uniform vec3 fog_color;\nuniform float fog_start;\nuniform float fog_end;\nvec3 addFog(inout psInternalData data, vec3 color) {\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n float fogFactor = (fog_end - depth) / (fog_end - fog_start);\n fogFactor = clamp(fogFactor, 0.0, 1.0);\n fogFactor = gammaCorrectInput(fogFactor);\n return mix(fog_color, color, fogFactor);\n}\n"; -pc.shaderChunks.fogNonePS = "vec3 addFog(inout psInternalData data, vec3 color) {\n return color;\n}\n\n\n"; -pc.shaderChunks.fresnelComplexPS = "// More physically-based Fresnel\nuniform float material_fresnelFactor; // should be IOR\nvoid getFresnel(inout psInternalData data) {\n float cosThetaI = max(dot(data.normalW, data.viewDirW), 0.0);\n float n = material_fresnelFactor;\n\n float cosThetaT = sqrt(max(0.0, 1.0 - (1.0 - cosThetaI * cosThetaI) / (n * n)));\n float nCosThetaT = n * cosThetaT;\n float nCosThetaI = n * cosThetaI;\n\n float rS = abs((cosThetaI - nCosThetaT) / (cosThetaI + nCosThetaT));\n float rP = abs((cosThetaT - nCosThetaI) / (cosThetaT + nCosThetaI));\n rS *= rS;\n rP *= rP;\n\n data.specularity *= (rS + rP) / 2.0;\n}\n\n"; -pc.shaderChunks.fresnelSchlickPS = "// Schlick's approximation\nuniform float material_fresnelFactor; // unused\nvoid getFresnel(inout psInternalData data) {\n float fresnel = 1.0 - max(dot(data.normalW, data.viewDirW), 0.0);\n float fresnel2 = fresnel * fresnel;\n fresnel *= fresnel2 * fresnel2;\n fresnel *= data.glossiness * data.glossiness;\n data.specularity = data.specularity + (1.0 - data.specularity) * fresnel;\n}\n\n"; -pc.shaderChunks.fresnelSimplePS = "// Easily tweakable but not very correct Fresnel\nuniform float material_fresnelFactor;\nvoid getFresnel(inout psInternalData data) {\n float fresnel = 1.0 - max(dot(data.normalW, data.viewDirW), 0.0);\n data.specularity *= pow(fresnel, material_fresnelFactor);\n}\n\n"; -pc.shaderChunks.fullscreenQuadPS = "varying vec2 vUv0;\nuniform sampler2D source;\n\nvoid main(void) {\n gl_FragColor = texture2D(source, vUv0);\n}\n"; -pc.shaderChunks.fullscreenQuadVS = "attribute vec2 aPosition;\n\nvarying vec2 vUv0;\n\nvoid main(void)\n{\n gl_Position = vec4(aPosition, 0.5, 1.0);\n vUv0 = aPosition.xy*0.5+0.5;\n}\n\n"; -pc.shaderChunks.gamma1_0PS = "vec4 texture2DSRGB(sampler2D tex, vec2 uv) {\n return texture2D(tex, uv);\n}\n\nvec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {\n return textureCube(tex, uvw);\n}\n\nvec3 gammaCorrectOutput(vec3 color) {\n return color;\n}\n\nvec3 gammaCorrectInput(vec3 color) {\n return color;\n}\n\nfloat gammaCorrectInput(float color) {\n return color;\n}\n\nvec4 gammaCorrectInput(vec4 color) {\n return color;\n}\n\n"; -pc.shaderChunks.gamma2_2PS = "vec3 gammaCorrectInput(vec3 color) {\n return pow(color, vec3(2.2));\n}\n\nfloat gammaCorrectInput(float color) {\n return pow(color, 2.2);\n}\n\nvec4 gammaCorrectInput(vec4 color) {\n return vec4(pow(color.rgb, vec3(2.2)), color.a);\n}\n\nvec4 texture2DSRGB(sampler2D tex, vec2 uv) {\n vec4 rgba = texture2D(tex, uv);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {\n vec4 rgba = textureCube(tex, uvw);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec3 gammaCorrectOutput(vec3 color) {\n color += vec3(0.0000001);\n return pow(color, vec3(0.45));\n}\n\n"; -pc.shaderChunks.gamma2_2FastPS = "vec3 gammaCorrectInput(vec3 color) {\n return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878);\n}\n\nfloat gammaCorrectInput(float color) {\n return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878);\n}\n\nvec4 gammaCorrectInput(vec4 color) {\n return vec4(gammaCorrectInput(color.rgb), color.a);\n}\n\nvec4 texture2DSRGB(sampler2D tex, vec2 uv) {\n vec4 rgba = texture2D(tex, uv);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {\n vec4 rgba = textureCube(tex, uvw);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec3 gammaCorrectOutput(vec3 color) {\n color += vec3(0.0000001);\n return pow(color, vec3(0.45));\n}\n\n"; -pc.shaderChunks.genParaboloidPS = "varying vec2 vUv0;\n\nuniform samplerCube source;\nuniform vec4 params; // x = mip\n\nvoid main(void) {\n\n vec2 uv = vUv0;\n\n float side = uv.x < 0.5? 1.0 : -1.0;\n vec2 tc;\n tc.x = fract(uv.x * 2.0) * 2.0 - 1.0;\n tc.y = uv.y * 2.0 - 1.0;\n\n // scale projection a bit to have a little overlap for filtering\n const float scale = 1.1;\n tc *= scale;\n\n vec3 dir;\n dir.y = (dot(tc, tc) - 1.0) * side; // from 1.0 center to 0.0 borders quadratically\n dir.xz = tc * -2.0;\n\n dir.x *= -side; // flip original cubemap x instead of doing it at runtime\n\n dir = fixSeams(dir, params.x);\n\n vec4 color = textureCube(source, dir, -100.0);\n gl_FragColor = color;\n}\n"; -pc.shaderChunks.glossConstPS = "uniform float material_shininess;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = material_shininess;\n}\n\n"; -pc.shaderChunks.glossTexPS = "uniform sampler2D texture_glossMap;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = texture2D(texture_glossMap, $UV).$CH;\n}\n\n"; -pc.shaderChunks.glossTexConstPS = "uniform sampler2D texture_glossMap;\nuniform float material_shininess;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = material_shininess * texture2D(texture_glossMap, $UV).$CH;\n}\n\n"; -pc.shaderChunks.glossVertPS = "void getGlossiness(inout psInternalData data) {\n data.glossiness = saturate(vVertexColor.$CH);\n}\n\n"; -pc.shaderChunks.glossVertConstPS = "uniform float material_shininess;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = material_shininess * saturate(vVertexColor.$CH);\n}\n\n"; -pc.shaderChunks.instancingVS = "\nattribute vec4 instance_line1;\nattribute vec4 instance_line2;\nattribute vec4 instance_line3;\nattribute vec4 instance_line4;\n\n"; -pc.shaderChunks.lightDiffuseLambertPS = "float getLightDiffuse(inout psInternalData data) {\n return max(dot(data.normalW, -data.lightDirNormW), 0.0);\n}\n\n"; -pc.shaderChunks.lightmapSinglePS = "uniform sampler2D texture_lightMap;\nvoid addAmbient(inout psInternalData data) {\n data.diffuseLight = $texture2DSAMPLE(texture_lightMap, $UV).$CH;\n}\n\n"; -pc.shaderChunks.lightmapSingleVertPS = "void addAmbient(inout psInternalData data) {\n data.diffuseLight = saturate(vVertexColor.$CH);\n}\n\n"; -pc.shaderChunks.lightSpecularBlinnPS = "// Energy-conserving (hopefully) Blinn-Phong\nfloat getLightSpecular(inout psInternalData data) {\n vec3 h = normalize( -data.lightDirNormW + data.viewDirW );\n float nh = max( dot( h, data.normalW ), 0.0 );\n\n float specPow = exp2(data.glossiness * 11.0); // glossiness is linear, power is not; 0 - 2048\n specPow = antiAliasGlossiness(data, specPow);\n\n // Hack: On Mac OS X, calling pow with zero for the exponent generates hideous artifacts so bias up a little\n specPow = max(specPow, 0.0001);\n\n return pow(nh, specPow) * (specPow + 2.0) / 8.0;\n}\n\n"; -pc.shaderChunks.lightSpecularPhongPS = "float getLightSpecular(inout psInternalData data) {\n float specPow = data.glossiness;\n\n specPow = antiAliasGlossiness(data, specPow);\n\n // Hack: On Mac OS X, calling pow with zero for the exponent generates hideous artifacts so bias up a little\n return pow(max(dot(data.reflDirW, -data.lightDirNormW), 0.0), specPow + 0.0001);\n}\n\n"; -pc.shaderChunks.metalnessConstPS = "uniform float material_metalness;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, material_metalness);\n}\n\n"; -pc.shaderChunks.metalnessTexPS = "uniform sampler2D texture_metalnessMap;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, texture2D(texture_metalnessMap, $UV).$CH);\n}\n\n"; -pc.shaderChunks.metalnessTexConstPS = "uniform sampler2D texture_metalnessMap;\nuniform float material_metalness;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, texture2D(texture_metalnessMap, $UV).$CH * material_metalness);\n}\n\n"; -pc.shaderChunks.metalnessVertPS = "void getSpecularity(inout psInternalData data) {\n processMetalness(data, saturate(vVertexColor.$CH));\n}\n\n"; -pc.shaderChunks.metalnessVertConstPS = "uniform float material_metalness;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, saturate(vVertexColor.$CH) * material_metalness);\n}\n\n"; -pc.shaderChunks.normalVS = "vec3 getNormal(inout vsInternalData data) {\n data.normalMatrix = matrix_normal;\n return normalize(data.normalMatrix * vertex_normal);\n}\n\n"; -pc.shaderChunks.normalInstancedVS = "vec3 getNormal(inout vsInternalData data) {\n data.normalMatrix = mat3(instance_line1.xyz, instance_line2.xyz, instance_line3.xyz);\n return normalize(data.normalMatrix * vertex_normal);\n}\n\n"; -pc.shaderChunks.normalMapPS = "uniform sampler2D texture_normalMap;\nuniform float material_bumpMapFactor;\nvoid getNormal(inout psInternalData data) {\n vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));\n data.normalMap = normalMap;\n data.normalW = data.TBN * normalMap;\n}\n\n"; -pc.shaderChunks.normalMapFloatPS = "uniform sampler2D texture_normalMap;\nuniform float material_bumpMapFactor;\nvoid getNormal(inout psInternalData data) {\n vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));\n data.normalMap = normalMap;\n normalMap = normalize(mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpMapFactor));\n data.normalW = data.TBN * normalMap;\n}\n\n"; -pc.shaderChunks.normalMapFloatTBNfastPS = "uniform sampler2D texture_normalMap;\nuniform float material_bumpMapFactor;\nvoid getNormal(inout psInternalData data) {\n vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));\n data.normalMap = normalMap;\n normalMap = mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpMapFactor);\n data.normalW = normalize(data.TBN * normalMap);\n}\n\n"; -pc.shaderChunks.normalSkinnedVS = "vec3 getNormal(inout vsInternalData data) {\n data.normalMatrix = mat3(data.modelMatrix[0].xyz, data.modelMatrix[1].xyz, data.modelMatrix[2].xyz);\n return normalize(data.normalMatrix * vertex_normal);\n}\n\n"; -pc.shaderChunks.normalVertexPS = "void getNormal(inout psInternalData data) {\n data.normalW = normalize(vNormalW);\n}\n\n"; -pc.shaderChunks.normalXYPS = "vec3 unpackNormal(vec4 nmap) {\n vec3 normal;\n normal.xy = nmap.wy * 2.0 - 1.0;\n normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n}\n\n"; -pc.shaderChunks.normalXYZPS = "vec3 unpackNormal(vec4 nmap) {\n return nmap.xyz * 2.0 - 1.0;\n}\n\n"; -pc.shaderChunks.opacityConstPS = "uniform float material_opacity;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = material_opacity;\n}\n\n"; -pc.shaderChunks.opacityTexPS = "uniform sampler2D texture_opacityMap;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = texture2D(texture_opacityMap, $UV).$CH;\n}\n\n"; -pc.shaderChunks.opacityTexConstPS = "uniform sampler2D texture_opacityMap;\nuniform float material_opacity;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = texture2D(texture_opacityMap, $UV).$CH * material_opacity;\n}\n\n"; -pc.shaderChunks.opacityVertPS = "void getOpacity(inout psInternalData data) {\n data.alpha = saturate(vVertexColor.$CH);\n}\n\n"; -pc.shaderChunks.opacityVertConstPS = "uniform float material_opacity;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = saturate(vVertexColor.$CH) * material_opacity;\n}\n\n"; -pc.shaderChunks.outputCubemapPS = "varying vec2 vUv0;\n\nuniform samplerCube source;\nuniform vec4 params;\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec4 encodeRGBM(vec4 color) { // modified RGBM\n color.rgb = pow(color.rgb, vec3(0.5));\n color.rgb *= 1.0 / 8.0;\n\n color.a = saturate( max( max( color.r, color.g ), max( color.b, 1.0 / 255.0 ) ) );\n color.a = ceil(color.a * 255.0) / 255.0;\n\n color.rgb /= color.a;\n return color;\n}\n\nvoid main(void) {\n\n vec2 st = vUv0 * 2.0 - 1.0;\n float face = params.x;\n\n vec3 vec;\n if (face==0.0) {\n vec = vec3(1, -st.y, -st.x);\n } else if (face==1.0) {\n vec = vec3(-1, -st.y, st.x);\n } else if (face==2.0) {\n vec = vec3(st.x, 1, st.y);\n } else if (face==3.0) {\n vec = vec3(st.x, -1, -st.y);\n } else if (face==4.0) {\n vec = vec3(st.x, -st.y, 1);\n } else {\n vec = vec3(-st.x, -st.y, -1);\n }\n\n gl_FragColor = textureCube(source, vec);\n if (params.w >= 2.0) gl_FragColor = encodeRGBM(gl_FragColor);\n}\n\n"; -pc.shaderChunks.packDepthPS = "// Packing a float in GLSL with multiplication and mod\n// http://blog.gradientstudios.com/2012/08/23/shadow-map-improvement\nvec4 packFloat(float depth) {\n const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\n\n // combination of mod and multiplication and division works better\n vec4 res = mod(depth * bit_shift * vec4(255), vec4(256) ) / vec4(255);\n res -= res.xxyz * bit_mask;\n return res;\n}\n\n\n"; -pc.shaderChunks.packDepthMaskPS = "vec4 packFloat(float depth) {\n const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\n\n // combination of mod and multiplication and division works better\n vec4 res = mod(depth * bit_shift * vec4(255), vec4(256) ) / vec4(255);\n res.x = 0.0;\n res -= res.xxyz * bit_mask;\n return res;\n}\n\n"; -pc.shaderChunks.parallaxPS = "uniform sampler2D texture_heightMap;\nuniform float material_heightMapFactor;\nvoid getParallax(inout psInternalData data) {\n float parallaxScale = material_heightMapFactor;\n const float parallaxBias = 0.01;\n\n float height = texture2D(texture_heightMap, $UV).$CH * parallaxScale - parallaxBias;\n vec3 viewDirT = data.viewDirW * data.TBN;\n\n data.uvOffset = min(height * viewDirT.xy, vec2(parallaxBias));\n}\n\n"; -pc.shaderChunks.particlePS = "varying vec4 texCoordsAlphaLife;\n\nuniform sampler2D colorMap;\nuniform sampler2D internalTex3;\nuniform float graphSampleSize;\nuniform float graphNumSamples;\nuniform vec4 screenSize;\nuniform float camera_far;\nuniform float softening;\nuniform float colorMult;\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat unpackFloat(vec4 rgbaDepth) {\n const vec4 bitShift = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n float depth = dot(rgbaDepth, bitShift);\n return depth;\n}\n\nvoid main(void) {\n psInternalData data;\n vec4 tex = texture2DSRGB(colorMap, texCoordsAlphaLife.xy);\n vec4 ramp = texture2DSRGB(internalTex3, vec2(texCoordsAlphaLife.w, 0.0));\n ramp.rgb *= colorMult;\n\n ramp.a += texCoordsAlphaLife.z;\n\n vec3 rgb = tex.rgb * ramp.rgb;\n float a = tex.a * ramp.a;\n\n"; -pc.shaderChunks.particleVS = "attribute vec4 particle_vertexData; // XYZ = particle position, W = particle ID + random factor\n\nuniform mat4 matrix_viewProjection;\nuniform mat4 matrix_model;\nuniform mat3 matrix_normal;\nuniform mat4 matrix_viewInverse;\nuniform mat4 matrix_view;\n\nuniform float numParticles, numParticlesPot;\nuniform float graphSampleSize;\nuniform float graphNumSamples;\nuniform float stretch;\nuniform vec3 wrapBounds;\nuniform vec3 emitterScale;\nuniform float rate, rateDiv, lifetime, deltaRandomnessStatic, scaleDivMult, alphaDivMult, seed;\nuniform sampler2D particleTexOUT, particleTexIN;\nuniform sampler2D internalTex0;\nuniform sampler2D internalTex1;\nuniform sampler2D internalTex2;\n\nvarying vec4 texCoordsAlphaLife;\n\nvec3 unpack3NFloats(float src) {\n float r = fract(src);\n float g = fract(src * 256.0);\n float b = fract(src * 65536.0);\n return vec3(r, g, b);\n}\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec4 tex1Dlod_lerp(sampler2D tex, vec2 tc) {\n return mix( texture2D(tex,tc), texture2D(tex,tc + graphSampleSize), fract(tc.x*graphNumSamples) );\n}\n\nvec4 tex1Dlod_lerp(sampler2D tex, vec2 tc, out vec3 w) {\n vec4 a = texture2D(tex,tc);\n vec4 b = texture2D(tex,tc + graphSampleSize);\n float c = fract(tc.x*graphNumSamples);\n\n vec3 unpackedA = unpack3NFloats(a.w);\n vec3 unpackedB = unpack3NFloats(b.w);\n w = mix(unpackedA, unpackedB, c);\n\n return mix(a, b, c);\n}\n\n\nvec2 rotate(vec2 quadXY, float pRotation, out mat2 rotMatrix) {\n float c = cos(pRotation);\n float s = sin(pRotation);\n\n mat2 m = mat2(c, -s, s, c);\n rotMatrix = m;\n\n return m * quadXY;\n}\n\nvec3 billboard(vec3 InstanceCoords, vec2 quadXY, out mat3 localMat) {\n vec3 viewUp = matrix_viewInverse[1].xyz;\n vec3 posCam = matrix_viewInverse[3].xyz;\n\n mat3 billMat;\n billMat[2] = normalize(InstanceCoords - posCam);\n billMat[0] = normalize(cross(viewUp, billMat[2]));\n billMat[1] = -viewUp;\n vec3 pos = billMat * vec3(quadXY, 0);\n\n localMat = billMat;\n\n return pos;\n}\n\nvoid main(void) {\n vec3 meshLocalPos = particle_vertexData.xyz;\n float id = floor(particle_vertexData.w);\n\n float rndFactor = fract(sin(id + 1.0 + seed));\n vec3 rndFactor3 = vec3(rndFactor, fract(rndFactor*10.0), fract(rndFactor*100.0));\n\n vec4 particleTex = texture2D(particleTexOUT, vec2(id / numParticlesPot, 0.125));\n vec3 pos = particleTex.xyz;\n float angle = (particleTex.w < 0.0? -particleTex.w : particleTex.w) - 1000.0;\n bool hide = particleTex.w < 0.0;\n\n vec4 particleTex2 = texture2D(particleTexOUT, vec2(id / numParticlesPot, 0.375));\n vec3 particleVelocity = particleTex2.xyz;\n vec2 velocityV = normalize((mat3(matrix_view) * particleVelocity).xy); // should be removed by compiler if align/stretch is not used\n float life = particleTex2.w;\n\n float particleLifetime = lifetime;\n\n if (life <= 0.0 || life > particleLifetime || hide) meshLocalPos = vec3(0.0);\n vec2 quadXY = meshLocalPos.xy;\n float nlife = clamp(life / particleLifetime, 0.0, 1.0);\n\n vec3 paramDiv;\n vec4 params = tex1Dlod_lerp(internalTex2, vec2(nlife, 0), paramDiv);\n float scale = params.y;\n float scaleDiv = paramDiv.x;\n float alphaDiv = paramDiv.z;\n\n scale += (scaleDiv * 2.0 - 1.0) * scaleDivMult * fract(rndFactor*10000.0);\n\n texCoordsAlphaLife = vec4(quadXY * -0.5 + 0.5, (alphaDiv * 2.0 - 1.0) * alphaDivMult * fract(rndFactor*1000.0), nlife);\n\n vec3 particlePos = pos;\n vec3 particlePosMoved = vec3(0.0);\n\n mat2 rotMatrix;\n mat3 localMat;\n\n\n"; -pc.shaderChunks.particleUpdaterAABBPS = "uniform mat3 spawnBounds;\nvec3 calcSpawnPosition(vec3 inBounds, float rndFactor) {\n return emitterPos + spawnBounds * (inBounds - vec3(0.5));\n}\n\nvoid addInitialVelocity(inout vec3 localVelocity, vec3 inBounds) {\n localVelocity -= vec3(0, 0, initialVelocity);\n}\n\n"; -pc.shaderChunks.particleUpdaterEndPS = "\n tex = vec4(outPosition, (outRotation + 1000.0) * visMode) * outMask0 +\n vec4(outVelocity, life) * outMask1 +\n texR * outMask2;\n\n gl_FragColor = tex;\n}\n\n"; -pc.shaderChunks.particleUpdaterInitPS = "varying vec2 vUv0;\n\nuniform sampler2D particleTexIN;\nuniform sampler2D internalTex0;\nuniform sampler2D internalTex1;\nuniform sampler2D internalTex2;\n\nuniform mat3 emitterMatrix;\nuniform vec3 emitterScale;\n\nuniform vec3 emitterPos, frameRandom, localVelocityDivMult, velocityDivMult;\nuniform float delta, rate, rateDiv, lifetime, numParticles, rotSpeedDivMult, seed;\nuniform float startAngle, startAngle2;\nuniform float initialVelocity;\n\nuniform float graphSampleSize;\nuniform float graphNumSamples;\n\n"; -pc.shaderChunks.particleUpdaterNoRespawnPS = " if (life >= particleLifetime) {\n life -= max(particleLifetime, (numParticles - 1.0) * particleRate);\n visMode = -1.0;\n }\n"; -pc.shaderChunks.particleUpdaterOnStopPS = " visMode = life < 0.0? -1.0: visMode;\n\n"; -pc.shaderChunks.particleUpdaterRespawnPS = " if (life >= particleLifetime) {\n life -= max(particleLifetime, (numParticles - 1.0) * particleRate);\n visMode = 1.0;\n }\n visMode = life < 0.0? 1.0: visMode;\n\n"; -pc.shaderChunks.particleUpdaterSpherePS = "uniform float spawnBoundsSphere;\nvec3 calcSpawnPosition(vec3 inBounds, float rndFactor) {\n float rnd4 = fract(rndFactor * 1000.0);\n return emitterPos + normalize(inBounds.xyz - vec3(0.5)) * rnd4 * spawnBoundsSphere;\n}\n\nvoid addInitialVelocity(inout vec3 localVelocity, vec3 inBounds) {\n localVelocity += normalize(inBounds - vec3(0.5)) * initialVelocity;\n}\n\n"; -pc.shaderChunks.particleUpdaterStartPS = "float saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 unpack3NFloats(float src) {\n float r = fract(src);\n float g = fract(src * 256.0);\n float b = fract(src * 65536.0);\n return vec3(r, g, b);\n}\n\nvec3 tex1Dlod_lerp(sampler2D tex, vec2 tc, out vec3 w) {\n vec4 a = texture2D(tex, tc);\n vec4 b = texture2D(tex, tc + graphSampleSize);\n float c = fract(tc.x * graphNumSamples);\n\n vec3 unpackedA = unpack3NFloats(a.w);\n vec3 unpackedB = unpack3NFloats(b.w);\n w = mix(unpackedA, unpackedB, c);\n\n return mix(a.xyz, b.xyz, c);\n}\n\nvoid main(void)\n{\n if (gl_FragCoord.x > numParticles) discard;\n float outMask0 = gl_FragCoord.y < 1.0? 1.0 : 0.0;\n float outMask1 = (gl_FragCoord.y < 2.0 && gl_FragCoord.y >= 1.0)? 1.0 : 0.0;\n float outMask2 = (gl_FragCoord.y < 3.0 && gl_FragCoord.y >= 2.0)? 1.0 : 0.0;\n\n vec4 tex = texture2D(particleTexIN, vec2(vUv0.x, 0.125));\n vec4 tex2 = texture2D(particleTexIN, vec2(vUv0.x, 0.375));\n vec4 texR = texture2D(particleTexIN, vec2(vUv0.x, 0.625));\n\n vec4 rndFactor = texR;\n float particleLifetime = lifetime;\n float life = tex2.w + delta;\n float particleRate = rate + rateDiv * rndFactor.x;\n\n float nlife = clamp(life / particleLifetime, 0.0, 1.0);\n vec3 localVelocityDiv;\n vec3 velocityDiv;\n vec3 paramDiv;\n vec3 localVelocity = tex1Dlod_lerp(internalTex0, vec2(nlife, 0), localVelocityDiv);\n vec3 velocity = tex1Dlod_lerp(internalTex1, vec2(nlife, 0), velocityDiv);\n vec3 params = tex1Dlod_lerp(internalTex2, vec2(nlife, 0), paramDiv);\n float rotSpeed = params.x;\n float rotSpeedDiv = paramDiv.y;\n float angle = (tex.w < 0.0? -tex.w : tex.w) - 1000.0;\n float visMode = tex.w < 0.0? -1.0 : 1.0;\n\n localVelocity += (localVelocityDiv * vec3(2.0) - vec3(1.0)) * localVelocityDivMult * rndFactor.xyz;\n velocity += (velocityDiv * vec3(2.0) - vec3(1.0)) * velocityDivMult * rndFactor.zxy;\n rotSpeed += (rotSpeedDiv * 2.0 - 1.0) * rotSpeedDivMult * rndFactor.y;\n\n addInitialVelocity(localVelocity, rndFactor.xyz);\n\n vec3 outVelocity = emitterMatrix * localVelocity.xyz + velocity.xyz * emitterScale;\n vec3 outPosition = tex.xyz + outVelocity * delta;\n float outRotation = angle + rotSpeed * delta;\n\n bool respawn = life <= 0.0 || life >= particleLifetime;\n outPosition = respawn? calcSpawnPosition(rndFactor.xyz, rndFactor.x) : outPosition;\n outRotation = respawn? mix(startAngle, startAngle2, rndFactor.x) : outRotation;\n outVelocity = respawn? vec3(0.0) : outVelocity;\n"; -pc.shaderChunks.particle_billboardVS = "\n quadXY = rotate(quadXY, angle, rotMatrix);\n vec3 localPos = billboard(particlePos, quadXY, localMat);\n\n"; -pc.shaderChunks.particle_blendAddPS = "\n rgb *= gammaCorrectInput(a);\n if ((rgb.r + rgb.g + rgb.b) < 0.000001) discard;\n\n"; -pc.shaderChunks.particle_blendMultiplyPS = "\n rgb = mix(vec3(1.0), rgb, vec3(a));\n if (rgb.r + rgb.g + rgb.b > 2.99) discard;\n\n"; -pc.shaderChunks.particle_blendNormalPS = "\n if (a < 0.01) discard;\n"; -pc.shaderChunks.particle_cpuVS = "attribute vec4 particle_vertexData; // XYZ = world pos, W = life\nattribute vec4 particle_vertexData2; // X = angle, Y = scale, Z = alpha, W = velocity.x\nattribute vec4 particle_vertexData3; // XYZ = particle local pos, W = velocity.y\nattribute vec2 particle_vertexData4; // X = velocity.z, W = particle ID\n\nuniform mat4 matrix_viewProjection;\nuniform mat4 matrix_model;\nuniform mat4 matrix_view;\nuniform mat3 matrix_normal;\nuniform mat4 matrix_viewInverse;\n\nuniform float numParticles;\nuniform float lifetime;\nuniform float stretch;\n//uniform float graphSampleSize;\n//uniform float graphNumSamples;\nuniform vec3 wrapBounds, emitterScale;\nuniform sampler2D texLifeAndSourcePosOUT;\nuniform sampler2D internalTex0;\nuniform sampler2D internalTex1;\nuniform sampler2D internalTex2;\n\nvarying vec4 texCoordsAlphaLife;\n\n\nvec2 rotate(vec2 quadXY, float pRotation, out mat2 rotMatrix)\n{\n float c = cos(pRotation);\n float s = sin(pRotation);\n //vec4 rotationMatrix = vec4(c, -s, s, c);\n\n mat2 m = mat2(c, -s, s, c);\n rotMatrix = m;\n\n return m * quadXY;\n}\n\nvec3 billboard(vec3 InstanceCoords, vec2 quadXY, out mat3 localMat)\n{\n vec3 viewUp = matrix_viewInverse[1].xyz;\n vec3 posCam = matrix_viewInverse[3].xyz;\n\n mat3 billMat;\n billMat[2] = normalize(InstanceCoords - posCam);\n billMat[0] = normalize(cross(viewUp, billMat[2]));\n billMat[1] = -viewUp;\n vec3 pos = billMat * vec3(quadXY, 0);\n\n localMat = billMat;\n\n return pos;\n}\n\n\nvoid main(void)\n{\n vec3 particlePos = particle_vertexData.xyz;\n vec3 pos = particlePos;\n vec3 vertPos = particle_vertexData3.xyz;\n vec3 particleVelocity = vec3(particle_vertexData2.w, particle_vertexData3.w, particle_vertexData4.x);\n vec2 velocityV = normalize((mat3(matrix_view) * particleVelocity).xy); // should be removed by compiler if align/stretch is not used\n\n vec2 quadXY = vertPos.xy;\n texCoordsAlphaLife = vec4(quadXY * -0.5 + 0.5, particle_vertexData2.z, particle_vertexData.w);\n\n mat2 rotMatrix;\n mat3 localMat;\n\n float angle = particle_vertexData2.x;\n vec3 particlePosMoved = vec3(0.0);\n vec3 meshLocalPos = particle_vertexData3.xyz;\n\n"; -pc.shaderChunks.particle_cpu_endVS = "\n localPos *= particle_vertexData2.y * emitterScale;\n localPos += particlePos;\n\n gl_Position = matrix_viewProjection * vec4(localPos, 1.0);\n}\n\n"; -pc.shaderChunks.particle_endPS = " rgb = addFog(data, rgb);\n rgb = toneMap(rgb);\n rgb = gammaCorrectOutput(rgb);\n gl_FragColor = vec4(rgb, a);\n}\n"; -pc.shaderChunks.particle_endVS = "\n localPos *= scale * emitterScale;\n localPos += particlePos;\n\n gl_Position = matrix_viewProjection * vec4(localPos.xyz, 1.0);\n}\n"; -pc.shaderChunks.particle_halflambertPS = "\n vec3 negNormal = normal*0.5+0.5;\n vec3 posNormal = -normal*0.5+0.5;\n negNormal *= negNormal;\n posNormal *= posNormal;\n\n\n"; -pc.shaderChunks.particle_lambertPS = "\n vec3 negNormal = max(normal, vec3(0.0));\n vec3 posNormal = max(-normal, vec3(0.0));\n\n\n"; -pc.shaderChunks.particle_lightingPS = "\n vec3 light = negNormal.x*lightCube[0] + posNormal.x*lightCube[1] +\n negNormal.y*lightCube[2] + posNormal.y*lightCube[3] +\n negNormal.z*lightCube[4] + posNormal.z*lightCube[5];\n\n\n rgb *= light;\n\n\n"; -pc.shaderChunks.particle_meshVS = "\n vec3 localPos = meshLocalPos;\n localPos.xy = rotate(localPos.xy, angle, rotMatrix);\n localPos.yz = rotate(localPos.yz, angle, rotMatrix);\n\n billboard(particlePos, quadXY, localMat);\n\n\n"; -pc.shaderChunks.particle_normalVS = "\n Normal = normalize(localPos - localMat[2]);\n\n\n"; -pc.shaderChunks.particle_normalMapPS = "\n vec3 normalMap = normalize( texture2D(normalMap, texCoordsAlphaLife.xy).xyz * 2.0 - 1.0 );\n vec3 normal = ParticleMat * normalMap;\n\n\n\n\n"; -pc.shaderChunks.particle_pointAlongVS = " angle = atan(velocityV.x, velocityV.y); // not the fastest way, but easier to plug in; TODO: create rot matrix right from vectors\n\n"; -pc.shaderChunks.particle_softPS = "\n vec2 screenTC = gl_FragCoord.xy / screenSize.xy;\n float depth = unpackFloat( texture2D(uDepthMap, screenTC) ) * camera_far;\n float particleDepth = gl_FragCoord.z / gl_FragCoord.w;\n float depthDiff = saturate(abs(particleDepth - depth) * softening);\n a *= depthDiff;\n\n"; -pc.shaderChunks.particle_stretchVS = " vec3 moveDir = particleVelocity * stretch;\n vec3 posPrev = pos - moveDir;\n posPrev += particlePosMoved;\n\n vec2 centerToVertexV = normalize((mat3(matrix_view) * localPos).xy);\n\n float interpolation = dot(-velocityV, centerToVertexV) * 0.5 + 0.5;\n\n particlePos = mix(particlePos, posPrev, interpolation);\n\n"; -pc.shaderChunks.particle_TBNVS = "\n mat3 rot3 = mat3(rotMatrix[0][0], rotMatrix[0][1], 0.0, rotMatrix[1][0], rotMatrix[1][1], 0.0, 0.0, 0.0, 1.0);\n localMat[2] *= -1.0;\n ParticleMat = localMat * rot3;\n\n\n\n\n"; -pc.shaderChunks.particle_wrapVS = "\n vec3 origParticlePos = particlePos;\n particlePos -= matrix_model[3].xyz;\n particlePos = mod(particlePos, wrapBounds) - wrapBounds * 0.5;\n particlePos += matrix_model[3].xyz;\n particlePosMoved = particlePos - origParticlePos;\n\n\n"; -pc.shaderChunks.prefilterCubemapPS = "varying vec2 vUv0;\n\nuniform samplerCube source;\nuniform vec4 params;\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat rnd(vec2 uv) {\n return fract(sin(dot(uv, vec2(12.9898, 78.233) * 2.0)) * 43758.5453);\n}\n\nconst float PI = 3.14159265358979;\nvec3 hemisphereSample_cos(vec2 uv, mat3 vecSpace, vec3 cubeDir, float gloss) { // cos + lerped cone size (better than just lerped)\n float phi = uv.y * 2.0 * PI;\n float cosTheta = sqrt(1.0 - uv.x);\n float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);\n return normalize(mix(vecSpace * sampleDir, cubeDir, params.y));\n}\n\nvec3 hemisphereSample_phong(vec2 uv, mat3 vecSpace, vec3 cubeDir, float specPow) {\n float phi = uv.y * 2.0 * PI;\n float cosTheta = pow(1.0 - uv.x, 1.0 / (specPow + 1.0));\n float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);\n return vecSpace * sampleDir;\n}\n\nmat3 matrixFromVector(vec3 n) { // frisvad\n float a = 1.0 / (1.0 + n.z);\n float b = -n.x * n.y * a;\n vec3 b1 = vec3(1.0 - n.x * n.x * a, b, -n.x);\n vec3 b2 = vec3(b, 1.0 - n.y * n.y * a, -n.y);\n return mat3(b1, b2, n);\n}\n\nvec4 encodeRGBM(vec4 color) { // modified RGBM\n color.rgb = pow(color.rgb, vec3(0.5));\n color.rgb *= 1.0 / 8.0;\n\n color.a = saturate( max( max( color.r, color.g ), max( color.b, 1.0 / 255.0 ) ) );\n color.a = ceil(color.a * 255.0) / 255.0;\n\n color.rgb /= color.a;\n return color;\n}\n\nvoid main(void) {\n\n vec2 st = vUv0 * 2.0 - 1.0;\n\n if (params.w==1.0 || params.w==3.0) {\n st = 2.0 * floor(gl_FragCoord.xy) / (params.z - 1.0) - 1.0;\n }\n\n float face = params.x;\n\n vec3 vec;\n if (face==0.0) {\n vec = vec3(1, -st.y, -st.x);\n } else if (face==1.0) {\n vec = vec3(-1, -st.y, st.x);\n } else if (face==2.0) {\n vec = vec3(st.x, 1, st.y);\n } else if (face==3.0) {\n vec = vec3(st.x, -1, -st.y);\n } else if (face==4.0) {\n vec = vec3(st.x, -st.y, 1);\n } else {\n vec = vec3(-st.x, -st.y, -1);\n }\n\n mat3 vecSpace = matrixFromVector(normalize(vec));\n\n vec4 color = vec4(0.0);\n const int samples = $NUMSAMPLES;\n vec3 vect;\n for(int i=0; i 0) { - vshader += chunk.particle_stretchVS - } - vshader += chunk.particle_endVS - }else { - if(options.normal == 1) { - vshader += "\nvarying vec3 Normal;\n" - } - if(options.normal == 2) { - vshader += "\nvarying mat3 ParticleMat;\n" - } - vshader += chunk.particle_cpuVS; - if(options.alignToMotion) { - vshader += chunk.particle_pointAlongVS - } - vshader += options.mesh ? chunk.particle_meshVS : chunk.particle_billboardVS; - if(options.normal == 1) { - vshader += chunk.particle_normalVS - } - if(options.normal == 2) { - vshader += chunk.particle_TBNVS - } - if(options.stretch > 0) { - vshader += chunk.particle_stretchVS - } - vshader += chunk.particle_cpu_endVS - } - if(options.normal > 0) { - if(options.normal == 1) { - fshader += "\nvarying vec3 Normal;\n" - }else { - if(options.normal == 2) { - fshader += "\nvarying mat3 ParticleMat;\n" - } - } - fshader += "\nuniform vec3 lightCube[6];\n" - } - if(options.normal == 0 && options.fog == "none") { - options.srgb = false - } - fshader += pc.programlib.gammaCode(options.gamma); - fshader += "struct psInternalData {float dummy;};\n"; - fshader += pc.programlib.tonemapCode(options.toneMap); - if(options.fog === "linear") { - fshader += chunk.fogLinearPS - }else { - if(options.fog === "exp") { - fshader += chunk.fogExpPS - }else { - if(options.fog === "exp2") { - fshader += chunk.fogExp2PS - }else { - fshader += chunk.fogNonePS - } - } - } - if(options.normal == 2) { - fshader += "\nuniform sampler2D normalMap;\n" - } - if(options.soft > 0) { - fshader += "\nuniform sampler2D uDepthMap;\n" - } - fshader += chunk.particlePS; - if(options.soft > 0) { - fshader += chunk.particle_softPS - } - if(options.normal == 1) { - fshader += "\nvec3 normal = Normal;\n" - } - if(options.normal == 2) { - fshader += chunk.particle_normalMapPS - } - if(options.normal > 0) { - fshader += options.halflambert ? chunk.particle_halflambertPS : chunk.particle_lambertPS - } - if(options.normal > 0) { - fshader += chunk.particle_lightingPS - } - if(options.blend == pc.BLEND_NORMAL) { - fshader += chunk.particle_blendNormalPS - }else { - if(options.blend == pc.BLEND_ADDITIVE) { - fshader += chunk.particle_blendAddPS - }else { - if(options.blend == pc.BLEND_MULTIPLICATIVE) { - fshader += chunk.particle_blendMultiplyPS - } - } - } - fshader += chunk.particle_endPS; - var attributes = pc.shaderChunks.collectAttribs(vshader); - return{attributes:attributes, vshader:vshader, fshader:fshader} -}}; -pc.programlib.phong = {hashCode:function(str) { - var hash = 0; - if(str.length == 0) { - return hash - } - for(i = 0;i < str.length;i++) { - char = str.charCodeAt(i); - hash = (hash << 5) - hash + char; - hash = hash & hash - } - return hash -}, generateKey:function(device, options) { - var props = []; - var key = "phong"; - for(prop in options) { - if(prop === "lights") { - for(var i = 0;i < options.lights.length;i++) { - props.push(options.lights[i].getType() + "_" + (options.lights[i].getCastShadows() ? 1 : 0) + "_" + options.lights[i].getFalloffMode() + "_" + !!options.lights[i].getNormalOffsetBias()) - } - }else { - if(prop === "chunks") { - for(var p in options[prop]) { - if(options[prop].hasOwnProperty(p)) { - props.push(p + options.chunks[p]) - } - } - }else { - if(options[prop]) { - props.push(prop) - } - } - } - } - props.sort(); - for(prop in props) { - key += props[prop] + options[props[prop]] - } - return this.hashCode(key) -}, _correctChannel:function(p, chan) { - if(pc._matTex2D[p] > 0) { - if(pc._matTex2D[p] < chan.length) { - return chan.substring(0, pc._matTex2D[p]) - }else { - if(pc._matTex2D[p] > chan.length) { - var str = chan; - var chr = str.charAt(str.length - 1); - var addLen = pc._matTex2D[p] - str.length; - for(i = 0;i < addLen;i++) { - str += chr - } - return str - } - } - return chan - } -}, _setMapTransform:function(codes, name, id, uv) { - codes[0] += "uniform vec4 texture_" + name + "MapTransform;\n"; - var checkId = id + uv * 100; - if(!codes[3][checkId]) { - codes[1] += "varying vec2 vUV" + uv + "_" + id + ";\n"; - codes[2] += " vUV" + uv + "_" + id + " = uv" + uv + " * texture_" + name + "MapTransform.xy + texture_" + name + "MapTransform.zw;\n"; - codes[3][checkId] = true - } - return codes -}, _uvSource:function(id, uv) { - return id == 0 ? "vUv" + uv : "vUV" + uv + "_" + id -}, _addMap:function(p, options, chunks, uvOffset, subCode, format) { - var mname = p + "Map"; - if(options[mname + "VertexColor"]) { - var cname = mname + "Channel"; - if(!subCode) { - if(options[p + "Tint"]) { - subCode = chunks[p + "VertConstPS"] - }else { - subCode = chunks[p + "VertPS"] - } - } - return subCode.replace(/\$CH/g, options[cname]) - }else { - if(options[mname]) { - var tname = mname + "Transform"; - var cname = mname + "Channel"; - var uname = mname + "Uv"; - var uv = this._uvSource(options[tname], options[uname]) + uvOffset; - if(!subCode) { - if(options[p + "Tint"]) { - subCode = chunks[p + "TexConstPS"] - }else { - subCode = chunks[p + "TexPS"] - } - } - if(format !== undefined) { - var fmt = format === 0 ? "texture2DSRGB" : format === 1 ? "texture2DRGBM" : "texture2D"; - subCode = subCode.replace(/\$texture2DSAMPLE/g, fmt) - } - return subCode.replace(/\$UV/g, uv).replace(/\$CH/g, options[cname]) - }else { - return chunks[p + "ConstPS"] - } - } -}, _nonPointShadowMapProjection:function(light, shadowCoordArgs) { - if(!light.getNormalOffsetBias()) { - if(light.getType() == pc.LIGHTTYPE_SPOT) { - return" getShadowCoordPersp" + shadowCoordArgs - }else { - return" getShadowCoordOrtho" + shadowCoordArgs - } - }else { - if(light.getType() == pc.LIGHTTYPE_SPOT) { - return" getShadowCoordPerspNormalOffset" + shadowCoordArgs - }else { - return" getShadowCoordOrthoNormalOffset" + shadowCoordArgs - } - } -}, _addVaryingIfNeeded:function(code, type, name) { - return code.indexOf(name) >= 0 ? "varying " + type + " " + name + ";\n" : "" -}, createShaderDefinition:function(device, options) { - var i; - var lighting = options.lights.length > 0; - if(options.shadingModel === pc.SPECULAR_PHONG) { - options.fresnelModel = 0; - options.specularAA = false; - options.prefilteredCubemap = false - }else { - options.fresnelModel = options.fresnelModel === 0 ? pc.FRESNEL_SCHLICK : options.fresnelModel - } - var cubemapReflection = options.cubeMap || options.prefilteredCubemap && options.useSpecular; - var reflections = options.sphereMap || cubemapReflection || options.dpAtlas; - var useTangents = pc.precalculatedTangents; - var useTexCubeLod = options.useTexCubeLod; - if(options.cubeMap || options.prefilteredCubemap) { - options.sphereMap = null - } - if(options.dpAtlas) { - options.sphereMap = options.cubeMap = options.prefilteredCubemap = cubemapReflection = null - } - if(!options.useSpecular) { - options.specularMap = options.glossMap = null - } - this.options = options; - var getSnippet = pc.programlib.getSnippet; - var code = ""; - var codeBody = ""; - var varyings = ""; - var chunks = pc.shaderChunks; - if(options.chunks) { - var customChunks = []; - for(var p in chunks) { - if(chunks.hasOwnProperty(p)) { - if(!options.chunks[p]) { - customChunks[p] = chunks[p] - }else { - customChunks[p] = options.chunks[p]; - if(!lighting && !reflections) { - customChunks[p] = customChunks[p].replace(/vertex_normal/g, "vec3(0)").replace(/vertex_tangent/g, "vec4(0)") - } - } - } - } - chunks = customChunks - } - code += chunks.baseVS; - var mainShadowLight = -1; - if(!options.noShadow) { - for(i = 0;i < options.lights.length;i++) { - var lightType = options.lights[i].getType(); - if(options.lights[i].getCastShadows()) { - if(lightType !== pc.LIGHTTYPE_POINT) { - code += "uniform mat4 light" + i + "_shadowMatrixVS;\n"; - code += "uniform vec3 light" + i + "_shadowParamsVS;\n"; - code += "uniform vec3 light" + i + (lightType === pc.LIGHTTYPE_DIRECTIONAL ? "_directionVS" : "_positionVS") + ";\n"; - mainShadowLight = i; - break - } - } - } - if(mainShadowLight >= 0) { - code += chunks.shadowCoordVS - } - } - var attributes = {vertex_position:pc.SEMANTIC_POSITION}; - codeBody += " vPositionW = getWorldPosition(data);\n"; - if(options.useInstancing) { - attributes.instance_line1 = pc.SEMANTIC_TEXCOORD2; - attributes.instance_line2 = pc.SEMANTIC_TEXCOORD3; - attributes.instance_line3 = pc.SEMANTIC_TEXCOORD4; - attributes.instance_line4 = pc.SEMANTIC_TEXCOORD5; - code += chunks.instancingVS - } - if(lighting || reflections) { - attributes.vertex_normal = pc.SEMANTIC_NORMAL; - codeBody += " vNormalW = data.normalW = getNormal(data);\n"; - if(options.sphereMap && device.fragmentUniformsCount <= 16) { - code += chunks.viewNormalVS; - codeBody += " vNormalV = getViewNormal(data);\n" - } - if((options.heightMap || options.normalMap) && useTangents) { - attributes.vertex_tangent = pc.SEMANTIC_TANGENT; - code += chunks.tangentBinormalVS; - codeBody += " vTangentW = getTangent(data);\n"; - codeBody += " vBinormalW = getBinormal(data);\n" - } - if(mainShadowLight >= 0) { - if(lightType == pc.LIGHTTYPE_DIRECTIONAL) { - codeBody += " data.lightDirNormW = light" + mainShadowLight + "_directionVS;\n" - }else { - codeBody += " getLightDirPoint(data, light" + mainShadowLight + "_positionVS);\n" - } - var shadowCoordArgs = "(data, light" + mainShadowLight + "_shadowMatrixVS, light" + mainShadowLight + "_shadowParamsVS);\n"; - codeBody += this._nonPointShadowMapProjection(options.lights[mainShadowLight], shadowCoordArgs) - } - } - var useUv = []; - var useUnmodifiedUv = []; - var maxUvSets = 2; - for(var p in pc._matTex2D) { - var mname = p + "Map"; - if(options[mname + "VertexColor"]) { - var cname = mname + "Channel"; - options[cname] = this._correctChannel(p, options[cname]) - }else { - if(options[mname]) { - var cname = mname + "Channel"; - var tname = mname + "Transform"; - var uname = mname + "Uv"; - var cname = mname + "Channel"; - options[uname] = Math.min(options[uname], maxUvSets - 1); - options[cname] = this._correctChannel(p, options[cname]); - var uvSet = options[uname]; - useUv[uvSet] = true; - useUnmodifiedUv[uvSet] = useUnmodifiedUv[uvSet] || options[mname] && !options[tname] - } - } - } - for(i = 0;i < maxUvSets;i++) { - if(useUv[i]) { - attributes["vertex_texCoord" + i] = pc["SEMANTIC_TEXCOORD" + i]; - code += chunks["uv" + i + "VS"]; - codeBody += " vec2 uv" + i + " = getUv" + i + "(data);\n" - } - if(useUnmodifiedUv[i]) { - codeBody += " vUv" + i + " = uv" + i + ";\n" - } - } - var codes = [code, varyings, codeBody, []]; - for(var p in pc._matTex2D) { - var mname = p + "Map"; - if(options[mname]) { - var tname = mname + "Transform"; - if(options[tname]) { - var uname = mname + "Uv"; - this._setMapTransform(codes, p, options[tname], options[uname]) - } - } - } - code = codes[0]; - varyings = codes[1]; - codeBody = codes[2]; - if(options.vertexColors) { - attributes.vertex_color = pc.SEMANTIC_COLOR; - codeBody += " vVertexColor = vertex_color;\n" - } - if(options.skin) { - attributes.vertex_boneWeights = pc.SEMANTIC_BLENDWEIGHT; - attributes.vertex_boneIndices = pc.SEMANTIC_BLENDINDICES; - code += getSnippet(device, "vs_skin_decl"); - code += chunks.transformSkinnedVS; - if(lighting || reflections) { - code += chunks.normalSkinnedVS - } - }else { - if(options.useInstancing) { - code += chunks.transformInstancedVS; - if(lighting || reflections) { - code += chunks.normalInstancedVS - } - }else { - code += chunks.transformVS; - if(lighting || reflections) { - code += chunks.normalVS - } - } - } - code += "\n"; - code += chunks.startVS; - code += codeBody; - code += "}"; - var vshader = code; - var oldVars = varyings; - varyings = ""; - varyings += this._addVaryingIfNeeded(code, "vec4", "vMainShadowUv"); - varyings += this._addVaryingIfNeeded(code, "vec4", "vVertexColor"); - varyings += this._addVaryingIfNeeded(code, "vec3", "vPositionW"); - varyings += this._addVaryingIfNeeded(code, "vec3", "vNormalV"); - varyings += this._addVaryingIfNeeded(code, "vec3", "vNormalW"); - varyings += this._addVaryingIfNeeded(code, "vec3", "vTangentW"); - varyings += this._addVaryingIfNeeded(code, "vec3", "vBinormalW"); - varyings += this._addVaryingIfNeeded(code, "vec2", "vUv0"); - varyings += this._addVaryingIfNeeded(code, "vec2", "vUv1"); - varyings += oldVars; - vshader = varyings + vshader; - if(options.forceFragmentPrecision && options.forceFragmentPrecision != "highp" && options.forceFragmentPrecision != "mediump" && options.forceFragmentPrecision != "lowp") { - options.forceFragmentPrecision = null - } - if(options.forceFragmentPrecision) { - if(options.forceFragmentPrecision === "highp" && device.maxPrecision !== "highp") { - options.forceFragmentPrecision = "mediump" - } - if(options.forceFragmentPrecision === "mediump" && device.maxPrecision === "lowp") { - options.forceFragmentPrecision = "lowp" - } - } - var fshader; - code = options.forceFragmentPrecision ? "precision " + options.forceFragmentPrecision + " float;\n\n" : getSnippet(device, "fs_precision"); - if(options.customFragmentShader) { - fshader = code + options.customFragmentShader; - return{attributes:attributes, vshader:vshader, fshader:fshader} - } - code += varyings; - code += chunks.basePS; - var numShadowLights = 0; - for(i = 0;i < options.lights.length;i++) { - var lightType = options.lights[i].getType(); - code += "uniform vec3 light" + i + "_color;\n"; - if(lightType == pc.LIGHTTYPE_DIRECTIONAL) { - code += "uniform vec3 light" + i + "_direction;\n" - }else { - code += "uniform vec3 light" + i + "_position;\n"; - code += "uniform float light" + i + "_radius;\n"; - if(lightType == pc.LIGHTTYPE_SPOT) { - code += "uniform vec3 light" + i + "_spotDirection;\n"; - code += "uniform float light" + i + "_innerConeAngle;\n"; - code += "uniform float light" + i + "_outerConeAngle;\n" - } - } - if(options.lights[i].getCastShadows() && !options.noShadow) { - code += "uniform mat4 light" + i + "_shadowMatrix;\n"; - if(lightType == pc.LIGHTTYPE_POINT) { - code += "uniform vec4 light" + i + "_shadowParams;\n" - }else { - code += "uniform vec3 light" + i + "_shadowParams;\n" - } - if(lightType == pc.LIGHTTYPE_POINT) { - code += "uniform samplerCube light" + i + "_shadowMap;\n" - }else { - code += "uniform sampler2D light" + i + "_shadowMap;\n" - } - numShadowLights++ - } - } - code += "\n"; - var uvOffset = options.heightMap ? " + data.uvOffset" : ""; - var tbn = options.fastTbn ? chunks.TBNfastPS : chunks.TBNPS; - if(lighting || reflections) { - if(options.normalMap && useTangents) { - code += options.packedNormal ? chunks.normalXYPS : chunks.normalXYZPS; - var uv = this._uvSource(options.normalMapTransform, options.normalMapUv) + uvOffset; - if(options.needsNormalFloat) { - code += (options.fastTbn ? chunks.normalMapFloatTBNfastPS : chunks.normalMapFloatPS).replace(/\$UV/g, uv) - }else { - code += chunks.normalMapPS.replace(/\$UV/g, uv) - } - code += tbn - }else { - code += chunks.normalVertexPS - } - } - code += pc.programlib.gammaCode(options.gamma); - code += pc.programlib.tonemapCode(options.toneMap); - if(options.fog === "linear") { - code += chunks.fogLinearPS - }else { - if(options.fog === "exp") { - code += chunks.fogExpPS - }else { - if(options.fog === "exp2") { - code += chunks.fogExp2PS - }else { - code += chunks.fogNonePS - } - } - } - if(options.useRgbm) { - code += chunks.rgbmPS - } - if(cubemapReflection || options.prefilteredCubemap) { - code += options.fixSeams ? chunks.fixCubemapSeamsStretchPS : chunks.fixCubemapSeamsNonePS - } - if(reflections || options.prefilteredCubemap) { - code += options.cubeMapProjection > 0 ? chunks.cubeMapProjectBoxPS : chunks.cubeMapProjectNonePS; - code += options.skyboxIntensity ? chunks.envMultiplyPS : chunks.envConstPS - } - code += this._addMap("diffuse", options, chunks, uvOffset); - if(options.blendType !== pc.BLEND_NONE || options.alphaTest) { - code += this._addMap("opacity", options, chunks, uvOffset) - } - code += this._addMap("emissive", options, chunks, uvOffset, null, options.emissiveFormat); - if(options.useSpecular) { - if(options.specularAA && options.normalMap) { - if(options.needsNormalFloat && (lighting || reflections)) { - code += chunks.specularAaToksvigFloatPS - }else { - code += chunks.specularAaToksvigPS - } - }else { - code += chunks.specularAaNonePS - } - code += this._addMap(options.useMetalness ? "metalness" : "specular", options, chunks, uvOffset); - code += this._addMap("gloss", options, chunks, uvOffset); - if(options.fresnelModel > 0) { - if(options.fresnelModel === pc.FRESNEL_SIMPLE) { - code += chunks.fresnelSimplePS - }else { - if(options.fresnelModel === pc.FRESNEL_SCHLICK) { - code += chunks.fresnelSchlickPS - }else { - if(options.fresnelModel === pc.FRESNEL_COMPLEX) { - code += chunks.fresnelComplexPS - } - } - } - } - } - if(options.heightMap) { - if(!options.normalMap) { - code += tbn - } - code += this._addMap("height", options, chunks, "", chunks.parallaxPS) - } - var useAo = options.aoMap || options.aoMapVertexColor; - if(useAo) { - code += this._addMap("ao", options, chunks, uvOffset, options.aoMapVertexColor ? chunks.aoVertPS : chunks.aoTexPS); - if(options.occludeSpecular) { - code += options.occludeSpecularFloat ? chunks.aoSpecOccPS : chunks.aoSpecOccConstPS - } - } - var reflectionDecode = options.rgbmReflection ? "decodeRGBM" : options.hdrReflection ? "" : "gammaCorrectInput"; - if(cubemapReflection || options.prefilteredCubemap) { - if(options.prefilteredCubemap) { - if(useTexCubeLod) { - code += chunks.reflectionPrefilteredCubeLodPS.replace(/\$DECODE/g, reflectionDecode) - }else { - code += chunks.reflectionPrefilteredCubePS.replace(/\$DECODE/g, reflectionDecode) - } - }else { - code += chunks.reflectionCubePS.replace(/\$textureCubeSAMPLE/g, options.rgbmReflection ? "textureCubeRGBM" : options.hdrReflection ? "textureCube" : "textureCubeSRGB") - } - } - if(options.sphereMap) { - var scode = device.fragmentUniformsCount > 16 ? chunks.reflectionSpherePS : chunks.reflectionSphereLowPS; - scode = scode.replace(/\$texture2DSAMPLE/g, options.rgbmReflection ? "texture2DRGBM" : options.hdrReflection ? "texture2D" : "texture2DSRGB"); - code += scode - } - if(options.dpAtlas) { - code += chunks.reflectionDpAtlasPS.replace(/\$texture2DSAMPLE/g, options.rgbmReflection ? "texture2DRGBM" : options.hdrReflection ? "texture2D" : "texture2DSRGB") - } - if((cubemapReflection || options.sphereMap || options.dpAtlas) && options.refraction) { - code += chunks.refractionPS - } - if(options.lightMap || options.lightMapVertexColor) { - code += this._addMap("light", options, chunks, uvOffset, options.lightMapVertexColor ? chunks.lightmapSingleVertPS : chunks.lightmapSinglePS, options.lightMapFormat) - }else { - if(options.ambientSH) { - code += chunks.ambientSHPS - }else { - if(options.prefilteredCubemap) { - if(useTexCubeLod) { - code += chunks.ambientPrefilteredCubeLodPS.replace(/\$DECODE/g, reflectionDecode) - }else { - code += chunks.ambientPrefilteredCubePS.replace(/\$DECODE/g, reflectionDecode) - } - }else { - code += chunks.ambientConstantPS - } - } - } - if(numShadowLights > 0) { - code += chunks.shadowCoordPS + chunks.shadowPS; - if(mainShadowLight >= 0) { - code += chunks.shadowVSPS - } - } - code += chunks.lightDiffuseLambertPS; - var useOldAmbient = false; - if(options.useSpecular) { - code += options.shadingModel === pc.SPECULAR_PHONG ? chunks.lightSpecularPhongPS : chunks.lightSpecularBlinnPS; - if(options.sphereMap || cubemapReflection || options.dpAtlas || options.fresnelModel > 0) { - if(options.fresnelModel > 0) { - if(options.conserveEnergy) { - code += chunks.combineDiffuseSpecularPS - }else { - code += chunks.combineDiffuseSpecularNoConservePS - } - }else { - code += chunks.combineDiffuseSpecularOldPS - } - }else { - if(options.diffuseMap) { - code += chunks.combineDiffuseSpecularNoReflPS - }else { - code += chunks.combineDiffuseSpecularNoReflSeparateAmbientPS; - useOldAmbient = true - } - } - }else { - code += chunks.combineDiffusePS - } - if(options.modulateAmbient && !useOldAmbient) { - code += "uniform vec3 material_ambient;\n" - } - if(options.alphaTest) { - code += " uniform float alpha_ref;\n" - } - code += chunks.startPS; - if(options.blendType === pc.BLEND_NONE && !options.alphaTest) { - code += " data.alpha = 1.0;" - }else { - code += " getOpacity(data);\n" - } - if(options.alphaTest) { - code += " if (data.alpha < alpha_ref) discard;\n" - } - if(lighting || reflections) { - code += " getViewDir(data);\n"; - if(options.heightMap || options.normalMap) { - code += " getTBN(data);\n" - } - if(options.heightMap) { - code += " getParallax(data);\n" - } - code += " getNormal(data);\n"; - if(options.useSpecular) { - code += " getReflDir(data);\n" - } - } - code += " getAlbedo(data);\n"; - if(lighting && options.useSpecular || reflections) { - code += " getSpecularity(data);\n"; - code += " getGlossiness(data);\n"; - if(options.fresnelModel > 0) { - code += " getFresnel(data);\n" - } - } - code += " addAmbient(data);\n"; - if(options.modulateAmbient && !useOldAmbient) { - code += " data.diffuseLight *= material_ambient;\n" - } - if(useAo && !options.occludeDirect) { - code += " applyAO(data);\n" - } - if(lighting || reflections) { - if(cubemapReflection || options.sphereMap || options.dpAtlas) { - code += " addReflection(data);\n" - } - var light; - for(i = 0;i < options.lights.length;i++) { - light = options.lights[i]; - var lightType = light.getType(); - if(lightType == pc.LIGHTTYPE_DIRECTIONAL) { - code += " data.lightDirNormW = light" + i + "_direction;\n"; - code += " data.atten = 1.0;\n" - }else { - code += " getLightDirPoint(data, light" + i + "_position);\n"; - if(light.getFalloffMode() == pc.LIGHTFALLOFF_LINEAR) { - code += " data.atten = getFalloffLinear(data, light" + i + "_radius);\n" - }else { - code += " data.atten = getFalloffInvSquared(data, light" + i + "_radius);\n" - } - if(lightType == pc.LIGHTTYPE_SPOT) { - code += " data.atten *= getSpotEffect(data, light" + i + "_spotDirection, light" + i + "_innerConeAngle, light" + i + "_outerConeAngle);\n" - } - } - code += " data.atten *= getLightDiffuse(data);\n"; - if(light.getCastShadows() && !options.noShadow) { - var shadowReadMode = null; - if(light._shadowType <= pc.SHADOW_DEPTHMASK) { - if(options.shadowSampleType === pc.SHADOWSAMPLE_HARD) { - shadowReadMode = "Hard" - }else { - if(light._shadowType === pc.SHADOW_DEPTH && options.shadowSampleType === pc.SHADOWSAMPLE_PCF3X3) { - shadowReadMode = "PCF3x3" - }else { - if(light._shadowType === pc.SHADOW_DEPTHMASK && options.shadowSampleType === pc.SHADOWSAMPLE_PCF3X3) { - shadowReadMode = "PCF3x3_YZW" - }else { - if(light._shadowType === pc.SHADOW_DEPTHMASK && options.shadowSampleType === pc.SHADOWSAMPLE_MASK) { - shadowReadMode = "Mask" - } - } - } - } - } - if(shadowReadMode !== null) { - if(lightType == pc.LIGHTTYPE_POINT) { - var shadowCoordArgs = "(data, light" + i + "_shadowMap, light" + i + "_shadowParams);\n"; - if(light.getNormalOffsetBias()) { - code += " normalOffsetPointShadow(data, light" + i + "_shadowParams);\n" - } - code += " data.atten *= getShadowPoint" + shadowReadMode + shadowCoordArgs - }else { - if(mainShadowLight === i) { - shadowReadMode += "VS" - }else { - var shadowCoordArgs = "(data, light" + i + "_shadowMatrix, light" + i + "_shadowParams);\n"; - code += this._nonPointShadowMapProjection(options.lights[i], shadowCoordArgs) - } - code += " data.atten *= getShadow" + shadowReadMode + "(data, light" + i + "_shadowMap, light" + i + "_shadowParams);\n" - } - } - } - code += " data.diffuseLight += data.atten * light" + i + "_color;\n"; - if(options.useSpecular) { - code += " data.atten *= getLightSpecular(data);\n"; - code += " data.specularLight += data.atten * light" + i + "_color;\n" - } - code += "\n" - } - if((cubemapReflection || options.sphereMap || options.dpAtlas) && options.refraction) { - code += " addRefraction(data);\n" - } - } - code += "\n"; - if(useAo) { - if(options.occludeDirect) { - code += " applyAO(data);\n" - } - if(options.occludeSpecular) { - code += " occludeSpecular(data);\n" - } - } - code += chunks.endPS; - if(options.blendType === pc.BLEND_NORMAL || options.blendType === pc.BLEND_ADDITIVEALPHA) { - code += "gl_FragColor.a = data.alpha;\n" - }else { - if(options.blendType === pc.BLEND_PREMULTIPLIED) { - code += "gl_FragColor.rgb *= data.alpha;\n"; - code += "gl_FragColor.a = data.alpha;\n" - }else { - code += "gl_FragColor.a = 1.0;\n" - } - } - code += getSnippet(device, "fs_clamp"); - code += getSnippet(device, "common_main_end"); - fshader = code; - return{attributes:attributes, vshader:vshader, fshader:fshader} -}}; -pc.programlib.pick = {generateKey:function(device, options) { - var key = "pick"; - if(options.skin) { - key += "_skin" - } - return key -}, createShaderDefinition:function(device, options) { - var attributes = {vertex_position:pc.SEMANTIC_POSITION}; - if(options.skin) { - attributes.vertex_boneWeights = pc.SEMANTIC_BLENDWEIGHT; - attributes.vertex_boneIndices = pc.SEMANTIC_BLENDINDICES - } - var getSnippet = pc.programlib.getSnippet; - var code = ""; - code += getSnippet(device, "vs_transform_decl"); - if(options.skin) { - code += getSnippet(device, "vs_skin_decl") - } - code += getSnippet(device, "common_main_begin"); - if(options.skin) { - code += " mat4 modelMatrix = vertex_boneWeights.x * getBoneMatrix(vertex_boneIndices.x) +\n"; - code += " vertex_boneWeights.y * getBoneMatrix(vertex_boneIndices.y) +\n"; - code += " vertex_boneWeights.z * getBoneMatrix(vertex_boneIndices.z) +\n"; - code += " vertex_boneWeights.w * getBoneMatrix(vertex_boneIndices.w);\n" - }else { - code += " mat4 modelMatrix = matrix_model;\n" - } - code += "\n"; - code += " vec4 positionW = modelMatrix * vec4(vertex_position, 1.0);\n"; - code += " gl_Position = matrix_viewProjection * positionW;\n\n"; - code += getSnippet(device, "common_main_end"); - var vshader = code; - code = getSnippet(device, "fs_precision"); - code += getSnippet(device, "fs_flat_color_decl"); - code += getSnippet(device, "common_main_begin"); - code += getSnippet(device, "fs_flat_color"); - code += getSnippet(device, "common_main_end"); - var fshader = code; - return{attributes:attributes, vshader:vshader, fshader:fshader} -}}; -pc.programlib.skybox = {generateKey:function(device, options) { - var key = "skybox" + options.rgbm + " " + options.hdr + " " + options.fixSeams + "" + options.toneMapping + "" + options.gamma + "" + options.useIntensity + "" + options.mip; - return key -}, createShaderDefinition:function(device, options) { - var getSnippet = pc.programlib.getSnippet; - var chunks = pc.shaderChunks; - var mip2size = [128, 64, 32, 16, 8, 4]; - return{attributes:{aPosition:pc.SEMANTIC_POSITION}, vshader:["attribute vec3 aPosition;", "", "uniform mat4 matrix_view;", "uniform mat4 matrix_projection;", "", "varying vec3 vViewDir;", "", "void main(void)", "{", " mat4 view = matrix_view;", " view[3][0] = view[3][1] = view[3][2] = 0.0;", " gl_Position = matrix_projection * view * vec4(aPosition, 1.0);", " gl_Position.z = gl_Position.w - 0.00001;", " vViewDir = aPosition;", " vViewDir.x *= -1.0;", "}"].join("\n"), fshader:getSnippet(device, - "fs_precision") + (options.mip ? chunks.fixCubemapSeamsStretchPS : chunks.fixCubemapSeamsNonePS) + (options.useIntensity ? chunks.envMultiplyPS : chunks.envConstPS) + pc.programlib.gammaCode(options.gamma) + pc.programlib.tonemapCode(options.toneMapping) + chunks.rgbmPS + chunks.skyboxHDRPS.replace(/\$textureCubeSAMPLE/g, options.rgbm ? "textureCubeRGBM" : options.hdr ? "textureCube" : "textureCubeSRGB").replace(/\$FIXCONST/g, 1 - 1 / mip2size[options.mip] + "")} -}}; -pc.extend(pc, function() { - var PostEffect = function(graphicsDevice) { - this.device = graphicsDevice; - this.shader = null; - this.depthMap = null; - this.vertexBuffer = pc.createFullscreenQuad(graphicsDevice); - this.needsDepthBuffer = false - }; - PostEffect.prototype = {render:function(inputTarget, outputTarget, rect) { - }}; - function createFullscreenQuad(device) { - var vertexFormat = new pc.VertexFormat(device, [{semantic:pc.SEMANTIC_POSITION, components:2, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(device, vertexFormat, 4); - var iterator = new pc.VertexIterator(vertexBuffer); - iterator.element[pc.SEMANTIC_POSITION].set(-1, -1); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(1, -1); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(-1, 1); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(1, 1); - iterator.end(); - return vertexBuffer - } - function drawFullscreenQuad(device, target, vertexBuffer, shader, rect) { - device.setRenderTarget(target); - device.updateBegin(); - var w = target !== null ? target.width : device.width; - var h = target !== null ? target.height : device.height; - var x = 0; - var y = 0; - if(rect) { - x = rect.x * w; - y = rect.y * h; - w *= rect.z; - h *= rect.w - } - device.setViewport(x, y, w, h); - device.setScissor(x, y, w, h); - var oldBlending = device.getBlending(); - var oldDepthTest = device.getDepthTest(); - var oldDepthWrite = device.getDepthWrite(); - device.setBlending(false); - device.setDepthTest(false); - device.setDepthWrite(false); - device.setVertexBuffer(vertexBuffer, 0); - device.setShader(shader); - device.draw({type:pc.PRIMITIVE_TRISTRIP, base:0, count:4, indexed:false}); - device.setBlending(oldBlending); - device.setDepthTest(oldDepthTest); - device.setDepthWrite(oldDepthWrite); - device.updateEnd() - } - return{PostEffect:PostEffect, createFullscreenQuad:createFullscreenQuad, drawFullscreenQuad:drawFullscreenQuad} -}()); -pc.extend(pc, function() { - function PostEffectQueue(app, camera) { - this.app = app; - this.camera = camera; - this.effects = []; - this.enabled = false; - this.depthTarget = null; - this.renderTargetScale = 1; - this.resizeTimeout = null; - camera.on("set_rect", this.onCameraRectChanged, this) - } - PostEffectQueue.prototype = {_createOffscreenTarget:function(useDepth) { - var rect = this.camera.rect; - var width = Math.floor(rect.z * this.app.graphicsDevice.width * this.renderTargetScale); - var height = Math.floor(rect.w * this.app.graphicsDevice.height * this.renderTargetScale); - var colorBuffer = new pc.Texture(this.app.graphicsDevice, {format:pc.PIXELFORMAT_R8_G8_B8_A8, width:width, height:height}); - colorBuffer.minFilter = pc.FILTER_NEAREST; - colorBuffer.magFilter = pc.FILTER_NEAREST; - colorBuffer.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - colorBuffer.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - return new pc.RenderTarget(this.app.graphicsDevice, colorBuffer, {depth:useDepth}) - }, _setDepthTarget:function(depthTarget) { - if(this.depthTarget !== depthTarget) { - if(this.depthTarget) { - this.depthTarget.destroy() - } - this.depthTarget = depthTarget - } - this.camera.camera._depthTarget = depthTarget - }, setRenderTargetScale:function(scale) { - this.renderTargetScale = scale; - this.resizeRenderTargets() - }, addEffect:function(effect) { - var isFirstEffect = this.effects.length === 0; - var effects = this.effects; - var newEntry = {effect:effect, inputTarget:this._createOffscreenTarget(isFirstEffect), outputTarget:null}; - if(effect.needsDepthBuffer) { - if(!this.depthTarget) { - this._setDepthTarget(this._createOffscreenTarget(true)) - } - effect.depthMap = this.depthTarget.colorBuffer - } - if(isFirstEffect) { - this.camera.renderTarget = newEntry.inputTarget - } - effects.push(newEntry); - var len = effects.length; - if(len > 1) { - effects[len - 2].outputTarget = newEntry.inputTarget - } - this.enable() - }, removeEffect:function(effect) { - var index = -1; - for(var i = 0, len = this.effects.length;i < len;i++) { - if(this.effects[i].effect === effect) { - index = i; - break - } - } - if(index >= 0) { - if(index > 0) { - this.effects[index - 1].outputTarget = index + 1 < this.effects.length ? this.effects[index + 1].inputTarget : null - }else { - if(this.effects.length > 1) { - if(!this.effects[1].inputTarget._depth) { - this.effects[1].inputTarget.destroy(); - this.effects[1].inputTarget = this._createOffscreenTarget(true) - } - this.camera.renderTarget = this.effects[1].inputTarget - } - } - this.effects[index].inputTarget.destroy(); - this.effects.splice(index, 1) - } - if(this.depthTarget) { - var isDepthTargetNeeded = false; - for(var i = 0, len = this.effects.length;i < len;i++) { - if(this.effects[i].effect.needsDepthBuffer) { - isDepthTargetNeeded = true; - break - } - } - if(!isDepthTargetNeeded) { - this._setDepthTarget(null) - } - } - if(this.effects.length === 0) { - this.disable() - } - }, destroy:function() { - if(this.depthTarget) { - this.depthTarget.destroy(); - this.depthTarget = null - } - for(var i = 0, len = this.effects.length;i < len;i++) { - this.effects[i].inputTarget.destroy() - } - this.effects.length = 0; - this.disable() - }, enable:function() { - if(!this.enabled && this.effects.length) { - this.enabled = true; - var effects = this.effects; - var camera = this.camera; - this.app.graphicsDevice.on("resizecanvas", this._onCanvasResized, this); - camera.camera.setRect(0, 0, 1, 1); - this.command = new pc.Command(pc.LAYER_FX, pc.BLEND_NONE, function() { - if(this.enabled && camera.data.isRendering) { - var rect = null; - var len = effects.length; - if(len) { - camera.renderTarget = effects[0].inputTarget; - this._setDepthTarget(this.depthTarget); - for(var i = 0;i < len;i++) { - var fx = effects[i]; - if(i === len - 1) { - rect = camera.rect - } - fx.effect.render(fx.inputTarget, fx.outputTarget, rect) - } - } - } - }.bind(this)); - this.app.scene.drawCalls.push(this.command) - } - }, disable:function() { - if(this.enabled) { - this.enabled = false; - this.app.graphicsDevice.off("resizecanvas", this._onCanvasResized, this); - this.camera.renderTarget = null; - this.camera.camera._depthTarget = null; - var rect = this.camera.rect; - this.camera.camera.setRect(rect.x, rect.y, rect.z, rect.w); - var i = this.app.scene.drawCalls.indexOf(this.command); - if(i >= 0) { - this.app.scene.drawCalls.splice(i, 1) - } - } - }, _onCanvasResized:function(width, height) { - if(this.resizeTimeout) { - clearTimeout(this.resizeTimeout) - } - this.resizeTimeout = setTimeout(this.resizeRenderTargets.bind(this), 500) - }, resizeRenderTargets:function() { - var rect = this.camera.rect; - var desiredWidth = Math.floor(rect.z * this.app.graphicsDevice.width * this.renderTargetScale); - var desiredHeight = Math.floor(rect.w * this.app.graphicsDevice.height * this.renderTargetScale); - var effects = this.effects; - if(this.depthTarget && this.depthTarget.width !== desiredWidth && this.depthTarget.height !== desiredHeight) { - this._setDepthTarget(this._createOffscreenTarget(true)) - } - for(var i = 0, len = effects.length;i < len;i++) { - var fx = effects[i]; - if(fx.inputTarget.width !== desiredWidth || fx.inputTarget.height !== desiredHeight) { - fx.inputTarget.destroy(); - fx.inputTarget = this._createOffscreenTarget(fx.effect.needsDepthBuffer || i === 0); - if(fx.effect.needsDepthBuffer) { - fx.depthMap = this.depthTarget - } - if(i > 0) { - effects[i - 1].outputTarget = fx.inputTarget - }else { - this.camera.renderTarget = fx.inputTarget - } - } - } - }, onCameraRectChanged:function(name, oldValue, newValue) { - if(this.enabled) { - this.camera.camera.setRect(0, 0, 1, 1); - this.resizeRenderTargets() - } - }}; - return{PostEffectQueue:PostEffectQueue} -}()); -(function() { - var enums = {BLEND_SUBTRACTIVE:0, BLEND_ADDITIVE:1, BLEND_NORMAL:2, BLEND_NONE:3, BLEND_PREMULTIPLIED:4, BLEND_MULTIPLICATIVE:5, BLEND_ADDITIVEALPHA:6, FOG_NONE:"none", FOG_LINEAR:"linear", FOG_EXP:"exp", FOG_EXP2:"exp2", FRESNEL_NONE:0, FRESNEL_SIMPLE:1, FRESNEL_SCHLICK:2, FRESNEL_COMPLEX:3, LAYER_HUD:0, LAYER_GIZMO:1, LAYER_FX:2, LAYER_WORLD:3, LIGHTTYPE_DIRECTIONAL:0, LIGHTTYPE_POINT:1, LIGHTTYPE_SPOT:2, LIGHTFALLOFF_LINEAR:0, LIGHTFALLOFF_INVERSESQUARED:1, SHADOW_DEPTH:0, SHADOW_DEPTHMASK:1, - SHADOWSAMPLE_HARD:0, SHADOWSAMPLE_PCF3X3:1, SHADOWSAMPLE_MASK:2, PARTICLESORT_NONE:0, PARTICLESORT_DISTANCE:1, PARTICLESORT_NEWER_FIRST:2, PARTICLESORT_OLDER_FIRST:3, PARTICLEMODE_GPU:0, PARTICLEMODE_CPU:1, EMITTERSHAPE_BOX:0, EMITTERSHAPE_SPHERE:1, PROJECTION_PERSPECTIVE:0, PROJECTION_ORTHOGRAPHIC:1, RENDERSTYLE_SOLID:0, RENDERSTYLE_WIREFRAME:1, RENDERSTYLE_POINTS:2, CUBEPROJ_NONE:0, CUBEPROJ_BOX:1, SPECULAR_PHONG:0, SPECULAR_BLINN:1, GAMMA_NONE:0, GAMMA_SRGB:1, GAMMA_SRGBFAST:2, TONEMAP_LINEAR:0, - TONEMAP_FILMIC:1, SHADERDEF_NOSHADOW:1, SHADERDEF_SKIN:2, SHADERDEF_UV1:4, SHADERDEF_VCOLOR:8, LINEBATCH_WORLD:0, LINEBATCH_OVERLAY:1, LINEBATCH_GIZMO:2, SHADOWUPDATE_NONE:0, SHADOWUPDATE_THISFRAME:1, SHADOWUPDATE_REALTIME:2}; - pc.extend(pc, enums); - pc.scene = {}; - pc.extend(pc.scene, enums) -})(); -pc.extend(pc, function() { - var Scene = function Scene() { - this.root = null; - this._gravity = new pc.Vec3(0, -9.8, 0); - this.drawCalls = []; - this.shadowCasters = []; - this.immediateDrawCalls = []; - this.depthDrawCalls = 0; - this.shadowDrawCalls = 0; - this.forwardDrawCalls = 0; - this.fog = pc.FOG_NONE; - this.fogColor = new pc.Color(0, 0, 0); - this.fogStart = 1; - this.fogEnd = 1E3; - this.fogDensity = 0; - this.ambientLight = new pc.Color(0, 0, 0); - this._gammaCorrection = pc.GAMMA_NONE; - this._toneMapping = 0; - this.exposure = 1; - this._skyboxPrefiltered128 = null; - this._skyboxPrefiltered64 = null; - this._skyboxPrefiltered32 = null; - this._skyboxPrefiltered16 = null; - this._skyboxPrefiltered8 = null; - this._skyboxPrefiltered4 = null; - this._skyboxCubeMap = null; - this._skyboxModel = null; - this._skyboxIntensity = 1; - this._skyboxMip = 0; - this._models = []; - this._lights = []; - this._globalLights = []; - this._localLights = [[], []]; - this.updateShaders = true - }; - Object.defineProperty(Scene.prototype, "fog", {get:function() { - return this._fog - }, set:function(type) { - if(type !== this._fog) { - this._fog = type; - this.updateShaders = true - } - }}); - Object.defineProperty(Scene.prototype, "gammaCorrection", {get:function() { - return this._gammaCorrection - }, set:function(value) { - if(value !== this._gammaCorrection) { - this._gammaCorrection = value; - this.updateShaders = true - } - }}); - Object.defineProperty(Scene.prototype, "toneMapping", {get:function() { - return this._toneMapping - }, set:function(value) { - if(value !== this._toneMapping) { - this._toneMapping = value; - this.updateShaders = true - } - }}); - Object.defineProperty(Scene.prototype, "skybox", {get:function() { - return this._skyboxCubeMap - }, set:function(value) { - this._skyboxCubeMap = value; - this._resetSkyboxModel(); - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxIntensity", {get:function() { - return this._skyboxIntensity - }, set:function(value) { - this._skyboxIntensity = value; - this._resetSkyboxModel(); - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxMip", {get:function() { - return this._skyboxMip - }, set:function(value) { - this._skyboxMip = value; - this._resetSkyboxModel(); - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxPrefiltered128", {get:function() { - return this._skyboxPrefiltered128 - }, set:function(value) { - this._skyboxPrefiltered128 = value; - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxPrefiltered64", {get:function() { - return this._skyboxPrefiltered64 - }, set:function(value) { - this._skyboxPrefiltered64 = value; - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxPrefiltered32", {get:function() { - return this._skyboxPrefiltered32 - }, set:function(value) { - this._skyboxPrefiltered32 = value; - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxPrefiltered16", {get:function() { - return this._skyboxPrefiltered16 - }, set:function(value) { - this._skyboxPrefiltered16 = value; - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxPrefiltered8", {get:function() { - return this._skyboxPrefiltered8 - }, set:function(value) { - this._skyboxPrefiltered8 = value; - this.updateShaders = true - }}); - Object.defineProperty(Scene.prototype, "skyboxPrefiltered4", {get:function() { - return this._skyboxPrefiltered4 - }, set:function(value) { - this._skyboxPrefiltered4 = value; - this.updateShaders = true - }}); - Scene.prototype.applySettings = function(settings) { - this._gravity.set(settings.physics.gravity[0], settings.physics.gravity[1], settings.physics.gravity[2]); - var al = settings.render.global_ambient; - this.ambientLight = new pc.Color(al[0], al[1], al[2]); - this.fog = settings.render.fog; - var fogColor = settings.render.fog_color; - this.fogColor = new pc.Color(fogColor[0], fogColor[1], fogColor[2]); - this.fogStart = settings.render.fog_start; - this.fogEnd = settings.render.fog_end; - this.fogDensity = settings.render.fog_density; - this.gammaCorrection = settings.render.gamma_correction; - this.toneMapping = settings.render.tonemapping; - this.exposure = settings.render.exposure; - this.skyboxIntensity = settings.render.skyboxIntensity === undefined ? 1 : settings.render.skyboxIntensity; - this.skyboxMip = settings.render.skyboxMip === undefined ? 0 : settings.render.skyboxMip; - this.skyboxAsset = settings.render.skybox - }; - Scene.prototype._updateShaders = function(device) { - var i; - if(this._skyboxCubeMap && !this._skyboxModel) { - var material = new pc.Material; - var scene = this; - material.updateShader = function() { - var library = device.getProgramLibrary(); - var shader = library.getProgram("skybox", {rgbm:scene._skyboxCubeMap.rgbm, hdr:scene._skyboxCubeMap.rgbm || scene._skyboxCubeMap.format === pc.PIXELFORMAT_RGBA32F, useIntensity:scene.skyboxIntensity !== 1, mip:scene._skyboxCubeMap.fixCubemapSeams ? scene.skyboxMip : 0, fixSeams:scene._skyboxCubeMap.fixCubemapSeams, gamma:scene.gammaCorrection, toneMapping:scene.toneMapping}); - this.setShader(shader) - }; - material.updateShader(); - if(!this._skyboxCubeMap.fixCubemapSeams || !scene._skyboxMip) { - material.setParameter("texture_cubeMap", this._skyboxCubeMap) - }else { - var mip2tex = [null, "64", "16", "8", "4"]; - var mipTex = this["skyboxPrefiltered" + mip2tex[scene._skyboxMip]]; - if(mipTex) { - material.setParameter("texture_cubeMap", mipTex) - } - } - material.cull = pc.CULLFACE_NONE; - var node = new pc.GraphNode; - var mesh = pc.createBox(device); - var meshInstance = new pc.MeshInstance(node, mesh, material); - meshInstance.updateKey = function() { - var material = this.material; - this.key = pc._getDrawcallSortKey(this.layer, material.blendType, false, 0) - }; - meshInstance.updateKey(); - meshInstance.cull = false; - var model = new pc.Model; - model.graph = node; - model.meshInstances = [meshInstance]; - this._skyboxModel = model; - this.addModel(model) - } - var materials = []; - var drawCalls = this.drawCalls; - for(i = 0;i < drawCalls.length;i++) { - var drawCall = drawCalls[i]; - if(drawCall.material !== undefined) { - if(materials.indexOf(drawCall.material) === -1) { - materials.push(drawCall.material) - } - } - } - for(i = 0;i < materials.length;i++) { - materials[i].clearVariants(); - materials[i].updateShader(device, this); - materials[i].variants[0] = materials[i].shader - } - }; - Scene.prototype.getModels = function() { - return this._models - }; - Scene.prototype.addModel = function(model) { - var i; - var index = this._models.indexOf(model); - if(index === -1) { - this._models.push(model); - var materials = model.getMaterials(); - for(i = 0;i < materials.length;i++) { - materials[i].scene = this - } - var meshInstance; - var numMeshInstances = model.meshInstances.length; - for(i = 0;i < numMeshInstances;i++) { - meshInstance = model.meshInstances[i]; - if(this.drawCalls.indexOf(meshInstance) === -1) { - this.drawCalls.push(meshInstance) - } - if(meshInstance.castShadow) { - if(this.shadowCasters.indexOf(meshInstance) === -1) { - this.shadowCasters.push(meshInstance) - } - } - } - var lights = model.getLights(); - for(i = 0, len = lights.length;i < len;i++) { - this.addLight(lights[i]) - } - } - }; - Scene.prototype.removeModel = function(model) { - var i; - var index = this._models.indexOf(model); - if(index !== -1) { - this._models.splice(index, 1); - var materials = model.getMaterials(); - for(i = 0;i < materials.length;i++) { - materials[i].scene = null - } - var meshInstance; - var numMeshInstances = model.meshInstances.length; - for(i = 0;i < numMeshInstances;i++) { - meshInstance = model.meshInstances[i]; - index = this.drawCalls.indexOf(meshInstance); - if(index !== -1) { - this.drawCalls.splice(index, 1) - } - if(meshInstance.castShadow) { - index = this.shadowCasters.indexOf(meshInstance); - if(index !== -1) { - this.shadowCasters.splice(index, 1) - } - } - } - var lights = model.getLights(); - for(i = 0, len = lights.length;i < len;i++) { - this.removeLight(lights[i]) - } - } - }; - Scene.prototype.containsModel = function(model) { - return this._models.indexOf(model) >= 0 - }; - Scene.prototype.addLight = function(light) { - var index = this._lights.indexOf(light); - if(index !== -1) { - console.warn("pc.Scene#addLight: light is already in the scene") - }else { - this._lights.push(light); - light._scene = this; - this.updateShaders = true - } - }; - Scene.prototype.removeLight = function(light) { - var index = this._lights.indexOf(light); - if(index === -1) { - console.warn("pc.Scene#removeLight: light is not in the scene") - }else { - this._lights.splice(index, 1); - light._scene = null; - this.updateShaders = true - } - }; - Scene.prototype.attachSkyboxAsset = function(asset) { - var scene = this; - this.setSkybox(asset.resources); - asset.off("change", this._onSkyBoxChanged, this); - asset.on("change", this._onSkyBoxChanged, this); - asset.off("remove", this._onSkyBoxRemoved, this); - asset.on("remove", this._onSkyBoxRemoved, this) - }; - Scene.prototype._resetSkyboxModel = function() { - if(this._skyboxModel) { - if(this.containsModel(this._skyboxModel)) { - this.removeModel(this._skyboxModel) - } - } - this._skyboxModel = null - }; - Scene.prototype._onSkyBoxChanged = function(asset, attribute, newValue, oldValue) { - if(attribute !== "resources") { - return - } - this.setSkybox(newValue) - }; - Scene.prototype._onSkyBoxRemoved = function(asset) { - asset.off("change", this._onSkyBoxChanged, this); - if(this.skybox === asset.resources[0]) { - this.setSkybox(null) - } - }; - Scene.prototype.setSkybox = function(cubemaps) { - if(cubemaps !== null) { - this._skyboxPrefiltered128 = cubemaps[1]; - this._skyboxPrefiltered64 = cubemaps[2]; - this._skyboxPrefiltered32 = cubemaps[3]; - this._skyboxPrefiltered16 = cubemaps[4]; - this._skyboxPrefiltered8 = cubemaps[5]; - this._skyboxPrefiltered4 = cubemaps[6]; - this.skybox = cubemaps[0] - }else { - this._skyboxPrefiltered128 = null; - this._skyboxPrefiltered64 = null; - this._skyboxPrefiltered32 = null; - this._skyboxPrefiltered16 = null; - this._skyboxPrefiltered8 = null; - this._skyboxPrefiltered4 = null; - this.skybox = null - } - }; - Scene.prototype.update = function() { - for(var i = 0, len = this._models.length;i < len;i++) { - this._models[i].getGraph().syncHierarchy() - } - }; - Scene.prototype.destroy = function() { - var i; - var models = this.getModels(); - for(i = 0;i < models.length;i++) { - this.removeModel(models[i]) - } - for(i = 0;i < this._lights.length;i++) { - this.removeLight(this._lights[i]) - } - this.skybox = null - }; - return{Scene:Scene} -}()); -pc.extend(pc, function() { - function sortDrawCalls(drawCallA, drawCallB) { - if(drawCallA.distSqr && drawCallB.distSqr) { - return drawCallB.distSqr - drawCallA.distSqr - }else { - return drawCallB.key - drawCallA.key - } - } - var scale = (new pc.Mat4).setScale(0.5, 0.5, 0.5); - var shift = (new pc.Mat4).setTranslate(0.5, 0.5, 0.5); - var scaleShift = (new pc.Mat4).mul2(shift, scale); - var camToLight = (new pc.Mat4).setFromAxisAngle(pc.Vec3.RIGHT, -90); - var shadowCamWtm = new pc.Mat4; - var shadowCamView = new pc.Mat4; - var shadowCamViewProj = new pc.Mat4; - var viewInvMat = new pc.Mat4; - var viewMat = new pc.Mat4; - var viewMat3 = new pc.Mat3; - var viewProjMat = new pc.Mat4; - var tempSphere = {}; - var c2sc = new pc.Mat4; - var frustumPoints = []; - for(i = 0;i < 8;i++) { - frustumPoints.push(new pc.Vec3) - } - function _calculateSceneAabb(scene) { - var meshInstances = scene.meshInstances; - if(meshInstances.length > 0) { - scene._sceneAabb.copy(meshInstances[0].aabb); - for(var i = 1;i < meshInstances.length;i++) { - scene._sceneAabb.add(meshInstances[i].aabb) - } - } - } - function _getFrustumCentroid(scene, camera, farClip, centroid) { - centroid.set(0, 0, -(farClip + camera._nearClip) * 0.5); - camera._node.getWorldTransform().transformPoint(centroid, centroid) - } - function _getFrustumPoints(scene, camera, farClip, points) { - var cam = camera; - var nearClip = cam.getNearClip(); - var fov = cam.getFov() * Math.PI / 180; - var aspect = cam.getAspectRatio(); - var projection = cam.getProjection(); - var x, y; - if(projection === pc.PROJECTION_PERSPECTIVE) { - y = Math.tan(fov / 2) * nearClip - }else { - y = camera._orthoHeight - } - x = y * aspect; - points[0].x = x; - points[0].y = -y; - points[0].z = -nearClip; - points[1].x = x; - points[1].y = y; - points[1].z = -nearClip; - points[2].x = -x; - points[2].y = y; - points[2].z = -nearClip; - points[3].x = -x; - points[3].y = -y; - points[3].z = -nearClip; - if(projection === pc.PROJECTION_PERSPECTIVE) { - y = Math.tan(fov / 2) * farClip; - x = y * aspect - } - points[4].x = x; - points[4].y = -y; - points[4].z = -farClip; - points[5].x = x; - points[5].y = y; - points[5].z = -farClip; - points[6].x = -x; - points[6].y = y; - points[6].z = -farClip; - points[7].x = -x; - points[7].y = -y; - points[7].z = -farClip; - return points - } - function createShadowMap(device, width, height) { - var shadowMap = new pc.Texture(device, {format:pc.PIXELFORMAT_R8_G8_B8_A8, width:width, height:height, autoMipmap:false}); - shadowMap.minFilter = pc.FILTER_NEAREST; - shadowMap.magFilter = pc.FILTER_NEAREST; - shadowMap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - shadowMap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - return new pc.RenderTarget(device, shadowMap, true) - } - function createShadowCubeMap(device, size) { - var cubemap = new pc.Texture(device, {format:pc.PIXELFORMAT_R8_G8_B8_A8, width:size, height:size, cubemap:true, autoMipmap:false}); - cubemap.minFilter = pc.FILTER_NEAREST; - cubemap.magFilter = pc.FILTER_NEAREST; - cubemap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - cubemap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - var targets = []; - for(var i = 0;i < 6;i++) { - var target = new pc.RenderTarget(device, cubemap, {face:i, depth:true}); - targets.push(target) - } - return targets - } - function createShadowCamera(device) { - var flags = pc.CLEARFLAG_DEPTH; - if(!device.extDepthTexture) { - flags |= pc.CLEARFLAG_COLOR - } - var shadowCam = new pc.Camera; - shadowCam.setClearOptions({color:[1, 1, 1, 1], depth:1, flags:flags}); - shadowCam._node = new pc.GraphNode; - return shadowCam - } - function createShadowBuffer(device, light) { - var shadowBuffer; - if(light.getType() === pc.LIGHTTYPE_POINT) { - shadowBuffer = createShadowCubeMap(device, light._shadowResolution); - light._shadowCamera.setRenderTarget(shadowBuffer[0]); - light._shadowCubeMap = shadowBuffer - }else { - shadowBuffer = createShadowMap(device, light._shadowResolution, light._shadowResolution); - light._shadowCamera.setRenderTarget(shadowBuffer) - } - } - function getShadowCamera(device, light) { - var shadowCam = light._shadowCamera; - var shadowBuffer; - if(shadowCam === null) { - shadowCam = light._shadowCamera = createShadowCamera(device); - createShadowBuffer(device, light) - }else { - shadowBuffer = shadowCam.getRenderTarget(); - if(shadowBuffer.width !== light._shadowResolution || shadowBuffer.height !== light._shadowResolution) { - createShadowBuffer(device, light) - } - } - return shadowCam - } - function ForwardRenderer(graphicsDevice) { - this.device = graphicsDevice; - var library = this.device.getProgramLibrary(); - this._depthShaderStatic = library.getProgram("depth", {skin:false}); - this._depthShaderSkin = library.getProgram("depth", {skin:true}); - this._depthProgStatic = []; - this._depthProgSkin = []; - this._depthProgStaticOp = []; - this._depthProgSkinOp = []; - this._depthProgStaticPoint = []; - this._depthProgSkinPoint = []; - this._depthProgStaticOpPoint = []; - this._depthProgSkinOpPoint = []; - var chan = ["r", "g", "b", "a"]; - for(var i = 0;i < pc.SHADOW_DEPTH + 1;i++) { - this._depthProgStatic[i] = library.getProgram("depthrgba", {skin:false, opacityMap:false, shadowType:i}); - this._depthProgSkin[i] = library.getProgram("depthrgba", {skin:true, opacityMap:false, shadowType:i}); - this._depthProgStaticPoint[i] = library.getProgram("depthrgba", {skin:false, opacityMap:false, point:true}); - this._depthProgSkinPoint[i] = library.getProgram("depthrgba", {skin:true, opacityMap:false, point:true}); - this._depthProgStaticOp[i] = {}; - this._depthProgSkinOp[i] = {}; - this._depthProgStaticOpPoint[i] = {}; - this._depthProgSkinOpPoint[i] = {}; - for(var c = 0;c < 4;c++) { - this._depthProgStaticOp[i][chan[c]] = library.getProgram("depthrgba", {skin:false, opacityMap:true, shadowType:i, opacityChannel:chan[c]}); - this._depthProgSkinOp[i][chan[c]] = library.getProgram("depthrgba", {skin:true, opacityMap:true, shadowType:i, opacityChannel:chan[c]}); - this._depthProgStaticOpPoint[i][chan[c]] = library.getProgram("depthrgba", {skin:false, opacityMap:true, point:true, opacityChannel:chan[c]}); - this._depthProgSkinOpPoint[i][chan[c]] = library.getProgram("depthrgba", {skin:true, opacityMap:true, point:true, opacityChannel:chan[c]}) - } - } - var scope = this.device.scope; - this.projId = scope.resolve("matrix_projection"); - this.viewId = scope.resolve("matrix_view"); - this.viewId3 = scope.resolve("matrix_view3"); - this.viewInvId = scope.resolve("matrix_viewInverse"); - this.viewProjId = scope.resolve("matrix_viewProjection"); - this.viewPosId = scope.resolve("view_position"); - this.nearClipId = scope.resolve("camera_near"); - this.farClipId = scope.resolve("camera_far"); - this.lightRadiusId = scope.resolve("light_radius"); - this.fogColorId = scope.resolve("fog_color"); - this.fogStartId = scope.resolve("fog_start"); - this.fogEndId = scope.resolve("fog_end"); - this.fogDensityId = scope.resolve("fog_density"); - this.modelMatrixId = scope.resolve("matrix_model"); - this.normalMatrixId = scope.resolve("matrix_normal"); - this.poseMatrixId = scope.resolve("matrix_pose[0]"); - this.boneTextureId = scope.resolve("texture_poseMap"); - this.boneTextureSizeId = scope.resolve("texture_poseMapSize"); - this.alphaTestId = scope.resolve("alpha_ref"); - this._shadowAabb = new pc.shape.Aabb; - this._sceneAabb = new pc.shape.Aabb; - this._shadowState = {blend:false}; - this.centroid = new pc.Vec3; - this.fogColor = new Float32Array(3); - this.ambientColor = new Float32Array(3) - } - pc.extend(ForwardRenderer.prototype, {setCamera:function(camera, cullBorder) { - var projMat = camera.getProjectionMatrix(); - this.projId.setValue(projMat.data); - var pos = camera._node.getPosition(); - var rot = camera._node.getRotation(); - viewInvMat.setTRS(pos, rot, pc.Vec3.ONE); - this.viewInvId.setValue(viewInvMat.data); - viewMat.copy(viewInvMat).invert(); - this.viewId.setValue(viewMat.data); - viewMat3.data[0] = viewMat.data[0]; - viewMat3.data[1] = viewMat.data[1]; - viewMat3.data[2] = viewMat.data[2]; - viewMat3.data[3] = viewMat.data[4]; - viewMat3.data[4] = viewMat.data[5]; - viewMat3.data[5] = viewMat.data[6]; - viewMat3.data[6] = viewMat.data[8]; - viewMat3.data[7] = viewMat.data[9]; - viewMat3.data[8] = viewMat.data[10]; - this.viewId3.setValue(viewMat3.data); - viewProjMat.mul2(projMat, viewMat); - this.viewProjId.setValue(viewProjMat.data); - this.viewPosId.setValue(camera._node.getPosition().data); - this.nearClipId.setValue(camera.getNearClip()); - this.farClipId.setValue(camera.getFarClip()); - camera._frustum.update(projMat, viewMat); - var device = this.device; - var target = camera.getRenderTarget(); - device.setRenderTarget(target); - device.updateBegin(); - var rect = camera.getRect(); - var pixelWidth = target ? target.width : device.width; - var pixelHeight = target ? target.height : device.height; - var x = Math.floor(rect.x * pixelWidth); - var y = Math.floor(rect.y * pixelHeight); - var w = Math.floor(rect.width * pixelWidth); - var h = Math.floor(rect.height * pixelHeight); - device.setViewport(x, y, w, h); - device.setScissor(x, y, w, h); - device.clear(camera.getClearOptions()); - if(cullBorder) { - device.setScissor(1, 1, pixelWidth - 2, pixelHeight - 2) - } - }, dispatchGlobalLights:function(scene) { - var i; - this.mainLight = -1; - this._activeShadowLights = []; - var scope = this.device.scope; - this.ambientColor[0] = scene.ambientLight.r; - this.ambientColor[1] = scene.ambientLight.g; - this.ambientColor[2] = scene.ambientLight.b; - if(scene.gammaCorrection) { - for(i = 0;i < 3;i++) { - this.ambientColor[i] = Math.pow(this.ambientColor[i], 2.2) - } - } - scope.resolve("light_globalAmbient").setValue(this.ambientColor); - scope.resolve("exposure").setValue(scene.exposure); - if(scene._skyboxModel) { - scope.resolve("skyboxIntensity").setValue(scene.skyboxIntensity) - } - }, dispatchDirectLights:function(scene, mask) { - var dirs = scene._globalLights; - var numDirs = dirs.length; - var i; - var directional, wtm, light; - var cnt = 0; - var scope = this.device.scope; - for(i = 0;i < numDirs;i++) { - if(!(dirs[i].mask & mask)) { - continue - } - directional = dirs[i]; - wtm = directional._node.getWorldTransform(); - light = "light" + cnt; - scope.resolve(light + "_color").setValue(scene.gammaCorrection ? directional._linearFinalColor.data : directional._finalColor.data); - wtm.getY(directional._direction).scale(-1); - scope.resolve(light + "_direction").setValue(directional._direction.normalize().data); - if(directional.getCastShadows()) { - var shadowMap = this.device.extDepthTexture ? directional._shadowCamera._renderTarget._depthTexture : directional._shadowCamera._renderTarget.colorBuffer; - scope.resolve(light + "_shadowMap").setValue(shadowMap); - scope.resolve(light + "_shadowMatrix").setValue(directional._shadowMatrix.data); - scope.resolve(light + "_shadowParams").setValue([directional._shadowResolution, directional._normalOffsetBias, directional._shadowBias]); - this._activeShadowLights.push(directional); - if(this.mainLight < 0) { - scope.resolve(light + "_shadowMatrixVS").setValue(directional._shadowMatrix.data); - scope.resolve(light + "_shadowParamsVS").setValue([directional._shadowResolution, directional._normalOffsetBias, directional._shadowBias]); - scope.resolve(light + "_directionVS").setValue(directional._direction.normalize().data); - this.mainLight = i - } - } - cnt++ - } - return cnt - }, dispatchLocalLights:function(scene, mask, usedDirLights) { - var i, wtm; - var point, spot; - var light; - var localLights = scene._localLights; - var cnt = 0; - var pnts = localLights[pc.LIGHTTYPE_POINT - 1]; - var spts = localLights[pc.LIGHTTYPE_SPOT - 1]; - var numDirs = usedDirLights; - var numPnts = pnts.length; - var numSpts = spts.length; - var scope = this.device.scope; - for(i = 0;i < numPnts;i++) { - if(!(pnts[i].mask & mask)) { - continue - } - point = pnts[i]; - wtm = point._node.getWorldTransform(); - light = "light" + (numDirs + cnt); - scope.resolve(light + "_radius").setValue(point._attenuationEnd); - scope.resolve(light + "_color").setValue(scene.gammaCorrection ? point._linearFinalColor.data : point._finalColor.data); - wtm.getTranslation(point._position); - scope.resolve(light + "_position").setValue(point._position.data); - if(point.getCastShadows()) { - var shadowMap = this.device.extDepthTexture ? point._shadowCamera._renderTarget._depthTexture : point._shadowCamera._renderTarget.colorBuffer; - scope.resolve(light + "_shadowMap").setValue(shadowMap); - scope.resolve(light + "_shadowMatrix").setValue(point._shadowMatrix.data); - scope.resolve(light + "_shadowParams").setValue([point._shadowResolution, point._normalOffsetBias, point._shadowBias, 1 / point.getAttenuationEnd()]); - this._activeShadowLights.push(point) - } - cnt++ - } - for(i = 0;i < numSpts;i++) { - if(!(spts[i].mask & mask)) { - continue - } - spot = spts[i]; - wtm = spot._node.getWorldTransform(); - light = "light" + (numDirs + cnt); - scope.resolve(light + "_innerConeAngle").setValue(spot._innerConeAngleCos); - scope.resolve(light + "_outerConeAngle").setValue(spot._outerConeAngleCos); - scope.resolve(light + "_radius").setValue(spot._attenuationEnd); - scope.resolve(light + "_color").setValue(scene.gammaCorrection ? spot._linearFinalColor.data : spot._finalColor.data); - wtm.getTranslation(spot._position); - scope.resolve(light + "_position").setValue(spot._position.data); - wtm.getY(spot._direction).scale(-1); - scope.resolve(light + "_spotDirection").setValue(spot._direction.data); - if(spot.getCastShadows()) { - var shadowMap = this.device.extDepthTexture ? spot._shadowCamera._renderTarget._depthTexture : spot._shadowCamera._renderTarget.colorBuffer; - scope.resolve(light + "_shadowMap").setValue(shadowMap); - scope.resolve(light + "_shadowMatrix").setValue(spot._shadowMatrix.data); - scope.resolve(light + "_shadowParams").setValue([spot._shadowResolution, spot._normalOffsetBias, spot._shadowBias]); - this._activeShadowLights.push(spot); - if(this.mainLight < 0) { - scope.resolve(light + "_shadowMatrixVS").setValue(spot._shadowMatrix.data); - scope.resolve(light + "_shadowParamsVS").setValue([spot._shadowResolution, spot._normalOffsetBias, spot._shadowBias]); - scope.resolve(light + "_positionVS").setValue(spot._position.data); - this.mainLight = i - } - } - cnt++ - } - }, render:function(scene, camera) { - var device = this.device; - var scope = device.scope; - scene.depthDrawCalls = 0; - scene.shadowDrawCalls = 0; - scene.forwardDrawCalls = 0; - scene._activeCamera = camera; - if(scene.updateShaders) { - scene._updateShaders(device); - scene.updateShaders = false - } - var i, j, numInstances; - var lights = scene._lights; - var models = scene._models; - var drawCalls = scene.drawCalls; - var drawCallsCount = drawCalls.length; - var shadowCasters = scene.shadowCasters; - var drawCall, meshInstance, prevMeshInstance = null, mesh, material, prevMaterial = null, style; - scene._globalLights.length = 0; - scene._localLights[0].length = 0; - scene._localLights[1].length = 0; - for(i = 0;i < lights.length;i++) { - var light = lights[i]; - if(light.getEnabled()) { - if(light.getType() === pc.LIGHTTYPE_DIRECTIONAL) { - scene._globalLights.push(light) - }else { - scene._localLights[light.getType() === pc.LIGHTTYPE_POINT ? 0 : 1].push(light) - } - } - } - this.culled = []; - var meshPos; - var visible; - var btype; - var camPos = camera._node.getPosition(); - for(i = 0;i < drawCallsCount;i++) { - drawCall = drawCalls[i]; - visible = true; - meshPos = null; - if(!drawCall.command) { - if(drawCall._hidden) { - continue - } - meshInstance = drawCall; - if(meshInstance.layer === pc.LAYER_WORLD) { - if(camera.frustumCulling && drawCall.cull) { - meshPos = meshInstance.aabb.center; - if(!meshInstance._aabb._radius) { - meshInstance._aabb._radius = meshInstance._aabb.halfExtents.length() - } - tempSphere.center = meshPos; - tempSphere.radius = meshInstance._aabb._radius; - if(!camera._frustum.containsSphere(tempSphere)) { - visible = false - } - } - if(visible) { - btype = meshInstance.material.blendType; - if(btype === pc.BLEND_NORMAL || btype === pc.BLEND_PREMULTIPLIED) { - if(!meshPos) { - meshPos = meshInstance.aabb.center - } - var tempx = meshPos.x - camPos.x; - var tempy = meshPos.y - camPos.y; - var tempz = meshPos.z - camPos.z; - meshInstance.distSqr = tempx * tempx + tempy * tempy + tempz * tempz - }else { - if(meshInstance.distSqr !== undefined) { - delete meshInstance.distSqr - } - } - } - } - } - if(visible) { - this.culled.push(drawCall) - } - } - for(i = 0;i < scene.immediateDrawCalls.length;i++) { - this.culled.push(scene.immediateDrawCalls[i]) - } - drawCalls = this.culled; - drawCallsCount = this.culled.length; - for(i = 0;i < drawCallsCount;i++) { - drawCall = drawCalls[i]; - if(drawCall.skinInstance) { - drawCall.skinInstance.updateMatrixPalette() - } - } - drawCalls.sort(sortDrawCalls); - if(camera._depthTarget) { - var oldTarget = camera.getRenderTarget(); - camera.setRenderTarget(camera._depthTarget); - this.setCamera(camera); - var oldBlending = device.getBlending(); - device.setBlending(false); - for(i = 0;i < drawCallsCount;i++) { - drawCall = drawCalls[i]; - if(!drawCall.command && drawCall.drawToDepth) { - meshInstance = drawCall; - mesh = meshInstance.mesh; - this.modelMatrixId.setValue(meshInstance.node.worldTransform.data); - if(meshInstance.skinInstance) { - if(device.supportsBoneTextures) { - this.boneTextureId.setValue(meshInstance.skinInstance.boneTexture); - var w = meshInstance.skinInstance.boneTexture.width; - var h = meshInstance.skinInstance.boneTexture.height; - this.boneTextureSizeId.setValue([w, h]) - }else { - this.poseMatrixId.setValue(meshInstance.skinInstance.matrixPalette) - } - device.setShader(this._depthShaderSkin) - }else { - device.setShader(this._depthShaderStatic) - } - style = meshInstance.renderStyle; - device.setVertexBuffer(mesh.vertexBuffer, 0); - device.setIndexBuffer(mesh.indexBuffer[style]); - device.draw(mesh.primitive[style]); - scene.depthDrawCalls++ - } - camera.setRenderTarget(oldTarget) - } - device.setBlending(oldBlending) - } - for(i = 0;i < lights.length;i++) { - var light = lights[i]; - var type = light.getType(); - if(light.getCastShadows() && light.getEnabled() && light.shadowUpdateMode !== pc.SHADOWUPDATE_NONE) { - if(light.shadowUpdateMode === pc.SHADOWUPDATE_THISFRAME) { - light.shadowUpdateMode = pc.SHADOWUPDATE_NONE - } - var shadowCam = getShadowCamera(device, light); - var passes = 1; - var pass; - if(type === pc.LIGHTTYPE_DIRECTIONAL) { - var shadowDistance = light.getShadowDistance(); - _getFrustumCentroid(scene, camera, shadowDistance, this.centroid); - shadowCam._node.setPosition(this.centroid); - shadowCam._node.setRotation(light._node.getRotation()); - shadowCam._node.rotateLocal(-90, 0, 0); - _getFrustumPoints(scene, camera, shadowDistance, frustumPoints); - shadowCamWtm.copy(shadowCam._node.getWorldTransform()); - var worldToShadowCam = shadowCamWtm.invert(); - var camToWorld = camera._node.worldTransform; - c2sc.mul2(worldToShadowCam, camToWorld); - for(j = 0;j < 8;j++) { - c2sc.transformPoint(frustumPoints[j], frustumPoints[j]) - } - var minx, miny, minz, maxx, maxy, maxz; - minx = miny = minz = 1E6; - maxx = maxy = maxz = -1E6; - for(j = 0;j < 8;j++) { - var p = frustumPoints[j]; - if(p.x < minx) { - minx = p.x - } - if(p.x > maxx) { - maxx = p.x - } - if(p.y < miny) { - miny = p.y - } - if(p.y > maxy) { - maxy = p.y - } - if(p.z < minz) { - minz = p.z - } - if(p.z > maxz) { - maxz = p.z - } - } - shadowCam._node.translateLocal(-(maxx + minx) * 0.5, (maxy + miny) * 0.5, maxz + (maxz - minz) * 0.25); - shadowCamWtm.copy(shadowCam._node.getWorldTransform()); - shadowCam.setProjection(pc.PROJECTION_ORTHOGRAPHIC); - shadowCam.setNearClip(0); - shadowCam.setFarClip((maxz - minz) * 1.5); - shadowCam.setAspectRatio((maxx - minx) / (maxy - miny)); - shadowCam.setOrthoHeight((maxy - miny) * 0.5) - }else { - if(type === pc.LIGHTTYPE_SPOT) { - shadowCam.setProjection(pc.PROJECTION_PERSPECTIVE); - shadowCam.setNearClip(light.getAttenuationEnd() / 1E3); - shadowCam.setFarClip(light.getAttenuationEnd()); - shadowCam.setAspectRatio(1); - shadowCam.setFov(light.getOuterConeAngle() * 2); - var spos = light._node.getPosition(); - var srot = light._node.getRotation(); - shadowCamWtm.setTRS(spos, srot, pc.Vec3.ONE); - shadowCamWtm.mul2(shadowCamWtm, camToLight) - }else { - if(type === pc.LIGHTTYPE_POINT) { - shadowCam.setProjection(pc.PROJECTION_PERSPECTIVE); - shadowCam.setNearClip(light.getAttenuationEnd() / 1E3); - shadowCam.setFarClip(light.getAttenuationEnd()); - shadowCam.setAspectRatio(1); - shadowCam.setFov(90); - passes = 6; - this.viewPosId.setValue(shadowCam._node.getPosition().data); - this.lightRadiusId.setValue(light.getAttenuationEnd()) - } - } - } - if(type != pc.LIGHTTYPE_POINT) { - shadowCamView.copy(shadowCamWtm).invert(); - shadowCamViewProj.mul2(shadowCam.getProjectionMatrix(), shadowCamView); - light._shadowMatrix.mul2(scaleShift, shadowCamViewProj); - shadowCam._node.worldTransform.copy(shadowCamWtm) - } - var opChan = "r"; - for(pass = 0;pass < passes;pass++) { - if(type === pc.LIGHTTYPE_POINT) { - if(pass === 0) { - shadowCam._node.setEulerAngles(0, 90, 180) - }else { - if(pass === 1) { - shadowCam._node.setEulerAngles(0, -90, 180) - }else { - if(pass === 2) { - shadowCam._node.setEulerAngles(90, 0, 0) - }else { - if(pass === 3) { - shadowCam._node.setEulerAngles(-90, 0, 0) - }else { - if(pass === 4) { - shadowCam._node.setEulerAngles(0, 180, 180) - }else { - if(pass === 5) { - shadowCam._node.setEulerAngles(0, 0, 180) - } - } - } - } - } - } - shadowCam._node.setPosition(light._node.getPosition()); - shadowCam.setRenderTarget(light._shadowCubeMap[pass]) - } - this.setCamera(shadowCam, type !== pc.LIGHTTYPE_POINT); - device.setBlending(false); - device.setColorWrite(true, true, true, true); - device.setDepthWrite(true); - device.setDepthTest(true); - if(device.extDepthTexture) { - device.setColorWrite(false, false, false, false) - } - for(j = 0, numInstances = shadowCasters.length;j < numInstances;j++) { - meshInstance = shadowCasters[j]; - mesh = meshInstance.mesh; - material = meshInstance.material; - device.setCullMode(material.cull); - this.modelMatrixId.setValue(meshInstance.node.worldTransform.data); - if(material.opacityMap) { - scope.resolve("texture_opacityMap").setValue(material.opacityMap); - if(material.opacityMapChannel) { - opChan = material.opacityMapChannel - } - } - if(meshInstance.skinInstance) { - if(device.supportsBoneTextures) { - this.boneTextureId.setValue(meshInstance.skinInstance.boneTexture); - var w = meshInstance.skinInstance.boneTexture.width; - var h = meshInstance.skinInstance.boneTexture.height; - this.boneTextureSizeId.setValue([w, h]) - }else { - this.poseMatrixId.setValue(meshInstance.skinInstance.matrixPalette) - } - if(type === pc.LIGHTTYPE_POINT) { - device.setShader(material.opacityMap ? this._depthProgSkinOpPoint[light._shadowType][opChan] : this._depthProgSkinPoint[light._shadowType]) - }else { - device.setShader(material.opacityMap ? this._depthProgSkinOp[light._shadowType][opChan] : this._depthProgSkin[light._shadowType]) - } - }else { - if(type === pc.LIGHTTYPE_POINT) { - device.setShader(material.opacityMap ? this._depthProgStaticOpPoint[light._shadowType][opChan] : this._depthProgStaticPoint[light._shadowType]) - }else { - device.setShader(material.opacityMap ? this._depthProgStaticOp[light._shadowType][opChan] : this._depthProgStatic[light._shadowType]) - } - } - style = meshInstance.renderStyle; - device.setVertexBuffer(mesh.vertexBuffer, 0); - device.setIndexBuffer(mesh.indexBuffer[style]); - device.draw(mesh.primitive[style]); - scene.shadowDrawCalls++ - } - } - } - } - this.setCamera(camera); - this.dispatchGlobalLights(scene); - if(scene.fog !== pc.FOG_NONE) { - this.fogColor[0] = scene.fogColor.r; - this.fogColor[1] = scene.fogColor.g; - this.fogColor[2] = scene.fogColor.b; - if(scene.gammaCorrection) { - for(i = 0;i < 3;i++) { - this.fogColor[i] = Math.pow(this.fogColor[i], 2.2) - } - } - this.fogColorId.setValue(this.fogColor); - if(scene.fog === pc.FOG_LINEAR) { - this.fogStartId.setValue(scene.fogStart); - this.fogEndId.setValue(scene.fogEnd) - }else { - this.fogDensityId.setValue(scene.fogDensity) - } - } - var k; - if(!pc._instanceVertexFormat) { - var formatDesc = [{semantic:pc.SEMANTIC_TEXCOORD2, components:4, type:pc.ELEMENTTYPE_FLOAT32}, {semantic:pc.SEMANTIC_TEXCOORD3, components:4, type:pc.ELEMENTTYPE_FLOAT32}, {semantic:pc.SEMANTIC_TEXCOORD4, components:4, type:pc.ELEMENTTYPE_FLOAT32}, {semantic:pc.SEMANTIC_TEXCOORD5, components:4, type:pc.ELEMENTTYPE_FLOAT32}]; - pc._instanceVertexFormat = new pc.VertexFormat(device, formatDesc) - } - if(device.enableAutoInstancing) { - if(!pc._autoInstanceBuffer) { - pc._autoInstanceBuffer = new pc.VertexBuffer(device, pc._instanceVertexFormat, device.autoInstancingMaxObjects, pc.BUFFER_DYNAMIC); - pc._autoInstanceBufferData = new Float32Array(pc._autoInstanceBuffer.lock()) - } - } - var next; - var autoInstances; - var j; - var objDefs, prevObjDefs, lightMask, prevLightMask; - for(i = 0;i < drawCallsCount;i++) { - drawCall = drawCalls[i]; - if(drawCall.command) { - drawCall.command() - }else { - meshInstance = drawCall; - mesh = meshInstance.mesh; - material = meshInstance.material; - objDefs = meshInstance._shaderDefs; - lightMask = meshInstance.mask; - if(device.enableAutoInstancing && i !== drawCallsCount - 1 && material.useInstancing) { - next = i + 1; - autoInstances = 0; - if(drawCalls[next].mesh === mesh && drawCalls[next].material === material) { - for(j = 0;j < 16;j++) { - pc._autoInstanceBufferData[j] = drawCall.node.worldTransform.data[j] - } - autoInstances = 1; - while(next !== drawCallsCount && drawCalls[next].mesh === mesh && drawCalls[next].material === material) { - for(j = 0;j < 16;j++) { - pc._autoInstanceBufferData[autoInstances * 16 + j] = drawCalls[next].node.worldTransform.data[j] - } - autoInstances++; - next++ - } - meshInstance.instancingData = {}; - meshInstance.instancingData.count = autoInstances; - meshInstance.instancingData._buffer = pc._autoInstanceBuffer; - meshInstance.instancingData._buffer.unlock(); - i = next - 1 - } - } - if(meshInstance.instancingData && device.extInstancing) { - if(!meshInstance.instancingData._buffer) { - meshInstance.instancingData._buffer = new pc.VertexBuffer(device, pc._instanceVertexFormat, drawCall.instancingData.count, drawCall.instancingData.usage, meshInstance.instancingData.buffer) - } - }else { - var modelMatrix = meshInstance.node.worldTransform; - var normalMatrix = meshInstance.normalMatrix; - modelMatrix.invertTo3x3(normalMatrix); - normalMatrix.transpose(); - this.modelMatrixId.setValue(modelMatrix.data); - this.normalMatrixId.setValue(normalMatrix.data) - } - if(meshInstance.skinInstance) { - if(device.supportsBoneTextures) { - this.boneTextureId.setValue(meshInstance.skinInstance.boneTexture); - var w = meshInstance.skinInstance.boneTexture.width; - var h = meshInstance.skinInstance.boneTexture.height; - this.boneTextureSizeId.setValue([w, h]) - }else { - this.poseMatrixId.setValue(meshInstance.skinInstance.matrixPalette) - } - } - if(material && material === prevMaterial && objDefs !== prevObjDefs) { - prevMaterial = null - } - if(material !== prevMaterial) { - if(!meshInstance._shader) { - meshInstance._shader = material.variants[objDefs]; - if(!meshInstance._shader) { - material.updateShader(device, scene, objDefs); - meshInstance._shader = material.variants[objDefs] = material.shader - } - } - device.setShader(meshInstance._shader); - var parameters = material.parameters; - for(var paramName in parameters) { - var parameter = parameters[paramName]; - if(!parameter.scopeId) { - parameter.scopeId = device.scope.resolve(paramName) - } - parameter.scopeId.setValue(parameter.data) - } - if(!prevMaterial || lightMask !== prevLightMask) { - this._activeShadowLights = []; - usedDirLights = this.dispatchDirectLights(scene, lightMask); - this.dispatchLocalLights(scene, lightMask, usedDirLights) - } - if(material.shadowSampleType !== undefined) { - for(k = 0;k < this._activeShadowLights.length;k++) { - if(this._activeShadowLights[k]._shadowType === pc.SHADOW_DEPTHMASK) { - if(material.shadowSampleType === pc.SHADOWSAMPLE_MASK) { - this._activeShadowLights[k]._shadowCamera._renderTarget.colorBuffer.minFilter = pc.FILTER_LINEAR; - this._activeShadowLights[k]._shadowCamera._renderTarget.colorBuffer.magFilter = pc.FILTER_LINEAR - }else { - this._activeShadowLights[k]._shadowCamera._renderTarget.colorBuffer.minFilter = pc.FILTER_NEAREST; - this._activeShadowLights[k]._shadowCamera._renderTarget.colorBuffer.magFilter = pc.FILTER_NEAREST - } - } - } - } - this.alphaTestId.setValue(material.alphaTest); - device.setBlending(material.blend); - device.setBlendFunction(material.blendSrc, material.blendDst); - device.setBlendEquation(material.blendEquation); - device.setColorWrite(material.redWrite, material.greenWrite, material.blueWrite, material.alphaWrite); - device.setCullMode(material.cull); - device.setDepthWrite(material.depthWrite); - device.setDepthTest(material.depthTest) - } - device.setVertexBuffer(mesh.vertexBuffer, 0); - style = meshInstance.renderStyle; - device.setIndexBuffer(mesh.indexBuffer[style]); - if(meshInstance.instancingData) { - device.setVertexBuffer(meshInstance.instancingData._buffer, 1); - device.draw(mesh.primitive[style], drawCall.instancingData.count); - if(meshInstance.instancingData._buffer === pc._autoInstanceBuffer) { - meshInstance.instancingData = null - } - }else { - device.draw(mesh.primitive[style]) - } - scene.forwardDrawCalls++; - prevMaterial = material; - prevMeshInstance = meshInstance; - prevObjDefs = objDefs; - prevLightMask = lightMask - } - } - if(scene.immediateDrawCalls.length > 0) { - scene.immediateDrawCalls = [] - } - }}); - return{ForwardRenderer:ForwardRenderer} -}()); -pc.extend(pc, function() { - var GraphNode = function GraphNode() { - this.name = "Untitled"; - this._labels = {}; - this.localPosition = new pc.Vec3(0, 0, 0); - this.localRotation = new pc.Quat(0, 0, 0, 1); - this.localScale = new pc.Vec3(1, 1, 1); - this.localEulerAngles = new pc.Vec3(0, 0, 0); - this.position = new pc.Vec3(0, 0, 0); - this.rotation = new pc.Quat(0, 0, 0, 1); - this.eulerAngles = new pc.Vec3(0, 0, 0); - this.localTransform = new pc.Mat4; - this.dirtyLocal = false; - this.worldTransform = new pc.Mat4; - this.dirtyWorld = false; - this._right = new pc.Vec3; - this._up = new pc.Vec3; - this._forward = new pc.Vec3; - this._parent = null; - this._children = []; - this._enabled = true; - this._enabledInHierarchy = true - }; - Object.defineProperty(GraphNode.prototype, "right", {get:function() { - return this.getWorldTransform().getX(this._right).normalize() - }}); - Object.defineProperty(GraphNode.prototype, "up", {get:function() { - return this.getWorldTransform().getY(this._up).normalize() - }}); - Object.defineProperty(GraphNode.prototype, "forward", {get:function() { - return this.getWorldTransform().getZ(this._forward).normalize().scale(-1) - }}); - Object.defineProperty(GraphNode.prototype, "forwards", {get:function() { - console.log("pc.GraphNode#forwards is DEPRECATED. Use pc.GraphNode#forward instead."); - return this.forward - }}); - Object.defineProperty(GraphNode.prototype, "enabled", {get:function() { - return this._enabled && this._enabledInHierarchy - }, set:function(enabled) { - if(this._enabled !== enabled) { - this._enabled = enabled; - if(!this._parent || this._parent.enabled) { - this._notifyHierarchyStateChanged(this, enabled) - } - } - }}); - pc.extend(GraphNode.prototype, {_notifyHierarchyStateChanged:function(node, enabled) { - node._onHierarchyStateChanged(enabled); - var c = node._children; - for(var i = 0, len = c.length;i < len;i++) { - if(c[i]._enabled) { - this._notifyHierarchyStateChanged(c[i], enabled) - } - } - }, _onHierarchyStateChanged:function(enabled) { - this._enabledInHierarchy = enabled - }, _cloneInternal:function(clone) { - clone.name = this.name; - clone._labels = pc.extend(this._labels, {}); - clone.localPosition.copy(this.localPosition); - clone.localRotation.copy(this.localRotation); - clone.localScale.copy(this.localScale); - clone.localEulerAngles.copy(this.localEulerAngles); - clone.position.copy(this.position); - clone.rotation.copy(this.rotation); - clone.eulerAngles.copy(this.eulerAngles); - clone.localTransform.copy(this.localTransform); - clone.dirtyLocal = this.dirtyLocal; - clone.worldTransform.copy(this.worldTransform); - clone.dirtyWorld = this.dirtyWorld; - clone._enabled = this._enabled; - clone._enabledInHierarchy = this._enabledInHierarchy - }, clone:function() { - var clone = new pc.GraphNode; - this._cloneInternal(clone); - return clone - }, find:function(attr, value) { - var i; - var children = this.getChildren(); - var length = children.length; - var results = []; - var testValue; - if(this[attr]) { - if(this[attr] instanceof Function) { - testValue = this[attr]() - }else { - testValue = this[attr] - } - if(testValue === value) { - results.push(this) - } - } - for(i = 0;i < length;++i) { - results = results.concat(children[i].find(attr, value)) - } - return results - }, findOne:function(attr, value) { - var i; - var children = this.getChildren(); - var length = children.length; - var result = null; - var testValue; - if(this[attr]) { - if(this[attr] instanceof Function) { - testValue = this[attr]() - }else { - testValue = this[attr] - } - if(testValue === value) { - return this - } - } - for(i = 0;i < length;++i) { - result = children[i].findOne(attr, value); - if(result !== null) { - return result - } - } - return null - }, findByName:function(name) { - if(this.name === name) { - return this - } - for(var i = 0;i < this._children.length;i++) { - var found = this._children[i].findByName(name); - if(found !== null) { - return found - } - } - return null - }, findByPath:function(path) { - var parts = path.split("/"); - var currentParent = this; - var result = null; - for(var i = 0, imax = parts.length;i < imax && currentParent;i++) { - var part = parts[i]; - result = null; - var children = currentParent._children; - for(var j = 0, jmax = children.length;j < jmax;j++) { - if(children[j].name == part) { - result = children[j]; - break - } - } - currentParent = result - } - return result - }, getPath:function() { - var parent = this._parent; - if(parent) { - var path = this.name; - var format = "{0}/{1}"; - while(parent && parent._parent) { - path = pc.string.format(format, parent.name, path); - parent = parent._parent - } - return path - }else { - return"" - } - }, getRoot:function() { - var parent = this.getParent(); - if(!parent) { - return this - } - while(parent.getParent()) { - parent = parent.getParent() - } - return parent - }, getParent:function() { - return this._parent - }, getChildren:function() { - return this._children - }, getEulerAngles:function() { - this.getWorldTransform().getEulerAngles(this.eulerAngles); - return this.eulerAngles - }, getLocalEulerAngles:function() { - this.localRotation.getEulerAngles(this.localEulerAngles); - return this.localEulerAngles - }, getLocalPosition:function() { - return this.localPosition - }, getLocalRotation:function() { - return this.localRotation - }, getLocalScale:function() { - return this.localScale - }, getLocalTransform:function() { - if(this.dirtyLocal) { - this.localTransform.setTRS(this.localPosition, this.localRotation, this.localScale); - this.dirtyLocal = false; - this.dirtyWorld = true - } - return this.localTransform - }, getName:function() { - return this.name - }, getPosition:function() { - this.getWorldTransform().getTranslation(this.position); - return this.position - }, getRotation:function() { - this.rotation.setFromMat4(this.getWorldTransform()); - return this.rotation - }, getWorldTransform:function() { - var syncList = []; - return function() { - var current = this; - syncList.length = 0; - while(current !== null) { - syncList.push(current); - current = current._parent - } - for(var i = syncList.length - 1;i >= 0;i--) { - syncList[i].sync() - } - return this.worldTransform - } - }(), reparent:function(parent, index) { - var current = this.getParent(); - if(current) { - current.removeChild(this) - } - if(parent) { - if(index >= 0) { - parent.insertChild(this, index) - }else { - parent.addChild(this) - } - } - }, setLocalEulerAngles:function() { - var ex, ey, ez; - switch(arguments.length) { - case 1: - ex = arguments[0].x; - ey = arguments[0].y; - ez = arguments[0].z; - break; - case 3: - ex = arguments[0]; - ey = arguments[1]; - ez = arguments[2]; - break - } - this.localRotation.setFromEulerAngles(ex, ey, ez); - this.dirtyLocal = true - }, setLocalPosition:function() { - if(arguments.length === 1) { - this.localPosition.copy(arguments[0]) - }else { - this.localPosition.set(arguments[0], arguments[1], arguments[2]) - } - this.dirtyLocal = true - }, setLocalRotation:function(q) { - if(arguments.length === 1) { - this.localRotation.copy(arguments[0]) - }else { - this.localRotation.set(arguments[0], arguments[1], arguments[2], arguments[3]) - } - this.dirtyLocal = true - }, setLocalScale:function() { - if(arguments.length === 1) { - this.localScale.copy(arguments[0]) - }else { - this.localScale.set(arguments[0], arguments[1], arguments[2]) - } - this.dirtyLocal = true - }, setName:function(name) { - this.name = name - }, setPosition:function() { - var position = new pc.Vec3; - var invParentWtm = new pc.Mat4; - return function() { - if(arguments.length === 1) { - position.copy(arguments[0]) - }else { - position.set(arguments[0], arguments[1], arguments[2]) - } - if(this._parent === null) { - this.localPosition.copy(position) - }else { - invParentWtm.copy(this._parent.getWorldTransform()).invert(); - invParentWtm.transformPoint(position, this.localPosition) - } - this.dirtyLocal = true - } - }(), setRotation:function() { - var rotation = new pc.Quat; - var invParentRot = new pc.Quat; - return function() { - if(arguments.length === 1) { - rotation.copy(arguments[0]) - }else { - rotation.set(arguments[0], arguments[1], arguments[2], arguments[3]) - } - if(this._parent === null) { - this.localRotation.copy(rotation) - }else { - var parentRot = this._parent.getRotation(); - invParentRot.copy(parentRot).invert(); - this.localRotation.copy(invParentRot).mul(rotation) - } - this.dirtyLocal = true - } - }(), setEulerAngles:function() { - var invParentRot = new pc.Quat; - return function() { - var ex, ey, ez; - switch(arguments.length) { - case 1: - ex = arguments[0].x; - ey = arguments[0].y; - ez = arguments[0].z; - break; - case 3: - ex = arguments[0]; - ey = arguments[1]; - ez = arguments[2]; - break - } - this.localRotation.setFromEulerAngles(ex, ey, ez); - if(this._parent !== null) { - var parentRot = this._parent.getRotation(); - invParentRot.copy(parentRot).invert(); - this.localRotation.mul2(invParentRot, this.localRotation) - } - this.dirtyLocal = true - } - }(), addChild:function(node) { - if(node.getParent() !== null) { - throw new Error("GraphNode is already parented"); - } - this._children.push(node); - this._onInsertChild(node) - }, addChildAndSaveTransform:function(node) { - var wPos = node.getPosition(); - var wRot = node.getRotation(); - var current = node.getParent(); - if(current) { - current.removeChild(node) - } - if(this.tmpMat4 == undefined) { - this.tmpMat4 = new pc.Mat4; - this.tmpQuat = new pc.Quat - } - node.setPosition(this.tmpMat4.copy(this.worldTransform).invert().transformPoint(wPos)); - node.setRotation(this.tmpQuat.copy(this.getRotation()).invert().mul(wRot)); - this._children.push(node); - this._onInsertChild(node) - }, insertChild:function(node, index) { - if(node.getParent() !== null) { - throw new Error("GraphNode is already parented"); - } - this._children.splice(index, 0, node); - this._onInsertChild(node) - }, _onInsertChild:function(node) { - node._parent = this; - var enabledInHierarchy = node._enabled && this.enabled; - if(node._enabledInHierarchy !== enabledInHierarchy) { - node._enabledInHierarchy = enabledInHierarchy; - node._notifyHierarchyStateChanged(node, enabledInHierarchy) - } - node.dirtyWorld = true - }, removeChild:function(child) { - var i; - var length = this._children.length; - child._parent = null; - for(i = 0;i < length;++i) { - if(this._children[i] === child) { - this._children.splice(i, 1); - return - } - } - }, addLabel:function(label) { - this._labels[label] = true - }, getLabels:function() { - return Object.keys(this._labels) - }, hasLabel:function(label) { - return!!this._labels[label] - }, removeLabel:function(label) { - delete this._labels[label] - }, findByLabel:function(label, results) { - var i, length = this._children.length; - results = results || []; - if(this.hasLabel(label)) { - results.push(this) - } - for(i = 0;i < length;++i) { - results = this._children[i].findByLabel(label, results) - } - return results - }, sync:function() { - if(this.dirtyLocal) { - this.localTransform.setTRS(this.localPosition, this.localRotation, this.localScale); - this.dirtyLocal = false; - this.dirtyWorld = true - } - if(this.dirtyWorld) { - if(this._parent === null) { - this.worldTransform.copy(this.localTransform) - }else { - this.worldTransform.mul2(this._parent.worldTransform, this.localTransform) - } - this.dirtyWorld = false; - for(var i = 0, len = this._children.length;i < len;i++) { - this._children[i].dirtyWorld = true - } - } - }, syncHierarchy:function() { - var F = function() { - if(!this._enabled) { - return - } - this.sync(); - var c = this._children; - for(var i = 0, len = c.length;i < len;i++) { - F.call(c[i]) - } - }; - return F - }(), lookAt:function() { - var matrix = new pc.Mat4; - var target = new pc.Vec3; - var up = new pc.Vec3; - var rotation = new pc.Quat; - return function() { - switch(arguments.length) { - case 1: - target.copy(arguments[0]); - up.copy(pc.Vec3.UP); - break; - case 2: - target.copy(arguments[0]); - up.copy(arguments[1]); - break; - case 3: - target.set(arguments[0], arguments[1], arguments[2]); - up.copy(pc.Vec3.UP); - break; - case 6: - target.set(arguments[0], arguments[1], arguments[2]); - up.set(arguments[3], arguments[4], arguments[5]); - break - } - matrix.setLookAt(this.getPosition(), target, up); - rotation.setFromMat4(matrix); - this.setRotation(rotation) - } - }(), translate:function() { - var translation = new pc.Vec3; - return function() { - switch(arguments.length) { - case 1: - translation.copy(arguments[0]); - break; - case 3: - translation.set(arguments[0], arguments[1], arguments[2]); - break - } - translation.add(this.getPosition()); - this.setPosition(translation) - } - }(), translateLocal:function() { - var translation = new pc.Vec3; - return function() { - switch(arguments.length) { - case 1: - translation.copy(arguments[0]); - break; - case 3: - translation.set(arguments[0], arguments[1], arguments[2]); - break - } - this.localRotation.transformVector(translation, translation); - this.localPosition.add(translation); - this.dirtyLocal = true - } - }(), rotate:function() { - var quaternion = new pc.Quat; - var invParentRot = new pc.Quat; - return function() { - var ex, ey, ez; - switch(arguments.length) { - case 1: - ex = arguments[0].x; - ey = arguments[0].y; - ez = arguments[0].z; - break; - case 3: - ex = arguments[0]; - ey = arguments[1]; - ez = arguments[2]; - break - } - quaternion.setFromEulerAngles(ex, ey, ez); - if(this._parent === null) { - this.localRotation.mul2(quaternion, this.localRotation) - }else { - var rot = this.getRotation(); - var parentRot = this._parent.getRotation(); - invParentRot.copy(parentRot).invert(); - quaternion.mul2(invParentRot, quaternion); - this.localRotation.mul2(quaternion, rot) - } - this.dirtyLocal = true - } - }(), rotateLocal:function() { - var quaternion = new pc.Quat; - return function() { - var ex, ey, ez; - switch(arguments.length) { - case 1: - ex = arguments[0].x; - ey = arguments[0].y; - ez = arguments[0].z; - break; - case 3: - ex = arguments[0]; - ey = arguments[1]; - ez = arguments[2]; - break - } - quaternion.setFromEulerAngles(ex, ey, ez); - this.localRotation.mul(quaternion); - this.dirtyLocal = true - } - }()}); - return{GraphNode:GraphNode} -}()); -pc.extend(pc, function() { - var Camera = function() { - this._projection = pc.PROJECTION_PERSPECTIVE; - this._nearClip = 0.1; - this._farClip = 1E4; - this._fov = 45; - this._orthoHeight = 10; - this._aspect = 16 / 9; - this.frustumCulling = false; - this._projMatDirty = true; - this._projMat = new pc.Mat4; - this._viewMat = new pc.Mat4; - this._viewProjMat = new pc.Mat4; - this._rect = {x:0, y:0, width:1, height:1}; - this._frustum = new pc.Frustum(this._projMat, this._viewMat); - this._renderTarget = null; - this._clearOptions = {color:[186 / 255, 186 / 255, 177 / 255, 1], depth:1, flags:pc.CLEARFLAG_COLOR | pc.CLEARFLAG_DEPTH}; - this._node = null - }; - Camera.prototype = {clone:function() { - var clone = new pc.Camera; - clone.setProjection(this.getProjection()); - clone.setNearClip(this.getNearClip()); - clone.setFarClip(this.getFarClip()); - clone.setFov(this.getFov()); - clone.setAspectRatio(this.getAspectRatio()); - clone.setRenderTarget(this.getRenderTarget()); - clone.setClearOptions(this.getClearOptions()); - clone.frustumCulling = this.frustumCulling; - return clone - }, worldToScreen:function(worldCoord, cw, ch, screenCoord) { - if(screenCoord === undefined) { - screenCoord = new pc.Vec3 - } - var projMat = this.getProjectionMatrix(); - var wtm = this._node.getWorldTransform(); - this._viewMat.copy(wtm).invert(); - this._viewProjMat.mul2(projMat, this._viewMat); - this._viewProjMat.transformPoint(worldCoord, screenCoord); - var wp = worldCoord.data; - var vpm = this._viewProjMat.data; - var w = wp[0] * vpm[3] + wp[1] * vpm[7] + wp[2] * vpm[11] + 1 * vpm[15]; - screenCoord.x = (screenCoord.x / w + 1) * 0.5 * cw; - screenCoord.y = (1 - screenCoord.y / w) * 0.5 * ch; - return screenCoord - }, screenToWorld:function(x, y, z, cw, ch, worldCoord) { - if(worldCoord === undefined) { - worldCoord = new pc.Vec3 - } - var projMat = this.getProjectionMatrix(); - var wtm = this._node.getWorldTransform(); - this._viewMat.copy(wtm).invert(); - this._viewProjMat.mul2(projMat, this._viewMat); - var invViewProjMat = this._viewProjMat.clone().invert(); - if(this._projection === pc.PROJECTION_PERSPECTIVE) { - var far = new pc.Vec3(x / cw * 2 - 1, (ch - y) / ch * 2 - 1, 1); - var farW = invViewProjMat.transformPoint(far); - var w = far.x * invViewProjMat.data[3] + far.y * invViewProjMat.data[7] + far.z * invViewProjMat.data[11] + invViewProjMat.data[15]; - farW.scale(1 / w); - var alpha = z / this._farClip; - worldCoord.lerp(this._node.getPosition(), farW, alpha) - }else { - var range = this._farClip - this._nearClip; - var deviceCoord = new pc.Vec3(x / cw * 2 - 1, (ch - y) / ch * 2 - 1, (this._farClip - z) / range * 2 - 1); - invViewProjMat.transformPoint(deviceCoord, worldCoord) - } - return worldCoord - }, getAspectRatio:function() { - return this._aspect - }, getClearOptions:function() { - return this._clearOptions - }, getFarClip:function() { - return this._farClip - }, getFov:function() { - return this._fov - }, getFrustum:function() { - return this._frustum - }, getNearClip:function() { - return this._nearClip - }, getOrthoHeight:function() { - return this._orthoHeight - }, getProjection:function() { - return this._projection - }, getProjectionMatrix:function() { - if(this._projMatDirty) { - if(this._projection === pc.PROJECTION_PERSPECTIVE) { - this._projMat.setPerspective(this._fov, this._aspect, this._nearClip, this._farClip) - }else { - var y = this._orthoHeight; - var x = y * this._aspect; - this._projMat.setOrtho(-x, x, -y, y, this._nearClip, this._farClip) - } - this._projMatDirty = false - } - return this._projMat - }, getRect:function() { - return this._rect - }, getRenderTarget:function() { - return this._renderTarget - }, setAspectRatio:function(aspect) { - this._aspect = aspect; - this._projMatDirty = true - }, setClearOptions:function(options) { - this._clearOptions = options - }, setFarClip:function(far) { - this._farClip = far; - this._projMatDirty = true - }, setFov:function(fov) { - this._fov = fov; - this._projMatDirty = true - }, setNearClip:function(near) { - this._nearClip = near; - this._projMatDirty = true - }, setOrthoHeight:function(height) { - this._orthoHeight = height; - this._projMatDirty = true - }, setProjection:function(type) { - this._projection = type; - this._projMatDirty = true - }, setRect:function(x, y, width, height) { - this._rect.x = x; - this._rect.y = y; - this._rect.width = width; - this._rect.height = height - }, setRenderTarget:function(target) { - this._renderTarget = target - }}; - return{Camera:Camera} -}()); -pc.extend(pc, function() { - var Light = function Light() { - this._type = pc.LIGHTTYPE_DIRECTIONAL; - this._color = new pc.Color(0.8, 0.8, 0.8); - this._intensity = 1; - this._castShadows = false; - this._enabled = false; - this._attenuationStart = 10; - this._attenuationEnd = 10; - this._falloffMode = 0; - this._shadowType = pc.SHADOW_DEPTH; - this.mask = 1; - this._innerConeAngle = 40; - this._outerConeAngle = 45; - this._finalColor = new pc.Vec3(0.8, 0.8, 0.8); - this._linearFinalColor = new pc.Vec3; - this._position = new pc.Vec3(0, 0, 0); - this._direction = new pc.Vec3(0, 0, 0); - this._innerConeAngleCos = Math.cos(this._innerConeAngle * Math.PI / 180); - this._outerConeAngleCos = Math.cos(this._outerConeAngle * Math.PI / 180); - this._shadowCamera = null; - this._shadowMatrix = new pc.Mat4; - this._shadowDistance = 40; - this._shadowResolution = 1024; - this._shadowBias = -5E-4; - this._normalOffsetBias = 0; - this.shadowUpdateMode = pc.SHADOWUPDATE_REALTIME; - this._scene = null; - this._node = null - }; - Light.prototype = {clone:function() { - var clone = new pc.Light; - clone.setType(this.getType()); - clone.setColor(this.getColor()); - clone.setIntensity(this.getIntensity()); - clone.setCastShadows(this.getCastShadows()); - clone.setEnabled(this.getEnabled()); - clone.setAttenuationStart(this.getAttenuationStart()); - clone.setAttenuationEnd(this.getAttenuationEnd()); - clone.setFalloffMode(this.getFalloffMode()); - clone.setShadowType(this.getShadowType()); - clone.shadowUpdateMode = this.shadowUpdateMode; - clone.mask = this.mask; - clone.setInnerConeAngle(this.getInnerConeAngle()); - clone.setOuterConeAngle(this.getOuterConeAngle()); - clone.setShadowBias(this.getShadowBias()); - clone.setNormalOffsetBias(this.getNormalOffsetBias()); - clone.setShadowResolution(this.getShadowResolution()); - clone.setShadowDistance(this.getShadowDistance()); - return clone - }, getAttenuationEnd:function() { - return this._attenuationEnd - }, getAttenuationStart:function() { - return this._attenuationStart - }, getFalloffMode:function() { - return this._falloffMode - }, getShadowType:function() { - return this._shadowType - }, getCastShadows:function() { - return this._castShadows - }, getColor:function() { - return this._color - }, getEnabled:function() { - return this._enabled - }, getInnerConeAngle:function() { - return this._innerConeAngle - }, getIntensity:function() { - return this._intensity - }, getOuterConeAngle:function() { - return this._outerConeAngle - }, getShadowBias:function() { - return this._shadowBias - }, getNormalOffsetBias:function() { - return this._normalOffsetBias - }, getShadowDistance:function() { - return this._shadowDistance - }, getShadowResolution:function() { - return this._shadowResolution - }, getType:function() { - return this._type - }, setAttenuationEnd:function(radius) { - this._attenuationEnd = radius - }, setAttenuationStart:function(radius) { - this._attenuationStart = radius - }, setFalloffMode:function(mode) { - this._falloffMode = mode; - if(this._scene !== null) { - this._scene.updateShaders = true - } - }, setShadowType:function(mode) { - this._shadowType = mode; - if(this._scene !== null) { - this._scene.updateShaders = true - } - }, setCastShadows:function(castShadows) { - this._castShadows = castShadows; - if(this._scene !== null) { - this._scene.updateShaders = true - } - }, setColor:function() { - var r, g, b; - if(arguments.length === 1) { - r = arguments[0].r; - g = arguments[0].g; - b = arguments[0].b - }else { - if(arguments.length === 3) { - r = arguments[0]; - g = arguments[1]; - b = arguments[2] - } - } - this._color.set(r, g, b); - var i = this._intensity; - this._finalColor.set(r * i, g * i, b * i); - for(var c = 0;c < 3;c++) { - if(i >= 1) { - this._linearFinalColor.data[c] = Math.pow(this._finalColor.data[c] / i, 2.2) * i - }else { - this._linearFinalColor.data[c] = Math.pow(this._finalColor.data[c], 2.2) - } - } - }, setEnabled:function(enable) { - if(this._enabled !== enable) { - this._enabled = enable; - if(this._scene !== null) { - this._scene.updateShaders = true - } - } - }, setInnerConeAngle:function(angle) { - this._innerConeAngle = angle; - this._innerConeAngleCos = Math.cos(angle * Math.PI / 180) - }, setIntensity:function(intensity) { - this._intensity = intensity; - var c = this._color; - var r = c.r; - var g = c.g; - var b = c.b; - var i = this._intensity; - this._finalColor.set(r * i, g * i, b * i); - for(var j = 0;j < 3;j++) { - if(i >= 1) { - this._linearFinalColor.data[j] = Math.pow(this._finalColor.data[j] / i, 2.2) * i - }else { - this._linearFinalColor.data[j] = Math.pow(this._finalColor.data[j], 2.2) - } - } - }, setOuterConeAngle:function(angle) { - this._outerConeAngle = angle; - this._outerConeAngleCos = Math.cos(angle * Math.PI / 180) - }, setShadowBias:function(bias) { - this._shadowBias = bias - }, setNormalOffsetBias:function(bias) { - if(!this._normalOffsetBias && bias || this._normalOffsetBias && !bias) { - this._scene.updateShaders = true - } - this._normalOffsetBias = bias - }, setShadowDistance:function(distance) { - this._shadowDistance = distance - }, setShadowResolution:function(resolution) { - this._shadowResolution = resolution - }, setType:function(type) { - this._type = type - }, updateShadow:function() { - if(this.shadowUpdateMode !== pc.SHADOWUPDATE_REALTIME) { - this.shadowUpdateMode = pc.SHADOWUPDATE_THISFRAME - } - }}; - return{Light:Light} -}()); -pc.extend(pc, function() { - var id = 0; - var Material = function Material() { - this.name = "Untitled"; - this.id = id++; - this.shader = null; - this.variants = {}; - this.parameters = {}; - this.alphaTest = 0; - this.blend = false; - this.blendSrc = pc.BLENDMODE_ONE; - this.blendDst = pc.BLENDMODE_ZERO; - this.blendEquation = pc.BLENDEQUATION_ADD; - this.cull = pc.CULLFACE_BACK; - this.depthTest = true; - this.depthWrite = true; - this.redWrite = true; - this.greenWrite = true; - this.blueWrite = true; - this.alphaWrite = true; - this.meshInstances = [] - }; - Object.defineProperty(Material.prototype, "blendType", {get:function() { - if(!this.blend && this.blendSrc === pc.BLENDMODE_ONE && this.blendDst === pc.BLENDMODE_ZERO && this.blendEquation === pc.BLENDEQUATION_ADD) { - return pc.BLEND_NONE - }else { - if(this.blend && this.blendSrc === pc.BLENDMODE_SRC_ALPHA && this.blendDst === pc.BLENDMODE_ONE_MINUS_SRC_ALPHA && this.blendEquation === pc.BLENDEQUATION_ADD) { - return pc.BLEND_NORMAL - }else { - if(this.blend && this.blendSrc === pc.BLENDMODE_ONE && this.blendDst === pc.BLENDMODE_ONE && this.blendEquation === pc.BLENDEQUATION_ADD) { - return pc.BLEND_ADDITIVE - }else { - if(this.blend && this.blendSrc === pc.BLENDMODE_SRC_ALPHA && this.blendDst === pc.BLENDMODE_ONE && this.blendEquation === pc.BLENDEQUATION_ADD) { - return pc.BLEND_ADDITIVEALPHA - }else { - if(this.blend && this.blendSrc === pc.BLENDMODE_DST_COLOR && this.blendDst === pc.BLENDMODE_ZERO && this.blendEquation === pc.BLENDEQUATION_ADD) { - return pc.BLEND_MULTIPLICATIVE - }else { - if(this.blend && this.blendSrc === pc.BLENDMODE_ONE && this.blendDst === pc.BLENDMODE_ONE_MINUS_SRC_ALPHA && this.blendEquation === pc.BLENDEQUATION_ADD) { - return pc.BLEND_PREMULTIPLIED - }else { - return pc.BLEND_NORMAL - } - } - } - } - } - } - }, set:function(type) { - switch(type) { - case pc.BLEND_NONE: - this.blend = false; - this.blendSrc = pc.BLENDMODE_ONE; - this.blendDst = pc.BLENDMODE_ZERO; - this.blendEquation = pc.BLENDEQUATION_ADD; - break; - case pc.BLEND_NORMAL: - this.blend = true; - this.blendSrc = pc.BLENDMODE_SRC_ALPHA; - this.blendDst = pc.BLENDMODE_ONE_MINUS_SRC_ALPHA; - this.blendEquation = pc.BLENDEQUATION_ADD; - break; - case pc.BLEND_PREMULTIPLIED: - this.blend = true; - this.blendSrc = pc.BLENDMODE_ONE; - this.blendDst = pc.BLENDMODE_ONE_MINUS_SRC_ALPHA; - this.blendEquation = pc.BLENDEQUATION_ADD; - break; - case pc.BLEND_ADDITIVE: - this.blend = true; - this.blendSrc = pc.BLENDMODE_ONE; - this.blendDst = pc.BLENDMODE_ONE; - this.blendEquation = pc.BLENDEQUATION_ADD; - break; - case pc.BLEND_ADDITIVEALPHA: - this.blend = true; - this.blendSrc = pc.BLENDMODE_SRC_ALPHA; - this.blendDst = pc.BLENDMODE_ONE; - this.blendEquation = pc.BLENDEQUATION_ADD; - break; - case pc.BLEND_MULTIPLICATIVE: - this.blend = true; - this.blendSrc = pc.BLENDMODE_DST_COLOR; - this.blendDst = pc.BLENDMODE_ZERO; - this.blendEquation = pc.BLENDEQUATION_ADD; - break - } - this._updateMeshInstanceKeys() - }}); - Material.prototype._cloneInternal = function(clone) { - clone.name = this.name; - clone.id = id++; - clone.shader = null; - clone.variants = {}; - clone.parameters = {}; - clone.alphaTest = this.alphaTest; - clone.blend = this.blend; - clone.blendSrc = this.blendSrc; - clone.blendDst = this.blendDst; - clone.blendEquation = this.blendEquation; - clone.cull = this.cull; - clone.depthTest = this.depthTest; - clone.depthWrite = this.depthWrite; - clone.redWrite = this.redWrite; - clone.greenWrite = this.greenWrite; - clone.blueWrite = this.blueWrite; - clone.alphaWrite = this.alphaWrite; - clone.meshInstances = [] - }, Material.prototype.clone = function() { - var clone = new pc.Material; - this._cloneInternal(clone); - return clone - }, Material.prototype._updateMeshInstanceKeys = function() { - var i, meshInstances = this.meshInstances; - for(var i = 0;i < meshInstances.length;i++) { - meshInstances[i].updateKey() - } - }; - Material.prototype.updateShader = function(device, scene, objDefs) { - }; - Material.prototype.getName = function() { - return this.name - }; - Material.prototype.setName = function(name) { - this.name = name - }; - Material.prototype.clearParameters = function() { - this.parameters = {} - }; - Material.prototype.getParameters = function() { - return this.parameters - }; - Material.prototype.clearVariants = function() { - this.variants = {}; - for(i = 0;i < this.meshInstances.length;i++) { - this.meshInstances[i]._shader = null - } - }; - Material.prototype.getParameter = function(name) { - return this.parameters[name] - }; - Material.prototype.setParameter = function(name, data) { - var param = this.parameters[name]; - if(param) { - param.data = data - }else { - this.parameters[name] = {scopeId:null, data:data} - } - }; - Material.prototype.deleteParameter = function(name) { - if(this.parameters[name]) { - delete this.parameters[name] - } - }; - Material.prototype.setParameters = function() { - for(var paramName in this.parameters) { - var parameter = this.parameters[paramName]; - if(!parameter.scopeId) { - parameter.scopeId = device.scope.resolve(paramName) - } - parameter.scopeId.setValue(parameter.data) - } - }; - Material.prototype.getShader = function() { - return this.shader - }; - Material.prototype.setShader = function(shader) { - this.shader = shader - }; - Material.prototype.update = function() { - throw Error("Not Implemented in base class"); - }; - Material.prototype.init = function(data) { - throw Error("Not Implemented in base class"); - }; - return{Material:Material} -}()); -pc.extend(pc, function() { - var BasicMaterial = function() { - this.color = new pc.Color(1, 1, 1, 1); - this.colorMap = null; - this.vertexColors = false; - this.update() - }; - BasicMaterial = pc.inherits(BasicMaterial, pc.Material); - pc.extend(BasicMaterial.prototype, {clone:function() { - var clone = new pc.BasicMaterial; - pc.Material.prototype._cloneInternal.call(this, clone); - clone.color.copy(this.color); - clone.colorMap = this.colorMap; - clone.vertexColors = this.vertexColors; - clone.update(); - return clone - }, update:function() { - this.clearParameters(); - this.setParameter("uColor", this.color.data); - if(this.colorMap) { - this.setParameter("texture_diffuseMap", this.colorMap) - } - }, updateShader:function(device) { - var options = {skin:!!this.meshInstances[0].skinInstance, vertexColors:this.vertexColors, diffuseMap:this.colorMap}; - var library = device.getProgramLibrary(); - this.shader = library.getProgram("basic", options) - }}); - return{BasicMaterial:BasicMaterial} -}()); -pc.extend(pc, function() { - var DepthMaterial = function() { - }; - DepthMaterial = pc.inherits(DepthMaterial, pc.Material); - pc.extend(DepthMaterial.prototype, {clone:function() { - var clone = new pc.DepthMaterial; - Material.prototype._cloneInternal.call(this, clone); - clone.update(); - return clone - }, update:function() { - }, updateShader:function(device) { - var options = {skin:!!this.meshInstances[0].skinInstance}; - var library = device.getProgramLibrary(); - this.shader = library.getProgram("depth", options) - }}); - return{DepthMaterial:DepthMaterial} -}()); -pc.extend(pc, function() { - var _tempTiling = new pc.Vec3; - var _tempOffset = new pc.Vec3; - var PhongMaterial = function() { - this.reset(); - this.update() - }; - var _createTexture = function(param) { - if(param.data) { - if(param.data instanceof pc.Texture) { - return param.data - }else { - return null - } - }else { - return null - } - }; - var _createCubemap = function(param) { - if(param.data) { - if(param.data instanceof pc.Texture) { - return param.data - } - } - return null - }; - var _createVec2 = function(param) { - return new pc.Vec2(param.data[0], param.data[1]) - }; - var _createVec3 = function(param) { - return new pc.Vec3(param.data[0], param.data[1], param.data[2]) - }; - var _createRgb = function(param) { - return new pc.Color(param.data[0], param.data[1], param.data[2]) - }; - var _beginProperties = function(obj) { - if(!pc._matSerialProps) { - obj._tempProps = []; - for(var p in obj) { - if(obj.hasOwnProperty(p)) { - obj._tempProps[p] = true - } - } - } - }; - var _endProperties = function(obj) { - if(!pc._matSerialProps) { - pc._matSerialProps = []; - for(var p in obj) { - if(obj.hasOwnProperty(p) && !obj._tempProps[p]) { - pc._matSerialProps.push(p) - } - } - } - }; - var _defineTex2D = function(obj, name, uv, channels) { - obj[name + "Map"] = null; - obj[name + "MapTiling"] = new pc.Vec2(1, 1); - obj[name + "MapOffset"] = new pc.Vec2(0, 0); - obj[name + "MapTransform"] = null; - obj[name + "MapUv"] = uv; - if(channels > 0) { - obj[name + "MapChannel"] = channels > 1 ? "rgb" : "g" - } - obj[name + "MapVertexColor"] = false; - if(!pc._matTex2D) { - pc._matTex2D = [] - } - pc._matTex2D[name] = channels - }; - PhongMaterial = pc.inherits(PhongMaterial, pc.Material); - pc.extend(PhongMaterial.prototype, {reset:function() { - _beginProperties(this); - this.ambient = new pc.Color(0.7, 0.7, 0.7); - this.diffuse = new pc.Color(1, 1, 1); - this.specular = new pc.Color(0, 0, 0); - this.shininess = 25; - this.emissive = new pc.Color(0, 0, 0); - this.opacity = 1; - this.blendType = pc.BLEND_NONE; - this.alphaTest = 0; - this.bumpiness = 1; - this.heightMapFactor = 1; - _defineTex2D(this, "diffuse", 0, 3); - _defineTex2D(this, "specular", 0, 3); - _defineTex2D(this, "emissive", 0, 3); - _defineTex2D(this, "normal", 0, -1); - _defineTex2D(this, "metalness", 0, 1); - _defineTex2D(this, "gloss", 0, 1); - _defineTex2D(this, "opacity", 0, 1); - _defineTex2D(this, "height", 0, 1); - _defineTex2D(this, "ao", 0, 1); - _defineTex2D(this, "light", 1, 3); - this.cubeMap = null; - this.sphereMap = null; - this.dpAtlas = null; - this.ambientSH = null; - this.reflectivity = 1; - this.aoUvSet = 0; - this.blendMapsWithColors = true; - this.specularAntialias = false; - this.conserveEnergy = true; - this.occludeSpecular = true; - this.occludeSpecularIntensity = 1; - this.shadingModel = pc.SPECULAR_PHONG; - this.fresnelModel = pc.FRESNEL_NONE; - this.fresnelFactor = 0; - this.ambientTint = false; - this.diffuseMapTint = false; - this.specularMapTint = false; - this.emissiveMapTint = false; - this.emissiveIntensity = 1; - this.normalizeNormalMap = true; - this.fastTbn = false; - this.useInstancing = false; - this.cubeMapProjection = 0; - this.cubeMapProjectionBox = null; - this.chunks = {}; - this.chunks.copy = function(from) { - for(var p in from) { - if(from.hasOwnProperty(p) && p !== "copy") { - this[p] = from[p] - } - } - }; - this.customFragmentShader = null; - this.refraction = 0; - this.refractionIndex = 1 / 1.5; - this.useMetalness = false; - this.metalness = 1; - this.shadowSampleType = pc.SHADOWSAMPLE_PCF3X3; - this.forceFragmentPrecision = null; - this.occludeDirect = false; - this.prefilteredCubeMap128 = null; - this.prefilteredCubeMap64 = null; - this.prefilteredCubeMap32 = null; - this.prefilteredCubeMap16 = null; - this.prefilteredCubeMap8 = null; - this.prefilteredCubeMap4 = null; - _endProperties(this); - this.ambientUniform = new Float32Array(3); - this.diffuseUniform = new Float32Array(3); - this.specularUniform = new Float32Array(3); - this.emissiveUniform = new Float32Array(3); - this.cubeMapMinUniform = new Float32Array(3); - this.cubeMapMaxUniform = new Float32Array(3) - }, clone:function() { - var clone = new pc.PhongMaterial; - pc.Material.prototype._cloneInternal.call(this, clone); - var pname; - for(var i = 0;i < pc._matSerialProps.length;i++) { - pname = pc._matSerialProps[i]; - if(this[pname] !== undefined) { - if(this[pname] && this[pname].copy) { - if(clone[pname]) { - clone[pname].copy(this[pname]) - }else { - clone[pname] = this[pname].clone() - } - }else { - clone[pname] = this[pname] - } - } - } - clone.update(); - return clone - }, init:function(data) { - this.reset(); - this.name = data.name; - for(var i = 0;i < data.parameters.length;i++) { - var param = data.parameters[i]; - if(param.type === "vec3") { - this[param.name] = _createRgb(param) - }else { - if(param.type === "vec2") { - this[param.name] = _createVec2(param) - }else { - if(param.type === "texture") { - this[param.name] = _createTexture(param) - }else { - if(param.type === "cubemap") { - this[param.name] = _createCubemap(param) - }else { - if(param.name === "bumpMapFactor") { - this.bumpiness = param.data - }else { - this[param.name] = param.data - } - } - } - } - } - } - this.update() - }, _updateMapTransform:function(transform, tiling, offset) { - transform = transform || new pc.Vec4; - transform.set(tiling.x, tiling.y, offset.x, offset.y); - if(transform.x == 1 && transform.y == 1 && transform.z == 0 && transform.w == 0) { - return null - } - return transform - }, _collectLights:function(lType, lights, lightsSorted, mask) { - for(var i = 0;i < lights.length;i++) { - if(lights[i].getEnabled()) { - if(lights[i].mask & mask) { - if(lights[i].getType() == lType) { - lightsSorted.push(lights[i]) - } - } - } - } - }, _updateMap:function(p) { - var mname = p + "Map"; - if(this[mname]) { - this.setParameter("texture_" + mname, this[mname]); - var tname = mname + "Transform"; - this[tname] = this._updateMapTransform(this[tname], this[mname + "Tiling"], this[mname + "Offset"]); - if(this[tname]) { - this.setParameter("texture_" + tname, this[tname].data) - } - } - }, update:function() { - this.clearParameters(); - this.ambientUniform[0] = this.ambient.r; - this.ambientUniform[1] = this.ambient.g; - this.ambientUniform[2] = this.ambient.b; - this.setParameter("material_ambient", this.ambientUniform); - if(!this.diffuseMap || this.diffuseMapTint) { - this.diffuseUniform[0] = this.diffuse.r; - this.diffuseUniform[1] = this.diffuse.g; - this.diffuseUniform[2] = this.diffuse.b; - this.setParameter("material_diffuse", this.diffuseUniform) - } - if(!this.useMetalness) { - if(!this.specularMap || this.specularMapTint) { - this.specularUniform[0] = this.specular.r; - this.specularUniform[1] = this.specular.g; - this.specularUniform[2] = this.specular.b; - this.setParameter("material_specular", this.specularUniform) - } - }else { - if(!this.metalnessMap || this.metalness < 1) { - this.setParameter("material_metalness", this.metalness) - } - } - if(this.shadingModel === pc.SPECULAR_PHONG) { - this.setParameter("material_shininess", Math.pow(2, this.shininess * 0.01 * 11)) - }else { - this.setParameter("material_shininess", this.shininess * 0.01) - } - if(!this.emissiveMap || this.emissiveMapTint) { - this.emissiveUniform[0] = this.emissive.r * this.emissiveIntensity; - this.emissiveUniform[1] = this.emissive.g * this.emissiveIntensity; - this.emissiveUniform[2] = this.emissive.b * this.emissiveIntensity; - this.setParameter("material_emissive", this.emissiveUniform) - } - if(this.refraction > 0) { - this.setParameter("material_refraction", this.refraction); - this.setParameter("material_refractionIor", this.refractionIndex) - } - this.setParameter("material_opacity", this.opacity); - if(this.occludeSpecular) { - this.setParameter("material_occludeSpecularIntensity", this.occludeSpecularIntensity) - } - if(this.cubeMapProjection === pc.CUBEPROJ_BOX) { - this.cubeMapMinUniform[0] = this.cubeMapProjectionBox.center.x - this.cubeMapProjectionBox.halfExtents.x; - this.cubeMapMinUniform[1] = this.cubeMapProjectionBox.center.y - this.cubeMapProjectionBox.halfExtents.y; - this.cubeMapMinUniform[2] = this.cubeMapProjectionBox.center.z - this.cubeMapProjectionBox.halfExtents.z; - this.cubeMapMaxUniform[0] = this.cubeMapProjectionBox.center.x + this.cubeMapProjectionBox.halfExtents.x; - this.cubeMapMaxUniform[1] = this.cubeMapProjectionBox.center.y + this.cubeMapProjectionBox.halfExtents.y; - this.cubeMapMaxUniform[2] = this.cubeMapProjectionBox.center.z + this.cubeMapProjectionBox.halfExtents.z; - this.setParameter("envBoxMin", this.cubeMapMinUniform); - this.setParameter("envBoxMax", this.cubeMapMaxUniform) - } - if(this.ambientSH) { - this.setParameter("ambientSH[0]", this.ambientSH) - } - var i = 0; - this._updateMap("diffuse"); - this._updateMap("specular"); - this._updateMap("gloss"); - this._updateMap("emissive"); - this._updateMap("opacity"); - this._updateMap("normal"); - this._updateMap("metalness"); - this._updateMap("height"); - this._updateMap("light"); - this._updateMap("ao"); - if(this.normalMap) { - this.setParameter("material_bumpMapFactor", this.bumpiness) - } - if(this.heightMap) { - this.setParameter("material_heightMapFactor", this.heightMapFactor * 0.025) - } - if(this.cubeMap) { - this.setParameter("texture_cubeMap", this.cubeMap) - } - if(this.prefilteredCubeMap128) { - this.setParameter("texture_prefilteredCubeMap128", this.prefilteredCubeMap128) - } - if(this.prefilteredCubeMap64) { - this.setParameter("texture_prefilteredCubeMap64", this.prefilteredCubeMap64) - } - if(this.prefilteredCubeMap32) { - this.setParameter("texture_prefilteredCubeMap32", this.prefilteredCubeMap32) - } - if(this.prefilteredCubeMap16) { - this.setParameter("texture_prefilteredCubeMap16", this.prefilteredCubeMap16) - } - if(this.prefilteredCubeMap8) { - this.setParameter("texture_prefilteredCubeMap8", this.prefilteredCubeMap8) - } - if(this.prefilteredCubeMap4) { - this.setParameter("texture_prefilteredCubeMap4", this.prefilteredCubeMap4) - } - if(this.sphereMap) { - this.setParameter("texture_sphereMap", this.sphereMap) - } - if(this.dpAtlas) { - this.setParameter("texture_sphereMap", this.dpAtlas) - } - this.setParameter("material_reflectionFactor", this.reflectivity); - if(this.fresnelFactor > 0) { - this.setParameter("material_fresnelFactor", this.fresnelFactor) - } - this.shader = null; - this.clearVariants() - }, _getMapTransformID:function(xform, uv) { - if(!xform) { - return 0 - } - if(!this._mapXForms[uv]) { - this._mapXForms[uv] = [] - } - var i, j, same; - for(i = 0;i < this._mapXForms[uv].length;i++) { - same = true; - for(j = 0;j < xform.data.length;j++) { - if(this._mapXForms[uv][i][j] != xform.data[j]) { - same = false; - break - } - } - if(same) { - return i + 1 - } - } - var newID = this._mapXForms[uv].length; - this._mapXForms[uv][newID] = []; - for(j = 0;j < xform.data.length;j++) { - this._mapXForms[uv][newID][j] = xform.data[j] - } - return newID + 1 - }, updateShader:function(device, scene, objDefs) { - var i; - var lights = scene._lights; - this._mapXForms = []; - var useTexCubeLod = device.useTexCubeLod; - var useDp = !device.extTextureLod; - var prefilteredCubeMap128 = this.prefilteredCubeMap128 || scene.skyboxPrefiltered128; - var prefilteredCubeMap64 = this.prefilteredCubeMap64 || scene.skyboxPrefiltered64; - var prefilteredCubeMap32 = this.prefilteredCubeMap32 || scene.skyboxPrefiltered32; - var prefilteredCubeMap16 = this.prefilteredCubeMap16 || scene.skyboxPrefiltered16; - var prefilteredCubeMap8 = this.prefilteredCubeMap8 || scene.skyboxPrefiltered8; - var prefilteredCubeMap4 = this.prefilteredCubeMap4 || scene.skyboxPrefiltered4; - if(prefilteredCubeMap128) { - var allMips = prefilteredCubeMap128 && prefilteredCubeMap64 && prefilteredCubeMap32 && prefilteredCubeMap16 && prefilteredCubeMap8 && prefilteredCubeMap4; - if(useDp && allMips) { - if(!prefilteredCubeMap128.dpAtlas) { - prefilteredCubeMap128.dpAtlas = pc.generateDpAtlas(device, [prefilteredCubeMap128, prefilteredCubeMap64, prefilteredCubeMap32, prefilteredCubeMap16, prefilteredCubeMap8, prefilteredCubeMap4]); - prefilteredCubeMap128.sh = pc.shFromCubemap(prefilteredCubeMap16) - } - this.dpAtlas = prefilteredCubeMap128.dpAtlas; - this.ambientSH = prefilteredCubeMap128.sh; - this.setParameter("ambientSH[0]", this.ambientSH); - this.setParameter("texture_sphereMap", this.dpAtlas) - }else { - if(useTexCubeLod) { - if(prefilteredCubeMap128._levels.length < 6) { - if(allMips) { - this.setParameter("texture_prefilteredCubeMap128", prefilteredCubeMap128) - }else { - console.log("Can't use prefiltered cubemap: " + allMips + ", " + useTexCubeLod + ", " + prefilteredCubeMap128._levels) - } - }else { - this.setParameter("texture_prefilteredCubeMap128", prefilteredCubeMap128) - } - }else { - if(allMips) { - this.setParameter("texture_prefilteredCubeMap128", prefilteredCubeMap128); - this.setParameter("texture_prefilteredCubeMap64", prefilteredCubeMap64); - this.setParameter("texture_prefilteredCubeMap32", prefilteredCubeMap32); - this.setParameter("texture_prefilteredCubeMap16", prefilteredCubeMap16); - this.setParameter("texture_prefilteredCubeMap8", prefilteredCubeMap8); - this.setParameter("texture_prefilteredCubeMap4", prefilteredCubeMap4) - }else { - console.log("Can't use prefiltered cubemap: " + allMips + ", " + useTexCubeLod + ", " + prefilteredCubeMap128._levels) - } - } - } - } - var specularTint = false; - var useSpecular = (this.useMetalness ? true : !!this.specularMap) || !!this.sphereMap || !!this.cubeMap || !!this.dpAtlas; - useSpecular = useSpecular || (this.useMetalness ? true : !(this.specular.r === 0 && this.specular.g === 0 && this.specular.b === 0)); - if(useSpecular) { - if(this.specularMapTint && !this.useMetalness) { - specularTint = this.specular.r !== 1 || this.specular.g !== 1 || this.specular.b !== 1 - } - } - var rgbmReflection = (prefilteredCubeMap128 ? prefilteredCubeMap128.rgbm : false) || (this.cubeMap ? this.cubeMap.rgbm : false) || (this.sphereMap ? this.sphereMap.rgbm : false) || (this.dpAtlas ? this.dpAtlas.rgbm : false); - var hdrReflection = (prefilteredCubeMap128 ? prefilteredCubeMap128.rgbm || prefilteredCubeMap128.format === pc.PIXELFORMAT_RGBA32F : false) || (this.cubeMap ? this.cubeMap.rgbm || this.cubeMap.format === pc.PIXELFORMAT_RGBA32F : false) || (this.sphereMap ? this.sphereMap.rgbm || this.sphereMap.format === pc.PIXELFORMAT_RGBA32F : false) || (this.dpAtlas ? this.dpAtlas.rgbm || this.dpAtlas.format === pc.PIXELFORMAT_RGBA32F : false); - var options = {fog:scene.fog, gamma:scene.gammaCorrection, toneMap:scene.toneMapping, blendMapsWithColors:this.blendMapsWithColors, modulateAmbient:this.ambientTint, diffuseTint:(this.diffuse.r != 1 || this.diffuse.g != 1 || this.diffuse.b != 1) && this.diffuseMapTint, specularTint:specularTint, metalnessTint:this.useMetalness && this.metalness < 1, glossTint:true, emissiveTint:(this.emissive.r != 1 || this.emissive.g != 1 || this.emissive.b != 1 || this.emissiveIntensity != 1) && this.emissiveMapTint, - opacityTint:this.opacity != 1 && this.blendType !== pc.BLEND_NONE, alphaTest:this.alphaTest > 0, needsNormalFloat:this.normalizeNormalMap, sphereMap:!!this.sphereMap, cubeMap:!!this.cubeMap, dpAtlas:!!this.dpAtlas, ambientSH:!!this.ambientSH, useSpecular:useSpecular, rgbmReflection:rgbmReflection, hdrReflection:hdrReflection, fixSeams:prefilteredCubeMap128 ? prefilteredCubeMap128.fixCubemapSeams : this.cubeMap ? this.cubeMap.fixCubemapSeams : false, prefilteredCubemap:!!prefilteredCubeMap128, - emissiveFormat:this.emissiveMap ? this.emissiveMap.rgbm ? 1 : this.emissiveMap.format === pc.PIXELFORMAT_RGBA32F ? 2 : 0 : null, lightMapFormat:this.lightMap ? this.lightMap.rgbm ? 1 : this.lightMap.format === pc.PIXELFORMAT_RGBA32F ? 2 : 0 : null, useRgbm:rgbmReflection || (this.emissiveMap ? this.emissiveMap.rgbm : 0) || (this.lightMap ? this.lightMap.rgbm : 0), specularAA:this.specularAntialias, conserveEnergy:this.conserveEnergy, occludeSpecular:this.occludeSpecular, occludeSpecularFloat:this.occludeSpecularIntensity !== - 1, occludeDirect:this.occludeDirect, shadingModel:this.shadingModel, fresnelModel:this.fresnelModel, packedNormal:this.normalMap ? this.normalMap._compressed : false, shadowSampleType:this.shadowSampleType, forceFragmentPrecision:this.forceFragmentPrecision, useInstancing:this.useInstancing, fastTbn:this.fastTbn, cubeMapProjection:this.cubeMapProjection, chunks:this.chunks, customFragmentShader:this.customFragmentShader, refraction:!!this.refraction, useMetalness:this.useMetalness, blendType:this.blendType, - skyboxIntensity:prefilteredCubeMap128 === scene.skyboxPrefiltered128 && prefilteredCubeMap128 && scene.skyboxIntensity !== 1, useTexCubeLod:useTexCubeLod}; - var hasUv1 = false; - var hasVcolor = false; - if(objDefs) { - options.noShadow = (objDefs & pc.SHADERDEF_NOSHADOW) !== 0; - options.skin = (objDefs & pc.SHADERDEF_SKIN) !== 0; - hasUv1 = (objDefs & pc.SHADERDEF_UV1) !== 0; - hasVcolor = (objDefs & pc.SHADERDEF_VCOLOR) !== 0 - } - for(var p in pc._matTex2D) { - if(p === "opacity" && this.blendType === pc.BLEND_NONE && this.alphaTest === 0) { - continue - } - var mname = p + "Map"; - var vname = mname + "VertexColor"; - if(p !== "height" && this[vname]) { - if(hasVcolor) { - var cname = mname + "Channel"; - options[vname] = this[vname]; - options[cname] = this[cname]; - options.vertexColors = true - } - }else { - if(this[mname]) { - var uname = mname + "Uv"; - var allow = true; - if(this[uname] === 1 && !hasUv1) { - allow = false - } - if(allow) { - options[mname] = !!this[mname]; - var tname = mname + "Transform"; - var cname = mname + "Channel"; - options[tname] = this._getMapTransformID(this[tname], this[uname]); - options[cname] = this[cname]; - options[uname] = this[uname] - } - } - } - } - options.aoMapUv = options.aoMapUv || this.aoUvSet; - this._mapXForms = null; - var lightsSorted = []; - var mask = objDefs ? objDefs >> 8 : 1; - this._collectLights(pc.LIGHTTYPE_DIRECTIONAL, lights, lightsSorted, mask); - this._collectLights(pc.LIGHTTYPE_POINT, lights, lightsSorted, mask); - this._collectLights(pc.LIGHTTYPE_SPOT, lights, lightsSorted, mask); - options.lights = lightsSorted; - for(i = 0;i < 3;i++) { - if(scene.gammaCorrection) { - this.ambientUniform[i] = Math.pow(this.ambient.data[i], 2.2); - this.diffuseUniform[i] = Math.pow(this.diffuse.data[i], 2.2); - this.specularUniform[i] = Math.pow(this.specular.data[i], 2.2); - this.emissiveUniform[i] = Math.pow(this.emissive.data[i], 2.2) * this.emissiveIntensity - }else { - this.ambientUniform[i] = this.ambient.data[i]; - this.diffuseUniform[i] = this.diffuse.data[i]; - this.specularUniform[i] = this.specular.data[i]; - this.emissiveUniform[i] = this.emissive.data[i] * this.emissiveIntensity - } - } - var library = device.getProgramLibrary(); - this.shader = library.getProgram("phong", options); - if(!objDefs) { - this.clearVariants(); - this.variants[0] = this.shader - } - }}); - return{PhongMaterial:PhongMaterial} -}()); -pc.extend(pc, function() { - var PickMaterial = function() { - this.color = new pc.Color(1, 1, 1, 1); - this.colorMap = null; - this.update() - }; - PickMaterial = pc.inherits(PickMaterial, pc.Material); - pc.extend(PickMaterial.prototype, {clone:function() { - var clone = new pc.PickMaterial; - Material.prototype._cloneInternal.call(this, clone); - clone.color.copy(this.color); - clone.update(); - return clone - }, update:function() { - this.clearParameters(); - this.setParameter("uColor", this.color.data) - }, updateShader:function(device) { - var options = {skin:!!this.meshInstances[0].skinInstance}; - var library = device.getProgramLibrary(); - this.shader = library.getProgram("pick", options) - }}); - return{PickMaterial:PickMaterial} -}()); -pc.extend(pc, function() { - function getKey(layer, blendType, isCommand, materialId) { - return(layer & 7) << 28 | (blendType & 3) << 26 | (isCommand ? 1 : 0) << 25 | (materialId & 33554431) << 0 - } - var Mesh = function() { - this.vertexBuffer = null; - this.indexBuffer = [null]; - this.primitive = [{type:0, base:0, count:0}]; - this.skin = null; - this.aabb = new pc.shape.Aabb; - this.boneAabb = null - }; - var InstancingData = function(numObjects, dynamic, instanceSize) { - instanceSize = instanceSize || 16; - this.buffer = new Float32Array(numObjects * instanceSize); - this.count = numObjects; - this.usage = dynamic ? pc.BUFFER_DYNAMIC : pc.BUFFER_STATIC; - this._buffer = null - }; - InstancingData.prototype = {update:function() { - if(this._buffer) { - this._buffer.setData(this.buffer) - } - }}; - var MeshInstance = function MeshInstance(node, mesh, material) { - this.node = node; - this.mesh = mesh; - this.material = material; - this._shader = null; - this._shaderDefs = 256; - this._shaderDefs |= mesh.vertexBuffer.format.hasUv1 ? pc.SHADERDEF_UV1 : 0; - this._shaderDefs |= mesh.vertexBuffer.format.hasColor ? pc.SHADERDEF_VCOLOR : 0; - this.layer = pc.LAYER_WORLD; - this.renderStyle = pc.RENDERSTYLE_SOLID; - this.castShadow = false; - this._receiveShadow = true; - this.drawToDepth = true; - this.cull = true; - this.key = 0; - this.updateKey(); - this._skinInstance = null; - this.aabb = new pc.shape.Aabb; - this.normalMatrix = new pc.Mat3; - this._boneAabb = null - }; - Object.defineProperty(MeshInstance.prototype, "aabb", {get:function() { - if(this.skinInstance) { - var numBones = this.mesh.skin.boneNames.length; - var i; - if(!this.mesh.boneAabb) { - this.mesh.boneAabb = []; - var elems = this.mesh.vertexBuffer.format.elements; - var numVerts = this.mesh.vertexBuffer.numVertices; - var vertSize = this.mesh.vertexBuffer.format.size; - var data = new DataView(this.mesh.vertexBuffer.storage); - var boneVerts; - var index; - var offsetP, offsetI; - var j, k; - for(i = 0;i < elems.length;i++) { - if(elems[i].name === pc.SEMANTIC_POSITION) { - offsetP = elems[i].offset - }else { - if(elems[i].name === pc.SEMANTIC_BLENDINDICES) { - offsetI = elems[i].offset - } - } - } - for(i = 0;i < numBones;i++) { - boneVerts = []; - for(j = 0;j < numVerts;j++) { - for(k = 0;k < 4;k++) { - index = data.getUint8(j * vertSize + offsetI + k, true); - if(index === i) { - boneVerts.push(data.getFloat32(j * vertSize + offsetP, true)); - boneVerts.push(data.getFloat32(j * vertSize + offsetP + 4, true)); - boneVerts.push(data.getFloat32(j * vertSize + offsetP + 8, true)) - } - } - } - this.mesh.boneAabb.push(new pc.shape.Aabb); - this.mesh.boneAabb[i].compute(boneVerts) - } - } - if(!this._boneAabb) { - this._boneAabb = []; - for(i = 0;i < this.mesh.boneAabb.length;i++) { - this._boneAabb[i] = new pc.shape.Aabb - } - } - for(i = 0;i < this.mesh.boneAabb.length;i++) { - this._boneAabb[i].setFromTransformedAabb(this.mesh.boneAabb[i], this.skinInstance.matrices[i]) - } - this._aabb.center.copy(this._boneAabb[0].center); - this._aabb.halfExtents.copy(this._boneAabb[0].halfExtents); - for(i = 0;i < this.mesh.boneAabb.length;i++) { - this._aabb.add(this._boneAabb[i]) - } - }else { - this._aabb.setFromTransformedAabb(this.mesh.aabb, this.node.worldTransform) - } - return this._aabb - }, set:function(aabb) { - this._aabb = aabb - }}); - Object.defineProperty(MeshInstance.prototype, "material", {get:function() { - return this._material - }, set:function(material) { - this._shader = null; - if(this._material) { - var meshInstances = this._material.meshInstances; - var index = meshInstances.indexOf(this); - if(index !== -1) { - meshInstances.splice(index, 1) - } - } - this._material = material; - this._material.meshInstances.push(this); - this.updateKey() - }}); - Object.defineProperty(MeshInstance.prototype, "layer", {get:function() { - return this._layer - }, set:function(layer) { - this._layer = layer; - this.updateKey() - }}); - Object.defineProperty(MeshInstance.prototype, "receiveShadow", {get:function() { - return this._receiveShadow - }, set:function(val) { - this._receiveShadow = val; - this._shaderDefs = val ? this._shaderDefs & ~pc.SHADERDEF_NOSHADOW : this._shaderDefs | pc.SHADERDEF_NOSHADOW; - this._shader = null - }}); - Object.defineProperty(MeshInstance.prototype, "skinInstance", {get:function() { - return this._skinInstance - }, set:function(val) { - this._skinInstance = val; - this._shaderDefs = val ? this._shaderDefs | pc.SHADERDEF_SKIN : this._shaderDefs & ~pc.SHADERDEF_SKIN; - this._shader = null - }}); - Object.defineProperty(MeshInstance.prototype, "mask", {get:function() { - return this._shaderDefs >> 8 - }, set:function(val) { - var toggles = this._shaderDefs & 255; - this._shaderDefs = toggles | val << 8; - this._shader = null - }}); - pc.extend(MeshInstance.prototype, {syncAabb:function() { - }, updateKey:function() { - var material = this.material; - this.key = getKey(this.layer, material.blendType, false, material.id) - }}); - var Command = function(layer, blendType, command) { - this.key = getKey(layer, blendType, true, 0); - this.command = command - }; - return{Command:Command, Mesh:Mesh, MeshInstance:MeshInstance, InstancingData:InstancingData, _getDrawcallSortKey:getKey} -}()); -pc.extend(pc, function() { - var Skin = function(graphicsDevice, ibp, boneNames) { - this.device = graphicsDevice; - this.inverseBindPose = ibp; - this.boneNames = boneNames - }; - var SkinInstance = function(skin) { - this.skin = skin; - this.bones = []; - var numBones = skin.inverseBindPose.length; - var device = skin.device; - if(device.supportsBoneTextures) { - var size; - if(numBones > 256) { - size = 64 - }else { - if(numBones > 64) { - size = 32 - }else { - if(numBones > 16) { - size = 16 - }else { - size = 8 - } - } - } - this.matrixPalette = new Float32Array(size * size * 4); - this.boneTexture = new pc.Texture(device, {width:size, height:size, format:pc.PIXELFORMAT_RGBA32F, autoMipmap:false}); - this.boneTexture.minFilter = pc.FILTER_NEAREST; - this.boneTexture.magFilter = pc.FILTER_NEAREST; - this.matrixPalette = this.boneTexture.lock() - }else { - this.matrixPalette = new Float32Array(numBones * 16) - } - this.matrices = []; - for(var i = 0;i < numBones;i++) { - this.matrices[i] = new pc.Mat4 - } - }; - SkinInstance.prototype = {updateMatrixPalette:function() { - var paletteEntry = new pc.Mat4; - return function() { - var pe = paletteEntry.data; - var mp = this.matrixPalette; - var base; - for(var i = this.bones.length - 1;i >= 0;i--) { - paletteEntry.mul2(this.bones[i].worldTransform, this.skin.inverseBindPose[i]); - this.matrices[i].copy(paletteEntry); - base = i * 16; - mp[base] = pe[0]; - mp[base + 1] = pe[1]; - mp[base + 2] = pe[2]; - mp[base + 3] = pe[3]; - mp[base + 4] = pe[4]; - mp[base + 5] = pe[5]; - mp[base + 6] = pe[6]; - mp[base + 7] = pe[7]; - mp[base + 8] = pe[8]; - mp[base + 9] = pe[9]; - mp[base + 10] = pe[10]; - mp[base + 11] = pe[11]; - mp[base + 12] = pe[12]; - mp[base + 13] = pe[13]; - mp[base + 14] = pe[14]; - mp[base + 15] = pe[15] - } - if(this.skin.device.supportsBoneTextures) { - this.boneTexture.lock(); - this.boneTexture.unlock() - } - } - }()}; - return{Skin:Skin, SkinInstance:SkinInstance} -}()); -pc.extend(pc, function() { - function PartitionedVertex() { - this.index = 0; - this.boneIndices = [0, 0, 0, 0] - } - function SkinPartition() { - this.partition = 0; - this.vertexStart = 0; - this.vertexCount = 0; - this.indexStart = 0; - this.indexCount = 0; - this.boneIndices = []; - this.vertices = []; - this.indices = []; - this.indexMap = {} - } - SkinPartition.prototype = {addVertex:function(vertex, idx, vertexArray) { - var remappedIndex = -1; - if(this.indexMap[idx] !== undefined) { - remappedIndex = this.indexMap[idx]; - this.indices.push(remappedIndex) - }else { - for(var influence = 0;influence < 4;influence++) { - if(vertexArray.blendWeight.data[idx * 4 + influence] === 0) { - continue - } - var originalBoneIndex = vertexArray.blendIndices.data[vertex.index * 4 + influence]; - vertex.boneIndices[influence] = this.getBoneRemap(originalBoneIndex) - } - remappedIndex = this.vertices.length; - this.indices.push(remappedIndex); - this.vertices.push(vertex); - this.indexMap[idx] = remappedIndex - } - }, addPrimitive:function(vertices, vertexIndices, vertexArray, boneLimit) { - var i, j; - var bonesToAdd = []; - var bonesToAddCount = 0; - var vertexCount = vertices.length; - for(i = 0;i < vertexCount;i++) { - var vertex = vertices[i]; - var idx = vertex.index; - for(var influence = 0;influence < 4;influence++) { - if(vertexArray.blendWeight.data[idx * 4 + influence] > 0) { - var boneIndex = vertexArray.blendIndices.data[idx * 4 + influence]; - var needToAdd = true; - for(j = 0;j < bonesToAddCount;j++) { - if(bonesToAdd[j] == boneIndex) { - needToAdd = false; - break - } - } - if(needToAdd) { - bonesToAdd[bonesToAddCount] = boneIndex; - var boneRemap = this.getBoneRemap(boneIndex); - bonesToAddCount += boneRemap === -1 ? 1 : 0 - } - } - } - } - if(this.boneIndices.length + bonesToAddCount > boneLimit) { - return false - } - for(i = 0;i < bonesToAddCount;i++) { - this.boneIndices.push(bonesToAdd[i]) - } - for(i = 0;i < vertexCount;i++) { - this.addVertex(vertices[i], vertexIndices[i], vertexArray) - } - return true - }, getBoneRemap:function(boneIndex) { - for(var i = 0;i < this.boneIndices.length;i++) { - if(this.boneIndices[i] === boneIndex) { - return i - } - } - return-1 - }}; - function indicesToReferences(model) { - var i; - var vertices = model.vertices; - var skins = model.skins; - var meshes = model.meshes; - var meshInstances = model.meshInstances; - for(i = 0;i < meshes.length;i++) { - meshes[i].vertices = vertices[meshes[i].vertices]; - if(meshes[i].skin !== undefined) { - meshes[i].skin = skins[meshes[i].skin] - } - } - for(i = 0;i < meshInstances.length;i++) { - meshInstances[i].mesh = meshes[meshInstances[i].mesh] - } - } - function referencesToIndices(model) { - var i; - var vertices = model.vertices; - var skins = model.skins; - var meshes = model.meshes; - var meshInstances = model.meshInstances; - for(i = 0;i < meshes.length;i++) { - meshes[i].vertices = vertices.indexOf(meshes[i].vertices); - if(meshes[i].skin !== undefined) { - meshes[i].skin = skins.indexOf(meshes[i].skin) - } - } - for(i = 0;i < meshInstances.length;i++) { - meshInstances[i].mesh = meshes.indexOf(meshInstances[i].mesh) - } - } - function partitionSkin(model, materialMappings, boneLimit) { - var i, j, k; - indicesToReferences(model); - var vertexArrays = model.vertices; - var skins = model.skins; - var meshes = model.meshes; - var meshInstances = model.meshInstances; - for(i = skins.length - 1;i >= 0;i--) { - if(skins[i].boneNames.length > boneLimit) { - var skin = skins.splice(i, 1)[0]; - var meshesToSplit = []; - for(j = 0;j < meshes.length;j++) { - if(meshes[j].skin === skin) { - meshesToSplit.push(meshes[j]) - } - } - for(j = 0;j < meshesToSplit.length;j++) { - var index = meshes.indexOf(meshesToSplit[j]); - if(index !== -1) { - meshes.splice(index, 1) - } - } - if(meshesToSplit.length === 0) { - throw new Error("partitionSkin: There should be at least one mesh that references a skin"); - } - var vertexArray = meshesToSplit[0].vertices; - for(j = 1;j < meshesToSplit.length;j++) { - if(meshesToSplit[j].vertices !== vertexArray) { - throw new Error("partitionSkin: All meshes that share a skin should also share the same vertex buffer"); - } - } - var partition; - var partitions = []; - var getVertex = function(idx) { - var vert = new PartitionedVertex; - vert.index = idx; - return vert - }; - var primitiveVertices = []; - var primitiveIndices = []; - var basePartition = 0; - for(j = 0;j < meshesToSplit.length;j++) { - var mesh = meshesToSplit[j]; - var indices = mesh.indices; - for(var iIndex = mesh.base;iIndex < mesh.base + mesh.count;) { - var index; - index = indices[iIndex++]; - primitiveVertices[0] = getVertex(index); - primitiveIndices[0] = index; - index = indices[iIndex++]; - primitiveVertices[1] = getVertex(index); - primitiveIndices[1] = index; - index = indices[iIndex++]; - primitiveVertices[2] = getVertex(index); - primitiveIndices[2] = index; - var added = false; - for(var iBonePartition = basePartition;iBonePartition < partitions.length;iBonePartition++) { - partition = partitions[iBonePartition]; - if(partition.addPrimitive(primitiveVertices, primitiveIndices, vertexArray, boneLimit)) { - added = true; - break - } - } - if(!added) { - partition = new SkinPartition; - partition.originalMesh = mesh; - partition.addPrimitive(primitiveVertices, primitiveIndices, vertexArray, boneLimit); - partitions.push(partition) - } - } - basePartition = partitions.length - } - var partitionedVertices = []; - var partitionedIndices = []; - for(j = 0;j < partitions.length;j++) { - partition = partitions[j]; - if(partition.vertices.length && partition.indices.length) { - var vertexStart = partitionedVertices.length; - var vertexCount = partition.vertices.length; - var indexStart = partitionedIndices.length; - var indexCount = partition.indices.length; - partition.partition = j; - partition.vertexStart = vertexStart; - partition.vertexCount = vertexCount; - partition.indexStart = indexStart; - partition.indexCount = indexCount; - var iSour; - var iDest; - iSour = 0; - iDest = vertexStart; - while(iSour < vertexCount) { - partitionedVertices[iDest++] = partition.vertices[iSour++] - } - iSour = 0; - iDest = indexStart; - while(iSour < indexCount) { - partitionedIndices[iDest++] = partition.indices[iSour++] + vertexStart - } - } - } - var splitSkins = []; - for(j = 0;j < partitions.length;j++) { - partition = partitions[j]; - var ibp = []; - var boneNames = []; - for(k = 0;k < partition.boneIndices.length;k++) { - ibp.push(skin.inverseBindMatrices[partition.boneIndices[k]]); - boneNames.push(skin.boneNames[partition.boneIndices[k]]) - } - var splitSkin = {inverseBindMatrices:ibp, boneNames:boneNames}; - splitSkins.push(splitSkin); - skins.push(splitSkin) - } - var attrib, attribName; - var splitVertexArray = {}; - for(attribName in vertexArray) { - splitVertexArray[attribName] = {components:vertexArray[attribName].components, data:[], type:vertexArray[attribName].type} - } - for(attribName in vertexArray) { - if(attribName === "blendIndices") { - var dstBoneIndices = splitVertexArray[attribName].data; - for(j = 0;j < partitionedVertices.length;j++) { - var srcBoneIndices = partitionedVertices[j].boneIndices; - dstBoneIndices.push(srcBoneIndices[0], srcBoneIndices[1], srcBoneIndices[2], srcBoneIndices[3]) - } - }else { - attrib = vertexArray[attribName]; - data = attrib.data; - components = attrib.components; - for(j = 0;j < partitionedVertices.length;j++) { - var index = partitionedVertices[j].index; - for(k = 0;k < components;k++) { - splitVertexArray[attribName].data.push(data[index * components + k]) - } - } - } - } - vertexArrays[vertexArrays.indexOf(vertexArray)] = splitVertexArray; - var base = 0; - for(j = 0;j < partitions.length;j++) { - partition = partitions[j]; - var mesh = {aabb:{min:[0, 0, 0], max:[0, 0, 0]}, vertices:splitVertexArray, skin:splitSkins[j], indices:partitionedIndices.splice(0, partition.indexCount), type:"triangles", base:0, count:partition.indexCount}; - meshes.push(mesh); - for(k = meshInstances.length - 1;k >= 0;k--) { - if(meshInstances[k].mesh === partition.originalMesh) { - meshInstances.push({mesh:mesh, node:meshInstances[k].node}); - if(materialMappings) { - materialMappings.push({material:materialMappings[k].material, path:materialMappings[k].path}) - } - } - } - base += partition.indexCount - } - for(j = 0;j < partitions.length;j++) { - partition = partitions[j]; - for(k = meshInstances.length - 1;k >= 0;k--) { - if(meshInstances[k].mesh === partition.originalMesh) { - meshInstances.splice(k, 1); - if(materialMappings) { - materialMappings.splice(k, 1) - } - } - } - } - } - } - referencesToIndices(model) - } - return{partitionSkin:partitionSkin} -}()); -pc.extend(pc, function() { - var Model = function Model() { - this.graph = null; - this.meshInstances = []; - this.skinInstances = []; - this.cameras = []; - this.lights = [] - }; - Model.prototype = {getGraph:function() { - return this.graph - }, setGraph:function(graph) { - this.graph = graph - }, getCameras:function() { - return this.cameras - }, setCameras:function(cameras) { - this.cameras = cameras - }, getLights:function() { - return this.lights - }, setLights:function(lights) { - this.lights = lights - }, getMaterials:function() { - var i; - var materials = []; - for(i = 0;i < this.meshInstances.length;i++) { - var meshInstance = this.meshInstances[i]; - if(materials.indexOf(meshInstance.material) === -1) { - materials.push(meshInstance.material) - } - } - return materials - }, clone:function() { - var i; - var srcNodes = []; - var cloneNodes = []; - var _duplicate = function(node) { - var newNode = node.clone(); - srcNodes.push(node); - cloneNodes.push(newNode); - var children = node.getChildren(); - for(var i = 0;i < children.length;i++) { - newNode.addChild(_duplicate(children[i])) - } - return newNode - }; - var cloneGraph = _duplicate(this.graph); - var cloneMeshInstances = []; - var cloneSkinInstances = []; - for(i = 0;i < this.skinInstances.length;i++) { - var skin = this.skinInstances[i].skin; - var cloneSkinInstance = new pc.SkinInstance(skin); - var bones = []; - for(j = 0;j < skin.boneNames.length;j++) { - var boneName = skin.boneNames[j]; - var bone = cloneGraph.findByName(boneName); - bones.push(bone) - } - cloneSkinInstance.bones = bones; - cloneSkinInstances.push(cloneSkinInstance) - } - for(i = 0;i < this.meshInstances.length;i++) { - var meshInstance = this.meshInstances[i]; - var nodeIndex = srcNodes.indexOf(meshInstance.node); - var cloneMeshInstance = new pc.MeshInstance(cloneNodes[nodeIndex], meshInstance.mesh, meshInstance.material); - if(meshInstance.skinInstance) { - var skinInstanceIndex = this.skinInstances.indexOf(meshInstance.skinInstance); - cloneMeshInstance.skinInstance = cloneSkinInstances[skinInstanceIndex] - } - cloneMeshInstances.push(cloneMeshInstance) - } - var clone = new pc.Model; - clone.graph = cloneGraph; - clone.meshInstances = cloneMeshInstances; - clone.skinInstances = cloneSkinInstances; - clone.getGraph().syncHierarchy(); - return clone - }, generateWireframe:function() { - var i, j, k; - var i1, i2; - var mesh, base, count, indexBuffer, wireBuffer; - var srcIndices, dstIndices; - var meshes = []; - for(i = 0;i < this.meshInstances.length;i++) { - mesh = this.meshInstances[i].mesh; - if(meshes.indexOf(mesh) === -1) { - meshes.push(mesh) - } - } - var offsets = [[0, 1], [1, 2], [2, 0]]; - for(i = 0;i < meshes.length;i++) { - mesh = meshes[i]; - base = mesh.primitive[pc.RENDERSTYLE_SOLID].base; - count = mesh.primitive[pc.RENDERSTYLE_SOLID].count; - indexBuffer = mesh.indexBuffer[pc.RENDERSTYLE_SOLID]; - srcIndices = new Uint16Array(indexBuffer.lock()); - var uniqueLineIndices = {}; - var lines = []; - for(j = base;j < base + count;j += 3) { - for(k = 0;k < 3;k++) { - i1 = srcIndices[j + offsets[k][0]]; - i2 = srcIndices[j + offsets[k][1]]; - var line = i1 > i2 ? i2 << 16 | i1 : i1 << 16 | i2; - if(uniqueLineIndices[line] === undefined) { - uniqueLineIndices[line] = 0; - lines.push(i1, i2) - } - } - } - indexBuffer.unlock(); - wireBuffer = new pc.IndexBuffer(indexBuffer.device, pc.INDEXFORMAT_UINT16, lines.length); - dstIndices = new Uint16Array(wireBuffer.lock()); - dstIndices.set(lines); - wireBuffer.unlock(); - mesh.primitive[pc.RENDERSTYLE_WIREFRAME] = {type:pc.PRIMITIVE_LINES, base:0, count:lines.length, indexed:true}; - mesh.indexBuffer[pc.RENDERSTYLE_WIREFRAME] = wireBuffer - } - }}; - return{Model:Model} -}()); -pc.extend(pc, function() { - var particleVerts = [[-1, -1], [1, -1], [1, 1], [-1, 1]]; - var _createTexture = function(device, width, height, pixelData, format, mult8Bit) { - if(!format) { - format = pc.PIXELFORMAT_RGBA32F - } - var texture = new pc.Texture(device, {width:width, height:height, format:format, cubemap:false, autoMipmap:false}); - texture.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - texture.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - texture.minFilter = pc.FILTER_NEAREST; - texture.magFilter = pc.FILTER_NEAREST; - var pixels = texture.lock(); - if(format == pc.PIXELFORMAT_R8_G8_B8_A8) { - texture.minFilter = pc.FILTER_LINEAR; - texture.magFilter = pc.FILTER_LINEAR; - var temp = new Uint8Array(pixelData.length); - for(var i = 0;i < pixelData.length;i++) { - temp[i] = pixelData[i] * mult8Bit * 255 - } - pixelData = temp - } - pixels.set(pixelData); - texture.unlock(); - return texture - }; - function saturate(x) { - return Math.max(Math.min(x, 1), 0) - } - function glMod(x, y) { - return x - y * Math.floor(x / y) - } - function tex1D(arr, u, chans, outArr, test) { - var a, b, c; - if(chans === undefined || chans < 2) { - u *= arr.length - 1; - a = arr[Math.floor(u)]; - b = arr[Math.ceil(u)]; - c = u % 1; - return pc.math.lerp(a, b, c) - } - u *= arr.length / chans - 1; - if(!outArr) { - outArr = [] - } - for(var i = 0;i < chans;i++) { - a = arr[Math.floor(u) * chans + i]; - b = arr[Math.ceil(u) * chans + i]; - c = u % 1; - outArr[i] = pc.math.lerp(a, b, c) - } - return outArr - } - var default0Curve = new pc.Curve([0, 0, 1, 0]); - var default1Curve = new pc.Curve([0, 1, 1, 1]); - var default0Curve3 = new pc.CurveSet([0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]); - var default1Curve3 = new pc.CurveSet([0, 1, 1, 1], [0, 1, 1, 1], [0, 1, 1, 1]); - var defaultParamTex = null; - var velocityVec = new pc.Vec3; - var localVelocityVec = new pc.Vec3; - var velocityVec2 = new pc.Vec3; - var localVelocityVec2 = new pc.Vec3; - var rndFactor3Vec = new pc.Vec3; - var particlePosPrev = new pc.Vec3; - var particlePos = new pc.Vec3; - var particleFinalPos = new pc.Vec3; - var moveDirVec = new pc.Vec3; - var rotMat = new pc.Mat4; - var spawnMatrix3 = new pc.Mat3; - var emitterMatrix3 = new pc.Mat3; - var uniformScale = 1; - var nonUniformScale; - var spawnMatrix = new pc.Mat4; - var randomPos = new pc.Vec3; - var randomPosTformed = new pc.Vec3; - var tmpVec3 = new pc.Vec3; - var velocityV = new pc.Vec3; - var setPropertyTarget; - var setPropertyOptions; - function setProperty(pName, defaultVal) { - if(setPropertyOptions[pName] !== undefined && setPropertyOptions[pName] !== null) { - setPropertyTarget[pName] = setPropertyOptions[pName] - }else { - setPropertyTarget[pName] = defaultVal - } - } - function pack3NFloats(a, b, c) { - var packed = a * 255 << 16 | b * 255 << 8 | c * 255; - return packed / (1 << 24) - } - function packTextureXYZ_NXYZ(qXYZ, qXYZ2) { - var num = qXYZ.length / 3; - var colors = new Array(num * 4); - for(var i = 0;i < num;i++) { - colors[i * 4] = qXYZ[i * 3]; - colors[i * 4 + 1] = qXYZ[i * 3 + 1]; - colors[i * 4 + 2] = qXYZ[i * 3 + 2]; - colors[i * 4 + 3] = pack3NFloats(qXYZ2[i * 3], qXYZ2[i * 3 + 1], qXYZ2[i * 3 + 2]) - } - return colors - } - function packTextureRGBA(qRGB, qA) { - var colors = new Array(qA.length * 4); - for(var i = 0;i < qA.length;i++) { - colors[i * 4] = qRGB[i * 3]; - colors[i * 4 + 1] = qRGB[i * 3 + 1]; - colors[i * 4 + 2] = qRGB[i * 3 + 2]; - colors[i * 4 + 3] = qA[i] - } - return colors - } - function packTexture5Floats(qA, qB, qC, qD, qE) { - var colors = new Array(qA.length * 4); - for(var i = 0;i < qA.length;i++) { - colors[i * 4] = qA[i]; - colors[i * 4 + 1] = qB[i]; - colors[i * 4 + 2] = 0; - colors[i * 4 + 3] = pack3NFloats(qC[i], qD[i], qE[i]) - } - return colors - } - function createOffscreenTarget(gd, camera) { - var rect = camera._rect; - var width = Math.floor(rect.width * gd.width); - var height = Math.floor(rect.height * gd.height); - var colorBuffer = new pc.Texture(gd, {format:pc.PIXELFORMAT_R8_G8_B8_A8, width:width, height:height}); - colorBuffer.minFilter = pc.FILTER_NEAREST; - colorBuffer.magFilter = pc.FILTER_NEAREST; - colorBuffer.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - colorBuffer.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - return new pc.RenderTarget(gd, colorBuffer, {depth:true}) - } - var ParticleEmitter = function(graphicsDevice, options) { - this.graphicsDevice = graphicsDevice; - var gd = graphicsDevice; - var precision = 32; - this.precision = precision; - if(!defaultParamTex) { - var resolution = 16; - var centerPoint = resolution * 0.5 + 0.5; - var dtex = new Float32Array(resolution * resolution * 4); - var x, y, xgrad, ygrad, p, c; - for(y = 0;y < resolution;y++) { - for(x = 0;x < resolution;x++) { - xgrad = x + 1 - centerPoint; - ygrad = y + 1 - centerPoint; - c = saturate(1 - saturate(Math.sqrt(xgrad * xgrad + ygrad * ygrad) / resolution) - 0.5); - p = y * resolution + x; - dtex[p * 4] = 1; - dtex[p * 4 + 1] = 1; - dtex[p * 4 + 2] = 1; - dtex[p * 4 + 3] = c - } - } - defaultParamTex = _createTexture(gd, resolution, resolution, dtex, pc.PIXELFORMAT_R8_G8_B8_A8, 1); - defaultParamTex.minFilter = pc.FILTER_LINEAR; - defaultParamTex.magFilter = pc.FILTER_LINEAR - } - setPropertyTarget = this; - setPropertyOptions = options; - setProperty("numParticles", 1); - setProperty("rate", 1); - setProperty("rate2", this.rate); - setProperty("lifetime", 50); - setProperty("emitterExtents", new pc.Vec3(0, 0, 0)); - setProperty("emitterRadius", 0); - setProperty("emitterShape", pc.EMITTERSHAPE_BOX); - setProperty("initialVelocity", 1); - setProperty("wrap", false); - setProperty("wrapBounds", null); - setProperty("colorMap", defaultParamTex); - setProperty("normalMap", null); - setProperty("loop", true); - setProperty("preWarm", false); - setProperty("sort", pc.PARTICLESORT_NONE); - setProperty("mode", pc.PARTICLEMODE_GPU); - setProperty("scene", null); - setProperty("lighting", false); - setProperty("halfLambert", false); - setProperty("intensity", 1); - setProperty("stretch", 0); - setProperty("alignToMotion", false); - setProperty("depthSoftening", 0); - setProperty("mesh", null); - setProperty("depthWrite", false); - setProperty("blendType", pc.BLEND_NORMAL); - setProperty("node", null); - setProperty("startAngle", 0); - setProperty("startAngle2", this.startAngle); - this.frameRandom = new pc.Vec3(0, 0, 0); - setProperty("colorGraph", default1Curve3); - setProperty("colorGraph2", this.colorGraph); - setProperty("scaleGraph", default1Curve); - setProperty("scaleGraph2", this.scaleGraph); - setProperty("alphaGraph", default1Curve); - setProperty("alphaGraph2", this.alphaGraph); - setProperty("localVelocityGraph", default0Curve3); - setProperty("localVelocityGraph2", this.localVelocityGraph); - setProperty("velocityGraph", default0Curve3); - setProperty("velocityGraph2", this.velocityGraph); - setProperty("rotationSpeedGraph", default0Curve); - setProperty("rotationSpeedGraph2", this.rotationSpeedGraph); - this.constantParticleTexIN = gd.scope.resolve("particleTexIN"); - this.constantParticleTexOUT = gd.scope.resolve("particleTexOUT"); - this.constantEmitterPos = gd.scope.resolve("emitterPos"); - this.constantEmitterScale = gd.scope.resolve("emitterScale"); - this.constantSpawnBounds = gd.scope.resolve("spawnBounds"); - this.constantSpawnBoundsSphere = gd.scope.resolve("spawnBoundsSphere"); - this.constantInitialVelocity = gd.scope.resolve("initialVelocity"); - this.constantFrameRandom = gd.scope.resolve("frameRandom"); - this.constantDelta = gd.scope.resolve("delta"); - this.constantRate = gd.scope.resolve("rate"); - this.constantRateDiv = gd.scope.resolve("rateDiv"); - this.constantLifetime = gd.scope.resolve("lifetime"); - this.constantLightCube = gd.scope.resolve("lightCube[0]"); - this.constantGraphSampleSize = gd.scope.resolve("graphSampleSize"); - this.constantGraphNumSamples = gd.scope.resolve("graphNumSamples"); - this.constantInternalTex0 = gd.scope.resolve("internalTex0"); - this.constantInternalTex1 = gd.scope.resolve("internalTex1"); - this.constantInternalTex2 = gd.scope.resolve("internalTex2"); - this.constantEmitterMatrix = gd.scope.resolve("emitterMatrix"); - this.constantNumParticles = gd.scope.resolve("numParticles"); - this.constantNumParticlesPot = gd.scope.resolve("numParticlesPot"); - this.constantLocalVelocityDivMult = gd.scope.resolve("localVelocityDivMult"); - this.constantVelocityDivMult = gd.scope.resolve("velocityDivMult"); - this.constantRotSpeedDivMult = gd.scope.resolve("rotSpeedDivMult"); - this.constantSeed = gd.scope.resolve("seed"); - this.constantStartAngle = gd.scope.resolve("startAngle"); - this.constantStartAngle2 = gd.scope.resolve("startAngle2"); - this.lightCube = new Float32Array(6 * 3); - this.lightCubeDir = new Array(6); - this.lightCubeDir[0] = new pc.Vec3(-1, 0, 0); - this.lightCubeDir[1] = new pc.Vec3(1, 0, 0); - this.lightCubeDir[2] = new pc.Vec3(0, -1, 0); - this.lightCubeDir[3] = new pc.Vec3(0, 1, 0); - this.lightCubeDir[4] = new pc.Vec3(0, 0, -1); - this.lightCubeDir[5] = new pc.Vec3(0, 0, 1); - this.internalTex0 = null; - this.internalTex1 = null; - this.internalTex2 = null; - this.internalTex3 = null; - this.vbToSort = null; - this.vbOld = null; - this.particleDistance = null; - this.camera = null; - this.swapTex = false; - this.useMesh = true; - this.useCpu = false; - this.shaderParticleUpdateRespawn = null; - this.shaderParticleUpdateNoRespawn = null; - this.shaderParticleUpdateOnStop = null; - this.numParticleVerts = 0; - this.numParticleIndices = 0; - this.material = null; - this.meshInstance = null; - this.seed = 0; - this.fixedTimeStep = 1 / 60; - this.maxSubSteps = 10; - this.simTime = 0; - this.beenReset = false; - this.rebuild() - }; - function calcEndTime(emitter) { - var interval = Math.max(emitter.rate, emitter.rate2) * emitter.numParticles + emitter.lifetime; - return Date.now() + interval * 1E3 - } - function subGraph(A, B) { - var r = new Float32Array(A.length); - for(var i = 0;i < A.length;i++) { - r[i] = A[i] - B[i] - } - return r - } - function maxUnsignedGraphValue(A, outUMax) { - var i, j; - var chans = outUMax.length; - var values = A.length / chans; - for(i = 0;i < values;i++) { - for(j = 0;j < chans;j++) { - var a = Math.abs(A[i * chans + j]); - outUMax[j] = Math.max(outUMax[j], a) - } - } - } - function normalizeGraph(A, uMax) { - var chans = uMax.length; - var i, j; - var values = A.length / chans; - for(i = 0;i < values;i++) { - for(j = 0;j < chans;j++) { - A[i * chans + j] /= uMax[j]; - A[i * chans + j] *= 0.5; - A[i * chans + j] += 0.5 - } - } - } - function divGraphFrom2Curves(curve1, curve2, outUMax) { - var sub = subGraph(curve2, curve1); - maxUnsignedGraphValue(sub, outUMax); - normalizeGraph(sub, outUMax); - return sub - } - function mat4ToMat3(mat4, mat3) { - mat3.data[0] = mat4.data[0]; - mat3.data[1] = mat4.data[1]; - mat3.data[2] = mat4.data[2]; - mat3.data[3] = mat4.data[4]; - mat3.data[4] = mat4.data[5]; - mat3.data[5] = mat4.data[6]; - mat3.data[6] = mat4.data[8]; - mat3.data[7] = mat4.data[9]; - mat3.data[8] = mat4.data[10] - } - ParticleEmitter.prototype = {onChangeCamera:function() { - if(this.depthSoftening > 0) { - if(this.camera) { - if(!this.camera._depthTarget) { - this.camera._depthTarget = createOffscreenTarget(this.graphicsDevice, this.camera); - this._depthTarget = this.camera._depthTarget - } - } - } - this.regenShader(); - this.resetMaterial() - }, rebuild:function() { - var i, len; - var precision = this.precision; - var gd = this.graphicsDevice; - this.spawnBounds = this.emitterShape === pc.EMITTERSHAPE_BOX ? this.emitterExtents : this.emitterRadius; - this.useCpu = this.useCpu || this.sort > pc.PARTICLESORT_NONE || !(gd.extTextureFloat && gd.maxVertexTextures >= 1 && gd.extTextureFloatRenderable) || gd.fragmentUniformsCount < 100; - this.vertexBuffer = undefined; - this.useMesh = false; - if(this.mesh) { - var totalVertCount = this.numParticles * this.mesh.vertexBuffer.numVertices; - if(totalVertCount > 65535) { - console.warn("WARNING: particle system can't render mesh particles because numParticles * numVertices is more than 65k. Reverting to quad particles.") - }else { - this.useMesh = true - } - } - this.numParticlesPot = pc.math.nextPowerOfTwo(this.numParticles); - this.rebuildGraphs(); - this.vbToSort = new Array(this.numParticles); - this.particleDistance = new Float32Array(this.numParticles); - this.frameRandom.x = Math.random(); - this.frameRandom.y = Math.random(); - this.frameRandom.z = Math.random(); - this.particleTex = new Float32Array(this.numParticlesPot * 4 * 4); - var emitterPos = this.node === null ? pc.Vec3.ZERO : this.node.getPosition(); - if(this.emitterShape === pc.EMITTERSHAPE_BOX) { - if(this.node === null) { - spawnMatrix.setTRS(pc.Vec3.ZERO, pc.Quat.IDENTITY, this.spawnBounds) - }else { - spawnMatrix.setTRS(pc.Vec3.ZERO, this.node.getRotation(), tmpVec3.copy(this.spawnBounds).mul(this.node.getLocalScale())) - } - } - for(i = 0;i < this.numParticles;i++) { - this.calcSpawnPosition(emitterPos, i); - this.particleTex[i * 4 + 3 + this.numParticlesPot * 2 * 4] = 1 - } - this.particleTexStart = new Float32Array(this.numParticlesPot * 4 * 4); - for(i = 0;i < this.particleTexStart.length;i++) { - this.particleTexStart[i] = this.particleTex[i] - } - if(!this.useCpu) { - this.particleTexIN = _createTexture(gd, this.numParticlesPot, 4, this.particleTex); - this.particleTexOUT = _createTexture(gd, this.numParticlesPot, 4, this.particleTex); - this.particleTexStart = _createTexture(gd, this.numParticlesPot, 4, this.particleTexStart); - this.rtParticleTexIN = new pc.RenderTarget(gd, this.particleTexIN, {depth:false}); - this.rtParticleTexOUT = new pc.RenderTarget(gd, this.particleTexOUT, {depth:false}); - this.swapTex = false - } - var chunks = pc.shaderChunks; - var shaderCodeStart = chunks.particleUpdaterInitPS + (this.emitterShape === pc.EMITTERSHAPE_BOX ? chunks.particleUpdaterAABBPS : chunks.particleUpdaterSpherePS) + chunks.particleUpdaterStartPS; - var shaderCodeRespawn = shaderCodeStart + chunks.particleUpdaterRespawnPS + chunks.particleUpdaterEndPS; - var shaderCodeNoRespawn = shaderCodeStart + chunks.particleUpdaterNoRespawnPS + chunks.particleUpdaterEndPS; - var shaderCodeOnStop = shaderCodeStart + chunks.particleUpdaterOnStopPS + chunks.particleUpdaterEndPS; - this.shaderParticleUpdateRespawn = chunks.createShaderFromCode(gd, chunks.fullscreenQuadVS, shaderCodeRespawn, "fsQuad0"); - this.shaderParticleUpdateNoRespawn = chunks.createShaderFromCode(gd, chunks.fullscreenQuadVS, shaderCodeNoRespawn, "fsQuad1"); - this.shaderParticleUpdateOnStop = chunks.createShaderFromCode(gd, chunks.fullscreenQuadVS, shaderCodeOnStop, "fsQuad2"); - this.numParticleVerts = this.useMesh ? this.mesh.vertexBuffer.numVertices : 4; - this.numParticleIndices = this.useMesh ? this.mesh.indexBuffer[0].numIndices : 6; - this._allocate(this.numParticles); - var mesh = new pc.Mesh; - mesh.vertexBuffer = this.vertexBuffer; - mesh.indexBuffer[0] = this.indexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_TRIANGLES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = this.numParticles * this.numParticleIndices; - mesh.primitive[0].indexed = true; - this.material = new pc.Material; - this.material.cullMode = pc.CULLFACE_NONE; - this.material.blend = true; - this.material.blendType = this.blendType; - this.material.depthWrite = this.depthWrite; - this.material.emitter = this; - this.regenShader(); - this.resetMaterial(); - this.meshInstance = new pc.MeshInstance(this.node, mesh, this.material); - this.meshInstance.updateKey(); - this.meshInstance.drawToDepth = false; - this._initializeTextures(); - this.addTime(0); - if(this.preWarm) { - this.prewarm(this.lifetime) - } - this.resetTime() - }, calcSpawnPosition:function(emitterPos, i) { - var rX = Math.random(); - var rY = Math.random(); - var rZ = Math.random(); - var rW = Math.random(); - this.particleTex[i * 4 + 0 + this.numParticlesPot * 2 * 4] = rX; - this.particleTex[i * 4 + 1 + this.numParticlesPot * 2 * 4] = rY; - this.particleTex[i * 4 + 2 + this.numParticlesPot * 2 * 4] = rZ; - randomPos.data[0] = rX - 0.5; - randomPos.data[1] = rY - 0.5; - randomPos.data[2] = rZ - 0.5; - if(this.emitterShape === pc.EMITTERSHAPE_BOX) { - randomPosTformed.copy(emitterPos).add(spawnMatrix.transformPoint(randomPos)) - }else { - randomPos.normalize(); - randomPosTformed.copy(emitterPos).add(randomPos.scale(rW * this.spawnBounds)) - } - this.particleTex[i * 4] = randomPosTformed.data[0]; - this.particleTex[i * 4 + 1] = randomPosTformed.data[1]; - this.particleTex[i * 4 + 2] = randomPosTformed.data[2]; - this.particleTex[i * 4 + 3] = pc.math.lerp(this.startAngle * pc.math.DEG_TO_RAD, this.startAngle2 * pc.math.DEG_TO_RAD, rX); - var particleRate = pc.math.lerp(this.rate, this.rate2, rX); - var startSpawnTime = -particleRate * i; - this.particleTex[i * 4 + 3 + this.numParticlesPot * 4] = startSpawnTime - }, rebuildGraphs:function() { - var precision = this.precision; - var gd = this.graphicsDevice; - var i; - this.qLocalVelocity = this.localVelocityGraph.quantize(precision); - this.qVelocity = this.velocityGraph.quantize(precision); - this.qColor = this.colorGraph.quantize(precision); - this.qRotSpeed = this.rotationSpeedGraph.quantize(precision); - this.qScale = this.scaleGraph.quantize(precision); - this.qAlpha = this.alphaGraph.quantize(precision); - this.qLocalVelocity2 = this.localVelocityGraph2.quantize(precision); - this.qVelocity2 = this.velocityGraph2.quantize(precision); - this.qColor2 = this.colorGraph2.quantize(precision); - this.qRotSpeed2 = this.rotationSpeedGraph2.quantize(precision); - this.qScale2 = this.scaleGraph2.quantize(precision); - this.qAlpha2 = this.alphaGraph2.quantize(precision); - for(i = 0;i < precision;i++) { - this.qRotSpeed[i] *= pc.math.DEG_TO_RAD; - this.qRotSpeed2[i] *= pc.math.DEG_TO_RAD - } - this.localVelocityUMax = new pc.Vec3(0, 0, 0); - this.velocityUMax = new pc.Vec3(0, 0, 0); - this.colorUMax = new pc.Vec3(0, 0, 0); - this.rotSpeedUMax = [0]; - this.scaleUMax = [0]; - this.alphaUMax = [0]; - this.qLocalVelocityDiv = divGraphFrom2Curves(this.qLocalVelocity, this.qLocalVelocity2, this.localVelocityUMax.data); - this.qVelocityDiv = divGraphFrom2Curves(this.qVelocity, this.qVelocity2, this.velocityUMax.data); - this.qColorDiv = divGraphFrom2Curves(this.qColor, this.qColor2, this.colorUMax.data); - this.qRotSpeedDiv = divGraphFrom2Curves(this.qRotSpeed, this.qRotSpeed2, this.rotSpeedUMax); - this.qScaleDiv = divGraphFrom2Curves(this.qScale, this.qScale2, this.scaleUMax); - this.qAlphaDiv = divGraphFrom2Curves(this.qAlpha, this.qAlpha2, this.alphaUMax); - if(!this.useCpu) { - this.internalTex0 = _createTexture(gd, precision, 1, packTextureXYZ_NXYZ(this.qLocalVelocity, this.qLocalVelocityDiv)); - this.internalTex1 = _createTexture(gd, precision, 1, packTextureXYZ_NXYZ(this.qVelocity, this.qVelocityDiv)); - this.internalTex2 = _createTexture(gd, precision, 1, packTexture5Floats(this.qRotSpeed, this.qScale, this.qScaleDiv, this.qRotSpeedDiv, this.qAlphaDiv)) - } - this.internalTex3 = _createTexture(gd, precision, 1, packTextureRGBA(this.qColor, this.qAlpha), pc.PIXELFORMAT_R8_G8_B8_A8, 1) - }, _initializeTextures:function() { - if(this.colorMap) { - this.material.setParameter("colorMap", this.colorMap); - if(this.lighting && this.normalMap) { - this.material.setParameter("normalMap", this.normalMap) - } - } - }, _hasDepthTarget:function() { - if(this.camera) { - return!!this.camera._depthTarget - } - return false - }, regenShader:function() { - var programLib = this.graphicsDevice.getProgramLibrary(); - var hasNormal = this.normalMap != null; - this.normalOption = 0; - if(this.lighting) { - this.normalOption = hasNormal ? 2 : 1 - } - this.material.updateShader = function() { - var shader = programLib.getProgram("particle", {useCpu:this.emitter.useCpu, normal:this.emitter.normalOption, halflambert:this.emitter.halfLambert, stretch:this.emitter.stretch, alignToMotion:this.emitter.alignToMotion, soft:this.emitter.depthSoftening && this.emitter._hasDepthTarget(), mesh:this.emitter.useMesh, gamma:this.emitter.scene ? this.emitter.scene.gammaCorrection : 0, toneMap:this.emitter.scene ? this.emitter.scene.toneMapping : 0, fog:this.emitter.scene ? this.emitter.scene.fog : - "none", wrap:this.emitter.wrap && this.emitter.wrapBounds, blend:this.blendType}); - this.setShader(shader) - }; - this.material.updateShader() - }, resetMaterial:function() { - var material = this.material; - var gd = this.graphicsDevice; - material.setParameter("stretch", this.stretch); - material.setParameter("colorMult", this.intensity); - if(!this.useCpu) { - material.setParameter("internalTex0", this.internalTex0); - material.setParameter("internalTex1", this.internalTex1); - material.setParameter("internalTex2", this.internalTex2) - } - material.setParameter("internalTex3", this.internalTex3); - material.setParameter("numParticles", this.numParticles); - material.setParameter("numParticlesPot", this.numParticlesPot); - material.setParameter("lifetime", this.lifetime); - material.setParameter("rate", this.rate); - material.setParameter("rateDiv", this.rate2 - this.rate); - material.setParameter("seed", this.seed); - material.setParameter("scaleDivMult", this.scaleUMax[0]); - material.setParameter("alphaDivMult", this.alphaUMax[0]); - material.setParameter("graphNumSamples", this.precision); - material.setParameter("graphSampleSize", 1 / this.precision); - material.setParameter("emitterScale", pc.Vec3.ONE.data); - if(this.wrap && this.wrapBounds) { - material.setParameter("wrapBounds", this.wrapBounds.data) - } - if(this.colorMap) { - material.setParameter("colorMap", this.colorMap) - } - if(this.lighting) { - if(this.normalMap) { - material.setParameter("normalMap", this.normalMap) - } - } - if(this.depthSoftening > 0 && this._hasDepthTarget()) { - material.setParameter("uDepthMap", this.camera._depthTarget.colorBuffer); - material.setParameter("screenSize", (new pc.Vec4(gd.width, gd.height, 1 / gd.width, 1 / gd.height)).data); - material.setParameter("softening", 1 / (this.depthSoftening * this.depthSoftening * 100)) - } - if(this.stretch > 0) { - material.cull = pc.CULLFACE_NONE - } - }, _allocate:function(numParticles) { - var psysVertCount = numParticles * this.numParticleVerts; - var psysIndexCount = numParticles * this.numParticleIndices; - var elements, particleFormat; - var i; - if(this.vertexBuffer === undefined || this.vertexBuffer.getNumVertices() !== psysVertCount) { - if(!this.useCpu) { - elements = [{semantic:pc.SEMANTIC_ATTR0, components:4, type:pc.ELEMENTTYPE_FLOAT32}]; - particleFormat = new pc.VertexFormat(this.graphicsDevice, elements); - this.vertexBuffer = new pc.VertexBuffer(this.graphicsDevice, particleFormat, psysVertCount, pc.BUFFER_DYNAMIC); - this.indexBuffer = new pc.IndexBuffer(this.graphicsDevice, pc.INDEXFORMAT_UINT16, psysIndexCount) - }else { - elements = [{semantic:pc.SEMANTIC_ATTR0, components:4, type:pc.ELEMENTTYPE_FLOAT32}, {semantic:pc.SEMANTIC_ATTR1, components:4, type:pc.ELEMENTTYPE_FLOAT32}, {semantic:pc.SEMANTIC_ATTR2, components:4, type:pc.ELEMENTTYPE_FLOAT32}, {semantic:pc.SEMANTIC_ATTR3, components:2, type:pc.ELEMENTTYPE_FLOAT32}]; - particleFormat = new pc.VertexFormat(this.graphicsDevice, elements); - this.vertexBuffer = new pc.VertexBuffer(this.graphicsDevice, particleFormat, psysVertCount, pc.BUFFER_DYNAMIC); - this.indexBuffer = new pc.IndexBuffer(this.graphicsDevice, pc.INDEXFORMAT_UINT16, psysIndexCount) - } - var data = new Float32Array(this.vertexBuffer.lock()); - var meshData, stride; - if(this.useMesh) { - meshData = new Float32Array(this.mesh.vertexBuffer.lock()); - stride = meshData.length / this.mesh.vertexBuffer.numVertices - } - var rnd; - for(i = 0;i < psysVertCount;i++) { - id = Math.floor(i / this.numParticleVerts); - if(i % this.numParticleVerts === 0) { - rnd = this.particleTex[i * 4 + 0 + this.numParticlesPot * 2 * 4] - } - if(!this.useMesh) { - var vertID = i % 4; - data[i * 4] = particleVerts[vertID][0]; - data[i * 4 + 1] = particleVerts[vertID][1]; - data[i * 4 + 2] = 0 - }else { - var vert = i % this.numParticleVerts; - data[i * 4] = meshData[vert * stride]; - data[i * 4 + 1] = meshData[vert * stride + 1]; - data[i * 4 + 2] = meshData[vert * stride + 2] - } - data[i * 4 + 3] = id - } - if(this.useCpu) { - this.vbCPU = new Float32Array(data); - this.vbOld = new Float32Array(this.vbCPU.length) - } - this.vertexBuffer.unlock(); - if(this.useMesh) { - this.mesh.vertexBuffer.unlock() - } - var dst = 0; - indices = new Uint16Array(this.indexBuffer.lock()); - if(this.useMesh) { - meshData = new Uint16Array(this.mesh.indexBuffer[0].lock()) - } - for(i = 0;i < numParticles;i++) { - if(!this.useMesh) { - var baseIndex = i * 4; - indices[dst++] = baseIndex; - indices[dst++] = baseIndex + 1; - indices[dst++] = baseIndex + 2; - indices[dst++] = baseIndex; - indices[dst++] = baseIndex + 2; - indices[dst++] = baseIndex + 3 - }else { - for(var j = 0;j < this.numParticleIndices;j++) { - indices[i * this.numParticleIndices + j] = meshData[j] + i * this.numParticleVerts - } - } - } - this.indexBuffer.unlock(); - if(this.useMesh) { - this.mesh.indexBuffer[0].unlock() - } - } - }, reset:function() { - this.beenReset = true; - this.seed = Math.random(); - this.material.setParameter("seed", this.seed); - if(this.useCpu) { - for(var i = 0;i < this.particleTexStart.length;i++) { - this.particleTex[i] = this.particleTexStart[i] - } - }else { - this._initializeTextures() - } - this.resetTime(); - var origLoop = this.loop; - this.loop = true; - this.addTime(0); - this.loop = origLoop; - if(this.preWarm) { - this.prewarm(this.lifetime) - } - }, prewarm:function(time) { - var lifetimeFraction = time / this.lifetime; - var iterations = Math.min(Math.floor(lifetimeFraction * this.precision), this.precision); - var stepDelta = time / iterations; - for(var i = 0;i < iterations;i++) { - this.addTime(stepDelta) - } - }, resetTime:function() { - this.endTime = calcEndTime(this) - }, addTime:function(delta, isOnStop) { - var i, j; - var device = this.graphicsDevice; - device.setBlending(false); - device.setColorWrite(true, true, true, true); - device.setCullMode(pc.CULLFACE_NONE); - device.setDepthTest(false); - device.setDepthWrite(false); - if(this.lighting) { - if(!this.scene) { - console.error("There is no scene defined for lighting particles"); - return - } - for(i = 0;i < 6;i++) { - this.lightCube[i * 3] = this.scene.ambientLight.r; - this.lightCube[i * 3 + 1] = this.scene.ambientLight.g; - this.lightCube[i * 3 + 2] = this.scene.ambientLight.b - } - var dirs = this.scene._globalLights; - for(i = 0;i < dirs.length;i++) { - for(var c = 0;c < 6;c++) { - var weight = Math.max(this.lightCubeDir[c].dot(dirs[i]._direction), 0) * dirs[i]._intensity; - this.lightCube[c * 3] += dirs[i]._color.r * weight; - this.lightCube[c * 3 + 1] += dirs[i]._color.g * weight; - this.lightCube[c * 3 + 2] += dirs[i]._color.b * weight - } - } - this.constantLightCube.setValue(this.lightCube) - } - if(this.scene) { - if(this.camera != this.scene._activeCamera) { - this.camera = this.scene._activeCamera; - this.onChangeCamera() - } - } - if(this.emitterShape === pc.EMITTERSHAPE_BOX) { - if(this.meshInstance.node === null) { - spawnMatrix.setTRS(pc.Vec3.ZERO, pc.Quat.IDENTITY, this.emitterExtents) - }else { - spawnMatrix.setTRS(pc.Vec3.ZERO, this.meshInstance.node.getRotation(), tmpVec3.copy(this.emitterExtents).mul(this.meshInstance.node.getLocalScale())) - } - } - var emitterScale = this.meshInstance.node === null ? pc.Vec3.ONE.data : this.meshInstance.node.getLocalScale().data; - this.material.setParameter("emitterScale", emitterScale); - if(!this.useCpu) { - this.frameRandom.x = Math.random(); - this.frameRandom.y = Math.random(); - this.frameRandom.z = Math.random(); - this.constantGraphSampleSize.setValue(1 / this.precision); - this.constantGraphNumSamples.setValue(this.precision); - this.constantNumParticles.setValue(this.numParticles); - this.constantNumParticlesPot.setValue(this.numParticlesPot); - this.constantInternalTex0.setValue(this.internalTex0); - this.constantInternalTex1.setValue(this.internalTex1); - this.constantInternalTex2.setValue(this.internalTex2); - var emitterPos = this.meshInstance.node === null ? pc.Vec3.ZERO.data : this.meshInstance.node.getPosition().data; - var emitterMatrix = this.meshInstance.node === null ? pc.Mat4.IDENTITY : this.meshInstance.node.getWorldTransform(); - if(this.emitterShape === pc.EMITTERSHAPE_BOX) { - mat4ToMat3(spawnMatrix, spawnMatrix3); - this.constantSpawnBounds.setValue(spawnMatrix3.data) - }else { - this.constantSpawnBoundsSphere.setValue(this.emitterRadius) - } - this.constantInitialVelocity.setValue(this.initialVelocity); - mat4ToMat3(emitterMatrix, emitterMatrix3); - this.constantEmitterPos.setValue(emitterPos); - this.constantFrameRandom.setValue(this.frameRandom.data); - this.constantDelta.setValue(delta); - this.constantRate.setValue(this.rate); - this.constantRateDiv.setValue(this.rate2 - this.rate); - this.constantStartAngle.setValue(this.startAngle * pc.math.DEG_TO_RAD); - this.constantStartAngle2.setValue(this.startAngle2 * pc.math.DEG_TO_RAD); - this.constantSeed.setValue(this.seed); - this.constantLifetime.setValue(this.lifetime); - this.constantEmitterScale.setValue(emitterScale); - this.constantEmitterMatrix.setValue(emitterMatrix3.data); - this.constantLocalVelocityDivMult.setValue(this.localVelocityUMax.data); - this.constantVelocityDivMult.setValue(this.velocityUMax.data); - this.constantRotSpeedDivMult.setValue(this.rotSpeedUMax[0]); - var texIN = this.swapTex ? this.particleTexOUT : this.particleTexIN; - texIN = this.beenReset ? this.particleTexStart : texIN; - var texOUT = this.swapTex ? this.particleTexIN : this.particleTexOUT; - this.constantParticleTexIN.setValue(texIN); - if(!isOnStop) { - pc.drawQuadWithShader(device, this.swapTex ? this.rtParticleTexIN : this.rtParticleTexOUT, this.loop ? this.shaderParticleUpdateRespawn : this.shaderParticleUpdateNoRespawn) - }else { - pc.drawQuadWithShader(device, this.swapTex ? this.rtParticleTexIN : this.rtParticleTexOUT, this.shaderParticleUpdateOnStop) - } - this.constantParticleTexOUT.setValue(texOUT); - this.material.setParameter("particleTexOUT", texOUT); - this.material.setParameter("particleTexIN", texIN); - this.beenReset = false; - this.swapTex = !this.swapTex - }else { - var data = new Float32Array(this.vertexBuffer.lock()); - if(this.meshInstance.node) { - var fullMat = this.meshInstance.node.worldTransform; - for(j = 0;j < 12;j++) { - rotMat.data[j] = fullMat.data[j] - } - nonUniformScale = this.meshInstance.node.getLocalScale(); - uniformScale = Math.max(Math.max(nonUniformScale.x, nonUniformScale.y), nonUniformScale.z) - } - var emitterPos = this.meshInstance.node === null ? pc.Vec3.ZERO : this.meshInstance.node.getPosition(); - var posCam = this.camera ? this.camera._node.getPosition() : pc.Vec3.ZERO; - var vertSize = 14; - for(i = 0;i < this.numParticles;i++) { - var id = Math.floor(this.vbCPU[i * this.numParticleVerts * 4 + 3]); - var rndFactor = this.particleTex[id * 4 + 0 + this.numParticlesPot * 2 * 4]; - rndFactor3Vec.x = rndFactor; - rndFactor3Vec.y = this.particleTex[id * 4 + 1 + this.numParticlesPot * 2 * 4]; - rndFactor3Vec.z = this.particleTex[id * 4 + 2 + this.numParticlesPot * 2 * 4]; - var particleRate = pc.math.lerp(this.rate, this.rate2, rndFactor); - var particleLifetime = this.lifetime; - var startSpawnTime = -particleRate * id; - var life = this.particleTex[id * 4 + 3 + this.numParticlesPot * 4] + delta; - var nlife = saturate(life / particleLifetime); - var scale = 0; - var alphaDiv = 0; - var angle = 0; - var len; - var interpolation; - var particleEnabled = life > 0 && life < particleLifetime; - if(particleEnabled) { - localVelocityVec.data = tex1D(this.qLocalVelocity, nlife, 3, localVelocityVec.data); - localVelocityVec2.data = tex1D(this.qLocalVelocity2, nlife, 3, localVelocityVec2.data); - velocityVec.data = tex1D(this.qVelocity, nlife, 3, velocityVec.data); - velocityVec2.data = tex1D(this.qVelocity2, nlife, 3, velocityVec2.data); - var rotSpeed = tex1D(this.qRotSpeed, nlife); - var rotSpeed2 = tex1D(this.qRotSpeed2, nlife); - scale = tex1D(this.qScale, nlife); - var scale2 = tex1D(this.qScale2, nlife); - var alpha = tex1D(this.qAlpha, nlife); - var alpha2 = tex1D(this.qAlpha2, nlife); - localVelocityVec.x = pc.math.lerp(localVelocityVec.x, localVelocityVec2.x, rndFactor3Vec.x); - localVelocityVec.y = pc.math.lerp(localVelocityVec.y, localVelocityVec2.y, rndFactor3Vec.y); - localVelocityVec.z = pc.math.lerp(localVelocityVec.z, localVelocityVec2.z, rndFactor3Vec.z); - if(this.initialVelocity > 0) { - if(this.emitterShape === pc.EMITTERSHAPE_SPHERE) { - randomPos.copy(rndFactor3Vec).scale(2).sub(pc.Vec3.ONE).normalize(); - localVelocityVec.add(randomPos.scale(this.initialVelocity)) - }else { - localVelocityVec.add(pc.Vec3.FORWARD.scale(this.initialVelocity)) - } - } - velocityVec.x = pc.math.lerp(velocityVec.x, velocityVec2.x, rndFactor3Vec.x); - velocityVec.y = pc.math.lerp(velocityVec.y, velocityVec2.y, rndFactor3Vec.y); - velocityVec.z = pc.math.lerp(velocityVec.z, velocityVec2.z, rndFactor3Vec.z); - rotSpeed = pc.math.lerp(rotSpeed, rotSpeed2, rndFactor3Vec.y); - scale = pc.math.lerp(scale, scale2, rndFactor * 1E4 % 1) * uniformScale; - alphaDiv = (alpha2 - alpha) * (rndFactor * 1E3 % 1); - if(this.meshInstance.node) { - rotMat.transformPoint(localVelocityVec, localVelocityVec) - } - localVelocityVec.add(velocityVec.mul(nonUniformScale)); - moveDirVec.copy(localVelocityVec); - particlePosPrev.x = this.particleTex[id * 4]; - particlePosPrev.y = this.particleTex[id * 4 + 1]; - particlePosPrev.z = this.particleTex[id * 4 + 2]; - particlePos.copy(particlePosPrev).add(localVelocityVec.scale(delta)); - particleFinalPos.copy(particlePos); - this.particleTex[id * 4] = particleFinalPos.x; - this.particleTex[id * 4 + 1] = particleFinalPos.y; - this.particleTex[id * 4 + 2] = particleFinalPos.z; - this.particleTex[id * 4 + 3] += rotSpeed * delta; - if(this.wrap && this.wrapBounds) { - particleFinalPos.sub(emitterPos); - particleFinalPos.x = glMod(particleFinalPos.x, this.wrapBounds.x) - this.wrapBounds.x * 0.5; - particleFinalPos.y = glMod(particleFinalPos.y, this.wrapBounds.y) - this.wrapBounds.y * 0.5; - particleFinalPos.z = glMod(particleFinalPos.z, this.wrapBounds.z) - this.wrapBounds.z * 0.5; - particleFinalPos.add(emitterPos) - } - if(this.sort > 0) { - if(this.sort === 1) { - tmpVec3.copy(particleFinalPos).sub(posCam); - this.particleDistance[id] = -(tmpVec3.x * tmpVec3.x + tmpVec3.y * tmpVec3.y + tmpVec3.z * tmpVec3.z) - }else { - if(this.sort === 2) { - this.particleDistance[id] = life - }else { - if(this.sort === 3) { - this.particleDistance[id] = -life - } - } - } - } - }else { - this.calcSpawnPosition(emitterPos, id) - } - if(isOnStop) { - if(life < 0) { - this.particleTex[id * 4 + 3 + this.numParticlesPot * 2 * 4] = -1 - } - }else { - if(life >= particleLifetime) { - life -= Math.max(particleLifetime, (this.numParticles - 1) * particleRate); - this.particleTex[id * 4 + 3 + this.numParticlesPot * 2 * 4] = this.loop ? 1 : -1 - } - if(life < 0 && this.loop) { - this.particleTex[id * 4 + 3 + this.numParticlesPot * 2 * 4] = 1 - } - } - if(this.particleTex[id * 4 + 3 + this.numParticlesPot * 2 * 4] < 0) { - particleEnabled = false - } - this.particleTex[id * 4 + 3 + this.numParticlesPot * 4] = life; - for(var v = 0;v < this.numParticleVerts;v++) { - var quadX = this.vbCPU[i * this.numParticleVerts * 4 + v * 4]; - var quadY = this.vbCPU[i * this.numParticleVerts * 4 + v * 4 + 1]; - var quadZ = this.vbCPU[i * this.numParticleVerts * 4 + v * 4 + 2]; - if(!particleEnabled) { - quadX = quadY = quadZ = 0 - } - var w = i * this.numParticleVerts * vertSize + v * vertSize; - data[w] = particleFinalPos.x; - data[w + 1] = particleFinalPos.y; - data[w + 2] = particleFinalPos.z; - data[w + 3] = nlife; - data[w + 4] = this.alignToMotion ? angle : this.particleTex[id * 4 + 3]; - data[w + 5] = scale; - data[w + 6] = alphaDiv; - data[w + 7] = moveDirVec.x; - data[w + 8] = quadX; - data[w + 9] = quadY; - data[w + 10] = quadZ; - data[w + 11] = moveDirVec.y; - data[w + 12] = moveDirVec.z - } - } - if(this.sort > pc.PARTICLESORT_NONE && this.camera) { - for(i = 0;i < this.numParticles;i++) { - this.vbToSort[i] = [i, Math.floor(this.vbCPU[i * this.numParticleVerts * 4 + 3])] - } - for(i = 0;i < this.vbCPU.length;i++) { - this.vbOld[i] = this.vbCPU[i] - } - var particleDistance = this.particleDistance; - this.vbToSort.sort(function(a, b) { - return particleDistance[a[1]] - particleDistance[b[1]] - }); - for(i = 0;i < this.numParticles;i++) { - var start = this.vbToSort[i][0]; - for(var corner = 0;corner < this.numParticleVerts;corner++) { - for(j = 0;j < 4;j++) { - this.vbCPU[i * this.numParticleVerts * 4 + corner * 4 + j] = this.vbOld[start * this.numParticleVerts * 4 + corner * 4 + j] - } - } - } - } - this.vertexBuffer.unlock() - } - if(!this.loop) { - if(this.onFinished) { - if(Date.now() > this.endTime) { - this.onFinished() - } - } - } - device.setDepthTest(true); - device.setDepthWrite(true) - }}; - return{ParticleEmitter:ParticleEmitter} -}()); -pc.extend(pc, function() { - function sortDrawCalls(drawCallA, drawCallB) { - return drawCallB.key - drawCallA.key - } - var Picker = function(device, width, height) { - this.device = device; - var library = device.getProgramLibrary(); - this.pickProgStatic = library.getProgram("pick", {skin:false}); - this.pickProgSkin = library.getProgram("pick", {skin:true}); - this.pickColor = new Float32Array(4); - this.scene = null; - this.drawCalls = []; - this.clearOptions = {color:[1, 1, 1, 1], depth:1, flags:pc.CLEARFLAG_COLOR | pc.CLEARFLAG_DEPTH}; - this.resize(width, height) - }; - Picker.prototype.getSelection = function(rect) { - var device = this.device; - rect.width = rect.width || 1; - rect.height = rect.height || 1; - var prevRenderTarget = device.getRenderTarget(); - device.setRenderTarget(this._pickBufferTarget); - device.updateBegin(); - var pixels = new Uint8Array(4 * rect.width * rect.height); - device.readPixels(rect.x, rect.y, rect.width, rect.height, pixels); - device.updateEnd(); - device.setRenderTarget(prevRenderTarget); - var selection = []; - for(var i = 0;i < rect.width * rect.height;i++) { - var r = pixels[4 * i + 0]; - var g = pixels[4 * i + 1]; - var b = pixels[4 * i + 2]; - var index = r << 16 | g << 8 | b; - if(index !== 16777215) { - var selectedMeshInstance = this.drawCalls[index]; - if(selection.indexOf(selectedMeshInstance) === -1) { - selection.push(selectedMeshInstance) - } - } - } - return selection - }; - Picker.prototype.prepare = function(camera, scene) { - var device = this.device; - this.scene = scene; - var prevRenderTarget = device.getRenderTarget(); - device.setRenderTarget(this._pickBufferTarget); - device.updateBegin(); - device.setViewport(0, 0, this._pickBufferTarget.width, this._pickBufferTarget.height); - device.setScissor(0, 0, this._pickBufferTarget.width, this._pickBufferTarget.height); - device.clear(this.clearOptions); - var i; - var mesh, meshInstance, material; - var type; - var device = this.device; - var scope = device.scope; - var modelMatrixId = scope.resolve("matrix_model"); - var boneTextureId = scope.resolve("texture_poseMap"); - var boneTextureSizeId = scope.resolve("texture_poseMapSize"); - var poseMatrixId = scope.resolve("matrix_pose[0]"); - var pickColorId = scope.resolve("uColor"); - var projId = scope.resolve("matrix_projection"); - var viewProjId = scope.resolve("matrix_viewProjection"); - var wtm = camera._node.getWorldTransform(); - var projMat = camera.getProjectionMatrix(); - var viewMat = wtm.clone().invert(); - var viewProjMat = new pc.Mat4; - viewProjMat.mul2(projMat, viewMat); - projId.setValue(projMat.data); - viewProjId.setValue(viewProjMat.data); - this.drawCalls = scene.drawCalls.slice(0); - this.drawCalls.sort(sortDrawCalls); - for(i = 0;i < this.drawCalls.length;i++) { - if(this.drawCalls[i].command) { - this.drawCalls[i].command() - }else { - meshInstance = this.drawCalls[i]; - mesh = meshInstance.mesh; - material = meshInstance.material; - type = mesh.primitive[pc.RENDERSTYLE_SOLID].type; - var isSolid = type === pc.PRIMITIVE_TRIANGLES || type === pc.PRIMITIVE_TRISTRIP || type === pc.PRIMITIVE_TRIFAN; - var isPickable = material instanceof pc.PhongMaterial || material instanceof pc.BasicMaterial; - if(isSolid && isPickable) { - device.setBlending(false); - device.setCullMode(material.cull); - device.setDepthWrite(material.depthWrite); - device.setDepthTest(material.depthTest); - modelMatrixId.setValue(meshInstance.node.worldTransform.data); - if(meshInstance.skinInstance) { - if(device.supportsBoneTextures) { - boneTextureId.setValue(meshInstance.skinInstance.boneTexture); - var w = meshInstance.skinInstance.boneTexture.width; - var h = meshInstance.skinInstance.boneTexture.height; - boneTextureSizeId.setValue([w, h]) - }else { - poseMatrixId.setValue(meshInstance.skinInstance.matrixPalette) - } - } - this.pickColor[0] = (i >> 16 & 255) / 255; - this.pickColor[1] = (i >> 8 & 255) / 255; - this.pickColor[2] = (i & 255) / 255; - this.pickColor[3] = 1; - pickColorId.setValue(this.pickColor); - device.setShader(mesh.skin ? this.pickProgSkin : this.pickProgStatic); - device.setVertexBuffer(mesh.vertexBuffer, 0); - device.setIndexBuffer(mesh.indexBuffer[pc.RENDERSTYLE_SOLID]); - device.draw(mesh.primitive[pc.RENDERSTYLE_SOLID]) - } - } - } - device.setViewport(0, 0, device.width, device.height); - device.setScissor(0, 0, device.width, device.height); - device.updateEnd(); - device.setRenderTarget(prevRenderTarget) - }; - Picker.prototype.resize = function(width, height) { - var colorBuffer = new pc.Texture(this.device, {format:pc.PIXELFORMAT_R8_G8_B8_A8, width:width, height:height, autoMipmap:false}); - colorBuffer.minFilter = pc.FILTER_NEAREST; - colorBuffer.magFilter = pc.FILTER_NEAREST; - colorBuffer.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - colorBuffer.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - this._pickBufferTarget = new pc.RenderTarget(this.device, colorBuffer, {depth:true}) - }; - Object.defineProperty(Picker.prototype, "renderTarget", {get:function() { - return this._pickBufferTarget - }}); - Object.defineProperty(Picker.prototype, "width", {get:function() { - return this._pickBufferTarget.width - }}); - Object.defineProperty(Picker.prototype, "height", {get:function() { - return this._pickBufferTarget.height - }}); - return{Picker:Picker} -}()); -pc.calculateTangents = function(vertices, normals, uvs, indices) { - var triangleCount = indices.length / 3; - var vertexCount = vertices.length / 3; - var i1, i2, i3; - var x1, x2, y1, y2, z1, z2, s1, s2, t1, t2, r; - var sdir = new pc.Vec3; - var tdir = new pc.Vec3; - var v1 = new pc.Vec3; - var v2 = new pc.Vec3; - var v3 = new pc.Vec3; - var w1 = new pc.Vec2; - var w2 = new pc.Vec2; - var w3 = new pc.Vec2; - var i; - var tan1 = new Float32Array(vertexCount * 3); - var tan2 = new Float32Array(vertexCount * 3); - var tangents = []; - for(i = 0;i < triangleCount;i++) { - i1 = indices[i * 3]; - i2 = indices[i * 3 + 1]; - i3 = indices[i * 3 + 2]; - v1.set(vertices[i1 * 3], vertices[i1 * 3 + 1], vertices[i1 * 3 + 2]); - v2.set(vertices[i2 * 3], vertices[i2 * 3 + 1], vertices[i2 * 3 + 2]); - v3.set(vertices[i3 * 3], vertices[i3 * 3 + 1], vertices[i3 * 3 + 2]); - w1.set(uvs[i1 * 2], uvs[i1 * 2 + 1]); - w2.set(uvs[i2 * 2], uvs[i2 * 2 + 1]); - w3.set(uvs[i3 * 2], uvs[i3 * 2 + 1]); - x1 = v2.x - v1.x; - x2 = v3.x - v1.x; - y1 = v2.y - v1.y; - y2 = v3.y - v1.y; - z1 = v2.z - v1.z; - z2 = v3.z - v1.z; - s1 = w2.x - w1.x; - s2 = w3.x - w1.x; - t1 = w2.y - w1.y; - t2 = w3.y - w1.y; - r = 1 / (s1 * t2 - s2 * t1); - sdir.set((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); - tdir.set((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); - tan1[i1 * 3 + 0] += sdir.x; - tan1[i1 * 3 + 1] += sdir.y; - tan1[i1 * 3 + 2] += sdir.z; - tan1[i2 * 3 + 0] += sdir.x; - tan1[i2 * 3 + 1] += sdir.y; - tan1[i2 * 3 + 2] += sdir.z; - tan1[i3 * 3 + 0] += sdir.x; - tan1[i3 * 3 + 1] += sdir.y; - tan1[i3 * 3 + 2] += sdir.z; - tan2[i1 * 3 + 0] += tdir.x; - tan2[i1 * 3 + 1] += tdir.y; - tan2[i1 * 3 + 2] += tdir.z; - tan2[i2 * 3 + 0] += tdir.x; - tan2[i2 * 3 + 1] += tdir.y; - tan2[i2 * 3 + 2] += tdir.z; - tan2[i3 * 3 + 0] += tdir.x; - tan2[i3 * 3 + 1] += tdir.y; - tan2[i3 * 3 + 2] += tdir.z - } - t1 = new pc.Vec3; - t2 = new pc.Vec3; - var n = new pc.Vec3; - var temp = new pc.Vec3; - for(i = 0;i < vertexCount;i++) { - n.set(normals[i * 3], normals[i * 3 + 1], normals[i * 3 + 2]); - t1.set(tan1[i * 3], tan1[i * 3 + 1], tan1[i * 3 + 2]); - t2.set(tan2[i * 3], tan2[i * 3 + 1], tan2[i * 3 + 2]); - var ndott = n.dot(t1); - temp.copy(n).scale(ndott); - temp.sub2(t1, temp).normalize(); - tangents[i * 4] = temp.x; - tangents[i * 4 + 1] = temp.y; - tangents[i * 4 + 2] = temp.z; - temp.cross(n, t1); - tangents[i * 4 + 3] = temp.dot(t2) < 0 ? -1 : 1 - } - return tangents -}; -pc.createMesh = function(device, positions, opts) { - var normals = opts && opts.normals !== undefined ? opts.normals : null; - var tangents = opts && opts.tangents !== undefined ? opts.tangents : null; - var uvs = opts && opts.uvs !== undefined ? opts.uvs : null; - var indices = opts && opts.indices !== undefined ? opts.indices : null; - var vertexDesc = [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]; - if(normals !== null) { - vertexDesc.push({semantic:pc.SEMANTIC_NORMAL, components:3, type:pc.ELEMENTTYPE_FLOAT32}) - } - if(tangents !== null) { - vertexDesc.push({semantic:pc.SEMANTIC_TANGENT, components:4, type:pc.ELEMENTTYPE_FLOAT32}) - } - if(uvs !== null) { - vertexDesc.push({semantic:pc.SEMANTIC_TEXCOORD0, components:2, type:pc.ELEMENTTYPE_FLOAT32}) - } - var vertexFormat = new pc.VertexFormat(device, vertexDesc); - var numVertices = positions.length / 3; - var vertexBuffer = new pc.VertexBuffer(device, vertexFormat, numVertices); - var iterator = new pc.VertexIterator(vertexBuffer); - for(var i = 0;i < numVertices;i++) { - iterator.element[pc.SEMANTIC_POSITION].set(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]); - if(normals !== null) { - iterator.element[pc.SEMANTIC_NORMAL].set(normals[i * 3], normals[i * 3 + 1], normals[i * 3 + 2]) - } - if(tangents !== null) { - iterator.element[pc.SEMANTIC_TANGENT].set(tangents[i * 4], tangents[i * 4 + 1], tangents[i * 4 + 2], tangents[i * 4 + 3]) - } - if(uvs !== null) { - iterator.element[pc.SEMANTIC_TEXCOORD0].set(uvs[i * 2], uvs[i * 2 + 1]) - } - iterator.next() - } - iterator.end(); - var indexBuffer = null; - var indexed = indices !== null; - if(indexed) { - indexBuffer = new pc.IndexBuffer(device, pc.INDEXFORMAT_UINT16, indices.length); - var dst = new Uint16Array(indexBuffer.lock()); - dst.set(indices); - indexBuffer.unlock() - } - var aabb = new pc.shape.Aabb; - aabb.compute(positions); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.indexBuffer[0] = indexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_TRIANGLES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = indexed ? indices.length : numVertices; - mesh.primitive[0].indexed = indexed; - mesh.aabb = aabb; - return mesh -}; -pc.createTorus = function(device, opts) { - var rc = opts && opts.tubeRadius !== undefined ? opts.tubeRadius : 0.2; - var rt = opts && opts.ringRadius !== undefined ? opts.ringRadius : 0.3; - var segments = opts && opts.segments !== undefined ? opts.segments : 30; - var sides = opts && opts.sides !== undefined ? opts.sides : 20; - var i, j; - var x, y, z, nx, ny, nz, u, v; - var positions = []; - var normals = []; - var uvs = []; - var indices = []; - for(i = 0;i <= sides;i++) { - for(j = 0;j <= segments;j++) { - x = Math.cos(2 * Math.PI * j / segments) * (rt + rc * Math.cos(2 * Math.PI * i / sides)); - y = Math.sin(2 * Math.PI * i / sides) * rc; - z = Math.sin(2 * Math.PI * j / segments) * (rt + rc * Math.cos(2 * Math.PI * i / sides)); - nx = Math.cos(2 * Math.PI * j / segments) * Math.cos(2 * Math.PI * i / sides); - ny = Math.sin(2 * Math.PI * i / sides); - nz = Math.sin(2 * Math.PI * j / segments) * Math.cos(2 * Math.PI * i / sides); - u = i / sides; - v = 1 - j / segments; - positions.push(x, y, z); - normals.push(nx, ny, nz); - uvs.push(u, v); - if(i < sides && j < segments) { - var first, second, third, fourth; - first = i * (segments + 1) + j; - second = (i + 1) * (segments + 1) + j; - third = i * (segments + 1) + (j + 1); - fourth = (i + 1) * (segments + 1) + (j + 1); - indices.push(first, second, third); - indices.push(second, fourth, third) - } - } - } - var options = {normals:normals, uvs:uvs, indices:indices}; - if(pc.precalculatedTangents) { - options.tangents = pc.calculateTangents(positions, normals, uvs, indices) - } - return pc.createMesh(device, positions, options) -}; -pc._createConeData = function(baseRadius, peakRadius, height, heightSegments, capSegments, roundedCaps) { - var i, j; - var x, y, z, u, v; - var pos = new pc.Vec3; - var bottomToTop = new pc.Vec3; - var norm = new pc.Vec3; - var top, bottom, tangent; - var positions = []; - var normals = []; - var uvs = []; - var indices = []; - var cosTheta, sinTheta; - var sinPhi, cosPhi; - var first, second, third, fourth; - var offset; - if(height > 0) { - for(i = 0;i <= heightSegments;i++) { - for(j = 0;j <= capSegments;j++) { - theta = j / capSegments * 2 * Math.PI - Math.PI; - sinTheta = Math.sin(theta); - cosTheta = Math.cos(theta); - bottom = new pc.Vec3(sinTheta * baseRadius, -height / 2, cosTheta * baseRadius); - top = new pc.Vec3(sinTheta * peakRadius, height / 2, cosTheta * peakRadius); - pos.lerp(bottom, top, i / heightSegments); - bottomToTop.sub2(top, bottom).normalize(); - tangent = new pc.Vec3(cosTheta, 0, -sinTheta); - norm.cross(tangent, bottomToTop).normalize(); - positions.push(pos.x, pos.y, pos.z); - normals.push(norm.x, norm.y, norm.z); - uvs.push(j / capSegments, i / heightSegments); - if(i < heightSegments && j < capSegments) { - first = i * (capSegments + 1) + j; - second = i * (capSegments + 1) + (j + 1); - third = (i + 1) * (capSegments + 1) + j; - fourth = (i + 1) * (capSegments + 1) + (j + 1); - indices.push(first, second, third); - indices.push(second, fourth, third) - } - } - } - } - if(roundedCaps) { - var lat, lon; - var latitudeBands = Math.floor(capSegments / 2); - var longitudeBands = capSegments; - var capOffset = height / 2; - for(lat = 0;lat <= latitudeBands;lat++) { - theta = lat * Math.PI * 0.5 / latitudeBands; - sinTheta = Math.sin(theta); - cosTheta = Math.cos(theta); - for(lon = 0;lon <= longitudeBands;lon++) { - phi = lon * 2 * Math.PI / longitudeBands - Math.PI / 2; - sinPhi = Math.sin(phi); - cosPhi = Math.cos(phi); - x = cosPhi * sinTheta; - y = cosTheta; - z = sinPhi * sinTheta; - u = 1 - lon / longitudeBands; - v = 1 - lat / latitudeBands; - positions.push(x * peakRadius, y * peakRadius + capOffset, z * peakRadius); - normals.push(x, y, z); - uvs.push(u, v) - } - } - offset = (heightSegments + 1) * (capSegments + 1); - for(lat = 0;lat < latitudeBands;++lat) { - for(lon = 0;lon < longitudeBands;++lon) { - first = lat * (longitudeBands + 1) + lon; - second = first + longitudeBands + 1; - indices.push(offset + first + 1, offset + second, offset + first); - indices.push(offset + first + 1, offset + second + 1, offset + second) - } - } - for(lat = 0;lat <= latitudeBands;lat++) { - theta = Math.PI * 0.5 + lat * Math.PI * 0.5 / latitudeBands; - sinTheta = Math.sin(theta); - cosTheta = Math.cos(theta); - for(lon = 0;lon <= longitudeBands;lon++) { - phi = lon * 2 * Math.PI / longitudeBands - Math.PI / 2; - sinPhi = Math.sin(phi); - cosPhi = Math.cos(phi); - x = cosPhi * sinTheta; - y = cosTheta; - z = sinPhi * sinTheta; - u = 1 - lon / longitudeBands; - v = 1 - lat / latitudeBands; - positions.push(x * peakRadius, y * peakRadius - capOffset, z * peakRadius); - normals.push(x, y, z); - uvs.push(u, v) - } - } - offset = (heightSegments + 1) * (capSegments + 1) + (longitudeBands + 1) * (latitudeBands + 1); - for(lat = 0;lat < latitudeBands;++lat) { - for(lon = 0;lon < longitudeBands;++lon) { - first = lat * (longitudeBands + 1) + lon; - second = first + longitudeBands + 1; - indices.push(offset + first + 1, offset + second, offset + first); - indices.push(offset + first + 1, offset + second + 1, offset + second) - } - } - }else { - offset = (heightSegments + 1) * (capSegments + 1); - if(baseRadius > 0) { - for(i = 0;i < capSegments;i++) { - theta = i / capSegments * 2 * Math.PI; - x = Math.sin(theta); - y = -height / 2; - z = Math.cos(theta); - u = 1 - (x + 1) / 2; - v = (z + 1) / 2; - positions.push(x * baseRadius, y, z * baseRadius); - normals.push(0, -1, 0); - uvs.push(u, v); - if(i > 1) { - indices.push(offset, offset + i, offset + i - 1) - } - } - } - offset += capSegments; - if(peakRadius > 0) { - for(i = 0;i < capSegments;i++) { - theta = i / capSegments * 2 * Math.PI; - x = Math.sin(theta); - y = height / 2; - z = Math.cos(theta); - u = 1 - (x + 1) / 2; - v = (z + 1) / 2; - positions.push(x * peakRadius, y, z * peakRadius); - normals.push(0, 1, 0); - uvs.push(u, v); - if(i > 1) { - indices.push(offset, offset + i - 1, offset + i) - } - } - } - } - return{positions:positions, normals:normals, uvs:uvs, indices:indices} -}; -pc.createCylinder = function(device, opts) { - var baseRadius = opts && opts.baseRadius !== undefined ? opts.baseRadius : 0.5; - var height = opts && opts.height !== undefined ? opts.height : 1; - var heightSegments = opts && opts.heightSegments !== undefined ? opts.heightSegments : 5; - var capSegments = opts && opts.capSegments !== undefined ? opts.capSegments : 20; - var options = pc._createConeData(baseRadius, baseRadius, height, heightSegments, capSegments, false); - if(pc.precalculatedTangents) { - options.tangents = pc.calculateTangents(options.positions, options.normals, options.uvs, options.indices) - } - return pc.createMesh(device, options.positions, options) -}; -pc.createCapsule = function(device, opts) { - var radius = opts && opts.radius !== undefined ? opts.radius : 0.3; - var height = opts && opts.height !== undefined ? opts.height : 1; - var heightSegments = opts && opts.heightSegments !== undefined ? opts.heightSegments : 1; - var sides = opts && opts.sides !== undefined ? opts.sides : 20; - var options = pc._createConeData(radius, radius, height - 2 * radius, heightSegments, sides, true); - if(pc.precalculatedTangents) { - options.tangents = pc.calculateTangents(options.positions, options.normals, options.uvs, options.indices) - } - return pc.createMesh(device, options.positions, options) -}; -pc.createCone = function(device, opts) { - var baseRadius = opts && opts.baseRadius !== undefined ? opts.baseRadius : 0.5; - var peakRadius = opts && opts.peakRadius !== undefined ? opts.peakRadius : 0; - var height = opts && opts.height !== undefined ? opts.height : 1; - var heightSegments = opts && opts.heightSegments !== undefined ? opts.heightSegments : 5; - var capSegments = opts && opts.capSegments !== undefined ? opts.capSegments : 18; - var options = pc._createConeData(baseRadius, peakRadius, height, heightSegments, capSegments, false); - if(pc.precalculatedTangents) { - options.tangents = pc.calculateTangents(options.positions, options.normals, options.uvs, options.indices) - } - return pc.createMesh(device, options.positions, options) -}; -pc.createSphere = function(device, opts) { - var radius = opts && opts.radius !== undefined ? opts.radius : 0.5; - var latitudeBands = opts && opts.latitudeBands !== undefined ? opts.latitudeBands : 16; - var longitudeBands = opts && opts.longitudeBands !== undefined ? opts.longitudeBands : 16; - var lon, lat; - var theta, sinTheta, cosTheta, phi, sinPhi, cosPhi; - var first, second; - var x, y, z, u, v; - var positions = []; - var normals = []; - var uvs = []; - var indices = []; - for(lat = 0;lat <= latitudeBands;lat++) { - theta = lat * Math.PI / latitudeBands; - sinTheta = Math.sin(theta); - cosTheta = Math.cos(theta); - for(lon = 0;lon <= longitudeBands;lon++) { - phi = lon * 2 * Math.PI / longitudeBands - Math.PI / 2; - sinPhi = Math.sin(phi); - cosPhi = Math.cos(phi); - x = cosPhi * sinTheta; - y = cosTheta; - z = sinPhi * sinTheta; - u = 1 - lon / longitudeBands; - v = 1 - lat / latitudeBands; - positions.push(x * radius, y * radius, z * radius); - normals.push(x, y, z); - uvs.push(u, v) - } - } - for(lat = 0;lat < latitudeBands;++lat) { - for(lon = 0;lon < longitudeBands;++lon) { - first = lat * (longitudeBands + 1) + lon; - second = first + longitudeBands + 1; - indices.push(first + 1, second, first); - indices.push(first + 1, second + 1, second) - } - } - var options = {normals:normals, uvs:uvs, indices:indices}; - if(pc.precalculatedTangents) { - options.tangents = pc.calculateTangents(positions, normals, uvs, indices) - } - return pc.createMesh(device, positions, options) -}; -pc.createPlane = function(device, opts) { - var he = opts && opts.halfExtents !== undefined ? opts.halfExtents : new pc.Vec2(0.5, 0.5); - var ws = opts && opts.widthSegments !== undefined ? opts.widthSegments : 5; - var ls = opts && opts.lengthSegments !== undefined ? opts.lengthSegments : 5; - var i, j; - var x, y, z, u, v; - var positions = []; - var normals = []; - var uvs = []; - var indices = []; - for(i = 0;i <= ws;i++) { - for(j = 0;j <= ls;j++) { - x = -he.x + 2 * he.x * i / ws; - y = 0; - z = -(-he.y + 2 * he.y * j / ls); - u = i / ws; - v = j / ls; - positions.push(x, y, z); - normals.push(0, 1, 0); - uvs.push(u, v); - if(i < ws && j < ls) { - indices.push(j + i * (ws + 1), j + (i + 1) * (ws + 1), j + i * (ws + 1) + 1); - indices.push(j + (i + 1) * (ws + 1), j + (i + 1) * (ws + 1) + 1, j + i * (ws + 1) + 1) - } - } - } - var options = {normals:normals, uvs:uvs, indices:indices}; - if(pc.precalculatedTangents) { - options.tangents = pc.calculateTangents(positions, normals, uvs, indices) - } - return pc.createMesh(device, positions, options) -}; -pc.createBox = function(device, opts) { - var he = opts && opts.halfExtents !== undefined ? opts.halfExtents : new pc.Vec3(0.5, 0.5, 0.5); - var ws = opts && opts.widthSegments !== undefined ? opts.widthSegments : 1; - var ls = opts && opts.lengthSegments !== undefined ? opts.lengthSegments : 1; - var hs = opts && opts.heightSegments !== undefined ? opts.heightSegments : 1; - var corners = [new pc.Vec3(-he.x, -he.y, he.z), new pc.Vec3(he.x, -he.y, he.z), new pc.Vec3(he.x, he.y, he.z), new pc.Vec3(-he.x, he.y, he.z), new pc.Vec3(he.x, -he.y, -he.z), new pc.Vec3(-he.x, -he.y, -he.z), new pc.Vec3(-he.x, he.y, -he.z), new pc.Vec3(he.x, he.y, -he.z)]; - var faceAxes = [[0, 1, 3], [4, 5, 7], [3, 2, 6], [1, 0, 4], [1, 4, 2], [5, 0, 6]]; - var faceNormals = [[0, 0, 1], [0, 0, -1], [0, 1, 0], [0, -1, 0], [1, 0, 0], [-1, 0, 0]]; - var sides = {FRONT:0, BACK:1, TOP:2, BOTTOM:3, RIGHT:4, LEFT:5}; - var side, i, j; - var positions = []; - var normals = []; - var uvs = []; - var indices = []; - var generateFace = function(side, uSegments, vSegments) { - var x, y, z, u, v; - var i, j; - var offset = positions.length / 3; - for(i = 0;i <= uSegments;i++) { - for(j = 0;j <= vSegments;j++) { - var temp1 = new pc.Vec3; - var temp2 = new pc.Vec3; - var temp3 = new pc.Vec3; - var r = new pc.Vec3; - temp1.lerp(corners[faceAxes[side][0]], corners[faceAxes[side][1]], i / uSegments); - temp2.lerp(corners[faceAxes[side][0]], corners[faceAxes[side][2]], j / vSegments); - temp3.sub2(temp2, corners[faceAxes[side][0]]); - r.add2(temp1, temp3); - u = i / uSegments; - v = j / vSegments; - positions.push(r.x, r.y, r.z); - normals.push(faceNormals[side][0], faceNormals[side][1], faceNormals[side][2]); - uvs.push(u, v); - if(i < uSegments && j < vSegments) { - indices.push(offset + j + i * (uSegments + 1), offset + j + (i + 1) * (uSegments + 1), offset + j + i * (uSegments + 1) + 1); - indices.push(offset + j + (i + 1) * (uSegments + 1), offset + j + (i + 1) * (uSegments + 1) + 1, offset + j + i * (uSegments + 1) + 1) - } - } - } - }; - generateFace(sides.FRONT, ws, hs); - generateFace(sides.BACK, ws, hs); - generateFace(sides.TOP, ws, ls); - generateFace(sides.BOTTOM, ws, ls); - generateFace(sides.RIGHT, ls, hs); - generateFace(sides.LEFT, ls, hs); - var options = {normals:normals, uvs:uvs, indices:indices}; - if(pc.precalculatedTangents) { - options.tangents = pc.calculateTangents(positions, normals, uvs, indices) - } - return pc.createMesh(device, positions, options) -}; -pc.extend(pc, function() { - var Key = function Key(time, position, rotation, scale) { - this.time = time; - this.position = position; - this.rotation = rotation; - this.scale = scale - }; - var Node = function Node() { - this._name = ""; - this._keys = [] - }; - var Animation = function Animation() { - this._name = ""; - this._duration = 0; - this._nodes = []; - this._nodeDict = {} - }; - Animation.prototype.getDuration = function() { - return this._duration - }; - Animation.prototype.getName = function() { - return this._name - }; - Animation.prototype.getNode = function(name) { - return this._nodeDict[name] - }; - Animation.prototype.getNodes = function() { - return this._nodes - }; - Animation.prototype.setDuration = function(duration) { - this._duration = duration - }; - Animation.prototype.setName = function(name) { - this._name = name - }; - Animation.prototype.addNode = function(node) { - this._nodes.push(node); - this._nodeDict[node._name] = node - }; - return{Animation:Animation, Key:Key, Node:Node} -}()); -pc.extend(pc, function() { - function InterpolatedKey() { - this._written = false; - this._name = ""; - this._keyFrames = []; - this._quat = new pc.Quat; - this._pos = new pc.Vec3; - this._scale = new pc.Vec3; - this._targetNode = null - } - InterpolatedKey.prototype = {getTarget:function() { - return this._targetNode - }, setTarget:function(node) { - this._targetNode = node - }}; - var Skeleton = function Skeleton(graph) { - this._animation = null; - this._time = 0; - this.looping = true; - this._interpolatedKeys = []; - this._interpolatedKeyDict = {}; - this._currKeyIndices = {}; - this.graph = null; - var self = this; - function addInterpolatedKeys(node) { - var name = node.getName(); - var interpKey = new InterpolatedKey; - interpKey._name = name; - self._interpolatedKeys.push(interpKey); - self._interpolatedKeyDict[name] = interpKey; - self._currKeyIndices[name] = 0; - var children = node.getChildren(); - for(var i = 0;i < children.length;i++) { - addInterpolatedKeys(children[i]) - } - } - addInterpolatedKeys(graph) - }; - Skeleton.prototype.addTime = function(delta) { - if(this._animation !== null) { - if(this._time === duration && !this.looping) { - return - } - var i; - var node, nodeName; - var keys, interpKey; - var k1, k2, alpha; - var nodes = this._animation.getNodes(); - this._time += delta; - var duration = this._animation.getDuration(); - if(this._time > duration) { - this._time = this.looping ? 0 : duration; - for(i = 0;i < nodes.length;i++) { - node = nodes[i]; - nodeName = node._name; - this._currKeyIndices[nodeName] = 0 - } - }else { - if(this._time < 0) { - this._time = this.looping ? duration : 0; - for(i = 0;i < nodes.length;i++) { - node = nodes[i]; - nodeName = node._name; - this._currKeyIndices[nodeName] = node._keys.length - 2 - } - } - } - var offset = delta > 0 ? 1 : -1; - for(i = 0;i < nodes.length;i++) { - node = nodes[i]; - nodeName = node._name; - keys = node._keys; - interpKey = this._interpolatedKeyDict[nodeName]; - if(keys.length === 1) { - interpKey._pos.copy(keys[0].position); - interpKey._quat.copy(keys[0].rotation); - interpKey._scale(keys[0].scale) - }else { - for(var currKeyIndex = this._currKeyIndices[nodeName];currKeyIndex < keys.length - 1 && currKeyIndex >= 0;currKeyIndex += offset) { - k1 = keys[currKeyIndex]; - k2 = keys[currKeyIndex + 1]; - if(k1.time <= this._time && k2.time >= this._time) { - alpha = (this._time - k1.time) / (k2.time - k1.time); - interpKey._pos.lerp(k1.position, k2.position, alpha); - interpKey._quat.slerp(k1.rotation, k2.rotation, alpha); - interpKey._scale.lerp(k1.scale, k2.scale, alpha); - interpKey._written = true; - this._currKeyIndices[nodeName] = currKeyIndex; - break - } - } - } - } - } - }; - Skeleton.prototype.blend = function(skel1, skel2, alpha) { - var numNodes = this._interpolatedKeys.length; - for(var i = 0;i < numNodes;i++) { - var key1 = skel1._interpolatedKeys[i]; - var key2 = skel2._interpolatedKeys[i]; - var dstKey = this._interpolatedKeys[i]; - if(key1._written && key2._written) { - dstKey._quat.slerp(key1._quat, skel2._interpolatedKeys[i]._quat, alpha); - dstKey._pos.lerp(key1._pos, skel2._interpolatedKeys[i]._pos, alpha); - dstKey._scale.lerp(key1._scale, key2._scale, alpha); - dstKey._written = true - }else { - if(key1._written) { - dstKey._quat.copy(key1._quat); - dstKey._pos.copy(key1._pos); - dstKey._scale.copy(key1._scale); - dstKey._written = true - }else { - if(key2._written) { - dstKey._quat.copy(key2._quat); - dstKey._pos.copy(key2._pos); - dstKey._scale.copy(key2._scale); - dstKey._written = true - } - } - } - } - }; - Skeleton.prototype.getAnimation = function() { - return this._animation - }; - Skeleton.prototype.getCurrentTime = function() { - return this._time - }; - Skeleton.prototype.setCurrentTime = function(time) { - this._time = time; - var numNodes = this._interpolatedKeys.length; - for(var i = 0;i < numNodes;i++) { - var node = this._interpolatedKeys[i]; - var nodeName = node._name; - this._currKeyIndices[nodeName] = 0 - } - this.addTime(0); - this.updateGraph() - }; - Skeleton.prototype.getNumNodes = function() { - return this._interpolatedKeys.length - }; - Skeleton.prototype.setAnimation = function(animation) { - this._animation = animation; - this.setCurrentTime(0) - }; - Skeleton.prototype.setGraph = function(graph) { - var i; - this.graph = graph; - if(graph) { - for(i = 0;i < this._interpolatedKeys.length;i++) { - var interpKey = this._interpolatedKeys[i]; - var graphNode = graph.findByName(interpKey._name); - this._interpolatedKeys[i].setTarget(graphNode) - } - }else { - for(i = 0;i < this._interpolatedKeys.length;i++) { - this._interpolatedKeys[i].setTarget(null) - } - } - }; - Skeleton.prototype.updateGraph = function() { - if(this.graph) { - for(var i = 0;i < this._interpolatedKeys.length;i++) { - var interpKey = this._interpolatedKeys[i]; - if(interpKey._written) { - var transform = interpKey.getTarget(); - transform.localPosition.copy(interpKey._pos); - transform.localRotation.copy(interpKey._quat); - transform.localScale.copy(interpKey._scale); - transform.dirtyLocal = true; - interpKey._written = false - } - } - } - }; - Skeleton.prototype.setLooping = function(looping) { - this.looping = looping - }; - Skeleton.prototype.getLooping = function() { - return this.looping - }; - return{Skeleton:Skeleton} -}()); -pc.extend(pc, function() { - function hasAudio() { - return typeof Audio !== "undefined" - } - function hasAudioContext() { - return!!(typeof AudioContext !== "undefined" || typeof webkitAudioContext !== "undefined") - } - function isSupported(url, audio) { - var toMIME = {".ogg":"audio/ogg", ".mp3":"audio/mpeg", ".wav":"audio/x-wav"}; - var ext = pc.path.getExtension(url); - if(toMIME[ext]) { - if(!audio) { - audio = new Audio - } - return audio.canPlayType(toMIME[ext]) !== "" - }else { - return false - } - } - var AudioManager = function() { - if(hasAudioContext()) { - if(typeof AudioContext !== "undefined") { - this.context = new AudioContext - }else { - if(typeof webkitAudioContext !== "undefined") { - this.context = new webkitAudioContext - } - } - } - this.listener = new pc.Listener(this); - this.volume = 1; - this.suspended = false; - pc.events.attach(this) - }; - AudioManager.hasAudio = hasAudio; - AudioManager.hasAudioContext = hasAudioContext; - AudioManager.isSupported = isSupported; - AudioManager.prototype = {createSound:function(url, success, error) { - var sound = null; - if(pc.Sound) { - sound = new pc.Sound(this, url, success, error) - }else { - error() - } - return sound - }, playSound:function(sound, options) { - options = options || {}; - var channel = null; - if(pc.Channel) { - channel = new pc.Channel(this, sound, options); - channel.play() - } - return channel - }, playSound3d:function(sound, position, options) { - options = options || {}; - var channel = null; - if(pc.Channel3d) { - channel = new pc.Channel3d(this, sound, options); - channel.setPosition(position); - if(options.volume) { - channel.setVolume(options.volume) - } - if(options.loop) { - channel.setLoop(options.loop) - } - if(options.maxDistance) { - channel.setMaxDistance(options.maxDistance) - } - if(options.minDistance) { - channel.setMinDistance(options.minDistance) - } - if(options.rollOffFactor) { - channel.setRollOffFactor(options.rollOffFactor) - } - channel.play() - } - return channel - }, getListener:function() { - return this.listener - }, getVolume:function() { - return this.volume - }, setVolume:function(volume) { - this.volume = volume; - this.fire("volumechange", volume) - }, suspend:function() { - this.suspended = true; - this.fire("suspend") - }, resume:function() { - this.suspended = false; - this.fire("resume") - }, destroy:function() { - if(this.context && this.context.close) { - this.context.close(); - this.context = null - } - }}; - return{AudioManager:AudioManager} -}()); -pc.extend(pc, function() { - var Sound; - if(pc.AudioManager.hasAudioContext()) { - Sound = function(manager, url, success, error) { - this.buffer = null; - this.isLoaded = false; - if(!pc.AudioManager.isSupported(url, this.audio)) { - setTimeout(function() { - error(pc.string.format("Audio format for {0} not supported", url)) - }, 0) - }else { - if(manager.context) { - pc.net.http.get(url, function(response) { - manager.context.decodeAudioData(response, function(buffer) { - this.buffer = buffer; - this.isLoaded = true; - success(this) - }.bind(this), error) - }.bind(this), {error:error}) - } - } - } - }else { - if(pc.AudioManager.hasAudio()) { - Sound = function(manager, url, success, error) { - this.isLoaded = false; - this.audio = new Audio; - this.audio.oncanplaythrough = function() { - if(!this.isLoaded) { - this.isLoaded = true; - success(this) - } - }.bind(this); - this.audio.src = url - } - } - } - return{Sound:Sound} -}()); -pc.extend(pc, function() { - var Listener = function(manager) { - this.position = new pc.Vec3; - this.velocity = new pc.Vec3; - this.orientation = new pc.Mat4; - if(pc.AudioManager.hasAudioContext()) { - this.listener = manager.context.listener - } - }; - Listener.prototype = {getPosition:function() { - return this.position - }, setPosition:function(position) { - this.position.copy(position); - if(this.listener) { - this.listener.setPosition(position.x, position.y, position.z) - } - }, getVelocity:function() { - return this.velocity - }, setVelocity:function(velocity) { - this.velocity.copy(velocity); - if(this.listener) { - this.listener.setPosition(velocity.x, velocity.y, velocity.z) - } - }, setOrientation:function(orientation) { - this.orientation.copy(orientation); - if(this.listener) { - this.listener.setOrientation(-orientation.data[8], -orientation.data[9], -orientation.data[10], orientation.data[4], orientation.data[5], orientation.data[6]) - } - }, getOrientation:function() { - return this.orientation - }}; - return{Listener:Listener} -}()); -pc.extend(pc, function() { - var Channel; - if(pc.AudioManager.hasAudioContext()) { - Channel = function(manager, sound, options) { - options = options || {}; - this.volume = options.volume === undefined ? 1 : options.volume; - this.loop = options.loop === undefined ? false : options.loop; - this.pitch = options.pitch === undefined ? 1 : options.pitch; - this.sound = sound; - this.paused = false; - this.suspended = false; - this.startTime = 0; - this.startOffset = 0; - this.manager = manager; - this.source = null; - var context = manager.context; - this.gain = context.createGain() - }; - Channel.prototype = {play:function() { - if(this.source) { - throw new Error("Call stop() before calling play()"); - } - this._createSource(); - this.startTime = this.manager.context.currentTime; - this.source.start(0, this.startOffset % this.source.buffer.duration); - this.setVolume(this.volume); - this.setLoop(this.loop); - this.setPitch(this.pitch); - this.manager.on("volumechange", this.onManagerVolumeChange, this); - this.manager.on("suspend", this.onManagerSuspend, this); - this.manager.on("resume", this.onManagerResume, this) - }, pause:function() { - if(this.source) { - this.paused = true; - this.startOffset += this.manager.context.currentTime - this.startTime; - this.source.stop(0); - this.source = null - } - }, unpause:function() { - if(this.source || !this.paused) { - throw new Error("Call pause() before unpausing."); - } - this._createSource(); - this.startTime = this.manager.context.currentTime; - this.source.start(0, this.startOffset % this.source.buffer.duration); - this.setVolume(this.volume); - this.setLoop(this.loop); - this.setPitch(this.pitch); - this.paused = false - }, stop:function() { - if(this.source) { - this.source.stop(0); - this.source = null - } - this.manager.off("volumechange", this.onManagerVolumeChange, this); - this.manager.off("suspend", this.onManagerSuspend, this); - this.manager.off("resume", this.onManagerResume, this) - }, setLoop:function(loop) { - this.loop = loop; - if(this.source) { - this.source.loop = loop - } - }, setVolume:function(volume) { - this.volume = volume; - if(this.gain) { - this.gain.gain.value = volume * this.manager.getVolume() - } - }, setPitch:function(pitch) { - this.pitch = pitch; - if(this.source) { - this.source.playbackRate.value = pitch - } - }, isPlaying:function() { - return!this.paused && this.source.playbackState === this.source.PLAYING_STATE - }, getDuration:function() { - if(this.source) { - return this.source.buffer.duration - }else { - return 0 - } - }, _createSource:function() { - var context = this.manager.context; - this.source = context.createBufferSource(); - this.source.buffer = this.sound.buffer; - this.source.connect(this.gain); - this.gain.connect(context.destination); - if(!this.loop) { - this.source.onended = this.pause.bind(this) - } - }} - }else { - if(pc.AudioManager.hasAudio()) { - Channel = function(manager, sound, options) { - this.volume = options.volume || 1; - this.loop = options.loop || false; - this.sound = sound; - this.pitch = options.pitch !== undefined ? options.pitch : 1; - this.paused = false; - this.suspended = false; - this.manager = manager; - this.source = sound.audio.cloneNode(false); - this.source.pause() - }; - Channel.prototype = {play:function() { - if(this.source) { - this.paused = false; - this.setVolume(this.volume); - this.setLoop(this.loop); - this.setPitch(this.pitch); - this.source.play() - } - this.manager.on("volumechange", this.onManagerVolumeChange, this); - this.manager.on("suspend", this.onManagerSuspend, this); - this.manager.on("resume", this.onManagerResume, this) - }, pause:function() { - if(this.source) { - this.paused = true; - this.source.pause() - } - }, unpause:function() { - if(this.source) { - this.paused = false; - this.source.play() - } - }, stop:function() { - if(this.source) { - this.source.pause() - } - this.manager.off("volumechange", this.onManagerVolumeChange, this); - this.manager.off("suspend", this.onManagerSuspend, this); - this.manager.off("resume", this.onManagerResume, this) - }, setVolume:function(volume) { - this.volume = volume; - if(this.source) { - this.source.volume = volume * this.manager.getVolume() - } - }, setLoop:function(loop) { - this.loop = loop; - if(this.source) { - this.source.loop = loop - } - }, setPitch:function(pitch) { - this.pitch = pitch; - if(this.source) { - this.source.playbackRate = pitch - } - }, getDuration:function() { - if(this.source) { - var d = this.source.duration; - if(d === d) { - return d - } - } - return 0 - }, isPlaying:function() { - return!this.source.paused - }} - }else { - console.warn("No support for 2D audio found"); - Channel = function() { - } - } - } - pc.extend(Channel.prototype, {getVolume:function() { - return this.volume - }, getLoop:function() { - return this.loop - }, getPitch:function() { - return this.pitch - }, onManagerVolumeChange:function() { - this.setVolume(this.getVolume()) - }, onManagerSuspend:function() { - if(this.isPlaying() && !this.suspended) { - this.suspended = true; - this.pause() - } - }, onManagerResume:function() { - if(this.suspended) { - this.suspended = false; - this.unpause() - } - }}); - return{Channel:Channel} -}()); -pc.extend(pc, function() { - var MAX_DISTANCE = 1E4; - var Channel3d; - if(pc.AudioManager.hasAudioContext()) { - Channel3d = function(manager, sound, options) { - this.position = new pc.Vec3; - this.velocity = new pc.Vec3; - var context = manager.context; - this.panner = context.createPanner() - }; - Channel3d = pc.inherits(Channel3d, pc.Channel); - Channel3d.prototype = pc.extend(Channel3d.prototype, {getPosition:function() { - return this.position - }, setPosition:function(position) { - this.position.copy(position); - this.panner.setPosition(position.x, position.y, position.z) - }, getVelocity:function() { - return this.velocity - }, setVelocity:function(velocity) { - this.velocity.copy(velocity); - this.panner.setVelocity(velocity.x, velocity.y, velocity.z) - }, getMaxDistance:function() { - return this.panner.maxDistance - }, setMaxDistance:function(max) { - this.panner.maxDistance = max - }, getMinDistance:function() { - return this.panner.refDistance - }, setMinDistance:function(min) { - this.panner.refDistance = min - }, getRollOffFactor:function() { - return this.panner.rolloffFactor - }, setRollOffFactor:function(factor) { - this.panner.rolloffFactor = factor - }, _createSource:function() { - var context = this.manager.context; - this.source = context.createBufferSource(); - this.source.buffer = this.sound.buffer; - this.source.connect(this.panner); - this.panner.connect(this.gain); - this.gain.connect(context.destination) - }}) - }else { - if(pc.AudioManager.hasAudio()) { - var offset = new pc.Vec3; - var distance; - var fallOff = function(posOne, posTwo, refDistance, maxDistance, rolloffFactor) { - var min = 0; - offset = offset.sub2(posOne, posTwo); - distance = offset.length(); - if(distance < refDistance) { - return 1 - }else { - if(distance > maxDistance) { - return 0 - }else { - var numerator = refDistance + rolloffFactor * (distance - refDistance); - if(numerator !== 0) { - return refDistance / numerator - }else { - return 1 - } - } - } - }; - Channel3d = function(manager, sound) { - this.position = new pc.Vec3; - this.velocity = new pc.Vec3; - this.maxDistance = MAX_DISTANCE; - this.minDistance = 1; - this.rollOffFactor = 1 - }; - Channel3d = pc.inherits(Channel3d, pc.Channel); - Channel3d.prototype = pc.extend(Channel3d.prototype, {getPosition:function() { - return this.position - }, setPosition:function(position) { - this.position.copy(position); - if(this.source) { - var listener = this.manager.getListener(); - var lpos = listener.getPosition(); - var factor = fallOff(lpos, this.position, this.minDistance, this.maxDistance, this.rollOffFactor); - var v = this.getVolume(); - this.source.volume = v * factor - } - }, getVelocity:function() { - return this.velocity - }, setVelocity:function(velocity) { - this.velocity.copy(velocity) - }, getMaxDistance:function() { - return this.maxDistance - }, setMaxDistance:function(max) { - this.maxDistance = max - }, getMinDistance:function() { - return this.minDistance - }, setMinDistance:function(min) { - this.minDistance = min - }, getRollOffFactor:function() { - return this.rolloffFactor - }, setRollOffFactor:function(factor) { - this.rolloffFactor = factor - }}) - }else { - console.warn("No support for 3D audio found"); - Channel3d = function() { - } - } - } - return{Channel3d:Channel3d} -}()); -(function() { - var enums = {ACTION_MOUSE:"mouse", ACTION_KEYBOARD:"keyboard", ACTION_GAMEPAD:"gamepad", AXIS_MOUSE_X:"mousex", AXIS_MOUSE_Y:"mousey", AXIS_PAD_L_X:"padlx", AXIS_PAD_L_Y:"padly", AXIS_PAD_R_X:"padrx", AXIS_PAD_R_Y:"padry", AXIS_KEY:"key", EVENT_KEYDOWN:"keydown", EVENT_KEYUP:"keyup", EVENT_MOUSEDOWN:"mousedown", EVENT_MOUSEMOVE:"mousemove", EVENT_MOUSEUP:"mouseup", EVENT_MOUSEWHEEL:"mousewheel", EVENT_TOUCHSTART:"touchstart", EVENT_TOUCHEND:"touchend", EVENT_TOUCHMOVE:"touchmove", EVENT_TOUCHCANCEL:"touchcancel", - KEY_BACKSPACE:8, KEY_TAB:9, KEY_RETURN:13, KEY_ENTER:14, KEY_SHIFT:16, KEY_CONTROL:17, KEY_ALT:18, KEY_PAUSE:19, KEY_CAPS_LOCK:20, KEY_ESCAPE:27, KEY_SPACE:32, KEY_PAGE_UP:33, KEY_PAGE_DOWN:34, KEY_END:35, KEY_HOME:36, KEY_LEFT:37, KEY_UP:38, KEY_RIGHT:39, KEY_DOWN:40, KEY_PRINT_SCREEN:44, KEY_INSERT:45, KEY_DELETE:46, KEY_0:48, KEY_1:49, KEY_2:50, KEY_3:51, KEY_4:52, KEY_5:53, KEY_6:54, KEY_7:55, KEY_8:56, KEY_9:57, KEY_SEMICOLON:59, KEY_EQUAL:61, KEY_A:65, KEY_B:66, KEY_C:67, KEY_D:68, KEY_E:69, - KEY_F:70, KEY_G:71, KEY_H:72, KEY_I:73, KEY_J:74, KEY_K:75, KEY_L:76, KEY_M:77, KEY_N:78, KEY_O:79, KEY_P:80, KEY_Q:81, KEY_R:82, KEY_S:83, KEY_T:84, KEY_U:85, KEY_V:86, KEY_W:87, KEY_X:88, KEY_Y:89, KEY_Z:90, KEY_WINDOWS:91, KEY_CONTEXT_MENU:93, KEY_NUMPAD_0:96, KEY_NUMPAD_1:97, KEY_NUMPAD_2:98, KEY_NUMPAD_3:99, KEY_NUMPAD_4:100, KEY_NUMPAD_5:101, KEY_NUMPAD_6:102, KEY_NUMPAD_7:103, KEY_NUMPAD_8:104, KEY_NUMPAD_9:105, KEY_MULTIPLY:106, KEY_ADD:107, KEY_SEPARATOR:108, KEY_SUBTRACT:109, KEY_DECIMAL:110, - KEY_DIVIDE:111, KEY_F1:112, KEY_F2:113, KEY_F3:114, KEY_F4:115, KEY_F5:116, KEY_F6:117, KEY_F7:118, KEY_F8:119, KEY_F9:120, KEY_F10:121, KEY_F11:122, KEY_F12:123, KEY_COMMA:188, KEY_PERIOD:190, KEY_SLASH:191, KEY_OPEN_BRACKET:219, KEY_BACK_SLASH:220, KEY_CLOSE_BRACKET:221, KEY_META:224, MOUSEBUTTON_NONE:-1, MOUSEBUTTON_LEFT:0, MOUSEBUTTON_MIDDLE:1, MOUSEBUTTON_RIGHT:2, PAD_1:0, PAD_2:1, PAD_3:2, PAD_4:3, PAD_FACE_1:0, PAD_FACE_2:1, PAD_FACE_3:2, PAD_FACE_4:3, PAD_L_SHOULDER_1:4, PAD_R_SHOULDER_1:5, - PAD_L_SHOULDER_2:6, PAD_R_SHOULDER_2:7, PAD_SELECT:8, PAD_START:9, PAD_L_STICK_BUTTON:10, PAD_R_STICK_BUTTON:11, PAD_UP:12, PAD_DOWN:13, PAD_LEFT:14, PAD_RIGHT:15, PAD_VENDOR:16, PAD_L_STICK_X:0, PAD_L_STICK_Y:1, PAD_R_STICK_X:2, PAD_R_STICK_Y:3}; - pc.extend(pc, enums); - pc.input = {}; - pc.extend(pc.input, enums) -})(); -pc.extend(pc, function() { - var MouseEvent = function(mouse, event) { - var coords = {x:0, y:0}; - if(event) { - if(event instanceof MouseEvent) { - throw Error("Expected MouseEvent"); - } - coords = mouse._getTargetCoords(event) - }else { - event = {} - } - if(coords) { - this.x = coords.x; - this.y = coords.y - }else { - if(pc.Mouse.isPointerLocked()) { - this.x = 0; - this.y = 0 - }else { - return - } - } - if(event.detail) { - this.wheel = -1 * event.detail - }else { - if(event.wheelDelta) { - this.wheel = event.wheelDelta / 120 - }else { - this.wheel = 0 - } - } - if(pc.Mouse.isPointerLocked()) { - this.dx = event.movementX || event.webkitMovementX || event.mozMovementX || 0; - this.dy = event.movementY || event.webkitMovementY || event.mozMovementY || 0 - }else { - this.dx = this.x - mouse._lastX; - this.dy = this.y - mouse._lastY - } - if(event.type === "mousedown" || event.type === "mouseup") { - this.button = event.button - }else { - this.button = pc.MOUSEBUTTON_NONE - } - this.buttons = mouse._buttons.slice(0); - this.element = event.target; - this.ctrlKey = event.ctrlKey || false; - this.altKey = event.altKey || false; - this.shiftKey = event.shiftKey || false; - this.metaKey = event.metaKey || false; - this.event = event - }; - var Mouse = function(element) { - this._lastX = 0; - this._lastY = 0; - this._buttons = [false, false, false]; - this._lastbuttons = [false, false, false]; - this._upHandler = this._handleUp.bind(this); - this._downHandler = this._handleDown.bind(this); - this._moveHandler = this._handleMove.bind(this); - this._wheelHandler = this._handleWheel.bind(this); - this._contextMenuHandler = function(event) { - event.preventDefault() - }; - this._target = null; - this._attached = false; - this.attach(element); - pc.events.attach(this) - }; - Mouse.isPointerLocked = function() { - return!!(document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement) - }; - Mouse.prototype = {attach:function(element) { - this._target = element; - if(this._attached) { - return - } - this._attached = true; - window.addEventListener("mouseup", this._upHandler, false); - window.addEventListener("mousedown", this._downHandler, false); - window.addEventListener("mousemove", this._moveHandler, false); - window.addEventListener("mousewheel", this._wheelHandler, false); - window.addEventListener("DOMMouseScroll", this._wheelHandler, false) - }, detach:function() { - if(!this._attached) { - return - } - this._attached = false; - window.removeEventListener("mouseup", this._upHandler); - window.removeEventListener("mousedown", this._downHandler); - window.removeEventListener("mousemove", this._moveHandler); - window.removeEventListener("mousewheel", this._wheelHandler); - window.removeEventListener("DOMMouseScroll", this._wheelHandler) - }, disableContextMenu:function() { - if(!this._target) { - return - } - this._target.addEventListener("contextmenu", this._contextMenuHandler) - }, enableContextMenu:function() { - if(!this._target) { - return - } - this._target.removeEventListener("contextmenu", this._contextMenuHandler) - }, enablePointerLock:function(success, error) { - var s = function() { - success(); - document.removeEventListener("pointerlockchange", s) - }; - var e = function() { - error(); - document.removeEventListener("pointerlockerror", e) - }; - if(success) { - document.addEventListener("pointerlockchange", s, false) - } - if(error) { - document.addEventListener("pointerlockerror", e, false) - } - document.body.requestPointerLock() - }, disablePointerLock:function(success) { - var s = function() { - success(); - document.removeEventListener("pointerlockchange", s) - }; - if(success) { - document.addEventListener("pointerlockchange", s, false) - } - document.exitPointerLock() - }, update:function(dt) { - this._lastbuttons[0] = this._buttons[0]; - this._lastbuttons[1] = this._buttons[1]; - this._lastbuttons[2] = this._buttons[2] - }, isPressed:function(button) { - return this._buttons[button] - }, wasPressed:function(button) { - return this._buttons[button] && !this._lastbuttons[button] - }, wasReleased:function(button) { - return!this._buttons[button] && this._lastbuttons[button] - }, _handleUp:function(event) { - this._buttons[event.button] = false; - var e = new MouseEvent(this, event); - if(!e.event) { - return - } - this.fire(pc.EVENT_MOUSEUP, e) - }, _handleDown:function(event) { - this._buttons[event.button] = true; - var e = new MouseEvent(this, event); - if(!e.event) { - return - } - this.fire(pc.EVENT_MOUSEDOWN, e) - }, _handleMove:function(event) { - var e = new MouseEvent(this, event); - if(!e.event) { - return - } - this.fire(pc.EVENT_MOUSEMOVE, e); - this._lastX = e.x; - this._lastY = e.y - }, _handleWheel:function(event) { - var e = new MouseEvent(this, event); - if(!e.event) { - return - } - this.fire(pc.EVENT_MOUSEWHEEL, e) - }, _getTargetCoords:function(event) { - var rect = this._target.getBoundingClientRect(); - var left = Math.floor(rect.left); - var top = Math.floor(rect.top); - if(event.clientX < left || event.clientX >= left + this._target.clientWidth || event.clientY < top || event.clientY >= top + this._target.clientHeight) { - return null - } - return{x:event.clientX - left, y:event.clientY - top} - }}; - (function() { - if(typeof navigator === "undefined" || typeof document === "undefined") { - return - } - navigator.pointer = navigator.pointer || navigator.webkitPointer || navigator.mozPointer; - var pointerlockchange = function() { - var e = document.createEvent("CustomEvent"); - e.initCustomEvent("pointerlockchange", true, false, null); - document.dispatchEvent(e) - }; - var pointerlockerror = function() { - var e = document.createEvent("CustomEvent"); - e.initCustomEvent("pointerlockerror", true, false, null); - document.dispatchEvent(e) - }; - document.addEventListener("webkitpointerlockchange", pointerlockchange, false); - document.addEventListener("webkitpointerlocklost", pointerlockchange, false); - document.addEventListener("mozpointerlockchange", pointerlockchange, false); - document.addEventListener("mozpointerlocklost", pointerlockchange, false); - document.addEventListener("webkitpointerlockerror", pointerlockerror, false); - document.addEventListener("mozpointerlockerror", pointerlockerror, false); - if(Element.prototype.mozRequestPointerLock) { - Element.prototype.requestPointerLock = function() { - this.mozRequestPointerLock() - } - }else { - Element.prototype.requestPointerLock = Element.prototype.requestPointerLock || Element.prototype.webkitRequestPointerLock || Element.prototype.mozRequestPointerLock - } - if(!Element.prototype.requestPointerLock && navigator.pointer) { - Element.prototype.requestPointerLock = function() { - var el = this; - document.pointerLockElement = el; - navigator.pointer.lock(el, pointerlockchange, pointerlockerror) - } - } - document.exitPointerLock = document.exitPointerLock || document.webkitExitPointerLock || document.mozExitPointerLock; - if(!document.exitPointerLock) { - document.exitPointerLock = function() { - if(navigator.pointer) { - document.pointerLockElement = null; - navigator.pointer.unlock() - } - } - } - })(); - return{Mouse:Mouse, MouseEvent:MouseEvent} -}()); -pc.extend(pc, function() { - var KeyboardEvent = function(keyboard, event) { - this.key = event.keyCode; - this.element = event.target; - this.event = event - }; - function toKeyCode(s) { - if(typeof s == "string") { - return s.toUpperCase().charCodeAt(0) - }else { - return s - } - } - var _keyCodeToKeyIdentifier = {9:"Tab", 13:"Enter", 16:"Shift", 17:"Control", 18:"Alt", 27:"Escape", 37:"Left", 38:"Up", 39:"Right", 40:"Down", 46:"Delete", 91:"Win"}; - var Keyboard = function(element, options) { - options = options || {}; - this._element = null; - this._keyDownHandler = this._handleKeyDown.bind(this); - this._keyUpHandler = this._handleKeyUp.bind(this); - this._keyPressHandler = this._handleKeyPress.bind(this); - pc.events.attach(this); - this._keymap = {}; - this._lastmap = {}; - if(element) { - this.attach(element) - } - this.preventDefault = options.preventDefault || false; - this.stopPropagation = options.stopPropagation || false - }; - Keyboard.prototype.attach = function(element) { - if(this._element) { - this.detach() - } - this._element = element; - this._element.addEventListener("keydown", this._keyDownHandler, false); - this._element.addEventListener("keypress", this._keyPressHandler, false); - this._element.addEventListener("keyup", this._keyUpHandler, false) - }; - Keyboard.prototype.detach = function() { - this._element.removeEventListener("keydown", this._keyDownHandler); - this._element.removeEventListener("keypress", this._keyPressHandler); - this._element.removeEventListener("keyup", this._keyUpHandler); - this._element = null - }; - Keyboard.prototype.toKeyIdentifier = function(keyCode) { - keyCode = toKeyCode(keyCode); - var count; - var hex; - var length; - var id = _keyCodeToKeyIdentifier[keyCode.toString()]; - if(id) { - return id - } - hex = keyCode.toString(16).toUpperCase(); - length = hex.length; - for(count = 0;count < 4 - length;count++) { - hex = "0" + hex - } - return"U+" + hex - }; - Keyboard.prototype._handleKeyDown = function(event) { - var code = event.keyCode || event.charCode; - var id = event.keyIdentifier || this.toKeyIdentifier(code); - this._keymap[id] = true; - this.fire("keydown", new KeyboardEvent(this, event)); - if(this.preventDefault) { - event.preventDefault() - } - if(this.stopPropagation) { - event.stopPropagation() - } - }; - Keyboard.prototype._handleKeyUp = function(event) { - var code = event.keyCode || event.charCode; - var id = event.keyIdentifier || this.toKeyIdentifier(code); - delete this._keymap[id]; - this.fire("keyup", new KeyboardEvent(this, event)); - if(this.preventDefault) { - event.preventDefault() - } - if(this.stopPropagation) { - event.stopPropagation() - } - }; - Keyboard.prototype._handleKeyPress = function(event) { - var code = event.keyCode || event.charCode; - var id = event.keyIdentifier || this.toKeyIdentifier(code); - this.fire("keypress", new KeyboardEvent(this, event)); - if(this.preventDefault) { - event.preventDefault() - } - if(this.stopPropagation) { - event.stopPropagation() - } - }; - Keyboard.prototype.update = function(dt) { - var prop; - this._lastmap = {}; - for(prop in this._keymap) { - if(this._keymap.hasOwnProperty(prop)) { - this._lastmap[prop] = this._keymap[prop] - } - } - }; - Keyboard.prototype.isPressed = function(key) { - var keyCode = toKeyCode(key); - var id = this.toKeyIdentifier(keyCode); - return!!this._keymap[id] - }; - Keyboard.prototype.wasPressed = function(key) { - var keyCode = toKeyCode(key); - var id = this.toKeyIdentifier(keyCode); - return!!this._keymap[id] && !!!this._lastmap[id] - }; - Keyboard.prototype.wasReleased = function(key) { - var keyCode = toKeyCode(key); - var id = this.toKeyIdentifier(keyCode); - return!!!this._keymap[id] && !!this._lastmap[id] - }; - return{Keyboard:Keyboard} -}()); -pc.extend(pc, function() { - var GamePads = function() { - this.gamepadsSupported = !!navigator.getGamepads || !!navigator.webkitGetGamepads; - this.current = []; - this.previous = []; - this.deadZone = 0.25 - }; - var MAPS = {DEFAULT:{buttons:["PAD_FACE_1", "PAD_FACE_2", "PAD_FACE_3", "PAD_FACE_4", "PAD_L_SHOULDER_1", "PAD_R_SHOULDER_1", "PAD_L_SHOULDER_2", "PAD_R_SHOULDER_2", "PAD_SELECT", "PAD_START", "PAD_L_STICK_BUTTON", "PAD_R_STICK_BUTTON", "PAD_UP", "PAD_DOWN", "PAD_LEFT", "PAD_RIGHT", "PAD_VENDOR"], axes:["PAD_L_STICK_X", "PAD_L_STICK_Y", "PAD_R_STICK_X", "PAD_R_STICK_Y"]}, PS3:{buttons:["PAD_FACE_1", "PAD_FACE_2", "PAD_FACE_4", "PAD_FACE_3", "PAD_L_SHOULDER_1", "PAD_R_SHOULDER_1", "PAD_L_SHOULDER_2", - "PAD_R_SHOULDER_2", "PAD_SELECT", "PAD_START", "PAD_L_STICK_BUTTON", "PAD_R_STICK_BUTTON", "PAD_UP", "PAD_DOWN", "PAD_LEFT", "PAD_RIGHT", "PAD_VENDOR"], axes:["PAD_L_STICK_X", "PAD_L_STICK_Y", "PAD_R_STICK_X", "PAD_R_STICK_Y"]}}; - var PRODUCT_CODES = {"Product: 0268":"PS3"}; - GamePads.prototype = {update:function(dt) { - var pads = this.poll(); - var i, len = pads.length; - for(i = 0;i < len;i++) { - this.previous[i] = this.current[i]; - this.current[i] = pads[i] - } - }, poll:function() { - var pads = []; - if(this.gamepadsSupported) { - var padDevices = navigator.getGamepads ? navigator.getGamepads() : navigator.webkitGetGamepads(); - var i, len = padDevices.length; - for(i = 0;i < len;i++) { - if(padDevices[i]) { - pads.push({map:this.getMap(padDevices[i]), pad:padDevices[i]}) - } - } - } - return pads - }, getMap:function(pad) { - for(var code in PRODUCT_CODES) { - if(pad.id.indexOf(code) >= 0) { - return MAPS[PRODUCT_CODES[code]] - } - } - return MAPS.DEFAULT - }, isPressed:function(index, button) { - if(!this.current[index]) { - return false - } - var key = this.current[index].map.buttons[button]; - return this.current[index].pad.buttons[pc[key]].pressed - }, wasPressed:function(index, button) { - if(!this.current[index]) { - return false - } - var key = this.current[index].map.buttons[button]; - var i = pc[key]; - return this.current[index].pad.buttons[i].pressed && !this.previous[index].pad.buttons[i].pressed - }, getAxis:function(index, axes) { - if(!this.current[index]) { - return false - } - var key = this.current[index].map.axes[axes]; - var value = this.current[index].pad.axes[pc[key]]; - if(Math.abs(value) < this.deadZone) { - value = 0 - } - return value - }}; - return{GamePads:GamePads} -}()); -pc.extend(pc, function() { - var TouchEvent = function(device, event) { - this.element = event.target; - this.event = event; - this.touches = []; - this.changedTouches = []; - if(event) { - var i, l = event.touches.length; - for(i = 0;i < l;i++) { - this.touches.push(new Touch(event.touches[i])) - } - l = event.changedTouches.length; - for(i = 0;i < l;i++) { - this.changedTouches.push(new Touch(event.changedTouches[i])) - } - } - }; - TouchEvent.prototype = {getTouchById:function(id, list) { - var i, l = list.length; - for(i = 0;i < l;i++) { - if(list[i].id === id) { - return list[i] - } - } - return null - }}; - var Touch = function(touch) { - var coords = pc.getTouchTargetCoords(touch); - this.id = touch.identifier; - this.x = coords.x; - this.y = coords.y; - this.target = touch.target; - this.touch = touch - }; - var TouchDevice = function(element) { - this._startHandler = this._handleTouchStart.bind(this); - this._endHandler = this._handleTouchEnd.bind(this); - this._moveHandler = this._handleTouchMove.bind(this); - this._cancelHandler = this._handleTouchCancel.bind(this); - this.attach(element); - pc.events.attach(this) - }; - TouchDevice.prototype = {attach:function(element) { - if(this._element) { - this.detach() - } - this._element = element; - this._element.addEventListener("touchstart", this._startHandler, false); - this._element.addEventListener("touchend", this._endHandler, false); - this._element.addEventListener("touchmove", this._moveHandler, false); - this._element.addEventListener("touchcancel", this._cancelHandler, false) - }, detach:function() { - if(this._element) { - this._element.removeEventListener("touchstart", this._startHandler, false); - this._element.removeEventListener("touchend", this._endHandler, false); - this._element.removeEventListener("touchmove", this._moveHandler, false); - this._element.removeEventListener("touchcancel", this._cancelHandler, false) - } - this._element = null - }, _handleTouchStart:function(e) { - this.fire("touchstart", new TouchEvent(this, e)) - }, _handleTouchEnd:function(e) { - this.fire("touchend", new TouchEvent(this, e)) - }, _handleTouchMove:function(e) { - e.preventDefault(); - this.fire("touchmove", new TouchEvent(this, e)) - }, _handleTouchCancel:function(e) { - this.fire("touchcancel", new TouchEvent(this, e)) - }}; - return{getTouchTargetCoords:function(touch) { - var totalOffsetX = 0; - var totalOffsetY = 0; - var canvasX = 0; - var canvasY = 0; - var target = touch.target; - while(!(target instanceof HTMLElement)) { - target = target.parentNode - } - var currentElement = target; - do { - totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft; - totalOffsetY += currentElement.offsetTop - currentElement.scrollTop; - currentElement = currentElement.offsetParent - }while(currentElement); - return{x:touch.pageX - totalOffsetX, y:touch.pageY - totalOffsetY} - }, TouchDevice:TouchDevice} -}()); -pc.extend(pc, function() { - var Controller = function(element, options) { - options = options || {}; - this._keyboard = options.keyboard || null; - this._mouse = options.mouse || null; - this._gamepads = options.gamepads || null; - this._element = null; - this._actions = {}; - this._axes = {}; - this._axesValues = {}; - if(element) { - this.attach(element) - } - }; - Controller.prototype.attach = function(element) { - this._element = element; - if(this._keyboard) { - this._keyboard.attach(element) - } - if(this._mouse) { - this._mouse.attach(element) - } - }; - Controller.prototype.detach = function() { - if(this._keyboard) { - this._keyboard.detach() - } - if(this._mouse) { - this._mouse.detach() - } - this._element = null - }; - Controller.prototype.disableContextMenu = function() { - if(!this._mouse) { - this._enableMouse() - } - this._mouse.disableContextMenu() - }; - Controller.prototype.enableContextMenu = function() { - if(!this._mouse) { - this._enableMouse() - } - this._mouse.enableContextMenu() - }; - Controller.prototype.update = function(dt) { - if(this._keyboard) { - this._keyboard.update(dt) - } - if(this._mouse) { - this._mouse.update(dt) - } - if(this._gamepads) { - this._gamepads.update(dt) - } - this._axesValues = {}; - for(var key in this._axes) { - this._axesValues[key] = [] - } - }; - Controller.prototype.registerKeys = function(action, keys) { - if(!this._keyboard) { - this._enableKeyboard() - } - if(this._actions[action]) { - throw new Error(pc.string.format("Action: {0} already registered", action)); - } - if(keys === undefined) { - throw new Error("Invalid button"); - } - if(!keys.length) { - keys = [keys] - } - if(this._actions[action]) { - this._actions[action].push({type:pc.ACTION_KEYBOARD, keys:keys}) - }else { - this._actions[action] = [{type:pc.ACTION_KEYBOARD, keys:keys}] - } - }; - Controller.prototype.registerMouse = function(action, button) { - if(!this._mouse) { - this._enableMouse() - } - if(button === undefined) { - throw new Error("Invalid button"); - } - if(this._actions[action]) { - this._actions[action].push({type:pc.ACTION_MOUSE, button:button}) - }else { - this._actions[action] = [{type:pc.ACTION_MOUSE, button:-button}] - } - }; - Controller.prototype.registerPadButton = function(action, pad, button) { - if(button === undefined) { - throw new Error("Invalid button"); - } - if(this._actions[action]) { - this._actions[action].push({type:pc.ACTION_GAMEPAD, button:button, pad:pad}) - }else { - this._actions[action] = [{type:pc.ACTION_GAMEPAD, button:button, pad:pad}] - } - }; - Controller.prototype.registerAxis = function(options) { - var name = options.name; - if(!this._axes[name]) { - this._axes[name] = [] - } - var i = this._axes[name].push(name); - options = options || {}; - options.pad = options.pad || pc.PAD_1; - var bind = function(controller, source, value, key) { - switch(source) { - case "mousex": - controller._mouse.on(pc.EVENT_MOUSEMOVE, function(e) { - controller._axesValues[name][i] = e.dx / 10 - }); - break; - case "mousey": - controller._mouse.on(pc.EVENT_MOUSEMOVE, function(e) { - controller._axesValues[name][i] = e.dy / 10 - }); - break; - case "key": - controller._axes[name].push(function() { - return controller._keyboard.isPressed(key) ? value : 0 - }); - break; - case "padrx": - controller._axes[name].push(function() { - return controller._gamepads.getAxis(options.pad, pc.PAD_R_STICK_X) - }); - break; - case "padry": - controller._axes[name].push(function() { - return controller._gamepads.getAxis(options.pad, pc.PAD_R_STICK_Y) - }); - break; - case "padlx": - controller._axes[name].push(function() { - return controller._gamepads.getAxis(options.pad, pc.PAD_L_STICK_X) - }); - break; - case "padly": - controller._axes[name].push(function() { - return controller._gamepads.getAxis(options.pad, pc.PAD_L_STICK_Y) - }); - break; - default: - throw new Error("Unknown axis"); - } - }; - bind(this, options.positive, 1, options.positiveKey); - if(options.negativeKey || options.negative !== options.positive) { - bind(this, options.negative, -1, options.negativeKey) - } - }; - Controller.prototype.isPressed = function(actionName) { - if(!this._actions[actionName]) { - return false - } - var action; - var index = 0; - var length = this._actions[actionName].length; - for(index = 0;index < length;++index) { - action = this._actions[actionName][index]; - switch(action.type) { - case pc.ACTION_KEYBOARD: - if(this._keyboard) { - var i, len = action.keys.length; - for(i = 0;i < len;i++) { - if(this._keyboard.isPressed(action.keys[i])) { - return true - } - } - } - break; - case pc.ACTION_MOUSE: - if(this._mouse && this._mouse.isPressed(action.button)) { - return true - } - break; - case pc.ACTION_GAMEPAD: - if(this._gamepads && this._gamepads.isPressed(action.pad, action.button)) { - return true - } - break - } - } - return false - }; - Controller.prototype.wasPressed = function(actionName) { - if(!this._actions[actionName]) { - return false - } - var index = 0; - var length = this._actions[actionName].length; - for(index = 0;index < length;++index) { - var action = this._actions[actionName][index]; - switch(action.type) { - case pc.ACTION_KEYBOARD: - if(this._keyboard) { - var i, len = action.keys.length; - for(i = 0;i < len;i++) { - if(this._keyboard.wasPressed(action.keys[i])) { - return true - } - } - } - break; - case pc.ACTION_MOUSE: - if(this._mouse && this._mouse.wasPressed(action.button)) { - return true - } - break; - case pc.ACTION_GAMEPAD: - if(this._gamepads && this._gamepads.wasPressed(action.pad, action.button)) { - return true - } - break - } - } - return false - }; - Controller.prototype.getAxis = function(name) { - var value = 0; - if(this._axes[name]) { - var i, len = this._axes[name].length; - for(i = 0;i < len;i++) { - if(pc.type(this._axes[name][i]) === "function") { - var v = this._axes[name][i](); - if(Math.abs(v) > Math.abs(value)) { - value = v - } - }else { - if(this._axesValues[name]) { - if(Math.abs(this._axesValues[name][i]) > Math.abs(value)) { - value = this._axesValues[name][i] - } - } - } - } - } - return value - }; - Controller.prototype._enableMouse = function() { - this._mouse = new pc.Mouse; - if(!this._element) { - throw new Error("Controller must be attached to a DOMElement"); - } - this._mouse.attach(this._element) - }; - Controller.prototype._enableKeyboard = function() { - this._keyboard = new pc.Keyboard; - if(!this._element) { - throw new Error("Controller must be attached to a DOMElement"); - } - this._keyboard.attach(this._element) - }; - return{Controller:Controller} -}()); -pc.net = function() { - return{} -}(); -pc.extend(pc.net, function() { - var Http = function Http() { - }; - Http.ContentType = {FORM_URLENCODED:"application/x-www-form-urlencoded", GIF:"image/gif", JPEG:"image/jpeg", DDS:"image/dds", JSON:"application/json", PNG:"image/png", TEXT:"text/plain", XML:"application/xml", WAV:"audio/x-wav", OGG:"audio/ogg", MP3:"audio/mpeg", BIN:"application/octet-stream"}; - Http.ResponseType = {TEXT:"text", ARRAY_BUFFER:"arraybuffer", BLOB:"blob", DOCUMENT:"document"}; - Http.binaryExtensions = [".model", ".wav", ".ogg", ".mp3", ".dds"]; - Http.prototype = {ContentType:Http.ContentType, ResponseType:Http.ResponseType, binaryExtensions:Http.binaryExtensions, get:function(url, success, options, xhr) { - options = options || {}; - options.success = success; - return this.request("GET", url, options, xhr) - }, post:function(url, success, data, options, xhr) { - options = options || {}; - options.success = success; - options.postdata = data; - return this.request("POST", url, options, xhr) - }, put:function(url, success, data, options, xhr) { - options = options || {}; - options.success = success; - options.postdata = data; - return this.request("PUT", url, options, xhr) - }, del:function(url, success, options, xhr) { - options = options || {}; - options.success = success; - return this.request("DELETE", url, options, xhr) - }, request:function(method, url, options, xhr) { - var uri, query, timestamp, postdata; - var errored = false; - options = options || {}; - if(options.success == null) { - options.success = function() { - } - } - if(options.error == null) { - options.error = function() { - } - } - if(options.async == null) { - options.async = true - } - if(options.headers == null) { - options.headers = {} - } - if(options.postdata != null) { - if(options.postdata instanceof Document) { - postdata = options.postdata - }else { - if(options.postdata instanceof FormData) { - postdata = options.postdata - }else { - if(options.postdata instanceof Object) { - var contentType = options.headers["Content-Type"]; - if(!pc.isDefined(contentType)) { - options.headers["Content-Type"] = Http.ContentType.FORM_URLENCODED; - contentType = options.headers["Content-Type"] - } - switch(contentType) { - case Http.ContentType.FORM_URLENCODED: - postdata = ""; - var bFirstItem = true; - for(var key in options.postdata) { - if(options.postdata.hasOwnProperty(key)) { - if(bFirstItem) { - bFirstItem = false - }else { - postdata += "&" - } - postdata += escape(key) + "=" + escape(options.postdata[key]) - } - } - break; - case Http.ContentType.JSON: - ; - default: - if(contentType == null) { - options.headers["Content-Type"] = Http.ContentType.JSON - } - postdata = JSON.stringify(options.postdata); - break - } - }else { - postdata = options.postdata - } - } - } - } - if(!xhr) { - xhr = new XMLHttpRequest - } - if(options.cache === false) { - timestamp = pc.time.now(); - uri = new pc.URI(url); - if(!uri.query) { - uri.query = "ts=" + timestamp - }else { - uri.query = uri.query + "&ts=" + timestamp - } - url = uri.toString() - } - if(options.query) { - uri = new pc.URI(url); - query = pc.extend(uri.getQuery(), options.query); - uri.setQuery(query); - url = uri.toString() - } - xhr.open(method, url, options.async); - xhr.withCredentials = true; - xhr.responseType = options.responseType || this.guessResponseType(url); - for(var header in options.headers) { - if(options.headers.hasOwnProperty(header)) { - xhr.setRequestHeader(header, options.headers[header]) - } - } - xhr.onreadystatechange = function() { - this.onReadyStateChange(method, url, options, xhr) - }.bind(this); - xhr.onerror = function() { - this.onError(method, url, options, xhr); - errored = true - }.bind(this); - try { - xhr.send(postdata) - }catch(e) { - if(!errored) { - options.error(xhr.status, xhr, e) - } - } - return xhr - }, guessResponseType:function(url) { - var uri = new pc.URI(url); - var ext = pc.path.getExtension(uri.path); - if(Http.binaryExtensions.indexOf(ext) >= 0) { - return Http.ResponseType.ARRAY_BUFFER - } - return Http.ResponseType.TEXT - }, isBinaryContentType:function(contentType) { - var binTypes = [Http.ContentType.WAV, Http.ContentType.OGG, Http.ContentType.MP3, Http.ContentType.BIN, Http.ContentType.DDS]; - if(binTypes.indexOf(contentType) >= 0) { - return true - } - return false - }, onReadyStateChange:function(method, url, options, xhr) { - if(xhr.readyState === 4) { - switch(xhr.status) { - case 0: - if(url[0] != "/") { - this.onSuccess(method, url, options, xhr) - } - break; - case 200: - ; - case 201: - ; - case 206: - ; - case 304: - this.onSuccess(method, url, options, xhr); - break; - default: - this.onError(method, url, options, xhr); - break - } - } - }, onSuccess:function(method, url, options, xhr) { - var response; - var header; - var contentType; - var parameter; - var parts; - header = xhr.getResponseHeader("Content-Type"); - if(header) { - parts = header.split(";"); - contentType = parts[0].trim(); - if(parts[1]) { - parameter = parts[1].trim() - } - } - if(contentType === this.ContentType.JSON || pc.string.endsWith(url, ".json")) { - response = JSON.parse(xhr.responseText) - }else { - if(this.isBinaryContentType(contentType)) { - response = xhr.response - }else { - if(xhr.responseType === Http.ResponseType.ARRAY_BUFFER) { - logWARNING(pc.string.format("responseType: {0} being served with Content-Type: {1}", Http.ResponseType.ARRAY_BUFFER, contentType)); - response = xhr.response - }else { - if(xhr.responseType === Http.ResponseType.DOCUMENT || contentType === this.ContentType.XML) { - response = xhr.responseXML - }else { - response = xhr.responseText - } - } - } - } - options.success(response, xhr.status, xhr) - }, onError:function(method, url, options, xhr) { - options.error(xhr.status, xhr, null) - }}; - Http.prototype.delete_ = Http.prototype.del; - return{Http:Http, http:new Http} -}()); -pc.extend(pc.net, function() { - var refreshCounter = 0; - var OAuth = function OAuth(endpoint, redirectUrl, origin, clientId, scope) { - this.clientId = clientId; - this.endpoint = endpoint; - this.redirectUrl = redirectUrl; - this.origin = origin; - this.scope = scope; - this.responseType = "token"; - this.accessToken = null; - this.OAUTH_IFRAME_ID_BASE = "pc-oauth-access-token-" - }; - OAuth = pc.inherits(OAuth, pc.net.Http); - OAuth.prototype.refreshAccessToken = function(success) { - var id = this.OAUTH_IFRAME_ID_BASE + refreshCounter++; - var handleMessage = function handleMessage(msg) { - if(msg.origin !== this.origin) { - return - } - if(msg.data.access_token) { - var iframe = document.getElementById(id); - if(iframe) { - iframe.parentNode.removeChild(iframe) - } - this.accessToken = msg.data.access_token; - success(msg.data.access_token) - }else { - if(msg.data.error) { - logERROR(msg.data.error) - }else { - logWARNING("Invalid message posted to Corazon API") - } - } - clearEvent() - }.bind(this); - window.addEventListener("message", handleMessage, false); - var clearEvent = function() { - window.removeEventListener("message", handleMessage) - }; - var params = {client_id:this.clientId, redirect_url:this.redirectUrl, scope:this.scope, response_type:this.responseType}; - var url = new pc.URI(this.endpoint); - url.setQuery(params); - var iframe = document.getElementById(id); - if(iframe) { - throw new Error("accessToken request already in progress"); - } - iframe = document.createElement("iframe"); - iframe.src = url.toString(); - iframe.id = id; - iframe.style.display = "none"; - document.body.appendChild(iframe) - }; - OAuth.prototype.request = function(method, url, options, xhr) { - options.query = options.query || {}; - options.query = pc.extend(options.query, {"access_token":this.accessToken}); - return pc.net.OAuth._super.request.call(this, method, url, options, xhr) - }; - OAuth.prototype.onError = function(method, url, options, xhr) { - if(xhr.status == 401) { - this.refreshAccessToken(function(accessToken) { - options.query.access_token = accessToken; - this.request(method, url, options, xhr) - }.bind(this)) - }else { - options.error(xhr.status, xhr, null) - } - }; - return{OAuth:OAuth, oauth:new OAuth} -}()); -pc.extend(pc.net, function() { - var Socket = function(url) { - this._ws = new WebSocket(url); - this._ws.onopen = this._handleOpen.bind(this); - this._ws.onerror = this._handleError.bind(this); - this._ws.onmessage = this._handleMessage.bind(this); - this._ws.onclose = this._handleClose.bind(this) - }; - Socket.prototype = {onopen:null, onerror:null, onmessage:null, get binaryType() { - return this._ws.binaryType - }, set binaryType(type) { - this._ws.binaryType = type - }, get readyState() { - return this._ws.readyState - }, get bufferedAmount() { - return this._ws.bufferedAmount - }, get extensions() { - return this._ws.extensions - }, get protocol() { - return this._ws.protocol - }, _handleOpen:function() { - if(this.onopen) { - this.onopen() - } - }, _handleError:function(error) { - if(this.onerror) { - this.onerror(error) - } - }, _handleMessage:function(msg) { - if(this.onmessage) { - this.onmessage(msg) - } - }, _handleClose:function() { - if(this.onclose) { - this.onclose() - } - }, send:function(msg) { - this._ws.send(msg) - }}; - return{Socket:Socket} -}()); -pc.script = function() { - var _main = null; - var _loader = null; - var script = {app:null, create:function(name, callback) { - if(callback === undefined) { - callback = attributes - } - var ScriptType = callback(pc.script.app); - ScriptType._pcScriptName = name; - pc.ScriptHandler._push(ScriptType); - this.fire("created", name, callback) - }, attribute:function(name, type, defaultValue, options) { - }}; - pc.events.attach(script); - return script -}(); -pc.extend(pc, function() { - var ContentFile = function(data) { - this.packs = data.packs || {}; - this.appProperties = data.application_properties || {}; - this.toc = data.toc || {} - }; - return{ContentFile:ContentFile} -}()); -pc.extend(pc, function() { - var Pack = function(data) { - this.hierarchy = data.hierarchy; - this.settings = data.settings - }; - return{Pack:Pack} -}()); -pc.extend(pc, function() { - var Application = function(canvas, options) { - options = options || {}; - pc.log.open(); - pc.events.attach(this); - Application._applications[canvas.id] = this; - Application._currentApplication = this; - this._time = 0; - this.timeScale = 1; - this._librariesLoaded = false; - this._fillMode = pc.FILLMODE_KEEP_ASPECT; - this._resolutionMode = pc.RESOLUTION_FIXED; - this.context = this; - this.graphicsDevice = new pc.GraphicsDevice(canvas); - this.systems = new pc.ComponentSystemRegistry; - this._audioManager = new pc.AudioManager; - this.loader = new pc.ResourceLoader; - this.scene = null; - this.root = new pc.fw.Entity(this); - this.assets = new pc.AssetRegistry(this.loader); - this.renderer = new pc.ForwardRenderer(this.graphicsDevice); - this.keyboard = options.keyboard || null; - this.mouse = options.mouse || null; - this.touch = options.touch || null; - this.gamepads = options.gamepads || null; - this._inTools = false; - this._scriptPrefix = options.scriptPrefix || ""; - this._scripts = []; - this.loader.addHandler("animation", new pc.AnimationHandler); - this.loader.addHandler("model", new pc.ModelHandler(this.graphicsDevice)); - this.loader.addHandler("material", new pc.MaterialHandler(this.assets)); - this.loader.addHandler("texture", new pc.TextureHandler(this.graphicsDevice, this.assets, this.loader)); - this.loader.addHandler("text", new pc.TextHandler); - this.loader.addHandler("json", new pc.JsonHandler); - this.loader.addHandler("audio", new pc.AudioHandler(this._audioManager)); - this.loader.addHandler("script", new pc.ScriptHandler(this)); - this.loader.addHandler("scene", new pc.SceneHandler(this)); - this.loader.addHandler("cubemap", new pc.CubemapHandler(this.graphicsDevice, this.assets, this.loader)); - this.loader.addHandler("hierarchy", new pc.HierarchyHandler(this)); - this.loader.addHandler("scenesettings", new pc.SceneSettingsHandler(this)); - var rigidbodysys = new pc.RigidBodyComponentSystem(this); - var collisionsys = new pc.CollisionComponentSystem(this); - var ballsocketjointsys = new pc.BallSocketJointComponentSystem(this); - var animationsys = new pc.AnimationComponentSystem(this); - var modelsys = new pc.ModelComponentSystem(this); - var camerasys = new pc.CameraComponentSystem(this); - var lightsys = new pc.LightComponentSystem(this); - var scriptsys = new pc.ScriptComponentSystem(this, options.scriptPrefix); - var picksys = new pc.PickComponentSystem(this); - var audiosourcesys = new pc.AudioSourceComponentSystem(this, this._audioManager); - var audiolistenersys = new pc.AudioListenerComponentSystem(this, this._audioManager); - var particlesystemsys = new pc.ParticleSystemComponentSystem(this); - if(document.hidden !== undefined) { - this._hiddenAttr = "hidden"; - document.addEventListener("visibilitychange", this.onVisibilityChange.bind(this), false) - }else { - if(document.mozHidden !== undefined) { - this._hiddenAttr = "mozHidden"; - document.addEventListener("mozvisibilitychange", this.onVisibilityChange.bind(this), false) - }else { - if(document.msHidden !== undefined) { - this._hiddenAttr = "msHidden"; - document.addEventListener("msvisibilitychange", this.onVisibilityChange.bind(this), false) - }else { - if(document.webkitHidden !== undefined) { - this._hiddenAttr = "webkitHidden"; - document.addEventListener("webkitvisibilitychange", this.onVisibilityChange.bind(this), false) - } - } - } - } - }; - Application._currentApplication = null; - Application._applications = {}; - Application.getApplication = function(id) { - if(id) { - return Application._applications[id] - }else { - return Application._currentApplication - } - }; - Application.prototype = {configure:function(url, callback) { - var self = this; - pc.net.http.get(url, function(response) { - var props = response["application_properties"]; - var assets = response["assets"]; - var scripts = response["scripts"]; - var priorityScripts = response["priority_scripts"]; - self._parseApplicationProperties(props, function(err) { - self._parseScripts(scripts, priorityScripts); - self._parseAssets(assets); - if(!err) { - callback(null) - }else { - callback(err) - } - }) - }, {error:function(status, xhr, e) { - callback(status) - }}) - }, preload:function(callback) { - var self = this; - this.systems.script.preloading = true; - var assets = this.assets.list({preload:true}); - var Progress = function(length) { - this.length = length; - this.count = 0; - this.inc = function() { - this.count++ - }; - this.done = function() { - return this.count === this.length - } - }; - var _assets = new Progress(assets.length); - var _scripts = new Progress(this._scripts.length); - var _done = false; - var done = function() { - if(!self.graphicsDevice) { - return - } - if(!_done && _assets.done() && _scripts.done()) { - _done = true; - self.systems.script.preloading = false; - callback() - } - }; - var total = assets.length + this._scripts.length; - var count = function() { - return _assets.count + _scripts.count - }; - var i; - if(_assets.length) { - for(i = 0;i < _assets.length;i++) { - if(!assets[i].loaded) { - assets[i].once("load", function(asset) { - _assets.inc(); - self.fire("preload:progress", count() / total); - if(_assets.done()) { - done() - } - }); - assets[i].once("error", function(err, asset) { - _assets.inc(); - self.fire("preload:progress", count() / total); - if(_assets.done()) { - done() - } - }); - this.assets.load(assets[i]) - }else { - _assets.inc(); - self.fire("preload:progress", count() / total); - if(_assets.done()) { - done() - } - } - } - }else { - done() - } - if(_scripts.length) { - for(i = 0;i < _scripts.length;i++) { - var url = pc.path.join(this._scriptPrefix, this._scripts[i]); - this.loader.load(url, "script", function(err, ScriptType) { - if(err) { - console.error(err) - } - _scripts.inc(); - if(_scripts.done()) { - done() - } - }) - } - }else { - done() - } - }, loadSceneHierarchy:function(url, callback) { - var parser = new pc.SceneParser(this); - this.loader.load(url, "hierarchy", function(err, entity) { - this.loader.clearCache(url, "hierarchy"); - this.root.addChild(entity); - pc.ComponentSystem.initialize(entity); - pc.ComponentSystem.postInitialize(entity); - if(callback) { - callback(err, entity) - } - }.bind(this)) - }, loadSceneSettings:function(url, callback) { - this.loader.load(url, "scenesettings", function(err, settings) { - if(!err) { - this.updateSceneSettings(settings); - if(callback) { - callback(null) - } - }else { - if(callback) { - callback(err) - } - } - }.bind(this)) - }, loadScene:function(url, callback) { - var first = true; - if(this.scene) { - first = false; - this.scene.root.destroy(); - this.scene.destroy(); - this.scene = null - } - this.loader.load(url, "scene", function(err, scene) { - if(!err) { - this.loader.clearCache(url, "scene"); - this.loader.patch({resource:scene, type:"scene"}, this.assets); - this.root.addChild(scene.root); - if(this.systems.rigidbody && typeof Ammo !== "undefined") { - this.systems.rigidbody.setGravity(scene._gravity.x, scene._gravity.y, scene._gravity.z) - } - if(!first) { - pc.ComponentSystem.initialize(scene.root); - pc.ComponentSystem.postInitialize(scene.root) - } - if(callback) { - callback(null, scene) - } - }else { - if(callback) { - callback(err) - } - } - }.bind(this)) - }, _parseApplicationProperties:function(props, callback) { - this._width = props["width"]; - this._height = props["height"]; - this.setCanvasResolution(props["resolution_mode"], this._width, this._height); - this.setCanvasFillMode(props["fill_mode"], this._width, this._height); - this._loadLibraries(props["libraries"], callback) - }, _loadLibraries:function(urls, callback) { - var len = urls.length; - var count = len; - if(len) { - for(var i = 0;i < len;++i) { - var url = urls[i]; - this.loader.load(url, "script", function(err, script) { - count--; - if(err) { - callback(err) - }else { - if(count === 0) { - this.onLibrariesLoaded(); - callback(null) - } - } - }.bind(this)) - } - }else { - callback(null) - } - }, _parseAssets:function(assets) { - for(var id in assets) { - var data = assets[id]; - var asset = new pc.Asset(data["name"], data["type"], data["file"], data["data"]); - asset.id = parseInt(id); - asset.preload = data.preload ? data.preload : false; - this.assets.add(asset) - } - }, _parseScripts:function(scripts, priorityScripts) { - var i; - this._scripts = []; - if(priorityScripts) { - for(i = 0;i < priorityScripts.length;i++) { - this._scripts.push(priorityScripts[i]) - } - } - for(i = 0;i < scripts.length;i++) { - if(this._scripts.indexOf(scripts[i]) < 0) { - this._scripts.push(scripts[i]) - } - } - }, start:function() { - if(!this.scene) { - this.scene = new pc.Scene; - this.scene.root = new pc.Entity; - this.root.addChild(this.scene.root) - } - if(!this._librariesLoaded) { - this.onLibrariesLoaded() - } - pc.ComponentSystem.initialize(this.root); - pc.ComponentSystem.postInitialize(this.root); - this.tick() - }, update:function(dt) { - pc.ComponentSystem.fixedUpdate(1 / 60, this._inTools); - pc.ComponentSystem.update(dt, this._inTools); - pc.ComponentSystem.postUpdate(dt, this._inTools); - this.fire("update", dt); - if(this.controller) { - this.controller.update(dt) - } - if(this.mouse) { - this.mouse.update(dt) - } - if(this.keyboard) { - this.keyboard.update(dt) - } - if(this.gamepads) { - this.gamepads.update(dt) - } - }, render:function() { - if(!this.scene) { - return - } - this.fire("preRender", null); - var cameras = this.systems.camera.cameras; - var camera = null; - var renderer = this.renderer; - this.root.syncHierarchy(); - for(var i = 0, len = cameras.length;i < len;i++) { - camera = cameras[i]; - camera.frameBegin(); - renderer.render(this.scene, camera.camera); - camera.frameEnd() - } - }, tick:function() { - if(!this.graphicsDevice) { - return - } - Application._currentApplication = this; - window.requestAnimationFrame(this.tick.bind(this)); - var now = window.performance && window.performance.now ? performance.now() : Date.now(); - var dt = (now - (this._time || now)) / 1E3; - this._time = now; - dt = pc.math.clamp(dt, 0, 0.1); - dt *= this.timeScale; - this.update(dt); - this.render() - }, setCanvasFillMode:function(mode, width, height) { - this._fillMode = mode; - this.resizeCanvas(width, height) - }, setCanvasResolution:function(mode, width, height) { - this._resolutionMode = mode; - if(mode === pc.RESOLUTION_AUTO && width === undefined) { - width = this.graphicsDevice.canvas.clientWidth; - height = this.graphicsDevice.canvas.clientHeight - } - this.graphicsDevice.resizeCanvas(width, height) - }, isFullscreen:function() { - return!!document.fullscreenElement - }, enableFullscreen:function(element, success, error) { - element = element || this.graphicsDevice.canvas; - var s = function() { - success(); - document.removeEventListener("fullscreenchange", s) - }; - var e = function() { - error(); - document.removeEventListener("fullscreenerror", e) - }; - if(success) { - document.addEventListener("fullscreenchange", s, false) - } - if(error) { - document.addEventListener("fullscreenerror", e, false) - } - element.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT) - }, disableFullscreen:function(success) { - var s = function() { - success(); - document.removeEventListener("fullscreenchange", s) - }; - if(success) { - document.addEventListener("fullscreenchange", s, false) - } - document.exitFullscreen() - }, isHidden:function() { - return document[this._hiddenAttr] - }, onVisibilityChange:function(e) { - if(this.isHidden()) { - this._audioManager.suspend() - }else { - this._audioManager.resume() - } - }, resizeCanvas:function(width, height) { - var windowWidth = window.innerWidth; - var windowHeight = window.innerHeight; - if(navigator.isCocoonJS) { - width = windowWidth; - height = windowHeight; - this.graphicsDevice.resizeCanvas(width, height) - }else { - if(this._fillMode === pc.FILLMODE_KEEP_ASPECT) { - var r = this.graphicsDevice.canvas.width / this.graphicsDevice.canvas.height; - var winR = windowWidth / windowHeight; - if(r > winR) { - width = windowWidth; - height = width / r - }else { - height = windowHeight; - width = height * r - } - }else { - if(this._fillMode === pc.FILLMODE_FILL_WINDOW) { - width = windowWidth; - height = windowHeight - }else { - } - } - this.graphicsDevice.canvas.style.width = width + "px"; - this.graphicsDevice.canvas.style.height = height + "px"; - if(this._resolutionMode === pc.RESOLUTION_AUTO) { - this.setCanvasResolution(pc.RESOLUTION_AUTO) - } - } - return{width:width, height:height} - }, onLibrariesLoaded:function() { - this._librariesLoaded = true; - this.systems.rigidbody.onLibraryLoaded(); - this.systems.collision.onLibraryLoaded() - }, updateSceneSettings:function(settings) { - var self = this; - if(self.systems.rigidbody && typeof Ammo !== "undefined") { - var gravity = settings.physics.gravity; - self.systems.rigidbody.setGravity(gravity[0], gravity[1], gravity[2]) - } - if(!self.scene) { - return - } - var ambient = settings.render.global_ambient; - self.scene.ambientLight.set(ambient[0], ambient[1], ambient[2]); - self.scene.fog = settings.render.fog; - self.scene.fogStart = settings.render.fog_start; - self.scene.fogEnd = settings.render.fog_end; - var fog = settings.render.fog_color; - self.scene.fogColor = new pc.Color(fog[0], fog[1], fog[2]); - self.scene.fogDensity = settings.render.fog_density; - self.scene.gammaCorrection = settings.render.gamma_correction; - self.scene.toneMapping = settings.render.tonemapping; - self.scene.exposure = settings.render.exposure; - self.scene.skyboxIntensity = settings.render.skyboxIntensity === undefined ? 1 : settings.render.skyboxIntensity; - self.scene.skyboxMip = settings.render.skyboxMip === undefined ? 0 : settings.render.skyboxMip; - if(settings.render.skybox) { - var asset = self.assets.get(settings.render.skybox); - if(asset) { - asset.ready(function(asset) { - self.scene.attachSkyboxAsset(asset) - }); - self.assets.load(asset) - }else { - self.assets.once("add:" + settings.render.skybox, function(asset) { - asset.ready(function(asset) { - self.scene.attachSkyboxAsset(asset) - }); - self.assets.load(asset) - }) - } - }else { - self.scene.setSkybox(null) - } - }, destroy:function() { - Application._applications[this.graphicsDevice.canvas.id] = null; - this.off("librariesloaded"); - document.removeEventListener("visibilitychange"); - document.removeEventListener("mozvisibilitychange"); - document.removeEventListener("msvisibilitychange"); - document.removeEventListener("webkitvisibilitychange"); - if(this.mouse) { - this.mouse.off("mouseup"); - this.mouse.off("mousedown"); - this.mouse.off("mousewheel"); - this.mouse.off("mousemove"); - this.mouse = null - } - if(this.keyboard) { - this.keyboard.off("keydown"); - this.keyboard.off("keyup"); - this.keyboard.off("keypress"); - this.keyboard = null - } - if(this.touch) { - this.touch.off("touchstart"); - this.touch.off("touchend"); - this.touch.off("touchmove"); - this.touch.off("touchcancel"); - this.touch = null - } - if(this.controller) { - this.controller = null - } - this.root.destroy(); - pc.ComponentSystem.destroy(); - this.loader.destroy(); - this.loader = null; - this.scene = null; - this.systems = []; - this.context = null; - this.graphicsDevice = null; - this.renderer = null; - if(this._audioManager) { - this._audioManager.destroy(); - this._audioManager = null - } - pc.net.http = new pc.net.Http - }}; - return{FILLMODE_NONE:"NONE", FILLMODE_FILL_WINDOW:"FILL_WINDOW", FILLMODE_KEEP_ASPECT:"KEEP_ASPECT", RESOLUTION_AUTO:"AUTO", RESOLUTION_FIXED:"FIXED", Application:Application} -}()); -pc.extend(pc, function() { - var ComponentSystemRegistry = function() { - }; - ComponentSystemRegistry.prototype = {add:function(name, system) { - if(!this[name]) { - this[name] = system; - system.name = name - }else { - throw new Error(pc.string.format("ComponentSystem name '{0}' already registered or not allowed", name)); - } - }, remove:function(name) { - if(!this[name]) { - throw new Error(pc.string.format("No ComponentSystem named '{0}' registered", name)); - } - delete this[name] - }, list:function() { - var list = Object.keys(this); - var defaultPriority = 1; - var priorities = {"collisionrect":0.5, "collisioncircle":0.5}; - list.sort(function(a, b) { - var pa = priorities[a] || defaultPriority; - var pb = priorities[b] || defaultPriority; - if(pa < pb) { - return-1 - }else { - if(pa > pb) { - return 1 - } - } - return 0 - }); - return list.map(function(key) { - return this[key] - }, this) - }, getComponentSystemOrder:function() { - var index; - var names = Object.keys(this); - index = names.indexOf("collisionrect"); - names.splice(index, 1); - names.unshift("collisionrect"); - index = names.indexOf("collisioncircle"); - names.splice(index, 1); - names.unshift("collisioncircle"); - return names - }}; - return{ComponentSystemRegistry:ComponentSystemRegistry} -}()); -pc.extend(pc, function() { - var ComponentSystem = function(app) { - this.app = app; - this.dataStore = {}; - this.schema = []; - pc.events.attach(this) - }; - pc.extend(ComponentSystem, {initialize:function(root) { - ComponentSystem.fire("initialize", root) - }, postInitialize:function(root) { - ComponentSystem.fire("postInitialize", root) - }, update:function(dt, inTools) { - if(inTools) { - ComponentSystem.fire("toolsUpdate", dt) - }else { - ComponentSystem.fire("update", dt) - } - }, fixedUpdate:function(dt, inTools) { - ComponentSystem.fire("fixedUpdate", dt) - }, postUpdate:function(dt, inTools) { - ComponentSystem.fire("postUpdate", dt) - }}); - ComponentSystem.prototype = {get store() { - return this.dataStore - }, addComponent:function(entity, data) { - var component = new this.ComponentType(this, entity); - var componentData = new this.DataType; - data = data || {}; - this.dataStore[entity.getGuid()] = {entity:entity, data:componentData}; - entity[this.id] = component; - entity.c[this.id] = component; - this.initializeComponentData(component, data, []); - this.fire("add", entity, component); - return component - }, removeComponent:function(entity) { - var record = this.dataStore[entity.getGuid()]; - var component = entity.c[this.id]; - this.fire("beforeremove", entity, component); - delete this.dataStore[entity.getGuid()]; - delete entity[this.id]; - delete entity.c[this.id]; - this.fire("remove", entity, record.data) - }, cloneComponent:function(entity, clone) { - var src = this.dataStore[entity.getGuid()]; - return this.addComponent(clone, src.data) - }, initializeComponentData:function(component, data, properties) { - data = data || {}; - properties.forEach(function(value) { - if(data[value] !== undefined) { - component[value] = data[value] - }else { - component[value] = component.data[value] - } - }, this); - if(component.enabled && component.entity.enabled) { - component.onEnable() - } - }}; - pc.events.attach(ComponentSystem); - ComponentSystem.destroy = function() { - ComponentSystem.off("initialize"); - ComponentSystem.off("postInitialize"); - ComponentSystem.off("toolsUpdate"); - ComponentSystem.off("update"); - ComponentSystem.off("fixedUpdate"); - ComponentSystem.off("postUpdate") - }; - return{ComponentSystem:ComponentSystem} -}()); -pc.extend(pc, function() { - var Component = function(system, entity) { - this.system = system; - this.entity = entity; - pc.events.attach(this); - if(this.system.schema) { - this.buildAccessors(this.system.schema) - } - this.on("set", function(name, oldValue, newValue) { - this.fire("set_" + name, name, oldValue, newValue) - }); - this.on("set_enabled", this.onSetEnabled, this) - }; - Component.prototype = {get data() { - var record = this.system.store[this.entity.getGuid()]; - if(record) { - return record.data - }else { - return null - } - }, buildAccessors:function(schema) { - var self = this; - schema.forEach(function(prop) { - Object.defineProperty(self, prop, {get:function() { - return self.data[prop] - }, set:function(value) { - var data = self.data; - var oldValue = data[prop]; - data[prop] = value; - self.fire("set", prop, oldValue, value) - }, configurable:true}) - }) - }, onSetEnabled:function(name, oldValue, newValue) { - if(oldValue !== newValue) { - if(this.entity.enabled) { - if(newValue) { - this.onEnable() - }else { - this.onDisable() - } - } - } - }, onEnable:function() { - }, onDisable:function() { - }}; - return{Component:Component} -}()); -pc.extend(pc, function() { - var ComponentData = function() { - }; - return{ComponentData:ComponentData} -}()); -pc.extend(pc, function() { - var AnimationComponent = function(system, entity) { - this.on("set_animations", this.onSetAnimations, this); - this.on("set_assets", this.onSetAssets, this); - this.on("set_loop", this.onSetLoop, this) - }; - AnimationComponent = pc.inherits(AnimationComponent, pc.Component); - pc.extend(AnimationComponent.prototype, {play:function(name, blendTime) { - if(!this.data.animations[name]) { - console.error(pc.string.format("Trying to play animation '{0}' which doesn't exist", name)); - return - } - if(!this.enabled || !this.entity.enabled) { - return - } - blendTime = blendTime || 0; - var data = this.data; - data.prevAnim = data.currAnim; - data.currAnim = name; - if(data.model) { - data.blending = blendTime > 0; - if(data.blending) { - data.blendTime = blendTime; - data.blendTimeRemaining = blendTime; - data.fromSkel.setAnimation(data.animations[data.prevAnim]); - data.fromSkel.addTime(data.skeleton.getCurrentTime()); - data.toSkel.setAnimation(data.animations[data.currAnim]) - }else { - data.skeleton.setAnimation(data.animations[data.currAnim]) - } - } - data.playing = true - }, getAnimation:function(name) { - return this.data.animations[name] - }, setModel:function(model) { - var data = this.data; - if(model) { - var graph = model.getGraph(); - data.fromSkel = new pc.Skeleton(graph); - data.toSkel = new pc.Skeleton(graph); - data.skeleton = new pc.Skeleton(graph); - data.skeleton.setLooping(data.loop); - data.skeleton.setGraph(graph) - } - data.model = model; - if(data.animations && data.currAnim && data.animations[data.currAnim]) { - this.play(data.currAnim) - } - }, loadAnimationAssets:function(ids) { - if(!ids || !ids.length) { - return - } - var self = this; - var assets = this.system.app.assets; - var i; - var l = ids.length; - for(i = 0;i < l;i++) { - var asset = assets.get(ids[i]); - if(asset) { - asset.off("change", self.onAssetChanged, self); - asset.on("change", self.onAssetChanged, self); - asset.off("remove", self.onAssetRemoved, self); - asset.on("remove", self.onAssetRemoved, self); - asset.ready(function(asset) { - self.animations[asset.name] = asset.resource; - self.animations = self.animations - }); - assets.load(asset) - }else { - assets.on("add:" + ids[i], function(asset) { - asset.off("change", self.onAssetChanged, self); - asset.on("change", self.onAssetChanged, self); - asset.off("remove", self.onAssetRemoved, self); - asset.on("remove", self.onAssetRemoved, self); - asset.ready(function(asset) { - self.animations[asset.name] = asset.resource; - self.animations = self.animations - }); - assets.load(asset) - }) - } - } - }, onAssetChanged:function(asset, attribute, newValue, oldValue) { - if(attribute === "resource") { - if(newValue) { - this.animations[asset.name] = newValue; - if(this.data.currAnim === asset.name) { - if(this.data.playing && this.data.enabled && this.entity.enabled) { - this.play(asset.name, 0) - } - } - }else { - delete this.animations[asset.name] - } - } - }, onAssetRemoved:function(asset) { - asset.off("remove", this.onAssetRemoved, this); - if(this.animations && this.animations[asset.name]) { - delete this.animations[asset.name]; - if(this.data.currAnim === asset.name) { - this._stopCurrentAnimation() - } - } - }, _stopCurrentAnimation:function() { - this.data.currAnim = null; - this.data.playing = false; - if(this.data.skeleton) { - this.data.skeleton.setCurrentTime(0); - this.data.skeleton.setAnimation(null) - } - }, onSetAnimations:function(name, oldValue, newValue) { - var data = this.data; - var modelComponent = this.entity.model; - if(modelComponent) { - var m = modelComponent.model; - if(m) { - this.entity.animation.setModel(m) - } - } - for(var animName in data.animations) { - if(data.activate && data.enabled && this.entity.enabled && !this.system._inTools) { - this.play(animName, 0) - } - break - } - }, onSetAssets:function(name, oldValue, newValue) { - if(oldValue && oldValue.length) { - for(var i = 0;i < oldValue.length;i++) { - if(oldValue[i]) { - var asset = this.system.app.assets.get(oldValue[i]); - if(asset) { - asset.off("change", this.onAssetChanged, this); - asset.off("remove", this.onAssetRemoved, this); - if(this.data.currAnim === asset.name) { - this._stopCurrentAnimation() - } - } - } - } - } - var ids = newValue.map(function(value) { - if(value instanceof pc.Asset) { - return value.id - }else { - return value - } - }); - this.loadAnimationAssets(ids) - }, onSetLoop:function(name, oldValue, newValue) { - if(this.data.skeleton) { - this.data.skeleton.setLooping(this.data.loop) - } - }, onSetCurrentTime:function(name, oldValue, newValue) { - this.data.skeleton.setCurrentTime(newValue); - this.data.skeleton.addTime(0); - this.data.skeleton.updateGraph() - }, onEnable:function() { - AnimationComponent._super.onEnable.call(this); - if(this.data.activate && !this.data.currAnim && !this.system._inTools) { - for(var animName in this.data.animations) { - this.play(animName, 0); - break - } - } - }}); - Object.defineProperties(AnimationComponent.prototype, {currentTime:{get:function() { - return this.data.skeleton.getCurrentTime() - }, set:function(currentTime) { - this.data.skeleton.setCurrentTime(currentTime); - this.data.skeleton.addTime(0); - this.data.skeleton.updateGraph() - }}, duration:{get:function() { - return this.data.animations[this.data.currAnim].getDuration() - }}}); - return{AnimationComponent:AnimationComponent} -}()); -pc.extend(pc, function() { - var AnimationComponentSystem = function AnimationComponentSystem(app) { - this.id = "animation"; - this.description = "Specifies the animation assets that can run on the model specified by the Entity's model Component."; - app.systems.add(this.id, this); - this.ComponentType = pc.AnimationComponent; - this.DataType = pc.AnimationComponentData; - this.schema = ["enabled", "assets", "speed", "loop", "activate", "animations", "skeleton", "model", "prevAnim", "currAnim", "fromSkel", "toSkel", "blending", "blendTimeRemaining", "playing"]; - this.on("remove", this.onRemove, this); - this.on("update", this.onUpdate, this); - pc.ComponentSystem.on("update", this.onUpdate, this) - }; - AnimationComponentSystem = pc.inherits(AnimationComponentSystem, pc.ComponentSystem); - pc.extend(AnimationComponentSystem.prototype, {initializeComponentData:function(component, data, properties) { - properties = ["activate", "loop", "speed", "assets", "enabled"]; - AnimationComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, cloneComponent:function(entity, clone) { - var component = this.addComponent(clone, {}); - clone.animation.data.assets = pc.extend([], entity.animation.assets); - clone.animation.data.speed = entity.animation.speed; - clone.animation.data.loop = entity.animation.loop; - clone.animation.data.activate = entity.animation.activate; - clone.animation.data.enabled = entity.animation.enabled; - var clonedAnimations = {}; - var animations = entity.animation.animations; - for(var key in animations) { - if(animations.hasOwnProperty(key)) { - clonedAnimations[key] = animations[key] - } - } - clone.animation.animations = clonedAnimations - }, onRemove:function(entity, data) { - delete data.animation; - delete data.skeleton; - delete data.fromSkel; - delete data.toSkel - }, onUpdate:function(dt) { - var components = this.store; - for(var id in components) { - if(components.hasOwnProperty(id)) { - var component = components[id]; - var componentData = component.data; - if(componentData.enabled && componentData.playing && component.entity.enabled) { - var skeleton = componentData.skeleton; - if(skeleton !== null && componentData.model !== null) { - if(componentData.blending) { - componentData.blendTimeRemaining -= dt; - if(componentData.blendTimeRemaining < 0) { - componentData.blendTimeRemaining = 0 - } - var alpha = 1 - componentData.blendTimeRemaining / componentData.blendTime; - skeleton.blend(componentData.fromSkel, componentData.toSkel, alpha) - }else { - var delta = dt * componentData.speed; - skeleton.addTime(delta); - if(skeleton.getCurrentTime() === skeleton.getAnimation().getDuration() && !componentData.loop) { - componentData.playing = false - } - } - if(componentData.blending && componentData.blendTimeRemaining === 0) { - componentData.blending = false; - skeleton.setAnimation(componentData.toSkel.getAnimation()) - } - skeleton.updateGraph() - } - } - } - } - }}); - return{AnimationComponentSystem:AnimationComponentSystem} -}()); -pc.extend(pc, function() { - var AnimationComponentData = function() { - this.assets = []; - this.speed = 1; - this.loop = true; - this.activate = true; - this.enabled = true; - this.animations = {}; - this.skeleton = null; - this.model = null; - this.prevAnim = null; - this.currAnim = null; - this.fromSkel = null; - this.toSkel = null; - this.blending = false; - this.blendTime = 0; - this.blendTimeRemaining = 0; - this.playing = false - }; - AnimationComponentData = pc.inherits(AnimationComponentData, pc.ComponentData); - return{AnimationComponentData:AnimationComponentData} -}()); -pc.extend(pc, function() { - var ModelComponentSystem = function ModelComponentSystem(app) { - this.id = "model"; - this.description = "Renders a 3D model at the location of the Entity."; - app.systems.add(this.id, this); - this.ComponentType = pc.ModelComponent; - this.DataType = pc.ModelComponentData; - this.schema = ["enabled", "type", "asset", "materialAsset", "castShadows", "receiveShadows", "material", "model"]; - var gd = app.graphicsDevice; - this.box = pc.createBox(gd, {halfExtents:new pc.Vec3(0.5, 0.5, 0.5)}); - this.capsule = pc.createCapsule(gd, {radius:0.5, height:2}); - this.sphere = pc.createSphere(gd, {radius:0.5}); - this.cone = pc.createCone(gd, {baseRadius:0.5, peakRadius:0, height:1}); - this.cylinder = pc.createCylinder(gd, {radius:0.5, height:1}); - this.plane = pc.createPlane(gd, {halfExtents:new pc.Vec2(0.5, 0.5), widthSegments:1, lengthSegments:1}); - this.defaultMaterial = new pc.PhongMaterial - }; - ModelComponentSystem = pc.inherits(ModelComponentSystem, pc.ComponentSystem); - pc.extend(ModelComponentSystem.prototype, {initializeComponentData:function(component, data, properties) { - data.material = this.defaultMaterial; - properties = ["material", "materialAsset", "asset", "castShadows", "receiveShadows", "type", "enabled"]; - ModelComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, removeComponent:function(entity) { - var data = entity.model.data; - entity.model.asset = null; - if(data.type !== "asset" && data.model) { - this.app.scene.removeModel(data.model); - entity.removeChild(data.model.getGraph()); - data.model = null - } - ModelComponentSystem._super.removeComponent.call(this, entity) - }, cloneComponent:function(entity, clone) { - var component = this.addComponent(clone, {}); - clone.model.data.type = entity.model.type; - clone.model.data.materialAsset = entity.model.materialAsset; - clone.model.data.asset = entity.model.asset; - clone.model.data.castShadows = entity.model.castShadows; - clone.model.data.receiveShadows = entity.model.receiveShadows; - clone.model.data.material = entity.model.material; - clone.model.data.enabled = entity.model.enabled; - if(entity.model.model) { - clone.model.model = entity.model.model.clone() - } - }}); - return{ModelComponentSystem:ModelComponentSystem} -}()); -pc.extend(pc, function() { - var ModelComponent = function ModelComponent(system, entity) { - this.on("set_type", this.onSetType, this); - this.on("set_asset", this.onSetAsset, this); - this.on("set_castShadows", this.onSetCastShadows, this); - this.on("set_model", this.onSetModel, this); - this.on("set_receiveShadows", this.onSetReceiveShadows, this); - this.on("set_material", this.onSetMaterial, this); - Object.defineProperty(this, "materialAsset", {set:this.setMaterialAsset.bind(this), get:this.getMaterialAsset.bind(this)}); - this._onAssetChange = function() { - } - }; - ModelComponent = pc.inherits(ModelComponent, pc.Component); - pc.extend(ModelComponent.prototype, {setVisible:function(visible) { - console.warn("WARNING: setVisible: Function is deprecated. Set enabled property instead."); - this.enabled = visible - }, _setModelAsset:function(id) { - var self = this; - var assets = this.system.app.assets; - var asset = assets.get(id); - if(asset) { - asset.ready(function(asset) { - var model = asset.resource.clone(); - asset.off("change", this._onAssetChange, this); - this._onAssetChange = function(asset, attribute, newValue, oldValue) { - if(attribute === "file") { - asset.unload(); - self.system.app.loader.clearCache(asset.file.url, asset.type); - self._setModelAsset(asset.id) - } - if(attribute === "data") { - var a = {resource:model, data:asset.data, type:"model"}; - self.system.app.loader.patch(a, self.system.app.assets) - } - }; - asset.on("change", this._onAssetChange, this); - this._onModelLoaded(model) - }.bind(this)); - assets.load(asset) - }else { - assets.once("add:" + id, function(asset) { - asset.ready(function(asset) { - asset.off("change", this._onAssetChange, this); - this._onAssetChange = function(asset, attribute, newValue, oldValue) { - if(attribute === "file") { - asset.unload(); - self.system.app.loader.clearCache(asset.file.url, asset.type); - self._setModelAsset(asset.id) - } - if(attribute === "data") { - var a = {resource:model, data:asset.data, type:"model"}; - self.system.app.loader.patch(a, self.system.app.assets) - } - }; - asset.on("change", this._onAssetChange, this); - var model = asset.resource.clone(); - this._onModelLoaded(model) - }.bind(this)); - assets.load(asset) - }, this) - } - }, _onModelLoaded:function(model) { - if(this.system._inTools) { - model.generateWireframe() - } - if(this.data.type === "asset") { - this.model = model - } - }, onSetType:function(name, oldValue, newValue) { - var data = this.data; - if(newValue) { - var mesh = null; - if(newValue === "asset") { - if(this.data.asset !== null) { - this._setModelAsset(this.data.asset) - }else { - this.model = null - } - }else { - switch(newValue) { - case "box": - mesh = this.system.box; - break; - case "capsule": - mesh = this.system.capsule; - break; - case "sphere": - mesh = this.system.sphere; - break; - case "cone": - mesh = this.system.cone; - break; - case "cylinder": - mesh = this.system.cylinder; - break; - case "plane": - mesh = this.system.plane; - break; - default: - throw new Error("Invalid model type: " + newValue); - } - var node = new pc.GraphNode; - var model = new pc.Model; - model.graph = node; - model.meshInstances = [new pc.MeshInstance(node, mesh, data.material)]; - if(this.system._inTools) { - model.generateWireframe() - } - this.model = model; - this.asset = null - } - } - }, onSetAsset:function(name, oldValue, newValue) { - if(oldValue) { - var asset = this.system.app.assets.get(oldValue); - if(asset) { - asset.off("change", this.onAssetChange, this); - asset.off("remove", this.onAssetRemoved, this) - } - } - if(this.data.type === "asset") { - if(newValue) { - if(newValue instanceof pc.Asset) { - this.data.asset = newValue.id; - this._setModelAsset(newValue.id) - }else { - this._setModelAsset(newValue) - } - }else { - this.model = null - } - }else { - if(!newValue) { - this.data.asset = null - } - } - }, onSetCastShadows:function(name, oldValue, newValue) { - var model = this.data.model; - if(model) { - var scene = this.system.app.scene; - var inScene = scene.containsModel(model); - if(inScene) { - scene.removeModel(model) - } - var meshInstances = model.meshInstances; - for(var i = 0;i < meshInstances.length;i++) { - meshInstances[i].castShadow = newValue - } - if(inScene) { - scene.addModel(model) - } - } - }, onSetModel:function(name, oldValue, newValue) { - if(oldValue) { - this.system.app.scene.removeModel(oldValue); - this.entity.removeChild(oldValue.getGraph()); - delete oldValue._entity - } - if(newValue) { - var componentData = this.data; - var meshInstances = newValue.meshInstances; - for(var i = 0;i < meshInstances.length;i++) { - meshInstances[i].castShadow = componentData.castShadows; - meshInstances[i].receiveShadow = componentData.receiveShadows - } - this.entity.addChild(newValue.graph); - if(this.enabled && this.entity.enabled) { - this.system.app.scene.addModel(newValue) - } - newValue._entity = this.entity; - if(this.entity.animation) { - this.entity.animation.setModel(newValue) - } - } - }, setMaterialAsset:function(newValue) { - var id = typeof newValue === "number" || !newValue ? newValue : newValue.id; - var assets = this.system.app.assets; - var self = this; - if(id !== undefined && id !== null) { - var asset = assets.get(id); - if(asset) { - asset.ready(function(asset) { - self.material = asset.resource - }); - assets.load(asset) - }else { - assets.on("add:" + id, function(asset) { - asset.ready(function(asset) { - self.material = asset.resource - }); - assets.load(asset) - }) - } - }else { - if(id === null) { - self.material = pc.ModelHandler.DEFAULT_MATERIAL - } - } - var oldValue = this.data.materialAsset; - this.data.materialAsset = id; - this.fire("set", "materialAsset", oldValue, id) - }, getMaterialAsset:function() { - return this.system.app.assets.get(this.data.materialAsset) - }, onSetMaterial:function(name, oldValue, newValue) { - if(newValue !== oldValue) { - this.data.material = newValue; - if(this.data.model && this.data.type !== "asset") { - var meshInstances = this.data.model.meshInstances; - for(var i = 0;i < meshInstances.length;i++) { - meshInstances[i].material = newValue - } - } - } - }, onSetReceiveShadows:function(name, oldValue, newValue) { - if(newValue !== undefined) { - var componentData = this.data; - if(componentData.model) { - var meshInstances = componentData.model.meshInstances; - for(var i = 0;i < meshInstances.length;i++) { - meshInstances[i].receiveShadow = newValue - } - } - } - }, onEnable:function() { - ModelComponent._super.onEnable.call(this); - var model = this.data.model; - if(model) { - var inScene = this.system.app.scene.containsModel(model); - if(!inScene) { - this.system.app.scene.addModel(model) - } - } - }, onDisable:function() { - ModelComponent._super.onDisable.call(this); - var model = this.data.model; - if(model) { - var inScene = this.system.app.scene.containsModel(model); - if(inScene) { - this.system.app.scene.removeModel(model) - } - } - }, onAssetRemoved:function(asset) { - asset.off("remove", this.onAssetRemoved, this); - if(this.asset === asset.id) { - this.asset = null - } - }}); - return{ModelComponent:ModelComponent} -}()); -pc.extend(pc, function() { - var ModelComponentData = function() { - this.enabled = true; - this.type = "asset"; - this.asset = null; - this.castShadows = false; - this.receiveShadows = true; - this.materialAsset = null; - this.material = null; - this.model = null - }; - ModelComponentData = pc.inherits(ModelComponentData, pc.ComponentData); - return{ModelComponentData:ModelComponentData} -}()); -pc.extend(pc, function() { - var CameraComponentSystem = function(app) { - this.id = "camera"; - this.description = "Renders the scene from the location of the Entity."; - app.systems.add(this.id, this); - this.ComponentType = pc.CameraComponent; - this.DataType = pc.CameraComponentData; - this.schema = ["enabled", "clearColorBuffer", "clearColor", "clearDepthBuffer", "frustumCulling", "projection", "fov", "orthoHeight", "nearClip", "farClip", "priority", "rect", "camera", "aspectRatio", "model", "renderTarget"]; - this.cameras = []; - this.on("beforeremove", this.onBeforeRemove, this); - this.on("remove", this.onRemove, this); - pc.ComponentSystem.on("toolsUpdate", this.toolsUpdate, this) - }; - CameraComponentSystem = pc.inherits(CameraComponentSystem, pc.ComponentSystem); - pc.extend(CameraComponentSystem.prototype, {initializeComponentData:function(component, _data, properties) { - properties = ["postEffects", "enabled", "model", "camera", "aspectRatio", "renderTarget", "clearColor", "fov", "orthoHeight", "nearClip", "farClip", "projection", "priority", "clearColorBuffer", "clearDepthBuffer", "frustumCulling", "rect"]; - var data = {}; - properties.forEach(function(prop) { - data[prop] = _data[prop] - }); - if(data.clearColor && pc.type(data.clearColor) === "array") { - var c = data.clearColor; - data.clearColor = new pc.Color(c[0], c[1], c[2], c[3]) - } - if(data.rect && pc.type(data.rect) === "array") { - var rect = data.rect; - data.rect = new pc.Vec4(rect[0], rect[1], rect[2], rect[3]) - } - if(data.activate) { - console.warn("WARNING: activate: Property is deprecated. Set enabled property instead."); - data.enabled = data.activate - } - data.camera = new pc.Camera; - data._node = component.entity; - data.postEffects = new pc.PostEffectQueue(this.app, component); - if(this._inTools) { - var material = new pc.BasicMaterial; - material.color = new pc.Color(1, 1, 0, 1); - material.update(); - var indexBuffer = new pc.IndexBuffer(this.app.graphicsDevice, pc.INDEXFORMAT_UINT8, 24); - var indices = new Uint8Array(indexBuffer.lock()); - indices.set([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]); - indexBuffer.unlock(); - var format = new pc.VertexFormat(this.app.graphicsDevice, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(this.app.graphicsDevice, format, 8, pc.BUFFER_DYNAMIC); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.indexBuffer[0] = indexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = indexBuffer.getNumIndices(); - mesh.primitive[0].indexed = true; - var model = new pc.Model; - model.graph = component.entity; - model.meshInstances = [new pc.MeshInstance(model.graph, mesh, material)]; - this.app.scene.addModel(model); - data.model = model - } - CameraComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, onBeforeRemove:function(entity, component) { - this.removeCamera(component) - }, onRemove:function(entity, data) { - if(this._inTools) { - if(this.app.scene.containsModel(data.model)) { - this.app.scene.removeModel(data.model) - } - } - data.camera = null - }, toolsUpdate:function(fn) { - var components = this.store; - for(var id in components) { - if(components.hasOwnProperty(id)) { - var entity = components[id].entity; - var data = components[id].data; - if(this._inTools) { - this._updateGfx(entity.camera) - } - } - } - }, _updateGfx:function(component) { - if(component.model && component.model.meshInstances.length) { - var vertexBuffer = component.model.meshInstances[0].mesh.vertexBuffer; - var nearClip = component.nearClip; - var farClip = component.farClip; - var fov = component.fov * Math.PI / 180; - var projection = component.projection; - var device = this.app.graphicsDevice; - var rect = component.rect; - var aspectRatio = device.width * rect.z / (device.height * rect.w); - var x, y; - if(projection === pc.PROJECTION_PERSPECTIVE) { - y = Math.tan(fov / 2) * nearClip - }else { - y = component.camera.getOrthoHeight() - } - x = y * aspectRatio; - var positions = new Float32Array(vertexBuffer.lock()); - positions[0] = x; - positions[1] = -y; - positions[2] = -nearClip; - positions[3] = x; - positions[4] = y; - positions[5] = -nearClip; - positions[6] = -x; - positions[7] = y; - positions[8] = -nearClip; - positions[9] = -x; - positions[10] = -y; - positions[11] = -nearClip; - if(projection === pc.PROJECTION_PERSPECTIVE) { - y = Math.tan(fov / 2) * farClip; - x = y * aspectRatio - } - positions[12] = x; - positions[13] = -y; - positions[14] = -farClip; - positions[15] = x; - positions[16] = y; - positions[17] = -farClip; - positions[18] = -x; - positions[19] = y; - positions[20] = -farClip; - positions[21] = -x; - positions[22] = -y; - positions[23] = -farClip; - vertexBuffer.unlock() - } - }, addCamera:function(camera) { - this.cameras.push(camera); - this.sortCamerasByPriority(); - if(this._inTools) { - var model = camera.data.model; - if(model) { - var scene = this.app.scene; - if(!scene.containsModel(model)) { - scene.addModel(model) - } - } - } - }, removeCamera:function(camera) { - var index = this.cameras.indexOf(camera); - if(index >= 0) { - this.cameras.splice(index, 1); - this.sortCamerasByPriority(); - if(this._inTools) { - var model = camera.data.model; - if(model) { - this.app.scene.removeModel(model) - } - } - } - }, sortCamerasByPriority:function() { - this.cameras.sort(function(a, b) { - return a.priority - b.priority - }) - }}); - return{CameraComponentSystem:CameraComponentSystem} -}()); -pc.extend(pc, function() { - var CameraComponent = function CameraComponent(system, entity) { - this.on("set_aspectRatio", this.onSetAspectRatio, this); - this.on("set_camera", this.onSetCamera, this); - this.on("set_clearColor", this.onSetClearColor, this); - this.on("set_fov", this.onSetFov, this); - this.on("set_orthoHeight", this.onSetOrthoHeight, this); - this.on("set_nearClip", this.onSetNearClip, this); - this.on("set_farClip", this.onSetFarClip, this); - this.on("set_projection", this.onSetProjection, this); - this.on("set_priority", this.onSetPriority, this); - this.on("set_clearColorBuffer", this.updateClearFlags, this); - this.on("set_clearDepthBuffer", this.updateClearFlags, this); - this.on("set_renderTarget", this.onSetRenderTarget, this); - this.on("set_rect", this.onSetRect, this); - this.on("set_frustumCulling", this.onSetFrustumCulling, this) - }; - CameraComponent = pc.inherits(CameraComponent, pc.Component); - Object.defineProperty(CameraComponent.prototype, "activate", {get:function() { - console.warn("WARNING: activate: Property is deprecated. Query enabled property instead."); - return this.enabled - }, set:function(value) { - console.warn("WARNING: activate: Property is deprecated. Set enabled property instead."); - this.enabled = value - }}); - Object.defineProperty(CameraComponent.prototype, "projectionMatrix", {get:function() { - return this.data.camera.getProjectionMatrix() - }}); - Object.defineProperty(CameraComponent.prototype, "viewMatrix", {get:function() { - var wtm = this.data.camera._node.getWorldTransform(); - return wtm.clone().invert() - }}); - Object.defineProperty(CameraComponent.prototype, "frustum", {get:function() { - return this.data.camera.getFrustum() - }}); - pc.extend(CameraComponent.prototype, {screenToWorld:function(screenx, screeny, cameraz, worldCoord) { - var device = this.system.app.graphicsDevice; - var width = parseInt(device.canvas.clientWidth); - var height = parseInt(device.canvas.clientHeight); - return this.data.camera.screenToWorld(screenx, screeny, cameraz, width, height, worldCoord) - }, worldToScreen:function(worldCoord, screenCoord) { - var device = this.system.app.graphicsDevice; - var width = parseInt(device.canvas.clientWidth); - var height = parseInt(device.canvas.clientHeight); - return this.data.camera.worldToScreen(worldCoord, width, height, screenCoord) - }, onSetAspectRatio:function(name, oldValue, newValue) { - this.data.camera.setAspectRatio(newValue) - }, onSetCamera:function(name, oldValue, newValue) { - if(oldValue) { - oldValue._node = null - } - newValue._node = this.entity - }, onSetClearColor:function(name, oldValue, newValue) { - var clearOptions = this.data.camera.getClearOptions(); - clearOptions.color[0] = newValue.r; - clearOptions.color[1] = newValue.g; - clearOptions.color[2] = newValue.b; - clearOptions.color[3] = newValue.a - }, onSetFov:function(name, oldValue, newValue) { - this.data.camera.setFov(newValue) - }, onSetOrthoHeight:function(name, oldValue, newValue) { - this.data.camera.setOrthoHeight(newValue) - }, onSetNearClip:function(name, oldValue, newValue) { - this.data.camera.setNearClip(newValue) - }, onSetFarClip:function(name, oldValue, newValue) { - this.data.camera.setFarClip(newValue) - }, onSetFrustumCulling:function(name, oldValue, newValue) { - this.data.camera.frustumCulling = newValue - }, onSetProjection:function(name, oldValue, newValue) { - this.data.camera.setProjection(newValue) - }, onSetPriority:function(name, oldValue, newValue) { - this.system.sortCamerasByPriority() - }, updateClearFlags:function() { - var clearOptions = this.data.camera.getClearOptions(); - var flags = 0; - if(this.clearColorBuffer) { - flags = flags | pc.CLEARFLAG_COLOR - } - if(this.clearDepthBuffer) { - flags = flags | pc.CLEARFLAG_DEPTH - } - clearOptions.flags = flags - }, onSetRenderTarget:function(name, oldValue, newValue) { - this.data.camera.setRenderTarget(newValue) - }, onSetRect:function(name, oldValue, newValue) { - this.data.camera.setRect(newValue.data[0], newValue.data[1], newValue.data[2], newValue.data[3]); - this._resetAspectRatio() - }, onEnable:function() { - CameraComponent._super.onEnable.call(this); - this.system.addCamera(this); - this.postEffects.enable() - }, onDisable:function() { - CameraComponent._super.onDisable.call(this); - this.postEffects.disable(); - this.system.removeCamera(this) - }, _resetAspectRatio:function() { - var camera = this.camera; - if(camera) { - var device = this.system.app.graphicsDevice; - var rect = this.rect; - var aspect = device.width * rect.z / (device.height * rect.w); - if(aspect !== camera.getAspectRatio()) { - camera.setAspectRatio(aspect) - } - } - }, frameBegin:function() { - this._resetAspectRatio(); - this.data.isRendering = true - }, frameEnd:function() { - this.data.isRendering = false - }}); - return{CameraComponent:CameraComponent} -}()); -pc.extend(pc, function() { - CameraComponentData = function() { - this.clearColor = new pc.Color(0.729411780834198, 0.729411780834198, 0.6941176652908325, 1); - this.clearColorBuffer = true; - this.clearDepthBuffer = true; - this.nearClip = 0.1; - this.farClip = 1E3; - this.fov = 45; - this.orthoHeight = 100; - this.projection = pc.PROJECTION_PERSPECTIVE; - this.priority = 0; - this.rect = new pc.Vec4(0, 0, 1, 1); - this.enabled = true; - this.frustumCulling = false; - this.camera = null; - this.aspectRatio = 16 / 9; - this.renderTarget = null; - this.postEffects = null; - this.isRendering = false - }; - CameraComponentData = pc.inherits(CameraComponentData, pc.ComponentData); - return{CameraComponentData:CameraComponentData} -}()); -pc.extend(pc, function() { - var LightComponentSystem = function(app) { - this.id = "light"; - this.description = "Enables the Entity to emit light."; - app.systems.add(this.id, this); - this.ComponentType = pc.LightComponent; - this.DataType = pc.LightComponentData; - this.schema = ["enabled", "type", "color", "intensity", "castShadows", "shadowDistance", "shadowResolution", "shadowBias", "normalOffsetBias", "range", "falloffMode", "shadowType", "shadowUpdateMode", "mask", "innerConeAngle", "outerConeAngle", "light", "model"]; - this.implementations = {}; - this.on("remove", this.onRemove, this); - pc.ComponentSystem.on("toolsUpdate", this.toolsUpdate, this) - }; - LightComponentSystem = pc.inherits(LightComponentSystem, pc.ComponentSystem); - pc.extend(LightComponentSystem.prototype, {initializeComponentData:function(component, _data, properties) { - properties = ["type", "light", "model", "enabled", "color", "intensity", "range", "falloffMode", "innerConeAngle", "outerConeAngle", "castShadows", "shadowDistance", "shadowResolution", "shadowUpdateMode", "shadowBias", "normalOffsetBias"]; - var data = {}; - properties.forEach(function(prop) { - data[prop] = _data[prop] - }); - if(!data.type) { - data.type = component.data.type - } - component.data.type = data.type; - if(data.color && pc.type(data.color) === "array") { - data.color = new pc.Color(data.color[0], data.color[1], data.color[2]) - } - if(data.enable) { - console.warn("WARNING: enable: Property is deprecated. Set enabled property instead."); - data.enabled = data.enable - } - var implementation = this._createImplementation(data.type); - implementation.initialize(component, data); - LightComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, _createImplementation:function(type) { - var implementation = this.implementations[type]; - if(!implementation) { - switch(type) { - case "directional": - implementation = new DirectionalLightImplementation(this); - break; - case "point": - implementation = new PointLightImplementation(this); - break; - case "spot": - implementation = new SpotLightImplementation(this); - break; - default: - throw new Error("Invalid light type: " + type); - } - this.implementations[type] = implementation - } - return implementation - }, onRemove:function(entity, data) { - this.implementations[data.type].remove(entity, data) - }, cloneComponent:function(entity, clone) { - var light = entity.light; - var data = {type:light.type, enabled:light.enabled, color:[light.color.r, light.color.g, light.color.b], intensity:light.intensity, range:light.range, innerConeAngle:light.innerConeAngle, outerConeAngle:light.outerConeAngle, castShadows:light.castShadows, shadowDistance:light.shadowDistance, shadowResolution:light.shadowResolution, falloffMode:light.falloffMode, shadowUpdateMode:light.shadowUpdateMode, shadowBias:light.shadowBias, normalOffsetBias:light.normalOffsetBias}; - this.addComponent(clone, data) - }, toolsUpdate:function(fn) { - var components = this.store; - for(var id in components) { - if(components.hasOwnProperty(id)) { - var entity = components[id].entity; - var componentData = components[id].data; - var implementation = this.implementations[componentData.type]; - if(implementation) { - implementation.toolsUpdate(componentData) - } - } - } - }, changeType:function(component, oldType, newType) { - this.implementations[oldType].remove(component.entity, component.data); - this._createImplementation(newType).initialize(component, component.data) - }}); - LightComponentImplementation = function(system) { - this.system = system - }; - LightComponentImplementation.prototype = {initialize:function(component, data) { - var light = new pc.Light; - light.setType(this._getLightType()); - light._node = component.entity; - var app = this.system.app; - app.scene.addLight(light); - data = data || {}; - data.light = light; - if(this.system._inTools) { - this._createDebugShape(component, data, light) - } - }, _getLightType:function() { - return undefined - }, _createDebugShape:function(component, data, light) { - this.mesh = this._createDebugMesh(); - if(!this.material) { - this.material = this._createDebugMaterial() - } - var model = new pc.Model; - model.graph = component.entity; - model.meshInstances = [new pc.MeshInstance(component.entity, this.mesh, this.material)]; - data.model = model - }, _createDebugMesh:function() { - return undefined - }, _createDebugMaterial:function() { - return undefined - }, remove:function(entity, data) { - var app = this.system.app; - app.scene.removeModel(data.model); - delete data.model; - app.scene.removeLight(data.light); - if(this.system._inTools) { - app.scene.removeModel(data.model); - delete data.model - } - }, toolsUpdate:function(data) { - }}; - DirectionalLightImplementation = function(system) { - }; - DirectionalLightImplementation = pc.inherits(DirectionalLightImplementation, LightComponentImplementation); - DirectionalLightImplementation.prototype = pc.extend(DirectionalLightImplementation.prototype, {_getLightType:function() { - return pc.LIGHTTYPE_DIRECTIONAL - }, _createDebugMesh:function() { - if(this.mesh) { - return this.mesh - } - var app = this.system.app; - var format = new pc.VertexFormat(app.graphicsDevice, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - vertexData = [0, 0, 0, 0, -8, 0, -0.5, -8, 0, 0.5, -8, 0, 0.5, -8, 0, 0, -10, 0, 0, -10, 0, -0.5, -8, 0, 0, 0, -2, 0, -8, -2, -0.25, -8, -2, 0.25, -8, -2, 0.25, -8, -2, 0, -10, -2, 0, -10, -2, -0.25, -8, -2, 0, 0, 2, 0, -8, 2, -0.25, -8, 2, 0.25, -8, 2, 0.25, -8, 2, 0, -10, 2, 0, -10, 2, -0.25, -8, 2]; - var rot = (new pc.Mat4).setFromAxisAngle(pc.Vec3.UP, 120); - var i; - for(i = 0;i < 24;i++) { - var pos = new pc.Vec3(vertexData[(i + 8) * 3], vertexData[(i + 8) * 3 + 1], vertexData[(i + 8) * 3 + 2]); - var posRot = rot.transformPoint(pos, pos); - vertexData[(i + 24) * 3] = posRot[0]; - vertexData[(i + 24) * 3 + 1] = posRot[1]; - vertexData[(i + 24) * 3 + 2] = posRot[2] - } - var vertexBuffer = new pc.VertexBuffer(app.graphicsDevice, format, 32); - var positions = new Float32Array(vertexBuffer.lock()); - for(i = 0;i < vertexData.length;i++) { - positions[i] = vertexData[i] - } - vertexBuffer.unlock(); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.indexBuffer[0] = null; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = vertexBuffer.getNumVertices(); - mesh.primitive[0].indexed = false; - return mesh - }, _createDebugMaterial:function() { - var material = new pc.BasicMaterial; - material.color = new pc.Color(1, 1, 0, 1); - material.update(); - return material - }}); - PointLightImplementation = function(system) { - }; - PointLightImplementation = pc.inherits(PointLightImplementation, LightComponentImplementation); - PointLightImplementation.prototype = pc.extend(PointLightImplementation.prototype, {_getLightType:function() { - return pc.LIGHTTYPE_POINT - }, _createDebugMesh:function() { - if(this.mesh) { - return this.mesh - } - var app = this.system.app; - return pc.createSphere(app.graphicsDevice, {radius:0.1}) - }, _createDebugMaterial:function() { - var material = new pc.BasicMaterial; - material.color = new pc.Color(1, 1, 0, 1); - material.update(); - return material - }}); - SpotLightImplementation = function(system) { - }; - SpotLightImplementation = pc.inherits(SpotLightImplementation, LightComponentImplementation); - SpotLightImplementation.prototype = pc.extend(SpotLightImplementation.prototype, {_getLightType:function() { - return pc.LIGHTTYPE_SPOT - }, _createDebugMesh:function() { - var app = this.system.app; - var indexBuffer = this.indexBuffer; - if(!indexBuffer) { - var indexBuffer = new pc.IndexBuffer(app.graphicsDevice, pc.INDEXFORMAT_UINT8, 88); - var inds = new Uint8Array(indexBuffer.lock()); - inds[0] = 0; - inds[1] = 1; - inds[2] = 0; - inds[3] = 11; - inds[4] = 0; - inds[5] = 21; - inds[6] = 0; - inds[7] = 31; - for(var i = 0;i < 40;i++) { - inds[8 + i * 2 + 0] = i + 1; - inds[8 + i * 2 + 1] = i + 2 - } - indexBuffer.unlock(); - this.indexBuffer = indexBuffer - } - var vertexFormat = new pc.VertexFormat(app.graphicsDevice, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(app.graphicsDevice, vertexFormat, 42, pc.BUFFER_DYNAMIC); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.indexBuffer[0] = indexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = indexBuffer.getNumIndices(); - mesh.primitive[0].indexed = true; - return mesh - }, _createDebugMaterial:function() { - return new pc.BasicMaterial - }, toolsUpdate:function(data) { - var model = data.model; - var meshInstance = model.meshInstances[0]; - var vertexBuffer = meshInstance.mesh.vertexBuffer; - var oca = Math.PI * data.outerConeAngle / 180; - var ae = data.range; - var y = -ae * Math.cos(oca); - var r = ae * Math.sin(oca); - var positions = new Float32Array(vertexBuffer.lock()); - positions[0] = 0; - positions[1] = 0; - positions[2] = 0; - var numVerts = vertexBuffer.getNumVertices(); - for(var i = 0;i < numVerts - 1;i++) { - var theta = 2 * Math.PI * (i / (numVerts - 2)); - var x = r * Math.cos(theta); - var z = r * Math.sin(theta); - positions[(i + 1) * 3 + 0] = x; - positions[(i + 1) * 3 + 1] = y; - positions[(i + 1) * 3 + 2] = z - } - vertexBuffer.unlock() - }}); - return{LightComponentSystem:LightComponentSystem} -}()); -pc.extend(pc, function() { - var LightComponent = function LightComponent(system, entity) { - this.on("set_type", this.onSetType, this); - this.on("set_color", this.onSetColor, this); - this.on("set_intensity", this.onSetIntensity, this); - this.on("set_castShadows", this.onSetCastShadows, this); - this.on("set_shadowDistance", this.onSetShadowDistance, this); - this.on("set_shadowResolution", this.onSetShadowResolution, this); - this.on("set_shadowBias", this.onSetShadowBias, this); - this.on("set_normalOffsetBias", this.onSetNormalOffsetBias, this); - this.on("set_range", this.onSetRange, this); - this.on("set_innerConeAngle", this.onSetInnerConeAngle, this); - this.on("set_outerConeAngle", this.onSetOuterConeAngle, this); - this.on("set_falloffMode", this.onSetFalloffMode, this); - this.on("set_shadowType", this.onSetShadowType, this); - this.on("set_shadowUpdateMode", this.onSetShadowUpdateMode, this); - this.on("set_mask", this.onSetMask, this) - }; - LightComponent = pc.inherits(LightComponent, pc.Component); - Object.defineProperty(LightComponent.prototype, "enable", {get:function() { - console.warn("WARNING: enable: Property is deprecated. Query enabled property instead."); - return this.enabled - }, set:function(value) { - console.warn("WARNING: enable: Property is deprecated. Set enabled property instead."); - this.enabled = value - }}); - pc.extend(LightComponent.prototype, {onSetType:function(name, oldValue, newValue) { - if(oldValue !== newValue) { - this.system.changeType(this, oldValue, newValue); - this.refreshProperties() - } - }, refreshProperties:function() { - this.onSetCastShadows("castShadows", this.castShadows, this.castShadows); - this.onSetColor("color", this.color, this.color); - this.onSetIntensity("intensity", this.intensity, this.intensity); - this.onSetShadowDistance("shadowDistance", this.shadowDistance, this.shadowDistance); - this.onSetShadowResolution("shadowResolution", this.shadowResolution, this.shadowResolution); - this.onSetShadowBias("shadowBias", this.shadowBias, this.shadowBias); - this.onSetNormalOffsetBias("normalOffsetBias", this.normalOffsetBias, this.normalOffsetBias); - this.onSetRange("range", this.range, this.range); - this.onSetInnerConeAngle("innerConeAngle", this.innerConeAngle, this.innerConeAngle); - this.onSetOuterConeAngle("outerConeAngle", this.outerConeAngle, this.outerConeAngle); - this.onSetFalloffMode("falloffMode", this.falloffMode, this.falloffMode); - this.onSetShadowType("shadowType", this.shadowType, this.shadowType); - this.onSetShadowUpdateMode("shadowUpdateMode", this.shadowUpdateMode, this.shadowUpdateMode); - this.onSetMask("mask", this.mask, this.mask); - if(this.enabled && this.entity.enabled) { - this.onEnable() - } - }, updateShadow:function() { - this.light.updateShadow() - }, onSetCastShadows:function(name, oldValue, newValue) { - this.light.setCastShadows(newValue) - }, onSetColor:function(name, oldValue, newValue) { - this.light.setColor(newValue) - }, onSetIntensity:function(name, oldValue, newValue) { - this.light.setIntensity(newValue) - }, onSetShadowDistance:function(name, oldValue, newValue) { - if(this.data.type === "directional") { - this.light.setShadowDistance(newValue) - } - }, onSetShadowResolution:function(name, oldValue, newValue) { - this.light.setShadowResolution(newValue) - }, onSetShadowBias:function(name, oldValue, newValue) { - this.light.setShadowBias(-0.01 * newValue) - }, onSetNormalOffsetBias:function(name, oldValue, newValue) { - this.light.setNormalOffsetBias(newValue) - }, onSetRange:function(name, oldValue, newValue) { - if(this.data.type === "point" || this.data.type === "spot") { - this.light.setAttenuationEnd(newValue) - } - }, onSetInnerConeAngle:function(name, oldValue, newValue) { - if(this.data.type === "spot") { - this.light.setInnerConeAngle(newValue) - } - }, onSetOuterConeAngle:function(name, oldValue, newValue) { - if(this.data.type === "spot") { - this.light.setOuterConeAngle(newValue) - } - }, onSetFalloffMode:function(name, oldValue, newValue) { - if(this.data.type === "point" || this.data.type === "spot") { - this.light.setFalloffMode(newValue) - } - }, onSetShadowType:function(name, oldValue, newValue) { - this.light.setShadowType(newValue) - }, onSetShadowUpdateMode:function(name, oldValue, newValue) { - this.light.shadowUpdateMode = newValue - }, onSetMask:function(name, oldValue, newValue) { - this.light.mask = newValue - }, onEnable:function() { - LightComponent._super.onEnable.call(this); - this.light.setEnabled(true); - var model = this.data.model; - if(model) { - var scene = this.system.app.scene; - if(!scene.containsModel(model)) { - scene.addModel(model) - } - } - }, onDisable:function() { - LightComponent._super.onDisable.call(this); - this.light.setEnabled(false); - var model = this.data.model; - if(model) { - var scene = this.system.app.scene; - scene.removeModel(model) - } - }}); - return{LightComponent:LightComponent} -}()); -pc.extend(pc, function() { - var LightComponentData = function() { - this.type = "directional"; - this.enabled = true; - this.color = new pc.Color(1, 1, 1); - this.intensity = 1; - this.castShadows = false; - this.shadowDistance = 40; - this.shadowResolution = 1024; - this.shadowBias = 0.05; - this.normalOffsetBias = 0; - this.range = 10; - this.innerConeAngle = 40; - this.outerConeAngle = 45; - this.falloffMode = pc.LIGHTFALLOFF_LINEAR; - this.shadowType = pc.SHADOW_DEPTH; - this.shadowUpdateMode = pc.SHADOWUPDATE_REALTIME; - this.mask = 1; - this.light = null; - this.model = null - }; - LightComponentData = pc.inherits(LightComponentData, pc.ComponentData); - return{LightComponentData:LightComponentData} -}()); -pc.extend(pc, function() { - var INITIALIZE = "initialize"; - var POST_INITIALIZE = "postInitialize"; - var UPDATE = "update"; - var POST_UPDATE = "postUpdate"; - var FIXED_UPDATE = "fixedUpdate"; - var TOOLS_UPDATE = "toolsUpdate"; - var ON_ENABLE = "onEnable"; - var ON_DISABLE = "onDisable"; - var ScriptComponentSystem = function ScriptComponentSystem(app, prefix) { - this.id = "script"; - this.description = "Allows the Entity to run JavaScript fragments to implement custom behavior."; - app.systems.add(this.id, this); - this.ComponentType = pc.ScriptComponent; - this.DataType = pc.ScriptComponentData; - this._prefix = prefix || null; - this.schema = ["enabled", "scripts", "instances", "runInTools"]; - this.preloading = false; - this.instancesWithUpdate = []; - this.instancesWithFixedUpdate = []; - this.instancesWithPostUpdate = []; - this.instancesWithToolsUpdate = []; - this.on("beforeremove", this.onBeforeRemove, this); - pc.ComponentSystem.on(INITIALIZE, this.onInitialize, this); - pc.ComponentSystem.on(POST_INITIALIZE, this.onPostInitialize, this); - pc.ComponentSystem.on(UPDATE, this.onUpdate, this); - pc.ComponentSystem.on(FIXED_UPDATE, this.onFixedUpdate, this); - pc.ComponentSystem.on(POST_UPDATE, this.onPostUpdate, this); - pc.ComponentSystem.on(TOOLS_UPDATE, this.onToolsUpdate, this) - }; - ScriptComponentSystem = pc.inherits(ScriptComponentSystem, pc.ComponentSystem); - pc.extend(ScriptComponentSystem.prototype, {initializeComponentData:function(component, data, properties) { - properties = ["runInTools", "enabled", "scripts"]; - if(data.scripts && data.scripts.length) { - data.scripts.forEach(function(script) { - if(script.attributes && pc.type(script.attributes) === "array") { - var dict = {}; - for(var i = 0;i < script.attributes.length;i++) { - dict[script.attributes[i].name] = script.attributes[i] - } - script.attributes = dict - } - }) - } - ScriptComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, cloneComponent:function(entity, clone) { - var src = this.dataStore[entity.getGuid()]; - var data = {runInTools:src.data.runInTools, scripts:pc.extend([], src.data.scripts), enabled:src.data.enabled}; - return this.addComponent(clone, data) - }, onBeforeRemove:function(entity, component) { - if(component.enabled) { - this._disableScriptComponent(component) - } - this._destroyScriptComponent(component) - }, onInitialize:function(root) { - this._registerInstances(root); - if(root.enabled) { - if(root.script && root.script.enabled) { - this._initializeScriptComponent(root.script) - } - var children = root.getChildren(); - var i, len = children.length; - for(i = 0;i < len;i++) { - if(children[i] instanceof pc.Entity) { - this.onInitialize(children[i]) - } - } - } - }, onPostInitialize:function(root) { - if(root.enabled) { - if(root.script && root.script.enabled) { - this._postInitializeScriptComponent(root.script) - } - var children = root.getChildren(); - var i, len = children.length; - for(i = 0;i < len;i++) { - if(children[i] instanceof pc.Entity) { - this.onPostInitialize(children[i]) - } - } - } - }, _callInstancesMethod:function(script, method) { - var instances = script.data.instances; - for(var name in instances) { - if(instances.hasOwnProperty(name)) { - var instance = instances[name].instance; - if(instance[method]) { - instance[method].call(instance) - } - } - } - }, _initializeScriptComponent:function(script) { - this._callInstancesMethod(script, INITIALIZE); - script.data.initialized = true; - if(script.enabled && script.entity.enabled) { - this._enableScriptComponent(script) - } - }, _enableScriptComponent:function(script) { - this._callInstancesMethod(script, ON_ENABLE) - }, _disableScriptComponent:function(script) { - this._callInstancesMethod(script, ON_DISABLE) - }, _destroyScriptComponent:function(script) { - var index; - var instances = script.data.instances; - for(var name in instances) { - if(instances.hasOwnProperty(name)) { - var instance = instances[name].instance; - if(instance.destroy) { - instance.destroy() - } - if(instance.update) { - index = this.instancesWithUpdate.indexOf(instance); - if(index >= 0) { - this.instancesWithUpdate.splice(index, 1) - } - } - if(instance.fixedUpdate) { - index = this.instancesWithFixedUpdate.indexOf(instance); - if(index >= 0) { - this.instancesWithFixedUpdate.splice(index, 1) - } - } - if(instance.postUpdate) { - index = this.instancesWithPostUpdate.indexOf(instance); - if(index >= 0) { - this.instancesWithPostUpdate.splice(index, 1) - } - } - if(instance.toolsUpdate) { - index = this.instancesWithToolsUpdate.indexOf(instance); - if(index >= 0) { - this.instancesWithToolsUpdate.splice(index, 1) - } - } - if(script.instances[name].instance === script[name]) { - delete script[name] - } - delete script.instances[name] - } - } - }, _postInitializeScriptComponent:function(script) { - this._callInstancesMethod(script, POST_INITIALIZE); - script.data.postInitialized = true - }, _updateInstances:function(method, updateList, dt) { - var item; - for(var i = 0, len = updateList.length;i < len;i++) { - item = updateList[i]; - if(item && item.entity.script.enabled && item.entity.enabled) { - item[method].call(item, dt) - } - } - }, onUpdate:function(dt) { - this._updateInstances(UPDATE, this.instancesWithUpdate, dt) - }, onFixedUpdate:function(dt) { - this._updateInstances(FIXED_UPDATE, this.instancesWithFixedUpdate, dt) - }, onPostUpdate:function(dt) { - this._updateInstances(POST_UPDATE, this.instancesWithPostUpdate, dt) - }, onToolsUpdate:function(dt) { - this._updateInstances(TOOLS_UPDATE, this.instancesWithToolsUpdate, dt) - }, broadcast:function(name, functionName) { - console.warn("DEPRECATED: ScriptComponentSystem.broadcast() is deprecated and will be removed soon. Please use: http://developer.playcanvas.com/user-manual/scripting/communication/"); - var args = pc.makeArray(arguments).slice(2); - var id, data, fn; - var dataStore = this.store; - for(id in dataStore) { - if(dataStore.hasOwnProperty(id)) { - data = dataStore[id].data; - if(data.instances[name]) { - fn = data.instances[name].instance[functionName]; - if(fn) { - fn.apply(data.instances[name].instance, args) - } - } - } - } - }, _preRegisterInstance:function(entity, url, name, instance) { - if(entity.script) { - entity.script.data._instances = entity.script.data._instances || {}; - if(entity.script.data._instances[name]) { - throw Error(pc.string.format("Script name collision '{0}'. Scripts from '{1}' and '{2}' {{3}}", name, url, entity.script.data._instances[name].url, entity.getGuid())); - } - entity.script.data._instances[name] = {url:url, name:name, instance:instance} - } - }, _registerInstances:function(entity) { - var preRegistered, instance, instanceName; - if(entity.script) { - if(entity.script.data._instances) { - entity.script.instances = entity.script.data._instances; - for(instanceName in entity.script.instances) { - preRegistered = entity.script.instances[instanceName]; - instance = preRegistered.instance; - pc.events.attach(instance); - if(instance.update) { - this.instancesWithUpdate.push(instance) - } - if(instance.fixedUpdate) { - this.instancesWithFixedUpdate.push(instance) - } - if(instance.postUpdate) { - this.instancesWithPostUpdate.push(instance) - } - if(instance.toolsUpdate) { - this.instancesWithToolsUpdate.push(instance) - } - if(entity.script.scripts) { - this._createAccessors(entity, preRegistered) - } - if(entity.script[instanceName]) { - throw Error(pc.string.format("Script with name '{0}' is already attached to Script Component", instanceName)); - }else { - entity.script[instanceName] = instance - } - } - delete entity.script.data._instances - } - } - var children = entity.getChildren(); - var i, len = children.length; - for(i = 0;i < len;i++) { - if(children[i] instanceof pc.Entity) { - this._registerInstances(children[i]) - } - } - }, _createAccessors:function(entity, instance) { - var self = this; - var i; - var len = entity.script.scripts.length; - var url = instance.url; - for(i = 0;i < len;i++) { - var script = entity.script.scripts[i]; - if(script.url === url) { - var attributes = script.attributes; - if(script.name && attributes) { - for(var key in attributes) { - if(attributes.hasOwnProperty(key)) { - self._createAccessor(attributes[key], instance) - } - } - entity.script.data.attributes[script.name] = pc.extend({}, attributes) - } - break - } - } - }, _createAccessor:function(attribute, instance) { - var self = this; - self._convertAttributeValue(attribute); - Object.defineProperty(instance.instance, attribute.name, {get:function() { - return attribute.value - }, set:function(value) { - var oldValue = attribute.value; - attribute.value = value; - self._convertAttributeValue(attribute); - instance.instance.fire("set", attribute.name, oldValue, attribute.value) - }, configurable:true}) - }, _updateAccessors:function(entity, instance) { - var self = this; - var i; - var len = entity.script.scripts.length; - var key; - var url = instance.url; - var scriptComponent, script, name, attributes; - var previousAttributes; - var oldAttribute; - for(i = 0;i < len;i++) { - scriptComponent = entity.script; - script = scriptComponent.scripts[i]; - if(script.url === url) { - name = script.name; - attributes = script.attributes; - if(name) { - if(attributes) { - for(key in attributes) { - if(attributes.hasOwnProperty(key)) { - self._createAccessor(attributes[key], instance) - } - } - } - previousAttributes = scriptComponent.data.attributes[name]; - if(previousAttributes) { - for(key in previousAttributes) { - oldAttribute = previousAttributes[key]; - if(!(key in attributes)) { - delete instance.instance[oldAttribute.name] - }else { - if(attributes[key].value !== oldAttribute.value) { - if(instance.instance.onAttributeChanged) { - instance.instance.onAttributeChanged(oldAttribute.name, oldAttribute.value, attributes[key].value) - } - } - } - } - } - if(attributes) { - scriptComponent.data.attributes[name] = pc.extend([], attributes) - }else { - delete scriptComponent.data.attributes[name] - } - } - break - } - } - }, _convertAttributeValue:function(attribute) { - if(attribute.type === "rgb" || attribute.type === "rgba") { - if(pc.type(attribute.value) === "array") { - attribute.value = attribute.value.length === 3 ? new pc.Color(attribute.value[0], attribute.value[1], attribute.value[2]) : new pc.Color(attribute.value[0], attribute.value[1], attribute.value[2], attribute.value[3]) - } - }else { - if(attribute.type === "vector") { - if(pc.type(attribute.value) === "array") { - attribute.value = new pc.Vec3(attribute.value[0], attribute.value[1], attribute.value[2]) - } - } - } - }}); - return{ScriptComponentSystem:ScriptComponentSystem} -}()); -pc.extend(pc, function() { - var ScriptComponent = function ScriptComponent(system, entity) { - this.on("set_scripts", this.onSetScripts, this) - }; - ScriptComponent = pc.inherits(ScriptComponent, pc.Component); - pc.extend(ScriptComponent.prototype, {send:function(name, functionName) { - console.warn("DEPRECATED: ScriptComponent.send() is deprecated and will be removed soon. Please use: http://developer.playcanvas.com/user-manual/scripting/communication/"); - var args = pc.makeArray(arguments).slice(2); - var instances = this.entity.script.instances; - var fn; - if(instances && instances[name]) { - fn = instances[name].instance[functionName]; - if(fn) { - return fn.apply(instances[name].instance, args) - } - } - }, onEnable:function() { - ScriptComponent._super.onEnable.call(this); - if(this.data.areScriptsLoaded && !this.system.preloading) { - if(!this.data.initialized) { - this.system._initializeScriptComponent(this) - }else { - this.system._enableScriptComponent(this) - } - if(!this.data.postInitialized) { - this.system._postInitializeScriptComponent(this) - } - } - }, onDisable:function() { - ScriptComponent._super.onDisable.call(this); - this.system._disableScriptComponent(this) - }, onSetScripts:function(name, oldValue, newValue) { - if(!this.system._inTools || this.runInTools) { - if(this._updateScriptAttributes(oldValue, newValue)) { - return - } - if(this.enabled) { - this.system._disableScriptComponent(this) - } - this.system._destroyScriptComponent(this); - this.data.areScriptsLoaded = false; - var scripts = newValue; - var urls = scripts.map(function(s) { - return s.url - }); - if(this._loadFromCache(urls)) { - return - } - this._loadScripts(urls) - } - }, _updateScriptAttributes:function(oldValue, newValue) { - var onlyUpdateAttributes = true; - if(oldValue.length !== newValue.length) { - onlyUpdateAttributes = false - }else { - var i; - len = newValue.length; - for(i = 0;i < len;i++) { - if(oldValue[i].url !== newValue[i].url) { - onlyUpdateAttributes = false; - break - } - } - } - if(onlyUpdateAttributes) { - for(var key in this.instances) { - if(this.instances.hasOwnProperty(key)) { - this.system._updateAccessors(this.entity, this.instances[key]) - } - } - } - return onlyUpdateAttributes - }, _loadFromCache:function(urls) { - var cached = []; - for(var i = 0, len = urls.length;i < len;i++) { - var type = this.system.app.loader.getFromCache(urls[i]); - if(!type) { - return false - }else { - cached.push(type) - } - } - for(var i = 0, len = cached.length;i < len;i++) { - var ScriptType = cached[i]; - if(ScriptType === true) { - continue - } - if(ScriptType && this.entity.script) { - if(!this.entity.script.instances[ScriptType._pcScriptName]) { - var instance = new ScriptType(this.entity); - this.system._preRegisterInstance(this.entity, urls[i], ScriptType._pcScriptName, instance) - } - } - } - if(this.data) { - this.data.areScriptsLoaded = true - } - if(!this.system.preloading) { - this.system.onInitialize(this.entity); - this.system.onPostInitialize(this.entity) - } - return true - }, _loadScripts:function(urls) { - var count = urls.length; - var prefix = this.system._prefix || ""; - urls.forEach(function(url) { - var _url = null; - var _unprefixed = null; - if(pc.string.startsWith(url.toLowerCase(), "http://") || pc.string.startsWith(url.toLowerCase(), "https://")) { - _unprefixed = url; - _url = url - }else { - _unprefixed = url; - _url = pc.path.join(prefix, url) - } - this.system.app.loader.load(_url, "script", function(err, ScriptType) { - count--; - if(!err) { - if(ScriptType && this.entity.script) { - if(!this.entity.script.instances[ScriptType._pcScriptName]) { - var instance = new ScriptType(this.entity); - this.system._preRegisterInstance(this.entity, _unprefixed, ScriptType._pcScriptName, instance) - } - } - }else { - console.error(err) - } - if(count === 0) { - this.data.areScriptsLoaded = true; - if(!this.system.preloading) { - this.system.onInitialize(this.entity); - this.system.onPostInitialize(this.entity) - } - } - }.bind(this)) - }.bind(this)) - }}); - return{ScriptComponent:ScriptComponent} -}()); -pc.extend(pc, function() { - var ScriptComponentData = function() { - this.scripts = []; - this.enabled = true; - this.instances = {}; - this._instances = {}; - this.runInTools = false; - this.attributes = {}; - this.initialized = false; - this.postInitialized = false; - this.areScriptsLoaded = false - }; - ScriptComponentData = pc.inherits(ScriptComponentData, pc.ComponentData); - return{ScriptComponentData:ScriptComponentData} -}()); -pc.extend(pc, function() { - var PickComponentSystem = function PickComponentSystem(app) { - this.id = "pick"; - app.systems.add(this.id, this); - this.ComponentType = pc.PickComponent; - this.DataType = pc.PickComponentData; - this.schema = ["layer", "shapes", "material"]; - this.layers = {"default":[]}; - this.display = false; - this.on("remove", this.onRemove, this) - }; - PickComponentSystem = pc.inherits(PickComponentSystem, pc.ComponentSystem); - pc.extend(PickComponentSystem.prototype, {initializeComponentData:function(component, data, properties) { - data.material = new pc.PhongMaterial; - properties = ["material"]; - PickComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, onRemove:function(entity, data) { - this.deleteShapes(data.layer, data.shapes) - }, addShape:function(layer, shape) { - if(this.layers[layer] === undefined) { - this.layers[layer] = [] - } - this.layers[layer].push(shape.model); - if(this.display) { - this.app.scene.addModel(shape.model) - } - }, deleteShapes:function(layer, shapes) { - var layerModels = this.layers[layer]; - for(var i = 0;i < shapes.length;i++) { - var model = shapes[i].model; - var index = layerModels.indexOf(model); - if(index !== -1) { - layerModels.splice(index, 1) - } - if(this.display) { - this.app.scene.removeModel(model) - } - } - }, getLayerModels:function(layerName) { - return this.layers[layerName] - }}); - return{PickComponentSystem:PickComponentSystem} -}()); -pc.extend(pc, function() { - var PickComponent = function PickComponent(system, entity) { - }; - PickComponent = pc.inherits(PickComponent, pc.Component); - pc.extend(PickComponent.prototype, {addShape:function(shape, shapeName) { - var material = this.data.material; - var mesh = null; - switch(shape.type) { - case pc.shape.Type.BOX: - mesh = pc.createBox(this.system.app.graphicsDevice, {halfExtents:shape.halfExtents}); - break; - case pc.shape.Type.SPHERE: - mesh = pc.createSphere(this.system.app.graphicsDevice, {radius:shape.radius}); - break; - case pc.shape.Type.TORUS: - mesh = pc.createTorus(this.system.app.graphicsDevice, {tubeRadius:shape.iradius, ringRadius:shape.oradius}); - break - } - var node = new pc.GraphNode; - var meshInstance = new pc.MeshInstance(node, mesh, material); - meshInstance._entity = this.entity; - var model = new pc.Model; - model.graph = node; - model.meshInstances = [meshInstance]; - var shape = {shape:shape, shapeName:shapeName, model:model}; - this.data.shapes.push(shape); - this.system.addShape(this.data.layer, shape) - }, deleteShapes:function() { - this.system.deleteShapes(this.data.layer, this.data.shapes); - this.data.shapes = [] - }}); - return{PickComponent:PickComponent} -}()); -pc.extend(pc, function() { - function PickComponentData() { - this.layer = "default"; - this.shapes = []; - this.material = null - } - PickComponentData = pc.inherits(PickComponentData, pc.ComponentData); - return{PickComponentData:PickComponentData} -}()); -pc.extend(pc, function() { - var AudioSourceComponentSystem = function(app, manager) { - this.id = "audiosource"; - this.description = "Specifies audio assets that can be played at the position of the Entity."; - app.systems.add(this.id, this); - this.ComponentType = pc.AudioSourceComponent; - this.DataType = pc.AudioSourceComponentData; - this.schema = ["enabled", "assets", "volume", "pitch", "loop", "activate", "3d", "minDistance", "maxDistance", "rollOffFactor", "sources", "currentSource", "channel"]; - this.manager = manager; - this.initialized = false; - pc.ComponentSystem.on("initialize", this.onInitialize, this); - pc.ComponentSystem.on("update", this.onUpdate, this); - this.on("remove", this.onRemove, this) - }; - AudioSourceComponentSystem = pc.inherits(AudioSourceComponentSystem, pc.ComponentSystem); - pc.extend(AudioSourceComponentSystem.prototype, {initializeComponentData:function(component, data, properties) { - properties = ["activate", "volume", "pitch", "loop", "3d", "minDistance", "maxDistance", "rollOffFactor", "enabled", "assets"]; - AudioSourceComponentSystem._super.initializeComponentData.call(this, component, data, properties); - component.paused = !(component.enabled && component.activate) - }, onInitialize:function(root) { - if(root.audiosource && root.enabled && root.audiosource.enabled && root.audiosource.activate) { - root.audiosource.play(root.audiosource.currentSource) - } - var children = root.getChildren(); - var i, len = children.length; - for(i = 0;i < len;i++) { - if(children[i] instanceof pc.Entity) { - this.onInitialize(children[i]) - } - } - this.initialized = true - }, onUpdate:function(dt) { - var components = this.store; - for(var id in components) { - if(components.hasOwnProperty(id)) { - var component = components[id]; - var entity = component.entity; - var componentData = component.data; - if(componentData.enabled && entity.enabled && componentData.channel instanceof pc.Channel3d) { - var pos = entity.getPosition(); - componentData.channel.setPosition(pos) - } - } - } - }, onRemove:function(entity, data) { - if(data.channel) { - data.channel.stop(); - data.channel = null - } - }, setVolume:function(volume) { - this.manager.setVolume(volume) - }}); - return{AudioSourceComponentSystem:AudioSourceComponentSystem} -}()); -pc.extend(pc, function() { - var AudioSourceComponent = function(system, entity) { - this.on("set_assets", this.onSetAssets, this); - this.on("set_loop", this.onSetLoop, this); - this.on("set_volume", this.onSetVolume, this); - this.on("set_pitch", this.onSetPitch, this); - this.on("set_minDistance", this.onSetMinDistance, this); - this.on("set_maxDistance", this.onSetMaxDistance, this); - this.on("set_rollOffFactor", this.onSetRollOffFactor, this); - this.on("set_3d", this.onSet3d, this) - }; - AudioSourceComponent = pc.inherits(AudioSourceComponent, pc.Component); - pc.extend(AudioSourceComponent.prototype, {play:function(name) { - if(!this.enabled || !this.entity.enabled) { - return - } - if(this.channel) { - this.stop() - } - var channel; - var componentData = this.data; - if(componentData.sources[name]) { - if(!componentData.sources[name].isLoaded) { - logWARNING(pc.string.format("Audio asset '{0}' is not loaded (probably an unsupported format) and will not be played", name)); - return - } - if(!componentData["3d"]) { - channel = this.system.manager.playSound(componentData.sources[name], componentData); - componentData.currentSource = name; - componentData.channel = channel - }else { - var pos = this.entity.getPosition(); - channel = this.system.manager.playSound3d(componentData.sources[name], pos, componentData); - componentData.currentSource = name; - componentData.channel = channel - } - } - }, pause:function() { - if(this.channel) { - this.channel.pause() - } - }, unpause:function() { - if(this.channel && this.channel.paused) { - this.channel.unpause() - } - }, stop:function() { - if(this.channel) { - this.channel.stop(); - this.channel = null - } - }, onSetAssets:function(name, oldValue, newValue) { - var componentData = this.data; - var newAssets = []; - var i, len = newValue.length; - if(oldValue && oldValue.length) { - for(var i = 0;i < oldValue.length;i++) { - if(oldValue[i]) { - var asset = this.system.app.assets.get(oldValue[i]); - if(asset) { - asset.off("change", this.onAssetChanged, this); - asset.off("remove", this.onAssetRemoved, this); - if(this.currentSource === asset.name) { - this.stop() - } - } - } - } - } - if(len) { - for(i = 0;i < len;i++) { - if(oldValue.indexOf(newValue[i]) < 0) { - if(newValue[i] instanceof pc.Asset) { - newAssets.push(newValue[i].id) - }else { - newAssets.push(newValue[i]) - } - } - } - } - if(!this.system._inTools && newAssets.length) { - this.loadAudioSourceAssets(newAssets) - } - }, onAssetChanged:function(asset, attribute, newValue, oldValue) { - if(attribute === "resource") { - var sources = this.data.sources; - if(sources) { - this.data.sources[asset.name] = newValue; - if(this.data.currentSource === asset.name) { - if(this.channel) { - if(this.channel.paused) { - this.play(asset.name); - this.pause() - }else { - this.play(asset.name) - } - } - } - } - } - }, onAssetRemoved:function(asset) { - asset.off("remove", this.onAssetRemoved, this); - if(this.data.sources[asset.name]) { - delete this.data.sources[asset.name]; - if(this.data.currentSource === asset.name) { - this.stop(); - this.data.currentSource = null - } - } - }, onSetLoop:function(name, oldValue, newValue) { - if(oldValue != newValue) { - if(this.channel) { - this.channel.setLoop(newValue) - } - } - }, onSetVolume:function(name, oldValue, newValue) { - if(oldValue != newValue) { - if(this.channel) { - this.channel.setVolume(newValue) - } - } - }, onSetPitch:function(name, oldValue, newValue) { - if(oldValue != newValue) { - if(this.channel) { - this.channel.setPitch(newValue) - } - } - }, onSetMaxDistance:function(name, oldValue, newValue) { - if(oldValue != newValue) { - if(this.channel instanceof pc.Channel3d) { - this.channel.setMaxDistance(newValue) - } - } - }, onSetMinDistance:function(name, oldValue, newValue) { - if(oldValue != newValue) { - if(this.channel instanceof pc.Channel3d) { - this.channel.setMinDistance(newValue) - } - } - }, onSetRollOffFactor:function(name, oldValue, newValue) { - if(oldValue != newValue) { - if(this.channel instanceof pc.Channel3d) { - this.channel.setRollOffFactor(newValue) - } - } - }, onSet3d:function(name, oldValue, newValue) { - if(oldValue !== newValue) { - if(this.system.initialized && this.currentSource) { - this.play(this.currentSource) - } - } - }, onEnable:function() { - AudioSourceComponent._super.onEnable.call(this); - if(this.system.initialized) { - if(this.data.activate && !this.channel) { - this.play(this.currentSource) - }else { - this.unpause() - } - } - }, onDisable:function() { - AudioSourceComponent._super.onDisable.call(this); - this.pause() - }, loadAudioSourceAssets:function(ids) { - var assets = ids.map(function(id) { - return this.system.app.assets.get(id) - }, this); - var sources = {}; - var currentSource = null; - var count = assets.length; - var _error = function(e) { - count-- - }; - var _done = function() { - this.data.sources = sources; - this.data.currentSource = currentSource; - if(this.enabled && this.activate && currentSource) { - this.onEnable() - } - }.bind(this); - assets.forEach(function(asset, index) { - if(asset) { - currentSource = currentSource || asset.name; - asset.off("change", this.onAssetChanged, this); - asset.on("change", this.onAssetChanged, this); - asset.off("remove", this.onAssetRemoved, this); - asset.on("remove", this.onAssetRemoved, this); - asset.off("error", _error, this); - asset.on("error", _error, this); - asset.ready(function(asset) { - sources[asset.name] = asset.resource; - count--; - if(count === 0) { - _done() - } - }) - }else { - count--; - if(count === 0) { - _done() - } - assets.on("add:" + ids[index], function(asset) { - asset.ready(function(asset) { - this.data.sources[asset.name] = asset.resource - }) - }) - } - }, this) - }}); - return{AudioSourceComponent:AudioSourceComponent} -}()); -pc.AudioSourceComponentData = function AudioSourceComponentData() { - this.enabled = true; - this.assets = []; - this.activate = true; - this.volume = 1; - this.pitch = 1; - this.loop = false; - this["3d"] = true; - this.minDistance = 1; - this.maxDistance = 1E4; - this.rollOffFactor = 1; - this.paused = true; - this.sources = {}; - this.currentSource = null; - this.channel = null -}; -pc.extend(pc, function() { - var AudioListenerComponentSystem = function(app, manager) { - this.id = "audiolistener"; - this.description = "Specifies the location of the listener for 3D audio playback."; - app.systems.add(this.id, this); - this.ComponentType = pc.AudioListenerComponent; - this.DataType = pc.AudioListenerComponentData; - this.schema = ["enabled"]; - this.manager = manager; - this.current = null; - pc.ComponentSystem.on("update", this.onUpdate, this) - }; - AudioListenerComponentSystem = pc.inherits(AudioListenerComponentSystem, pc.ComponentSystem); - pc.extend(AudioListenerComponentSystem.prototype, {initializeComponentData:function(component, data, properties) { - properties = ["enabled"]; - AudioListenerComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, onUpdate:function(dt) { - if(this.current) { - var position = this.current.getPosition(); - this.manager.listener.setPosition(position); - var wtm = this.current.getWorldTransform(); - this.manager.listener.setOrientation(wtm) - } - }}); - return{AudioListenerComponentSystem:AudioListenerComponentSystem} -}()); -pc.extend(pc, function() { - var AudioListenerComponent = function(system, entity) { - }; - AudioListenerComponent = pc.inherits(AudioListenerComponent, pc.Component); - pc.extend(AudioListenerComponent.prototype, {setCurrentListener:function() { - if(this.enabled && this.entity.audiolistener && this.entity.enabled) { - this.system.current = this.entity; - var position = this.system.current.getPosition(); - this.system.manager.listener.setPosition(position) - } - }, onEnable:function() { - AudioListenerComponent._super.onEnable.call(this); - this.setCurrentListener() - }, onDisable:function() { - AudioListenerComponent._super.onDisable.call(this); - if(this.system.current === this.entity) { - this.system.current = null - } - }}); - return{AudioListenerComponent:AudioListenerComponent} -}()); -pc.extend(pc, function() { - var AudioListenerComponentData = function() { - this.enabled = true - }; - AudioListenerComponentData = pc.inherits(AudioListenerComponentData, pc.ComponentData); - return{AudioListenerComponentData:AudioListenerComponentData} -}()); -pc.extend(pc, {BODYTYPE_STATIC:"static", BODYTYPE_DYNAMIC:"dynamic", BODYTYPE_KINEMATIC:"kinematic", BODYFLAG_STATIC_OBJECT:1, BODYFLAG_KINEMATIC_OBJECT:2, BODYFLAG_NORESPONSE_OBJECT:4, BODYSTATE_ACTIVE_TAG:1, BODYSTATE_ISLAND_SLEEPING:2, BODYSTATE_WANTS_DEACTIVATION:3, BODYSTATE_DISABLE_DEACTIVATION:4, BODYSTATE_DISABLE_SIMULATION:5, BODYGROUP_NONE:0, BODYGROUP_DEFAULT:1, BODYGROUP_DYNAMIC:1, BODYGROUP_STATIC:2, BODYGROUP_KINEMATIC:4, BODYGROUP_ENGINE_1:8, BODYGROUP_TRIGGER:16, BODYGROUP_ENGINE_2:32, -BODYGROUP_ENGINE_3:64, BODYGROUP_USER_1:128, BODYGROUP_USER_2:256, BODYGROUP_USER_3:512, BODYGROUP_USER_4:1024, BODYGROUP_USER_5:2048, BODYGROUP_USER_6:4096, BODYGROUP_USER_7:8192, BODYGROUP_USER_8:16384, BODYMASK_NONE:0, BODYMASK_ALL:65535, BODYMASK_STATIC:2, BODYMASK_NOT_STATIC:65535 ^ 2, BODYMASK_NOT_STATIC_KINEMATIC:65535 ^ (2 | 4)}); -pc.extend(pc, function() { - var transform = new pc.Mat4; - var newWtm = new pc.Mat4; - var position = new pc.Vec3; - var rotation = new pc.Vec3; - var scale = new pc.Vec3; - var ammoRayStart, ammoRayEnd; - var collisions = {}; - var frameCollisions = {}; - var RaycastResult = function RaycastResult(entity, point, normal) { - this.entity = entity; - this.point = point; - this.normal = normal - }; - var SingleContactResult = function SingleContactResult(a, b, contactPoint) { - if(arguments.length === 0) { - this.a = null; - this.b = null; - this.localPointA = new pc.Vec3; - this.localPointB = new pc.Vec3; - this.pointA = new pc.Vec3; - this.pointB = new pc.Vec3; - this.normal = new pc.Vec3 - }else { - this.a = a; - this.b = b; - this.localPointA = contactPoint.localPoint; - this.localPointB = contactPoint.localPointOther; - this.pointA = contactPoint.point; - this.pointB = contactPoint.pointOther; - this.normal = contactPoint.normal - } - }; - var ContactPoint = function ContactPoint(localPoint, localPointOther, point, pointOther, normal) { - if(arguments.length === 0) { - this.localPoint = new pc.Vec3; - this.localPointOther = new pc.Vec3; - this.point = new pc.Vec3; - this.pointOther = new pc.Vec3; - this.normal = new pc.Vec3 - }else { - this.localPoint = localPoint; - this.localPointOther = localPointOther; - this.point = point; - this.pointOther = pointOther; - this.normal = normal - } - }; - var ContactResult = function ContactResult(other, contacts) { - this.other = other; - this.contacts = contacts - }; - var RigidBodyComponentSystem = function RigidBodyComponentSystem(app) { - this.id = "rigidbody"; - this.description = "Adds the entity to the scene's physical simulation."; - app.systems.add(this.id, this); - this.ComponentType = pc.RigidBodyComponent; - this.DataType = pc.RigidBodyComponentData; - this.contactPointPool = new pc.AllocatePool(ContactPoint, 1); - this.contactResultPool = new pc.AllocatePool(ContactResult, 1); - this.singleContactResultPool = new pc.AllocatePool(SingleContactResult, 1); - this.schema = ["enabled", "type", "mass", "linearDamping", "angularDamping", "linearFactor", "angularFactor", "friction", "restitution", "group", "mask", "body"]; - this.maxSubSteps = 10; - this.fixedTimeStep = 1 / 60; - this.on("remove", this.onRemove, this) - }; - RigidBodyComponentSystem = pc.inherits(RigidBodyComponentSystem, pc.ComponentSystem); - pc.extend(RigidBodyComponentSystem.prototype, {onLibraryLoaded:function() { - if(typeof Ammo !== "undefined") { - var collisionConfiguration = new Ammo.btDefaultCollisionConfiguration; - var dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration); - var overlappingPairCache = new Ammo.btDbvtBroadphase; - var solver = new Ammo.btSequentialImpulseConstraintSolver; - this.dynamicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); - this._ammoGravity = new Ammo.btVector3(0, -9.82, 0); - this.dynamicsWorld.setGravity(this._ammoGravity); - ammoRayStart = new Ammo.btVector3; - ammoRayEnd = new Ammo.btVector3; - pc.ComponentSystem.on("update", this.onUpdate, this) - }else { - pc.ComponentSystem.off("update", this.onUpdate, this) - } - }, initializeComponentData:function(component, _data, properties) { - properties = ["enabled", "mass", "linearDamping", "angularDamping", "linearFactor", "angularFactor", "friction", "restitution", "type", "group", "mask"]; - var data = {}; - properties.forEach(function(prop) { - data[prop] = _data[prop] - }); - if(_data.bodyType) { - data.type = _data.bodyType; - console.warn("WARNING: rigidbody.bodyType: Property is deprecated. Use type instead.") - } - if(data.linearFactor && pc.type(data.linearFactor) === "array") { - data.linearFactor = new pc.Vec3(data.linearFactor[0], data.linearFactor[1], data.linearFactor[2]) - } - if(data.angularFactor && pc.type(data.angularFactor) === "array") { - data.angularFactor = new pc.Vec3(data.angularFactor[0], data.angularFactor[1], data.angularFactor[2]) - } - RigidBodyComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, cloneComponent:function(entity, clone) { - var data = {enabled:entity.rigidbody.enabled, mass:entity.rigidbody.mass, linearDamping:entity.rigidbody.linearDamping, angularDamping:entity.rigidbody.angularDamping, linearFactor:[entity.rigidbody.linearFactor.x, entity.rigidbody.linearFactor.y, entity.rigidbody.linearFactor.z], angularFactor:[entity.rigidbody.angularFactor.x, entity.rigidbody.angularFactor.y, entity.rigidbody.angularFactor.z], friction:entity.rigidbody.friction, restitution:entity.rigidbody.restitution, type:entity.rigidbody.type, - group:entity.rigidbody.group, mask:entity.rigidbody.mask}; - this.addComponent(clone, data) - }, onRemove:function(entity, data) { - if(data.body) { - this.removeBody(data.body); - Ammo.destroy(data.body) - } - data.body = null - }, addBody:function(body, group, mask) { - if(group !== undefined && mask !== undefined) { - this.dynamicsWorld.addRigidBody(body, group, mask) - }else { - this.dynamicsWorld.addRigidBody(body) - } - return body - }, removeBody:function(body) { - this.dynamicsWorld.removeRigidBody(body) - }, addConstraint:function(constraint) { - this.dynamicsWorld.addConstraint(constraint); - return constraint - }, removeConstraint:function(constraint) { - this.dynamicsWorld.removeConstraint(constraint) - }, setGravity:function() { - var x, y, z; - if(arguments.length === 1) { - x = arguments[0].x; - y = arguments[0].y; - z = arguments[0].z - }else { - x = arguments[0]; - y = arguments[1]; - z = arguments[2] - } - this._ammoGravity.setValue(x, y, z); - this.dynamicsWorld.setGravity(this._ammoGravity) - }, raycastFirst:function(start, end, callback) { - ammoRayStart.setValue(start.x, start.y, start.z); - ammoRayEnd.setValue(end.x, end.y, end.z); - var rayCallback = new Ammo.ClosestRayResultCallback(ammoRayStart, ammoRayEnd); - this.dynamicsWorld.rayTest(ammoRayStart, ammoRayEnd, rayCallback); - if(rayCallback.hasHit()) { - var collisionObj = rayCallback.get_m_collisionObject(); - var body = Ammo.castObject(collisionObj, Ammo.btRigidBody); - var point = rayCallback.get_m_hitPointWorld(); - var normal = rayCallback.get_m_hitNormalWorld(); - if(body) { - callback(new RaycastResult(body.entity, new pc.Vec3(point.x(), point.y(), point.z()), new pc.Vec3(normal.x(), normal.y(), normal.z()))) - } - } - Ammo.destroy(rayCallback) - }, _storeCollision:function(entity, other) { - var isNewCollision = false; - var guid = entity.getGuid(); - collisions[guid] = collisions[guid] || {others:[], entity:entity}; - if(collisions[guid].others.indexOf(other) < 0) { - collisions[guid].others.push(other); - isNewCollision = true - } - frameCollisions[guid] = frameCollisions[guid] || {others:[], entity:entity}; - frameCollisions[guid].others.push(other); - return isNewCollision - }, _createContactPointFromAmmo:function(contactPoint) { - var contact = this.contactPointPool.allocate(); - contact.localPoint.set(contactPoint.get_m_localPointA().x(), contactPoint.get_m_localPointA().y(), contactPoint.get_m_localPointA().z()); - contact.localPointOther.set(contactPoint.get_m_localPointB().x(), contactPoint.get_m_localPointB().y(), contactPoint.get_m_localPointB().z()); - contact.point.set(contactPoint.getPositionWorldOnA().x(), contactPoint.getPositionWorldOnA().y(), contactPoint.getPositionWorldOnA().z()); - contact.pointOther.set(contactPoint.getPositionWorldOnB().x(), contactPoint.getPositionWorldOnB().y(), contactPoint.getPositionWorldOnB().z()); - contact.normal.set(contactPoint.get_m_normalWorldOnB().x(), contactPoint.get_m_normalWorldOnB().y(), contactPoint.get_m_normalWorldOnB().z()); - return contact - }, _createReverseContactPointFromAmmo:function(contactPoint) { - var contact = this.contactPointPool.allocate(); - contact.localPointOther.set(contactPoint.get_m_localPointA().x(), contactPoint.get_m_localPointA().y(), contactPoint.get_m_localPointA().z()); - contact.localPoint.set(contactPoint.get_m_localPointB().x(), contactPoint.get_m_localPointB().y(), contactPoint.get_m_localPointB().z()); - contact.pointOther.set(contactPoint.getPositionWorldOnA().x(), contactPoint.getPositionWorldOnA().y(), contactPoint.getPositionWorldOnA().z()); - contact.point.set(contactPoint.getPositionWorldOnB().x(), contactPoint.getPositionWorldOnB().y(), contactPoint.getPositionWorldOnB().z()); - contact.normal.set(contactPoint.get_m_normalWorldOnB().x(), contactPoint.get_m_normalWorldOnB().y(), contactPoint.get_m_normalWorldOnB().z()); - return contact - }, _createSingleContactResult:function(a, b, contactPoint) { - var result = this.singleContactResultPool.allocate(); - result.a = a; - result.b = b; - result.localPointA = contactPoint.localPoint; - result.localPointB = contactPoint.localPointOther; - result.pointA = contactPoint.point; - result.pointB = contactPoint.pointOther; - result.normal = contactPoint.normal; - return result - }, _createContactResult:function(other, contacts) { - var result = this.contactResultPool.allocate(); - result.other = other; - result.contacts = contacts; - return result - }, _cleanOldCollisions:function() { - for(var guid in collisions) { - if(collisions.hasOwnProperty(guid)) { - var entity = collisions[guid].entity; - var entityCollision = entity.collision; - var others = collisions[guid].others; - var length = others.length; - var i = length; - while(i--) { - var other = others[i]; - if(!frameCollisions[guid] || frameCollisions[guid].others.indexOf(other) < 0) { - others.splice(i, 1); - if(entityCollision && other.collision) { - if(entity.rigidbody && other.rigidbody) { - entityCollision.fire("collisionend", other) - }else { - if(entity.trigger) { - entityCollision.fire("triggerleave", other) - } - } - } - } - } - if(others.length === 0) { - delete collisions[guid] - } - } - } - }, onUpdate:function(dt) { - frameContacts = 0; - this.dynamicsWorld.stepSimulation(dt, this.maxSubSteps, this.fixedTimeStep); - var components = this.store; - for(var id in components) { - if(components.hasOwnProperty(id)) { - var entity = components[id].entity; - var componentData = components[id].data; - if(componentData.body && componentData.body.isActive() && componentData.enabled && entity.enabled) { - if(componentData.type === pc.BODYTYPE_DYNAMIC) { - entity.rigidbody.syncBodyToEntity() - }else { - if(componentData.type === pc.BODYTYPE_KINEMATIC) { - entity.rigidbody._updateKinematic(dt) - } - } - } - } - } - var dispatcher = this.dynamicsWorld.getDispatcher(); - var numManifolds = dispatcher.getNumManifolds(); - var i, j; - frameCollisions = {}; - for(i = 0;i < numManifolds;i++) { - var manifold = dispatcher.getManifoldByIndexInternal(i); - var body0 = manifold.getBody0(); - var body1 = manifold.getBody1(); - var wb0 = Ammo.castObject(body0, Ammo.btRigidBody); - var wb1 = Ammo.castObject(body1, Ammo.btRigidBody); - var e0 = wb0.entity; - var e1 = wb1.entity; - if(!e0 || !e1) { - continue - } - var flags0 = body0.getCollisionFlags(); - var flags1 = body1.getCollisionFlags(); - var numContacts = manifold.getNumContacts(); - var forwardContacts = []; - var reverseContacts = []; - if(numContacts > 0) { - if(flags0 & pc.BODYFLAG_NORESPONSE_OBJECT || flags1 & pc.BODYFLAG_NORESPONSE_OBJECT) { - var e0Events = e0.collision ? e0.collision.hasEvent("triggerenter") || e0.collision.hasEvent("triggerleave") : false; - var e1Events = e1.collision ? e1.collision.hasEvent("triggerenter") || e1.collision.hasEvent("triggerleave") : false; - if(e0Events) { - var newCollision = this._storeCollision(e0, e1); - if(newCollision) { - if(e0.collision && !(flags1 & pc.BODYFLAG_NORESPONSE_OBJECT)) { - e0.collision.fire("triggerenter", e1) - } - } - } - if(e1Events) { - var newCollision = this._storeCollision(e1, e0); - if(newCollision) { - if(e1.collision && !(flags0 & pc.BODYFLAG_NORESPONSE_OBJECT)) { - e1.collision.fire("triggerenter", e0) - } - } - } - }else { - var e0Events = e0.collision ? e0.collision.hasEvent("collisionstart") || e0.collision.hasEvent("collisionend") || e0.collision.hasEvent("contact") : false; - var e1Events = e1.collision ? e1.collision.hasEvent("collisionstart") || e1.collision.hasEvent("collisionend") || e1.collision.hasEvent("contact") : false; - var globalEvents = this.hasEvent("contact"); - if(globalEvents || e0Events || e1Events) { - for(j = 0;j < numContacts;j++) { - var btContactPoint = manifold.getContactPoint(j); - var contactPoint = this._createContactPointFromAmmo(btContactPoint); - var reverseContactPoint = null; - if(e0Events || e1Events) { - reverseContactPoint = this._createReverseContactPointFromAmmo(btContactPoint); - forwardContacts.push(contactPoint); - reverseContacts.push(reverseContactPoint) - } - if(globalEvents) { - var result = this._createSingleContactResult(e0, e1, contactPoint); - this.fire("contact", result) - } - } - if(e0Events) { - var forwardResult = this._createContactResult(e1, forwardContacts); - if(e0.collision) { - e0.collision.fire("contact", forwardResult) - } - var newCollision = this._storeCollision(e0, e1); - if(newCollision && e0.collision) { - e0.collision.fire("collisionstart", forwardResult) - } - } - if(e1Events) { - var reverseResult = this._createContactResult(e0, reverseContacts); - if(e1.collision) { - e1.collision.fire("contact", reverseResult) - } - var newCollision = this._storeCollision(e1, e0); - if(newCollision && e1.collision) { - e1.collision.fire("collisionstart", reverseResult) - } - } - } - } - } - } - this._cleanOldCollisions(); - this.contactPointPool.freeAll(); - this.contactResultPool.freeAll(); - this.singleContactResultPool.freeAll() - }}); - return{RIGIDBODY_TYPE_STATIC:"static", RIGIDBODY_TYPE_DYNAMIC:"dynamic", RIGIDBODY_TYPE_KINEMATIC:"kinematic", RIGIDBODY_CF_STATIC_OBJECT:1, RIGIDBODY_CF_KINEMATIC_OBJECT:2, RIGIDBODY_CF_NORESPONSE_OBJECT:4, RIGIDBODY_ACTIVE_TAG:1, RIGIDBODY_ISLAND_SLEEPING:2, RIGIDBODY_WANTS_DEACTIVATION:3, RIGIDBODY_DISABLE_DEACTIVATION:4, RIGIDBODY_DISABLE_SIMULATION:5, RigidBodyComponentSystem:RigidBodyComponentSystem} -}()); -pc.extend(pc, function() { - var ammoTransform; - var ammoVec1, ammoVec2, ammoQuat, ammoOrigin; - var RigidBodyComponent = function RigidBodyComponent(system, entity) { - if(typeof Ammo !== "undefined" && !ammoTransform) { - ammoTransform = new Ammo.btTransform; - ammoVec1 = new Ammo.btVector3; - ammoVec2 = new Ammo.btVector3; - ammoQuat = new Ammo.btQuaternion; - ammoOrigin = new Ammo.btVector3(0, 0, 0) - } - this.on("set_mass", this.onSetMass, this); - this.on("set_linearDamping", this.onSetLinearDamping, this); - this.on("set_angularDamping", this.onSetAngularDamping, this); - this.on("set_linearFactor", this.onSetLinearFactor, this); - this.on("set_angularFactor", this.onSetAngularFactor, this); - this.on("set_friction", this.onSetFriction, this); - this.on("set_restitution", this.onSetRestitution, this); - this.on("set_type", this.onSetType, this); - this.on("set_group", this.onSetGroupOrMask, this); - this.on("set_mask", this.onSetGroupOrMask, this); - this.on("set_body", this.onSetBody, this); - this._displacement = new pc.Vec3(0, 0, 0); - this._linearVelocity = new pc.Vec3(0, 0, 0); - this._angularVelocity = new pc.Vec3(0, 0, 0) - }; - RigidBodyComponent = pc.inherits(RigidBodyComponent, pc.Component); - Object.defineProperty(RigidBodyComponent.prototype, "bodyType", {get:function() { - console.warn("WARNING: bodyType: Function is deprecated. Query type property instead."); - return this.type - }, set:function(type) { - console.warn("WARNING: bodyType: Function is deprecated. Set type property instead."); - this.type = type - }}); - Object.defineProperty(RigidBodyComponent.prototype, "linearVelocity", {get:function() { - if(!this.isKinematic()) { - if(this.body) { - var vel = this.body.getLinearVelocity(); - this._linearVelocity.set(vel.x(), vel.y(), vel.z()); - return this._linearVelocity - } - }else { - return this._linearVelocity - } - }, set:function(lv) { - this.activate(); - if(!this.isKinematic()) { - var body = this.body; - if(body) { - ammoVec1.setValue(lv.x, lv.y, lv.z); - body.setLinearVelocity(ammoVec1) - } - }else { - this._linearVelocity.copy(lv) - } - }}); - Object.defineProperty(RigidBodyComponent.prototype, "angularVelocity", {get:function() { - if(!this.isKinematic()) { - if(this.body) { - var vel = this.body.getAngularVelocity(); - this._angularVelocity.set(vel.x(), vel.y(), vel.z()); - return this._angularVelocity - } - }else { - return this._angularVelocity - } - }, set:function(av) { - this.activate(); - if(!this.isKinematic()) { - var body = this.body; - if(body) { - ammoVec1.setValue(av.x, av.y, av.z); - body.setAngularVelocity(ammoVec1) - } - }else { - this._angularVelocity.copy(av) - } - }}); - pc.extend(RigidBodyComponent.prototype, {createBody:function() { - var entity = this.entity; - var shape; - if(entity.collision) { - shape = entity.collision.shape; - if(entity.trigger) { - entity.trigger.destroy(); - delete entity.trigger - } - } - if(shape) { - if(this.body) { - this.system.removeBody(this.body); - Ammo.destroy(this.body) - } - var isStaticOrKinematic = this.isStaticOrKinematic(); - var mass = isStaticOrKinematic ? 0 : this.mass; - var localInertia = new Ammo.btVector3(0, 0, 0); - if(!isStaticOrKinematic) { - shape.calculateLocalInertia(mass, localInertia) - } - var pos = entity.getPosition(); - var rot = entity.getRotation(); - ammoQuat.setValue(rot.x, rot.y, rot.z, rot.w); - var startTransform = new Ammo.btTransform; - startTransform.setIdentity(); - startTransform.getOrigin().setValue(pos.x, pos.y, pos.z); - startTransform.setRotation(ammoQuat); - var motionState = new Ammo.btDefaultMotionState(startTransform); - var bodyInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, shape, localInertia); - var body = new Ammo.btRigidBody(bodyInfo); - body.setRestitution(this.restitution); - body.setFriction(this.friction); - body.setDamping(this.linearDamping, this.angularDamping); - var v; - v = this.linearFactor; - ammoVec1.setValue(v.x, v.y, v.z); - body.setLinearFactor(ammoVec1); - v = this.angularFactor; - ammoVec1.setValue(v.x, v.y, v.z); - body.setAngularFactor(ammoVec1); - body.entity = entity; - if(this.isKinematic()) { - body.setCollisionFlags(body.getCollisionFlags() | pc.BODYFLAG_KINEMATIC_OBJECT); - body.setActivationState(pc.BODYSTATE_DISABLE_DEACTIVATION) - } - entity.rigidbody.body = body; - if(this.enabled && this.entity.enabled) { - this.enableSimulation() - } - } - }, isActive:function() { - if(this.body) { - return this.body.isActive() - } - return false - }, activate:function() { - if(this.body) { - this.body.activate() - } - }, enableSimulation:function() { - if(this.entity.collision && this.entity.collision.enabled && !this.data.simulationEnabled) { - var body = this.body; - if(body) { - this.system.addBody(body, this.group, this.mask); - if(this.isKinematic()) { - body.forceActivationState(pc.BODYSTATE_DISABLE_DEACTIVATION); - body.activate() - }else { - body.forceActivationState(pc.BODYFLAG_ACTIVE_TAG); - this.syncEntityToBody() - } - this.data.simulationEnabled = true - } - } - }, disableSimulation:function() { - var body = this.body; - if(body && this.data.simulationEnabled) { - this.system.removeBody(body); - body.forceActivationState(pc.BODYSTATE_DISABLE_SIMULATION); - this.data.simulationEnabled = false - } - }, applyForce:function() { - var x, y, z; - var px, py, pz; - switch(arguments.length) { - case 1: - x = arguments[0].x; - y = arguments[0].y; - z = arguments[0].z; - break; - case 2: - x = arguments[0].x; - y = arguments[0].y; - z = arguments[0].z; - px = arguments[1].x; - py = arguments[1].y; - pz = arguments[1].z; - break; - case 3: - x = arguments[0]; - y = arguments[1]; - z = arguments[2]; - break; - case 6: - x = arguments[0]; - y = arguments[1]; - z = arguments[2]; - px = arguments[3]; - py = arguments[4]; - pz = arguments[5]; - break - } - var body = this.body; - if(body) { - body.activate(); - ammoVec1.setValue(x, y, z); - if(px !== undefined) { - ammoVec2.setValue(px, py, pz); - body.applyForce(ammoVec1, ammoVec2) - }else { - body.applyForce(ammoVec1, ammoOrigin) - } - } - }, applyTorque:function() { - var x, y, z; - switch(arguments.length) { - case 1: - x = arguments[0].x; - y = arguments[0].y; - z = arguments[0].z; - break; - case 3: - x = arguments[0]; - y = arguments[1]; - z = arguments[2]; - break; - default: - console.error("ERROR: applyTorque: function takes 1 or 3 arguments"); - return - } - var body = this.body; - if(body) { - body.activate(); - ammoVec1.setValue(x, y, z); - body.applyTorque(ammoVec1) - } - }, applyImpulse:function() { - var x, y, z; - var px, py, pz; - switch(arguments.length) { - case 1: - x = arguments[0].x; - y = arguments[0].y; - z = arguments[0].z; - break; - case 2: - x = arguments[0].x; - y = arguments[0].y; - z = arguments[0].z; - px = arguments[1].x; - py = arguments[1].y; - pz = arguments[1].z; - break; - case 3: - x = arguments[0]; - y = arguments[1]; - z = arguments[2]; - break; - case 6: - x = arguments[0]; - y = arguments[1]; - z = arguments[2]; - px = arguments[0]; - py = arguments[1]; - pz = arguments[2]; - break - } - var body = this.body; - if(body) { - body.activate(); - ammoVec1.setValue(x, y, z); - if(px !== undefined) { - ammoVec2.setValue(px, py, pz); - body.applyImpulse(ammoVec1, ammoVec2) - }else { - body.applyImpulse(ammoVec1, ammoOrigin) - } - } - }, applyTorqueImpulse:function() { - var x, y, z; - switch(arguments.length) { - case 1: - x = arguments[0].x; - y = arguments[0].y; - z = arguments[0].z; - break; - case 3: - x = arguments[0]; - y = arguments[1]; - z = arguments[2]; - break; - default: - console.error("ERROR: applyTorqueImpulse: function takes 1 or 3 arguments"); - return - } - var body = this.body; - if(body) { - body.activate(); - ammoVec1.setValue(x, y, z); - body.applyTorqueImpulse(ammoVec1) - } - }, isStatic:function() { - return this.type === pc.BODYTYPE_STATIC - }, isStaticOrKinematic:function() { - return this.type === pc.BODYTYPE_STATIC || this.type === pc.BODYTYPE_KINEMATIC - }, isKinematic:function() { - return this.type === pc.BODYTYPE_KINEMATIC - }, syncEntityToBody:function() { - var body = this.body; - if(body) { - var pos = this.entity.getPosition(); - var rot = this.entity.getRotation(); - var transform = body.getWorldTransform(); - transform.getOrigin().setValue(pos.x, pos.y, pos.z); - ammoQuat.setValue(rot.x, rot.y, rot.z, rot.w); - transform.setRotation(ammoQuat); - if(this.isKinematic()) { - var motionState = this.body.getMotionState(); - if(motionState) { - motionState.setWorldTransform(transform) - } - } - body.activate() - } - }, syncBodyToEntity:function() { - var body = this.body; - if(body.isActive()) { - var motionState = body.getMotionState(); - if(motionState) { - motionState.getWorldTransform(ammoTransform); - var p = ammoTransform.getOrigin(); - var q = ammoTransform.getRotation(); - this.entity.setPosition(p.x(), p.y(), p.z()); - this.entity.setRotation(q.x(), q.y(), q.z(), q.w()) - } - } - }, teleport:function() { - if(arguments.length < 3) { - if(arguments[0]) { - this.entity.setPosition(arguments[0]) - } - if(arguments[1]) { - if(arguments[1] instanceof pc.Quat) { - this.entity.setRotation(arguments[1]) - }else { - this.entity.setEulerAngles(arguments[1]) - } - } - }else { - if(arguments.length === 6) { - this.entity.setEulerAngles(arguments[3], arguments[4], arguments[5]) - } - this.entity.setPosition(arguments[0], arguments[1], arguments[2]) - } - this.syncEntityToBody() - }, _updateKinematic:function(dt) { - this._displacement.copy(this._linearVelocity).scale(dt); - this.entity.translate(this._displacement); - this._displacement.copy(this._angularVelocity).scale(dt); - this.entity.rotate(this._displacement.x, this._displacement.y, this._displacement.z); - if(this.body.getMotionState()) { - var pos = this.entity.getPosition(); - var rot = this.entity.getRotation(); - ammoTransform.getOrigin().setValue(pos.x, pos.y, pos.z); - ammoQuat.setValue(rot.x, rot.y, rot.z, rot.w); - ammoTransform.setRotation(ammoQuat); - this.body.getMotionState().setWorldTransform(ammoTransform) - } - }, onEnable:function() { - RigidBodyComponent._super.onEnable.call(this); - if(!this.body) { - this.createBody() - } - this.enableSimulation() - }, onDisable:function() { - RigidBodyComponent._super.onDisable.call(this); - this.disableSimulation() - }, onSetMass:function(name, oldValue, newValue) { - var body = this.data.body; - if(body) { - var isEnabled = this.enabled && this.entity.enabled; - if(isEnabled) { - this.disableSimulation() - } - var mass = newValue; - var localInertia = new Ammo.btVector3(0, 0, 0); - body.getCollisionShape().calculateLocalInertia(mass, localInertia); - body.setMassProps(mass, localInertia); - body.updateInertiaTensor(); - if(isEnabled) { - this.enableSimulation() - } - } - }, onSetLinearDamping:function(name, oldValue, newValue) { - var body = this.data.body; - if(body) { - body.setDamping(newValue, this.data.angularDamping) - } - }, onSetAngularDamping:function(name, oldValue, newValue) { - var body = this.data.body; - if(body) { - body.setDamping(this.data.linearDamping, newValue) - } - }, onSetLinearFactor:function(name, oldValue, newValue) { - var body = this.data.body; - if(body) { - ammoVec1.setValue(newValue.x, newValue.y, newValue.z); - body.setLinearFactor(ammoVec1) - } - }, onSetAngularFactor:function(name, oldValue, newValue) { - var body = this.data.body; - if(body) { - ammoVec1.setValue(newValue.x, newValue.y, newValue.z); - body.setAngularFactor(ammoVec1) - } - }, onSetFriction:function(name, oldValue, newValue) { - var body = this.data.body; - if(body) { - body.setFriction(newValue) - } - }, onSetRestitution:function(name, oldValue, newValue) { - var body = this.data.body; - if(body) { - body.setRestitution(newValue) - } - }, onSetType:function(name, oldValue, newValue) { - if(newValue !== oldValue) { - this.disableSimulation(); - if(newValue === pc.BODYTYPE_DYNAMIC) { - this.data.group = pc.BODYGROUP_DYNAMIC; - this.data.mask = pc.BODYMASK_ALL - }else { - if(newValue === pc.BODYTYPE_KINEMATIC) { - this.data.group = pc.BODYGROUP_KINEMATIC; - this.data.mask = pc.BODYMASK_ALL - }else { - this.data.group = pc.BODYGROUP_STATIC; - this.data.mask = pc.BODYMASK_NOT_STATIC - } - } - this.createBody() - } - }, onSetGroupOrMask:function(name, oldValue, newValue) { - if(newValue !== oldValue) { - var isEnabled = this.enabled && this.entity.enabled; - if(isEnabled) { - this.disableSimulation(); - this.enableSimulation() - } - } - }, onSetBody:function(name, oldValue, newValue) { - if(this.body && this.data.simulationEnabled) { - this.body.activate() - } - }}); - return{RigidBodyComponent:RigidBodyComponent} -}()); -pc.extend(pc, function() { - var RigidBodyComponentData = function() { - this.enabled = true; - this.mass = 1; - this.linearDamping = 0; - this.angularDamping = 0; - this.linearFactor = new pc.Vec3(1, 1, 1); - this.angularFactor = new pc.Vec3(1, 1, 1); - this.friction = 0.5; - this.restitution = 0; - this.type = pc.BODYTYPE_STATIC; - this.group = pc.BODYGROUP_STATIC; - this.mask = pc.BODYMASK_NOT_STATIC; - this.body = null; - this.simulationEnabled = false - }; - RigidBodyComponentData = pc.inherits(RigidBodyComponentData, pc.ComponentData); - return{RigidBodyComponentData:RigidBodyComponentData} -}()); -pc.extend(pc, function() { - var ammoVec1, ammoQuat; - var Trigger = function Trigger(app, component, data) { - this.entity = component.entity; - this.component = component; - this.app = app; - if(typeof Ammo !== "undefined") { - ammoVec1 = new Ammo.btVector3; - ammoQuat = new Ammo.btQuaternion - } - this.initialize(data) - }; - Trigger.prototype = {initialize:function(data) { - var entity = this.entity; - var shape = data.shape; - if(shape && typeof Ammo !== "undefined") { - if(entity.trigger) { - entity.trigger.destroy() - } - var mass = 1; - var localInertia = new Ammo.btVector3(0, 0, 0); - shape.calculateLocalInertia(mass, localInertia); - var pos = entity.getPosition(); - var rot = entity.getRotation(); - ammoQuat.setValue(rot.x, rot.y, rot.z, rot.w); - var startTransform = new Ammo.btTransform; - startTransform.setIdentity(); - startTransform.getOrigin().setValue(pos.x, pos.y, pos.z); - startTransform.setRotation(ammoQuat); - var motionState = new Ammo.btDefaultMotionState(startTransform); - var bodyInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, shape, localInertia); - var body = new Ammo.btRigidBody(bodyInfo); - this.body = body; - body.setRestitution(0); - body.setFriction(0); - body.setDamping(0, 0); - ammoVec1.setValue(0, 0, 0); - body.setLinearFactor(ammoVec1); - body.setAngularFactor(ammoVec1); - body.setCollisionFlags(body.getCollisionFlags() | pc.BODYFLAG_NORESPONSE_OBJECT); - body.entity = entity; - if(this.component.enabled && entity.enabled) { - this.enable() - } - } - }, destroy:function() { - if(this.body) { - this.app.systems.rigidbody.removeBody(this.body) - } - }, syncEntityToBody:function() { - var body = this.body; - if(body) { - var position = this.entity.getPosition(); - var rotation = this.entity.getRotation(); - var transform = body.getWorldTransform(); - transform.getOrigin().setValue(position.x, position.y, position.z); - ammoQuat.setValue(rotation.x, rotation.y, rotation.z, rotation.w); - transform.setRotation(ammoQuat); - body.activate() - } - }, enable:function() { - var body = this.body; - this.app.systems.rigidbody.addBody(body, pc.BODYGROUP_TRIGGER, pc.BODYMASK_NOT_STATIC ^ pc.BODYGROUP_TRIGGER); - body.forceActivationState(pc.BODYSTATE_ACTIVE_TAG); - body.activate() - }, disable:function() { - var body = this.body; - this.app.systems.rigidbody.removeBody(body); - body.forceActivationState(pc.BODYSTATE_DISABLE_SIMULATION) - }}; - return{Trigger:Trigger} -}()); -pc.extend(pc, function() { - var CollisionComponentSystem = function CollisionComponentSystem(app) { - this.id = "collision"; - this.description = "Specifies a collision volume."; - app.systems.add(this.id, this); - this.ComponentType = pc.CollisionComponent; - this.DataType = pc.CollisionComponentData; - this.schema = ["enabled", "type", "halfExtents", "radius", "axis", "height", "asset", "shape", "model"]; - this.implementations = {}; - this.debugRender = false; - this.on("remove", this.onRemove, this); - pc.ComponentSystem.on("update", this.onUpdate, this); - pc.ComponentSystem.on("toolsUpdate", this.onToolsUpdate, this) - }; - CollisionComponentSystem = pc.inherits(CollisionComponentSystem, pc.ComponentSystem); - CollisionComponentSystem.prototype = pc.extend(CollisionComponentSystem.prototype, {onLibraryLoaded:function() { - if(typeof Ammo !== "undefined") { - }else { - pc.ComponentSystem.off("update", this.onUpdate, this) - } - }, initializeComponentData:function(component, _data, properties) { - var data = {}; - properties = ["type", "halfExtents", "radius", "axis", "height", "shape", "model", "asset", "enabled"]; - properties.forEach(function(prop) { - data[prop] = _data[prop] - }); - if(!data.type) { - data.type = component.data.type - } - component.data.type = data.type; - if(data.halfExtents && pc.type(data.halfExtents) === "array") { - data.halfExtents = new pc.Vec3(data.halfExtents[0], data.halfExtents[1], data.halfExtents[2]) - } - var impl = this._createImplementation(data.type); - impl.beforeInitialize(component, data); - CollisionComponentSystem._super.initializeComponentData.call(this.system, component, data, properties); - impl.afterInitialize(component, data) - }, _createImplementation:function(type) { - if(this.implementations[type] === undefined) { - var impl; - switch(type) { - case "box": - impl = new CollisionBoxSystemImpl(this); - break; - case "sphere": - impl = new CollisionSphereSystemImpl(this); - break; - case "capsule": - impl = new CollisionCapsuleSystemImpl(this); - break; - case "cylinder": - impl = new CollisionCylinderSystemImpl(this); - break; - case "mesh": - impl = new CollisionMeshSystemImpl(this); - break; - default: - throw"Invalid collision system type: " + type;break - } - this.implementations[type] = impl - } - return this.implementations[type] - }, _getImplementation:function(entity) { - return this.implementations[entity.collision.data.type] - }, cloneComponent:function(entity, clone) { - return this._getImplementation(entity).clone(entity, clone) - }, onRemove:function(entity, data) { - this.implementations[data.type].remove(entity, data) - }, onUpdate:function(dt) { - var id, entity, data; - var components = this.store; - for(id in components) { - entity = components[id].entity; - data = components[id].data; - if(data.enabled && entity.enabled) { - if(!entity.rigidbody && entity.trigger) { - entity.trigger.syncEntityToBody() - } - } - if(this.debugRender) { - this.updateDebugShape(entity, data, this._getImplementation(entity)) - } - } - }, updateDebugShape:function(entity, data, impl) { - var app = this.app; - if(impl !== undefined) { - if(impl.hasDebugShape) { - if(data.model) { - if(!app.scene.containsModel(data.model)) { - if(entity.enabled && data.enabled) { - app.scene.addModel(data.model); - app.root.addChild(data.model.graph) - } - }else { - if(!data.enabled || !entity.enabled) { - app.root.removeChild(data.model.graph); - app.scene.removeModel(data.model) - } - } - } - if(data.enabled && entity.enabled) { - impl.updateDebugShape(entity, data) - } - } - } - }, onTransformChanged:function(component, position, rotation, scale) { - this.implementations[component.data.type].updateTransform(component, position, rotation, scale) - }, onToolsUpdate:function(dt) { - var id, entity; - var components = this.store; - for(id in components) { - entity = components[id].entity; - this.updateDebugShape(entity, components[id].data, this._getImplementation(entity)) - } - }, setDebugRender:function(value) { - this.debugRender = value - }, changeType:function(component, previousType, newType) { - this.implementations[previousType].remove(component.entity, component.data); - this._createImplementation(newType).reset(component, component.data) - }, recreatePhysicalShapes:function(component) { - this.implementations[component.data.type].recreatePhysicalShapes(component) - }}); - CollisionSystemImpl = function(system) { - this.system = system; - this.hasDebugShape = true - }; - CollisionSystemImpl.prototype = {beforeInitialize:function(component, data) { - data.shape = this.createPhysicalShape(component.entity, data); - data.model = new pc.Model; - data.model.graph = new pc.GraphNode; - data.model.meshInstances = [this.createDebugMesh(data)] - }, afterInitialize:function(component, data) { - this.recreatePhysicalShapes(component); - component.data.initialized = true - }, reset:function(component, data) { - this.beforeInitialize(component, data); - this.afterInitialize(component, data) - }, recreatePhysicalShapes:function(component) { - var entity = component.entity; - var data = component.data; - if(typeof Ammo !== "undefined") { - data.shape = this.createPhysicalShape(component.entity, data); - if(entity.rigidbody) { - entity.rigidbody.disableSimulation(); - entity.rigidbody.createBody() - }else { - if(!entity.trigger) { - entity.trigger = new pc.Trigger(this.system.app, component, data) - }else { - entity.trigger.initialize(data) - } - } - } - }, createDebugMesh:function(data) { - return undefined - }, createPhysicalShape:function(entity, data) { - return undefined - }, updateDebugShape:function(entity, data) { - }, updateTransform:function(component, position, rotation, scale) { - if(component.entity.trigger) { - component.entity.trigger.syncEntityToBody() - } - }, remove:function(entity, data) { - var app = this.system.app; - if(entity.rigidbody && entity.rigidbody.body) { - app.systems.rigidbody.removeBody(entity.rigidbody.body) - } - if(entity.trigger) { - entity.trigger.destroy(); - delete entity.trigger - } - if(app.scene.containsModel(data.model)) { - app.root.removeChild(data.model.graph); - app.scene.removeModel(data.model) - } - }, clone:function(entity, clone) { - var src = this.system.dataStore[entity.getGuid()]; - var data = {enabled:src.data.enabled, type:src.data.type, halfExtents:[src.data.halfExtents.x, src.data.halfExtents.y, src.data.halfExtents.z], radius:src.data.radius, axis:src.data.axis, height:src.data.height, asset:src.data.asset, model:src.data.model}; - return this.system.addComponent(clone, data) - }}; - CollisionBoxSystemImpl = function(system) { - }; - CollisionBoxSystemImpl = pc.inherits(CollisionBoxSystemImpl, CollisionSystemImpl); - CollisionBoxSystemImpl.prototype = pc.extend(CollisionBoxSystemImpl.prototype, {createDebugMesh:function(data) { - if(!this.mesh) { - var gd = this.system.app.graphicsDevice; - var format = new pc.VertexFormat(gd, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(gd, format, 8); - var positions = new Float32Array(vertexBuffer.lock()); - positions.set([-0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5]); - vertexBuffer.unlock(); - var indexBuffer = new pc.IndexBuffer(gd, pc.INDEXFORMAT_UINT8, 24); - var indices = new Uint8Array(indexBuffer.lock()); - indices.set([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]); - indexBuffer.unlock(); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.indexBuffer[0] = indexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = indexBuffer.getNumIndices(); - mesh.primitive[0].indexed = true; - this.mesh = mesh - } - if(!this.material) { - var material = new pc.BasicMaterial; - material.color = new pc.Color(0, 0, 1, 1); - material.update(); - this.material = material - } - return new pc.MeshInstance(data.model.graph, this.mesh, this.material) - }, createPhysicalShape:function(entity, data) { - if(typeof Ammo !== "undefined") { - var he = data.halfExtents; - var ammoHe = new Ammo.btVector3(he.x, he.y, he.z); - return new Ammo.btBoxShape(ammoHe) - }else { - return undefined - } - }, updateDebugShape:function(entity, data) { - var he = data.halfExtents; - var x = he.x; - var y = he.y; - var z = he.z; - var root = data.model.graph; - root.setPosition(entity.getPosition()); - root.setRotation(entity.getRotation()); - root.setLocalScale(x * 2, y * 2, z * 2) - }}); - CollisionSphereSystemImpl = function(system) { - }; - CollisionSphereSystemImpl = pc.inherits(CollisionSphereSystemImpl, CollisionSystemImpl); - CollisionSphereSystemImpl.prototype = pc.extend(CollisionSphereSystemImpl.prototype, {createDebugMesh:function(data) { - if(!this.mesh) { - var app = this.system.app; - var gd = app.graphicsDevice; - var format = new pc.VertexFormat(gd, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(gd, format, 240); - var positions = new Float32Array(vertexBuffer.lock()); - var i, x = 0; - var theta; - for(var ring = 0;ring < 3;ring++) { - var xo = 0; - var yo = 1; - var zo = 2; - if(ring === 1) { - xo = 1; - yo = 0; - zo = 2 - }else { - if(ring === 2) { - xo = 0; - yo = 2; - zo = 1 - } - } - for(i = 0;i < 40;i++) { - theta = 2 * Math.PI * (i / 40); - positions[x + xo] = 0.5 * Math.cos(theta); - positions[x + yo] = 0; - positions[x + zo] = 0.5 * Math.sin(theta); - x += 3; - theta = 2 * Math.PI * ((i + 1) / 40); - positions[x + xo] = 0.5 * Math.cos(theta); - positions[x + yo] = 0; - positions[x + zo] = 0.5 * Math.sin(theta); - x += 3 - } - } - vertexBuffer.unlock(); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = vertexBuffer.getNumVertices(); - mesh.primitive[0].indexed = false; - this.mesh = mesh - } - if(!this.material) { - var material = new pc.BasicMaterial; - material.color = new pc.Color(0, 0, 1, 1); - material.update(); - this.material = material - } - return new pc.MeshInstance(data.model.graph, this.mesh, this.material) - }, createPhysicalShape:function(entity, data) { - if(typeof Ammo !== "undefined") { - return new Ammo.btSphereShape(data.radius) - }else { - return undefined - } - }, updateDebugShape:function(entity, data) { - var root = data.model.graph; - root.setPosition(entity.getPosition()); - root.setRotation(entity.getRotation()); - var s = data.radius * 2; - root.setLocalScale(s, s, s) - }}); - CollisionCapsuleSystemImpl = function(system) { - }; - CollisionCapsuleSystemImpl = pc.inherits(CollisionCapsuleSystemImpl, CollisionSystemImpl); - CollisionCapsuleSystemImpl.prototype = pc.extend(CollisionCapsuleSystemImpl.prototype, {createDebugMesh:function(data) { - if(data.model && data.model.meshInstances && data.model.meshInstances.length) { - return data.model.meshInstances[0] - }else { - var gd = this.system.app.graphicsDevice; - var format = new pc.VertexFormat(gd, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(gd, format, 328, pc.BUFFER_DYNAMIC); - this.updateCapsuleShape(data, vertexBuffer); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = vertexBuffer.getNumVertices(); - mesh.primitive[0].indexed = false; - this.mesh = mesh - } - if(!this.material) { - var material = new pc.BasicMaterial; - material.color = new pc.Color(0, 0, 1, 1); - material.update(); - this.material = material - } - return new pc.MeshInstance(data.model.graph, mesh, this.material) - }, updateCapsuleShape:function(data, vertexBuffer) { - var axis = data.axis !== undefined ? data.axis : 1; - var radius = data.radius || 0.5; - var height = Math.max((data.height || 2) - 2 * radius, 0); - var positions = new Float32Array(vertexBuffer.lock()); - var xo = 0; - var yo = 1; - var zo = 2; - if(axis === 0) { - xo = 1; - yo = 0; - zo = 2 - }else { - if(axis === 2) { - xo = 0; - yo = 2; - zo = 1 - } - } - var i, x = 0; - var theta; - for(cap = -1;cap < 2;cap += 2) { - for(i = 0;i < 40;i++) { - theta = 2 * Math.PI * (i / 40); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = cap * height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3; - theta = 2 * Math.PI * ((i + 1) / 40); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = cap * height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3 - } - for(i = 0;i < 20;i++) { - theta = Math.PI * (i / 20) + Math.PI * 1.5; - positions[x + xo] = 0; - positions[x + yo] = cap * (height * 0.5 + radius * Math.cos(theta)); - positions[x + zo] = cap * radius * Math.sin(theta); - x += 3; - theta = Math.PI * ((i + 1) / 20) + Math.PI * 1.5; - positions[x + xo] = 0; - positions[x + yo] = cap * (height * 0.5 + radius * Math.cos(theta)); - positions[x + zo] = cap * radius * Math.sin(theta); - x += 3 - } - for(i = 0;i < 20;i++) { - theta = Math.PI * (i / 20) + Math.PI * 1.5; - positions[x + xo] = cap * radius * Math.sin(theta); - positions[x + yo] = cap * (height * 0.5 + radius * Math.cos(theta)); - positions[x + zo] = 0; - x += 3; - theta = Math.PI * ((i + 1) / 20) + Math.PI * 1.5; - positions[x + xo] = cap * radius * Math.sin(theta); - positions[x + yo] = cap * (height * 0.5 + radius * Math.cos(theta)); - positions[x + zo] = 0; - x += 3 - } - } - for(i = 0;i < 4;i++) { - theta = 2 * Math.PI * (i / 4); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3; - theta = 2 * Math.PI * (i / 4); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = -height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3 - } - vertexBuffer.unlock() - }, createPhysicalShape:function(entity, data) { - var shape = null; - var axis = data.axis !== undefined ? data.axis : 1; - var radius = data.radius || 0.5; - var height = Math.max((data.height || 2) - 2 * radius, 0); - if(typeof Ammo !== "undefined") { - switch(axis) { - case 0: - shape = new Ammo.btCapsuleShapeX(radius, height); - break; - case 1: - shape = new Ammo.btCapsuleShape(radius, height); - break; - case 2: - shape = new Ammo.btCapsuleShapeZ(radius, height); - break - } - } - return shape - }, updateDebugShape:function(entity, data) { - var root = data.model.graph; - root.setPosition(entity.getPosition()); - root.setRotation(entity.getRotation()); - root.setLocalScale(1, 1, 1) - }, recreatePhysicalShapes:function(component) { - var model = component.data.model; - if(model) { - var vertexBuffer = this.createDebugMesh(component.data).mesh.vertexBuffer; - this.updateCapsuleShape(component.data, vertexBuffer); - CollisionCapsuleSystemImpl._super.recreatePhysicalShapes.call(this, component) - } - }}); - CollisionCylinderSystemImpl = function(system) { - }; - CollisionCylinderSystemImpl = pc.inherits(CollisionCylinderSystemImpl, CollisionSystemImpl); - CollisionCylinderSystemImpl.prototype = pc.extend(CollisionCylinderSystemImpl.prototype, {createDebugMesh:function(data) { - if(data.model && data.model.meshInstances && data.model.meshInstances.length) { - return data.model.meshInstances[0] - }else { - var gd = this.system.app.graphicsDevice; - var format = new pc.VertexFormat(gd, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(gd, format, 168, pc.BUFFER_DYNAMIC); - this.updateCylinderShape(data, vertexBuffer); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = vertexBuffer.getNumVertices(); - mesh.primitive[0].indexed = false; - if(!this.material) { - var material = new pc.BasicMaterial; - material.color = new pc.Color(0, 0, 1, 1); - material.update(); - this.material = material - } - return new pc.MeshInstance(data.model.graph, mesh, this.material) - } - }, updateCylinderShape:function(data, vertexBuffer) { - var axis = data.axis !== undefined ? data.axis : 1; - var radius = data.radius !== undefined ? data.radius : 0.5; - var height = data.height !== undefined ? data.height : 1; - var positions = new Float32Array(vertexBuffer.lock()); - var xo = 0; - var yo = 1; - var zo = 2; - if(axis === 0) { - xo = 1; - yo = 0; - zo = 2 - }else { - if(axis === 2) { - xo = 0; - yo = 2; - zo = 1 - } - } - var i, x = 0; - var theta; - for(cap = -1;cap < 2;cap += 2) { - for(i = 0;i < 40;i++) { - theta = 2 * Math.PI * (i / 40); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = cap * height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3; - theta = 2 * Math.PI * ((i + 1) / 40); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = cap * height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3 - } - } - for(i = 0;i < 4;i++) { - theta = 2 * Math.PI * (i / 4); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3; - theta = 2 * Math.PI * (i / 4); - positions[x + xo] = radius * Math.cos(theta); - positions[x + yo] = -height * 0.5; - positions[x + zo] = radius * Math.sin(theta); - x += 3 - } - vertexBuffer.unlock() - }, createPhysicalShape:function(entity, data) { - var halfExtents = null; - var shape = null; - var axis = data.axis !== undefined ? data.axis : 1; - var radius = data.radius !== undefined ? data.radius : 0.5; - var height = data.height !== undefined ? data.height : 1; - if(typeof Ammo !== "undefined") { - switch(axis) { - case 0: - halfExtents = new Ammo.btVector3(height * 0.5, radius, radius); - shape = new Ammo.btCylinderShapeX(halfExtents); - break; - case 1: - halfExtents = new Ammo.btVector3(radius, height * 0.5, radius); - shape = new Ammo.btCylinderShape(halfExtents); - break; - case 2: - halfExtents = new Ammo.btVector3(radius, radius, height * 0.5); - shape = new Ammo.btCylinderShapeZ(halfExtents); - break - } - } - return shape - }, updateDebugShape:function(entity, data) { - var root = data.model.graph; - root.setPosition(entity.getPosition()); - root.setRotation(entity.getRotation()); - root.setLocalScale(1, 1, 1) - }, recreatePhysicalShapes:function(component) { - var model = component.data.model; - if(model) { - var vertexBuffer = this.createDebugMesh(component.data).mesh.vertexBuffer; - this.updateCylinderShape(component.data, vertexBuffer); - CollisionCylinderSystemImpl._super.recreatePhysicalShapes.call(this, component) - } - }}); - CollisionMeshSystemImpl = function(system) { - this.hasDebugShape = false - }; - CollisionMeshSystemImpl = pc.inherits(CollisionMeshSystemImpl, CollisionSystemImpl); - CollisionMeshSystemImpl.prototype = pc.extend(CollisionMeshSystemImpl.prototype, {beforeInitialize:function(component, data) { - }, createPhysicalShape:function(entity, data) { - if(typeof Ammo !== "undefined" && data.model) { - var model = data.model; - var shape = new Ammo.btCompoundShape; - var i, j; - for(i = 0;i < model.meshInstances.length;i++) { - var meshInstance = model.meshInstances[i]; - var mesh = meshInstance.mesh; - var ib = mesh.indexBuffer[pc.RENDERSTYLE_SOLID]; - var vb = mesh.vertexBuffer; - var format = vb.getFormat(); - var stride = format.size / 4; - var positions; - for(j = 0;j < format.elements.length;j++) { - var element = format.elements[j]; - if(element.name === pc.SEMANTIC_POSITION) { - positions = new Float32Array(vb.lock(), element.offset) - } - } - var indices = new Uint16Array(ib.lock()); - var numTriangles = mesh.primitive[0].count / 3; - var v1 = new Ammo.btVector3; - var v2 = new Ammo.btVector3; - var v3 = new Ammo.btVector3; - var i1, i2, i3; - var base = mesh.primitive[0].base; - var triMesh = new Ammo.btTriangleMesh; - for(j = 0;j < numTriangles;j++) { - i1 = indices[base + j * 3] * stride; - i2 = indices[base + j * 3 + 1] * stride; - i3 = indices[base + j * 3 + 2] * stride; - v1.setValue(positions[i1], positions[i1 + 1], positions[i1 + 2]); - v2.setValue(positions[i2], positions[i2 + 1], positions[i2 + 2]); - v3.setValue(positions[i3], positions[i3 + 1], positions[i3 + 2]); - triMesh.addTriangle(v1, v2, v3, true) - } - var useQuantizedAabbCompression = true; - var triMeshShape = new Ammo.btBvhTriangleMeshShape(triMesh, useQuantizedAabbCompression); - var wtm = meshInstance.node.getWorldTransform(); - var scl = wtm.getScale(); - triMeshShape.setLocalScaling(new Ammo.btVector3(scl.x, scl.y, scl.z)); - var pos = meshInstance.node.getPosition(); - var rot = meshInstance.node.getRotation(); - var transform = new Ammo.btTransform; - transform.setIdentity(); - transform.getOrigin().setValue(pos.x, pos.y, pos.z); - var ammoQuat = new Ammo.btQuaternion; - ammoQuat.setValue(rot.x, rot.y, rot.z, rot.w); - transform.setRotation(ammoQuat); - shape.addChildShape(transform, triMeshShape) - } - var entityTransform = entity.getWorldTransform(); - var scale = entityTransform.getScale(); - var vec = new Ammo.btVector3; - vec.setValue(scale.x, scale.y, scale.z); - shape.setLocalScaling(vec); - return shape - }else { - return undefined - } - }, recreatePhysicalShapes:function(component) { - var data = component.data; - if(data.asset !== null) { - this.loadModelAsset(component) - }else { - data.model = null; - this.doRecreatePhysicalShape(component) - } - }, loadModelAsset:function(component) { - var self = this; - var id = component.data.asset; - var data = component.data; - var assets = this.system.app.assets; - var asset = assets.get(id); - if(asset) { - asset.ready(function(asset) { - data.model = asset.resource; - self.doRecreatePhysicalShape(component) - }); - assets.load(asset) - }else { - asset.once("add:" + id, function(asset) { - asset.ready(function(asset) { - data.model = asset.resource; - self.doRecreatePhysicalShape(component) - }); - assets.load(asset) - }) - } - }, doRecreatePhysicalShape:function(component) { - var entity = component.entity; - var data = component.data; - if(data.model) { - if(data.shape) { - Ammo.destroy(data.shape) - } - data.shape = this.createPhysicalShape(entity, data); - if(entity.rigidbody) { - entity.rigidbody.createBody() - }else { - if(!entity.trigger) { - entity.trigger = new pc.Trigger(this.system.app, component, data) - }else { - entity.trigger.initialize(data) - } - } - }else { - this.remove(entity, data) - } - }, updateTransform:function(component, position, rotation, scale) { - if(component.shape) { - var entityTransform = component.entity.getWorldTransform(); - var worldScale = entityTransform.getScale(); - var previousScale = component.shape.getLocalScaling(); - if(worldScale.x !== previousScale.x() || worldScale.y !== previousScale.y() || worldScale.z !== previousScale.z()) { - this.doRecreatePhysicalShape(component) - } - } - CollisionMeshSystemImpl._super.updateTransform.call(this, component, position, rotation, scale) - }}); - return{CollisionComponentSystem:CollisionComponentSystem} -}()); -pc.extend(pc, function() { - var CollisionComponent = function CollisionComponent(system, entity) { - this.on("set_type", this.onSetType, this); - this.on("set_halfExtents", this.onSetHalfExtents, this); - this.on("set_radius", this.onSetRadius, this); - this.on("set_height", this.onSetHeight, this); - this.on("set_axis", this.onSetAxis, this); - this.on("set_asset", this.onSetAsset, this) - }; - CollisionComponent = pc.inherits(CollisionComponent, pc.Component); - pc.extend(CollisionComponent.prototype, {onSetType:function(name, oldValue, newValue) { - if(oldValue !== newValue) { - this.system.changeType(this, oldValue, newValue) - } - }, onSetHalfExtents:function(name, oldValue, newValue) { - if(this.data.initialized && this.data.type === "box") { - this.system.recreatePhysicalShapes(this) - } - }, onSetRadius:function(name, oldValue, newValue) { - if(this.data.initialized && (this.data.type === "sphere" || this.data.type === "capsule" || this.data.type === "cylinder")) { - this.system.recreatePhysicalShapes(this) - } - }, onSetHeight:function(name, oldValue, newValue) { - if(this.data.initialized && (this.data.type === "capsule" || this.data.type === "cylinder")) { - this.system.recreatePhysicalShapes(this) - } - }, onSetAxis:function(name, oldValue, newValue) { - if(this.data.initialized && (this.data.type === "capsule" || this.data.type === "cylinder")) { - this.system.recreatePhysicalShapes(this) - } - }, onSetAsset:function(name, oldValue, newValue) { - var self = this; - var asset; - var assets = this.system.app.assets; - if(oldValue) { - asset = assets.get(oldValue); - if(asset) { - asset.off("remove", this.onAssetRemoved, this) - } - } - if(newValue) { - if(newValue instanceof pc.Asset) { - this.data.asset = newValue.id - } - asset = assets.get(this.data.asset); - if(asset) { - asset.off("remove", this.onAssetRemoved, this); - asset.on("remove", this.onAssetRemoved, this) - } - } - if(this.data.initialized && this.data.type === "mesh") { - this.system.recreatePhysicalShapes(this) - } - }, onAssetRemoved:function(asset) { - asset.off("remove", this.onAssetRemoved, this); - if(this.data.asset === asset.id) { - this.asset = null - } - }, onEnable:function() { - CollisionComponent._super.onEnable.call(this); - if(this.entity.trigger) { - this.entity.trigger.enable() - }else { - if(this.entity.rigidbody) { - if(this.entity.rigidbody.enabled) { - this.entity.rigidbody.enableSimulation() - } - } - } - }, onDisable:function() { - CollisionComponent._super.onDisable.call(this); - if(this.entity.trigger) { - this.entity.trigger.disable() - }else { - if(this.entity.rigidbody) { - this.entity.rigidbody.disableSimulation() - } - } - }}); - return{CollisionComponent:CollisionComponent} -}()); -pc.extend(pc, function() { - var CollisionComponentData = function() { - this.enabled = true; - this.type = "box"; - this.halfExtents = new pc.Vec3(0.5, 0.5, 0.5); - this.radius = 0.5; - this.axis = 1; - this.height = 2; - this.asset = null; - this.shape = null; - this.model = null; - this.initialized = false - }; - CollisionComponentData = pc.inherits(CollisionComponentData, pc.ComponentData); - return{CollisionComponentData:CollisionComponentData} -}()); -pc.extend(pc, function() { - var BallSocketJointComponentSystem = function BallSocketJointComponentSystem(app) { - this.id = "ballsocketjoint"; - app.systems.add(this.id, this); - this.ComponentType = pc.BallSocketJointComponent; - this.DataType = pc.BallSocketJointComponentData; - this.schema = [{name:"pivot", displayName:"Pivot", description:"Local space pivot", type:"vector", options:{min:0, step:0.1}, defaultValue:[0, 0, 0]}, {name:"position", displayName:"Position", description:"World space joint position", type:"vector", options:{min:0, step:0.1}, defaultValue:[0, 0, 0]}, {name:"tau", displayName:"Tau", description:"TBD", type:"number", defaultValue:0.001, options:{min:0, max:1}}, {name:"damping", displayName:"Damping", description:"Damping", type:"number", defaultValue:1, - options:{min:0, max:1}}, {name:"impulseClamp", displayName:"Impulse Clamp", description:"Impulse Clamp", type:"number", defaultValue:0, options:{min:0, max:100}}, {name:"constraint", exposed:false}]; - this.debugRender = false; - this.on("remove", this.onRemove, this); - pc.ComponentSystem.on("update", this.onUpdate, this); - pc.ComponentSystem.on("toolsUpdate", this.onToolsUpdate, this) - }; - BallSocketJointComponentSystem = pc.inherits(BallSocketJointComponentSystem, pc.ComponentSystem); - BallSocketJointComponentSystem.prototype = pc.extend(BallSocketJointComponentSystem.prototype, {onLibraryLoaded:function() { - if(typeof Ammo !== "undefined") { - }else { - pc.ComponentSystem.off("update", this.onUpdate, this) - } - }, initializeComponentData:function(component, _data, properties) { - if(typeof Ammo !== "undefined") { - var data = pc.extend({}, _data); - if(component.entity.rigidbody) { - if(data.pivot && pc.type(data.pivot) === "array") { - data.pivot = new pc.Vec3(data.pivot[0], data.pivot[1], data.pivot[2]) - } - if(data.position && pc.type(data.position) === "array") { - data.position = new pc.Vec3(data.position[0], data.position[1], data.position[2]) - } - var pivotA = new Ammo.btVector3(data.pivot.x, data.pivot.y, data.pivot.z); - var body = component.entity.rigidbody.body; - data.constraint = new Ammo.btPoint2PointConstraint(body, pivotA); - var pivotB = data.constraint.getPivotInB(); - data.position = [pivotB.x(), pivotB.y(), pivotB.z()]; - var app = this.app; - app.systems.rigidbody.addConstraint(data.constraint) - } - } - properties = ["constraint", "pivot", "position", "tau", "damping", "impulseClamp"]; - BallSocketJointComponentSystem._super.initializeComponentData.call(this, component, data, properties) - }, cloneComponent:function(entity, clone) { - var data = {pivot:[entity.ballsocketjoint.pivot.x, entity.ballsocketjoint.pivot.y, entity.ballsocketjoint.pivot.z], position:[entity.ballsocketjoint.position.x, entity.ballsocketjoint.position.y, entity.ballsocketjoint.position.z], tau:entity.ballsocketjoint.tau, damping:entity.ballsocketjoint.damping, impulseClamp:entity.ballsocketjoint.impulseClamp}; - return this.addComponent(clone, data) - }, onRemove:function(entity, data) { - if(data.constraint) { - this.app.systems.rigidbody.removeConstraint(data.constraint) - } - }, setDebugRender:function(value) { - this.debugRender = value - }, onUpdate:function(dt) { - if(this.debugRender) { - this.updateDebugShapes() - } - }, onToolsUpdate:function(dt) { - this.updateDebugShapes() - }, updateDebugShapes:function() { - var components = this.store; - for(var id in components) { - var entity = components[id].entity; - var data = components[id].data - } - }}); - return{BallSocketJointComponentSystem:BallSocketJointComponentSystem} -}()); -pc.extend(pc, function() { - var BallSocketJointComponent = function BallSocketJointComponent(system, entity) { - this.on("set_pivot", this.onSetPivot, this); - this.on("set_position", this.onSetPosition, this); - this.on("set_tau", this.onSetTau, this); - this.on("set_damping", this.onSetDamping, this); - this.on("set_impulseClamp", this.onSetImpulseClamp, this) - }; - BallSocketJointComponent = pc.inherits(BallSocketJointComponent, pc.Component); - pc.extend(BallSocketJointComponent.prototype, {onSetPivot:function(name, oldValue, newValue) { - if(typeof Ammo !== "undefined") { - if(this.data.constraint) { - var pivotA = new Ammo.btVector3(newValue.x, newValue.y, newValue.z); - this.data.constraint.setPivotA(pivotA) - } - } - }, onSetPosition:function(name, oldValue, newValue) { - if(typeof Ammo !== "undefined") { - if(this.data.constraint) { - var pivotB = new Ammo.btVector3(newValue.x, newValue.y, newValue.z); - this.data.constraint.setPivotB(pivotB) - } - } - }, onSetTau:function(name, oldValue, newValue) { - if(typeof Ammo !== "undefined") { - if(this.data.constraint) { - this.data.constraint.get_m_setting().set_m_tau(newValue) - } - } - }, onSetDamping:function(name, oldValue, newValue) { - if(typeof Ammo !== "undefined") { - if(this.data.constraint) { - this.data.constraint.get_m_setting().set_m_damping(newValue) - } - } - }, onSetImpulseClamp:function(name, oldValue, newValue) { - if(typeof Ammo !== "undefined") { - if(this.data.constraint) { - this.data.constraint.get_m_setting().set_m_impulseClamp(newValue) - } - } - }}); - return{BallSocketJointComponent:BallSocketJointComponent} -}()); -pc.extend(pc, function() { - var BallSocketJointComponentData = function() { - this.pivot = new pc.Vec3(0, 0, 0); - this.position = new pc.Vec3(0, 0, 0); - this.tau = 0.3; - this.damping = 1; - this.impulseClamp = 0; - this.constraint = null - }; - BallSocketJointComponentData = pc.inherits(BallSocketJointComponentData, pc.ComponentData); - return{BallSocketJointComponentData:BallSocketJointComponentData} -}()); -pc.extend(pc, function() { - var ParticleSystemComponentSystem = function ParticleSystemComponentSystem(app) { - this.id = "particlesystem"; - this.description = "Updates and renders particle system in the scene."; - app.systems.add(this.id, this); - this.ComponentType = pc.ParticleSystemComponent; - this.DataType = pc.ParticleSystemComponentData; - this.schema = ["enabled", "autoPlay", "numParticles", "lifetime", "rate", "rate2", "startAngle", "startAngle2", "loop", "preWarm", "lighting", "halfLambert", "intensity", "depthWrite", "depthSoftening", "sort", "blendType", "stretch", "alignToMotion", "emitterShape", "emitterExtents", "emitterRadius", "initialVelocity", "wrap", "wrapBounds", "colorMapAsset", "normalMapAsset", "mesh", "localVelocityGraph", "localVelocityGraph2", "velocityGraph", "velocityGraph2", "rotationSpeedGraph", "rotationSpeedGraph2", - "scaleGraph", "scaleGraph2", "colorGraph", "colorGraph2", "alphaGraph", "alphaGraph2", "colorMap", "normalMap"]; - this.propertyTypes = {emitterExtents:"vector", wrapBounds:"vector", localVelocityGraph:"curveset", localVelocityGraph2:"curveset", velocityGraph:"curveset", velocityGraph2:"curveset", colorGraph:"curveset", colorGraph2:"curveset", alphaGraph:"curve", alphaGraph2:"curve", rotationSpeedGraph:"curve", rotationSpeedGraph2:"curve", scaleGraph:"curve", scaleGraph2:"curve"}; - this.on("remove", this.onRemove, this); - pc.ComponentSystem.on("update", this.onUpdate, this); - pc.ComponentSystem.on("toolsUpdate", this.onToolsUpdate, this); - var gd = app.graphicsDevice; - this.debugMesh = this._createDebugMesh(); - this.debugMaterial = new pc.BasicMaterial; - this.debugMaterial.color = new pc.Color(1, 0.5, 0, 1); - this.debugMaterial.update() - }; - ParticleSystemComponentSystem = pc.inherits(ParticleSystemComponentSystem, pc.ComponentSystem); - pc.extend(ParticleSystemComponentSystem.prototype, {initializeComponentData:function(component, _data, properties) { - var data = {}; - properties = []; - var types = this.propertyTypes; - var type; - for(var prop in _data) { - if(_data.hasOwnProperty(prop)) { - properties.push(prop); - data[prop] = _data[prop] - } - if(types[prop] === "vector") { - if(pc.type(data[prop]) === "array") { - data[prop] = new pc.Vec3(data[prop][0], data[prop][1], data[prop][2]) - } - }else { - if(types[prop] === "curve") { - if(!(data[prop] instanceof pc.Curve)) { - type = data[prop].type; - data[prop] = new pc.Curve(data[prop].keys); - data[prop].type = type - } - }else { - if(types[prop] === "curveset") { - if(!(data[prop] instanceof pc.CurveSet)) { - type = data[prop].type; - data[prop] = new pc.CurveSet(data[prop].keys); - data[prop].type = type - } - } - } - } - } - ParticleSystemComponentSystem._super.initializeComponentData.call(this, component, data, properties); - if(this._inTools) { - this._createDebugShape(component) - } - }, cloneComponent:function(entity, clone) { - var source = entity.particlesystem.data; - var schema = this.schema; - var data = {}; - for(var i = 0, len = schema.length;i < len;i++) { - var prop = schema[i]; - var sourceProp = source[prop]; - if(sourceProp instanceof pc.Vec3 || sourceProp instanceof pc.Curve || sourceProp instanceof pc.CurveSet) { - sourceProp = sourceProp.clone(); - data[prop] = sourceProp - }else { - if(sourceProp !== null && sourceProp !== undefined) { - data[prop] = sourceProp - } - } - } - return this.addComponent(clone, data) - }, onUpdate:function(dt) { - var components = this.store; - var currentCamera; - var numSteps, i; - for(var id in components) { - if(components.hasOwnProperty(id)) { - var c = components[id]; - var entity = c.entity; - var data = c.data; - if(data.enabled && entity.enabled) { - var emitter = data.model.emitter; - if(!data.paused) { - emitter.simTime += dt; - numSteps = 0; - if(emitter.simTime > emitter.fixedTimeStep) { - numSteps = Math.floor(emitter.simTime / emitter.fixedTimeStep); - emitter.simTime -= numSteps * emitter.fixedTimeStep - } - if(numSteps) { - numSteps = Math.min(numSteps, emitter.maxSubSteps); - for(i = 0;i < numSteps;i++) { - emitter.addTime(emitter.fixedTimeStep) - } - } - } - } - } - } - }, onToolsUpdate:function(dt) { - var components = this.store; - for(var id in components) { - if(components.hasOwnProperty(id)) { - var c = components[id]; - if(c.data.enabled && c.entity.enabled) { - this._updateDebugShape(c) - } - } - } - }, onRemove:function(entity, data) { - if(data.model) { - this.app.scene.removeModel(data.model); - entity.removeChild(data.model.getGraph()); - data.model = null - } - }, _createDebugMesh:function() { - var gd = this.app.graphicsDevice; - var format = new pc.VertexFormat(gd, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - var vertexBuffer = new pc.VertexBuffer(gd, format, 8); - var positions = new Float32Array(vertexBuffer.lock()); - positions.set([-0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5]); - vertexBuffer.unlock(); - var indexBuffer = new pc.IndexBuffer(gd, pc.INDEXFORMAT_UINT8, 24); - var indices = new Uint8Array(indexBuffer.lock()); - indices.set([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]); - indexBuffer.unlock(); - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffer; - mesh.indexBuffer[0] = indexBuffer; - mesh.primitive[0].type = pc.PRIMITIVE_LINES; - mesh.primitive[0].base = 0; - mesh.primitive[0].count = indexBuffer.getNumIndices(); - mesh.primitive[0].indexed = true; - return mesh - }, _createDebugShape:function(component) { - var node = new pc.GraphNode; - var model = new pc.Model; - model.graph = node; - model.meshInstances = [new pc.MeshInstance(node, this.debugMesh, this.debugMaterial)]; - component.data.debugShape = model; - if(component.data.enabled && component.entity.enabled) { - this.app.root.addChild(node); - this.app.scene.addModel(model) - } - return model - }, _updateDebugShape:function(component) { - var he = component.data.emitterExtents; - var x = he.x; - var y = he.y; - var z = he.z; - var entity = component.entity; - var root = component.data.debugShape.graph; - root.setPosition(entity.getPosition()); - root.setRotation(entity.getRotation()); - x = x || 5E-4; - y = y || 5E-4; - z = z || 5E-4; - root.setLocalScale(x, y, z) - }}); - return{ParticleSystemComponentSystem:ParticleSystemComponentSystem} -}()); -pc.extend(pc, function() { - var SIMPLE_PROPERTIES = ["emitterExtents", "emitterRadius", "colorMap", "normalMap", "loop", "initialVelocity"]; - var COMPLEX_PROPERTIES = ["numParticles", "lifetime", "rate", "rate2", "startAngle", "startAngle2", "lighting", "halfLambert", "intensity", "wrap", "wrapBounds", "depthWrite", "depthSoftening", "sort", "stretch", "alignToMotion", "preWarm", "emitterShape"]; - var GRAPH_PROPERTIES = ["scaleGraph", "scaleGraph2", "colorGraph", "colorGraph2", "alphaGraph", "alphaGraph2", "velocityGraph", "velocityGraph2", "localVelocityGraph", "localVelocityGraph2", "rotationSpeedGraph", "rotationSpeedGraph2"]; - var ParticleSystemComponent = function ParticleSystemComponent(system, entity) { - this.on("set_colorMapAsset", this.onSetColorMapAsset, this); - this.on("set_normalMapAsset", this.onSetNormalMapAsset, this); - this.on("set_mesh", this.onSetMesh, this); - this.on("set_loop", this.onSetLoop, this); - this.on("set_blendType", this.onSetBlendType, this); - SIMPLE_PROPERTIES.forEach(function(prop) { - this.on("set_" + prop, this.onSetSimpleProperty, this) - }.bind(this)); - COMPLEX_PROPERTIES.forEach(function(prop) { - this.on("set_" + prop, this.onSetComplexProperty, this) - }.bind(this)); - GRAPH_PROPERTIES.forEach(function(prop) { - this.on("set_" + prop, this.onSetGraphProperty, this) - }.bind(this)) - }; - ParticleSystemComponent = pc.inherits(ParticleSystemComponent, pc.Component); - pc.extend(ParticleSystemComponent.prototype, {onSetColorMapAsset:function(name, oldValue, newValue) { - var self = this; - var asset; - var assets = this.system.app.assets; - if(oldValue) { - asset = assets.get(oldValue); - if(asset) { - asset.off("remove", this.onColorMapRemoved, this) - } - } - if(newValue) { - if(newValue instanceof pc.Asset) { - this.data.colorMapAsset = newValue.id; - newValue = newValue.id - } - asset = assets.get(newValue); - if(asset) { - asset.on("remove", this.onColorMapRemoved, this); - asset.ready(function(asset) { - self.colorMap = asset.resource - }); - assets.load(asset) - }else { - assets.once("add:" + asset.id, function(asset) { - asset.on("remove", this.onColorMapRemoved, this); - asset.ready(function(asset) { - self.colorMap = asset.resource - }); - assets.load(asset) - }) - } - }else { - this.colorMap = null - } - }, onColorMapRemoved:function(asset) { - asset.off("remove", this.onColorMapRemoved, this); - this.colorMapAsset = null - }, onSetNormalMapAsset:function(name, oldValue, newValue) { - var self = this; - var asset; - var assets = this.system.app.assets; - if(oldValue) { - asset = assets.get(oldValue); - if(asset) { - asset.off("remove", this.onNormalMapRemoved, this) - } - } - if(newValue) { - if(newValue instanceof pc.Asset) { - this.data.normalMapAsset = newValue.id; - newValue = newValue.id - } - asset = assets.get(newValue); - if(asset) { - asset.on("remove", this.onNormalMapRemoved, this); - asset.ready(function(asset) { - self.normalMap = asset.resource - }); - assets.load(asset) - }else { - assets.once("add:" + asset.id, function(asset) { - asset.on("remove", this.onNormalMapRemoved, this); - asset.ready(function(asset) { - self.normalMap = asset.resource - }); - assets.load(asset) - }) - } - }else { - this.normalMap = null - } - }, onNormalMapRemoved:function(asset) { - asset.off("remove", this.onNormalMapRemoved, this); - this.normalMapAsset = null - }, onSetMesh:function(name, oldValue, newValue) { - var self = this; - var asset; - var assets = this.system.app.assets; - if(oldValue && typeof oldValue === "number") { - asset = assets.get(oldValue); - if(asset) { - asset.off("remove", this.onMeshRemoved, this) - } - } - if(newValue) { - if(newValue instanceof pc.Asset) { - this.data.mesh = newValue.id; - newValue = newValue.id - } - if(typeof newValue === "number") { - asset = assets.get(newValue); - if(asset) { - asset.on("remove", this.onMeshRemoved, this); - asset.ready(function(asset) { - self._onMeshChanged(asset.resource) - }); - assets.load(asset) - }else { - assets.once("add:" + newValue, function(asset) { - asset.on("remove", this.onMeshRemoved, this); - asset.ready(function(asset) { - self._onMeshChanged(asset.resource) - }); - assets.load(asset) - }) - } - }else { - this._onMeshChanged(newValue) - } - }else { - this._onMeshChanged(null) - } - }, _onMeshChanged:function(mesh) { - if(mesh) { - if(mesh.meshInstances[0]) { - mesh = mesh.meshInstances[0].mesh - }else { - mesh = null - } - } - this.data.mesh = mesh; - if(this.emitter) { - this.emitter.mesh = mesh; - this.emitter.resetMaterial(); - this.rebuild() - } - }, onMeshRemoved:function(asset) { - asset.off("remove", this.onMeshRemoved, this); - this.mesh = null - }, onSetLoop:function(name, oldValue, newValue) { - if(this.emitter) { - this.emitter[name] = newValue; - this.emitter.resetTime() - } - }, onSetBlendType:function(name, oldValue, newValue) { - if(this.emitter) { - this.emitter[name] = newValue; - this.emitter.material.blendType = newValue; - this.emitter.resetMaterial(); - this.rebuild() - } - }, onSetSimpleProperty:function(name, oldValue, newValue) { - if(this.emitter) { - this.emitter[name] = newValue; - this.emitter.resetMaterial() - } - }, onSetComplexProperty:function(name, oldValue, newValue) { - if(this.emitter) { - this.emitter[name] = newValue; - this.reset(); - this.emitter.resetMaterial(); - this.rebuild() - } - }, onSetGraphProperty:function(name, oldValue, newValue) { - if(this.emitter) { - this.emitter[name] = newValue; - this.emitter.rebuildGraphs(); - this.emitter.resetMaterial() - } - }, onEnable:function() { - if(!this.emitter && !this.system._inTools) { - this.emitter = new pc.ParticleEmitter(this.system.app.graphicsDevice, {numParticles:this.data.numParticles, emitterExtents:this.data.emitterExtents, emitterRadius:this.data.emitterRadius, emitterShape:this.data.emitterShape, initialVelocity:this.data.initialVelocity, wrap:this.data.wrap, wrapBounds:this.data.wrapBounds, lifetime:this.data.lifetime, rate:this.data.rate, rate2:this.data.rate2, startAngle:this.data.startAngle, startAngle2:this.data.startAngle2, scaleGraph:this.data.scaleGraph, - scaleGraph2:this.data.scaleGraph2, colorGraph:this.data.colorGraph, colorGraph2:this.data.colorGraph2, alphaGraph:this.data.alphaGraph, alphaGraph2:this.data.alphaGraph2, localVelocityGraph:this.data.localVelocityGraph, localVelocityGraph2:this.data.localVelocityGraph2, velocityGraph:this.data.velocityGraph, velocityGraph2:this.data.velocityGraph2, rotationSpeedGraph:this.data.rotationSpeedGraph, rotationSpeedGraph2:this.data.rotationSpeedGraph2, colorMap:this.data.colorMap, normalMap:this.data.normalMap, - loop:this.data.loop, preWarm:this.data.preWarm, sort:this.data.sort, stretch:this.data.stretch, alignToMotion:this.data.alignToMotion, lighting:this.data.lighting, halfLambert:this.data.halfLambert, intensity:this.data.intensity, depthSoftening:this.data.depthSoftening, scene:this.system.app.scene, mesh:this.data.mesh, depthWrite:this.data.depthWrite, node:this.entity, blendType:this.data.blendType}); - this.emitter.meshInstance.node = this.entity; - this.psys = new pc.Model; - this.psys.graph = this.entity; - this.psys.emitter = this.emitter; - this.psys.meshInstances = [this.emitter.meshInstance]; - this.data.model = this.psys; - this.emitter.psys = this.psys; - if(!this.data.loop && !this.data.autoPlay) { - this.pause() - } - } - if(this.data.model) { - if(!this.system.app.scene.containsModel(this.data.model)) { - if(this.emitter.colorMap) { - this.system.app.scene.addModel(this.data.model) - } - } - } - if(this.data.debugShape) { - if(!this.system.app.scene.containsModel(this.data.debugShape)) { - this.system.app.scene.addModel(this.data.debugShape); - this.system.app.root.addChild(this.data.debugShape.graph) - } - } - ParticleSystemComponent._super.onEnable.call(this) - }, onDisable:function() { - ParticleSystemComponent._super.onDisable.call(this); - if(this.data.model) { - if(this.system.app.scene.containsModel(this.data.model)) { - this.system.app.scene.removeModel(this.data.model) - } - } - if(this.data.debugShape) { - this.system.app.root.removeChild(this.data.debugShape.graph); - this.system.app.scene.removeModel(this.data.debugShape) - } - }, reset:function() { - this.emitter.reset() - }, stop:function() { - if(this.emitter) { - this.emitter.loop = false; - this.emitter.resetTime(); - this.emitter.addTime(0, true) - } - }, pause:function() { - this.data.paused = true - }, unpause:function() { - this.data.paused = false - }, play:function() { - this.data.paused = false; - if(this.emitter) { - this.emitter.loop = this.data.loop; - this.emitter.resetTime() - } - }, isPlaying:function() { - if(this.data.paused) { - return false - }else { - if(this.emitter && this.emitter.loop) { - return true - }else { - return Date.now() <= this.emitter.endTime - } - } - }, rebuild:function() { - var enabled = this.enabled; - this.enabled = false; - if(this.emitter) { - this.emitter.rebuild(); - this.emitter.meshInstance.node = this.entity; - this.data.model.meshInstances = [this.emitter.meshInstance] - } - this.enabled = enabled - }}); - return{ParticleSystemComponent:ParticleSystemComponent} -}()); -pc.extend(pc, function() { - var ParticleSystemComponentData = function() { - this.numParticles = 1; - this.rate = 1; - this.rate2 = null; - this.startAngle = 0; - this.startAngle2 = null; - this.lifetime = 50; - this.emitterExtents = new pc.Vec3; - this.emitterRadius = 0; - this.emitterShape = pc.EMITTERSHAPE_BOX; - this.initialVelocity = 0; - this.wrapBounds = new pc.Vec3; - this.colorMap = null; - this.colorMapAsset = null; - this.normalMap = null; - this.normalMapAsset = null; - this.loop = true; - this.preWarm = false; - this.sort = 0; - this.mode = pc.PARTICLEMODE_GPU; - this.scene = null; - this.lighting = false; - this.halfLambert = false; - this.intensity = 1; - this.stretch = 0; - this.alignToMotion = false; - this.depthSoftening = 0; - this.mesh = null; - this.depthWrite = false; - this.scaleGraph = null; - this.scaleGraph2 = null; - this.colorGraph = null; - this.colorGraph2 = null; - this.alphaGraph = null; - this.alphaGraph2 = null; - this.localVelocityGraph = null; - this.localVelocityGraph2 = null; - this.velocityGraph = null; - this.velocityGraph2 = null; - this.rotationSpeedGraph = null; - this.rotationSpeedGraph2 = null; - this.blendType = pc.BLEND_NORMAL; - this.model = null; - this.enabled = true; - this.paused = false; - this.debugShape = null - }; - ParticleSystemComponentData = pc.inherits(ParticleSystemComponentData, pc.ComponentData); - return{ParticleSystemComponentData:ParticleSystemComponentData} -}()); -pc.extend(pc, function() { - var Entity = function(app) { - this._guid = pc.guid.create(); - this._batchHandle = null; - this.c = {}; - this._app = app; - if(!app) { - this._app = pc.Application.getApplication(); - if(!this._app) { - console.error("Couldn't find current application") - } - } - pc.events.attach(this) - }; - Entity = pc.inherits(Entity, pc.GraphNode); - Entity.prototype.addComponent = function(type, data) { - var system = this._app.systems[type]; - if(system) { - if(!this.c[type]) { - return system.addComponent(this, data) - }else { - logERROR(pc.string.format("Entity already has {0} Component", type)) - } - }else { - logERROR(pc.string.format("System: '{0}' doesn't exist", type)); - return null - } - }; - Entity.prototype.removeComponent = function(type) { - var system = this._app.systems[type]; - if(system) { - if(this.c[type]) { - system.removeComponent(this) - }else { - logERROR(pc.string.format("Entity doesn't have {0} Component", type)) - } - }else { - logERROR(pc.string.format("System: '{0}' doesn't exist", type)) - } - }; - Entity.prototype.getGuid = function() { - return this._guid - }; - Entity.prototype.setGuid = function(guid) { - this._guid = guid - }; - Entity.prototype._onHierarchyStateChanged = function(enabled) { - pc.Entity._super._onHierarchyStateChanged.call(this, enabled); - var component; - var components = this.c; - for(type in components) { - if(components.hasOwnProperty(type)) { - component = components[type]; - if(component.enabled) { - if(enabled) { - component.onEnable() - }else { - component.onDisable() - } - } - } - } - }; - Entity.prototype.setRequest = function(request) { - this._request = request - }; - Entity.prototype.getRequest = function() { - return this._request - }; - Entity.prototype.addChild = function(child) { - if(child instanceof pc.Entity) { - var _debug = true; - if(_debug) { - var root = this.getRoot(); - var dupe = root.findOne("getGuid", child.getGuid()); - if(dupe) { - throw new Error("GUID already exists in graph"); - } - } - } - pc.GraphNode.prototype.addChild.call(this, child) - }; - Entity.prototype.findByGuid = function(guid) { - if(this._guid === guid) { - return this - } - for(var i = 0;i < this._children.length;i++) { - if(this._children[i].findByGuid) { - var found = this._children[i].findByGuid(guid); - if(found !== null) { - return found - } - } - } - return null - }; - Entity.prototype.destroy = function() { - var parent = this.getParent(); - var childGuids; - for(var name in this.c) { - this.c[name].enabled = false - } - for(var name in this.c) { - this.c[name].system.removeComponent(this) - } - if(parent) { - parent.removeChild(this) - } - var children = this.getChildren(); - var length = children.length; - var child = children.shift(); - while(child) { - if(child instanceof pc.Entity) { - child.destroy() - } - child = children.shift() - } - }; - Entity.prototype.clone = function() { - var type; - var c = new pc.Entity(this._app); - pc.Entity._super._cloneInternal.call(this, c); - for(type in this.c) { - var component = this.c[type]; - component.system.cloneComponent(this, c) - } - var i; - for(i = 0;i < this.getChildren().length;i++) { - var child = this.getChildren()[i]; - if(child instanceof pc.Entity) { - c.addChild(child.clone()) - } - } - return c - }; - Entity.deserialize = function(data) { - var template = pc.json.parse(data.template); - var parent = pc.json.parse(data.parent); - var children = pc.json.parse(data.children); - var transform = pc.json.parse(data.transform); - var components = pc.json.parse(data.components); - var labels = pc.json.parse(data.labels); - var model = {_id:data._id, resource_id:data.resource_id, _rev:data._rev, name:data.name, enabled:data.enabled, labels:labels, template:template, parent:parent, children:children, transform:transform, components:components}; - return model - }; - Entity.serialize = function(model) { - var data = {_id:model._id, resource_id:model.resource_id, name:model.name, enabled:model.enabled, labels:pc.json.stringify(model.labels), template:pc.json.stringify(model.template), parent:pc.json.stringify(model.parent), children:pc.json.stringify(model.children), transform:pc.json.stringify(model.transform), components:pc.json.stringify(model.components)}; - if(model._rev) { - data._rev = model._rev - } - return data - }; - return{Entity:Entity} -}()); -pc.extend(pc, function() { - var ResourceLoader = function() { - this._handlers = {}; - this._requests = {}; - this._cache = {} - }; - ResourceLoader.prototype = {addHandler:function(type, handler) { - this._handlers[type] = handler - }, removeHandler:function(type) { - delete this._handlers[type] - }, load:function(url, type, callback) { - var handler = this._handlers[type]; - if(!handler) { - var err = "No handler for asset type: " + type; - callback(err); - return - } - var key = url + type; - if(this._cache[key] !== undefined) { - callback(null, this._cache[key]) - }else { - if(this._requests[key]) { - this._requests[key].push(callback) - }else { - this._requests[key] = [callback]; - handler.load(url, function(err, data) { - if(!this._requests[key]) { - return - } - var i, len = this._requests[key].length; - if(!err) { - var resource = handler.open(url, data); - this._cache[key] = resource; - for(var i = 0;i < len;i++) { - this._requests[key][i](null, resource) - } - }else { - for(var i = 0;i < len;i++) { - this._requests[key][i](err) - } - } - delete this._requests[key] - }.bind(this)) - } - } - }, open:function(type, data) { - var handler = this._handlers[type]; - return handler.open(null, data) - }, patch:function(asset, assets) { - var handler = this._handlers[asset.type]; - if(handler.patch) { - handler.patch(asset, assets) - } - }, clearCache:function(url, type) { - delete this._cache[url + type] - }, getFromCache:function(url, type) { - if(this._cache[url + type]) { - return this._cache[url + type] - } - }, destroy:function() { - this._handlers = {}; - this._requests = {}; - this._cache = {} - }}; - return{ResourceLoader:ResourceLoader} -}()); -pc.extend(pc, function() { - var AnimationHandler = function() { - }; - AnimationHandler.prototype = {load:function(url, callback) { - pc.net.http.get(url, function(response) { - callback(null, response) - }.bind(this), {error:function(status, xhr, e) { - callback(pc.string.format("Error loading animation resource: {0} [{1}]", url, status)) - }}) - }, open:function(url, data) { - return this["_parseAnimationV" + data.animation.version](data) - }, _parseAnimationV3:function(data) { - var animData = data.animation; - var anim = new pc.Animation; - anim.setName(animData.name); - anim.setDuration(animData.duration); - for(var i = 0;i < animData.nodes.length;i++) { - var node = new pc.Node; - var n = animData.nodes[i]; - node._name = n.name; - for(var j = 0;j < n.keys.length;j++) { - var k = n.keys[j]; - var t = k.time; - var p = k.pos; - var r = k.rot; - var s = k.scale; - var pos = new pc.Vec3(p[0], p[1], p[2]); - var rot = (new pc.Quat).setFromEulerAngles(r[0], r[1], r[2]); - var scl = new pc.Vec3(s[0], s[1], s[2]); - var key = new pc.Key(t, pos, rot, scl); - node._keys.push(key) - } - anim.addNode(node) - } - return anim - }, _parseAnimationV4:function(data) { - var animData = data.animation; - var anim = new pc.Animation; - anim.setName(animData.name); - anim.setDuration(animData.duration); - for(var i = 0;i < animData.nodes.length;i++) { - var node = new pc.Node; - var n = animData.nodes[i]; - node._name = n.name; - var defPos = n.defaults.p; - var defRot = n.defaults.r; - var defScl = n.defaults.s; - for(var j = 0;j < n.keys.length;j++) { - var k = n.keys[j]; - var t = k.t; - var p = defPos ? defPos : k.p; - var r = defRot ? defRot : k.r; - var s = defScl ? defScl : k.s; - var pos = new pc.Vec3(p[0], p[1], p[2]); - var rot = (new pc.Quat).setFromEulerAngles(r[0], r[1], r[2]); - var scl = new pc.Vec3(s[0], s[1], s[2]); - var key = new pc.Key(t, pos, rot, scl); - node._keys.push(key) - } - anim.addNode(node) - } - return anim - }}; - return{AnimationHandler:AnimationHandler} -}()); -pc.extend(pc, function() { - var AudioHandler = function(manager) { - this.manager = manager - }; - AudioHandler.prototype = {load:function(url, callback) { - var sound = this.manager.createSound(url, function(sound) { - callback(null, sound) - }, function(error) { - callback("Error loading: " + url, null) - }) - }, open:function(url, data) { - return data - }}; - return{AudioHandler:AudioHandler} -}()); -pc.extend(pc, function() { - function onTextureAssetChanged(asset, attribute, newValue, oldValue) { - if(attribute !== "resource") { - return - } - var cubemapAsset = this; - var cubemap = cubemapAsset.resource; - if(!cubemap) { - return - } - var sources = cubemap.getSource(); - var dirty = false; - if(oldValue) { - var oldImage = oldValue.getSource(); - for(var i = 0;i < sources.length;i++) { - if(sources[i] === oldImage) { - sources[i] = newValue.getSource(); - dirty = true - } - } - } - if(dirty) { - cubemap.setSource(sources); - var old = cubemapAsset.resources.slice(0); - cubemapAsset.fire("change", cubemapAsset, "resources", cubemapAsset.resources, old) - }else { - asset.off("change", onTextureAssetChanged, cubemap) - } - } - var CubemapHandler = function(device, assets, loader) { - this._device = device; - this._assets = assets; - this._loader = loader - }; - CubemapHandler.prototype = {load:function(url, callback) { - var count = 0; - var data = {}; - if(pc.string.endsWith(url, ".dds")) { - this._loader.load(url, "texture", function(err, texture) { - count--; - if(!err) { - data.dds = texture; - if(count === 0) { - callback(null, data) - } - }else { - callback(err) - } - }) - }else { - if(pc.string.endsWith(url, ".json")) { - } - } - }, open:function(url, data) { - var i; - var resources = []; - var cubemap = new pc.Texture(this._device, {format:pc.PIXELFORMAT_R8_G8_B8_A8, cubemap:true, autoMipmap:true, fixCubemapSeams:!!data.dds}); - cubemap.name = data.name; - cubemap.minFilter = data.minFilter; - cubemap.magFilter = data.magFilter; - cubemap.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - cubemap.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - cubemap.anisotropy = data.anisotropy; - cubemap.rgbm = !!data.rgbm; - resources.push(cubemap); - if(data.dds) { - data.dds.fixCubemapSeams = true; - data.dds.minFilter = this._device.useTexCubeLod ? pc.FILTER_LINEAR_MIPMAP_LINEAR : pc.FILTER_LINEAR; - data.dds.magFilter = pc.FILTER_LINEAR; - data.dds.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - data.dds.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - resources.push(data.dds); - var mipSize = 64; - for(i = 1;i < 6;i++) { - var mip = new pc.gfx.Texture(this._device, {cubemap:true, fixCubemapSeams:true, autoMipmap:true, format:data.dds.format, rgbm:data.dds.rgbm, width:mipSize, height:mipSize}); - mip.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - mip.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - mipSize *= 0.5; - mip._levels[0] = data.dds._levels[i]; - mip.upload(); - resources.push(mip) - } - } - return resources - }, patch:function(cubemapAsset, assets) { - var i; - var cubemap = cubemapAsset.resource; - var textureAssets = []; - var sources = []; - var count = 0; - cubemapAsset.data.textures.forEach(function(id, index) { - var _asset = assets.get(cubemapAsset.data.textures[index]); - if(_asset) { - _asset.ready(function(asset) { - count++; - sources[index] = asset.resource.getSource(); - if(count === 6) { - cubemap.setSource(sources) - } - _asset.off("change", onTextureAssetChanged, cubemapAsset); - _asset.on("change", onTextureAssetChanged, cubemapAsset) - }); - assets.load(_asset) - }else { - assets.once("load:" + id, function(asset) { - asset.ready(function(asset) { - count++; - sources[index] = asset.resource.getSource(); - if(count === 6) { - cubemap.setSource(sources) - } - asset.off("change", onTextureAssetChanged, cubemapAsset); - asset.on("change", onTextureAssetChanged, cubemapAsset) - }) - }) - } - }); - cubemapAsset.off("change", this._onCubemapAssetChanged, this); - cubemapAsset.on("change", this._onCubemapAssetChanged, this) - }, _onCubemapAssetChanged:function(asset, attribute, newValue, oldValue) { - var self = this; - if(attribute === "data") { - var l = newValue.textures.length; - var count = l; - var sources = []; - newValue.textures.forEach(function(id, index) { - var texture = self._assets.get(id); - if(texture) { - texture.ready(function(texture) { - sources[index] = texture.resource.getSource(); - count--; - if(count === 0) { - asset.resource.setSource(sources) - } - texture.off("change", onTextureAssetChanged, asset); - texture.on("change", onTextureAssetChanged, asset) - }); - self._assets.load(texture) - } - }); - asset.resource.minFilter = newValue.minFilter; - asset.resource.magFilter = newValue.magFilter; - asset.resource.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - asset.resource.addressV = pc.ADDRESS_CLAMP_TO_EDGE; - asset.resource.anisotropy = newValue.anisotropy; - asset.resource.rgbm = newValue.rgbm ? true : false; - asset.resource.upload() - }else { - if(attribute === "file") { - if(asset.file && asset.file.url) { - this._loader.load(asset.file.url, "texture", function(err, texture) { - if(!err) { - self._loader.patch({resource:texture, type:"texture", data:asset.data}, this._assets); - asset.data.dds = texture; - asset.resources = self._loader.open(asset.type, asset.data); - self._loader.patch(asset, self._assets) - }else { - console.error(err) - } - }) - }else { - asset.resources = [asset.resource] - } - } - } - }}; - return{CubemapHandler:CubemapHandler} -}()); -pc.extend(pc, function() { - var JsonHandler = function() { - }; - JsonHandler.prototype = {load:function(url, callback) { - pc.net.http.get(url, function(response) { - callback(null, response) - }, {error:function(status, xhr, e) { - callback(pc.string.format("Error loading JSON resource: {0} [{1}]", url, status)) - }}) - }, open:function(url, data) { - return data - }, patch:function(asset, assets) { - }}; - return{JsonHandler:JsonHandler} -}()); -pc.extend(pc, function() { - var onTextureAssetChanged = function(asset, attribute, newValue, oldValue) { - if(attribute !== "resource") { - return - } - var material = this; - var dirty = false; - if(oldValue) { - for(var key in material) { - if(material.hasOwnProperty(key)) { - if(material[key] === oldValue) { - material[key] = newValue; - dirty = true - } - } - } - } - if(dirty) { - material.update() - }else { - asset.off("change", onTextureAssetChanged, material) - } - }; - var MaterialHandler = function(assets) { - this._assets = assets - }; - MaterialHandler.prototype = {load:function(url, callback) { - if(pc.string.startsWith(url, "asset://")) { - }else { - pc.net.http.get(url, function(response) { - if(callback) { - callback(null, response) - } - }, {error:function(status, xhr, e) { - if(callback) { - callback(pc.string.format("Error loading material: {0} [{1}]", url, status)) - } - }}) - } - }, open:function(url, data) { - var material = new pc.PhongMaterial; - material.init(data); - material._data = data; - return material - }, patch:function(asset, assets) { - if(asset.data.shader === undefined) { - asset.data = asset.resource._data; - delete asset.resource._data - } - this._updatePhongMaterial(asset, asset.data, assets); - asset.off("change", this._onAssetChange, this); - asset.on("change", this._onAssetChange, this) - }, _onAssetChange:function(asset, attribute, value) { - if(attribute === "data") { - this._updatePhongMaterial(asset, value, this._assets) - } - }, _updatePhongMaterial:function(asset, data, assets) { - var material = asset.resource; - if(asset.file) { - var dir = pc.path.getDirectory(asset.getFileUrl()) - } - data.parameters.push({name:"shadingModel", type:"float", data:data.shader === "blinn" ? pc.SPECULAR_BLINN : pc.SPECULAR_PHONG}); - var pathMapping = data.mapping_format === "path"; - var id; - data.parameters.forEach(function(param, i) { - if(param.type === "texture" && param.data && !(param.data instanceof pc.Texture)) { - if(pathMapping) { - asset = assets.getByUrl(pc.path.join(dir, param.data)) - }else { - id = param.data; - asset = assets.get(param.data) - } - if(asset) { - asset.ready(function(asset) { - data.parameters[i].data = asset.resource; - material.init(data); - asset.off("change", onTextureAssetChanged, material); - asset.on("change", onTextureAssetChanged, material) - }); - assets.load(asset) - }else { - if(id) { - assets.once("add:" + id, function(asset) { - asset.ready(function(asset) { - data.parameters[i].data = asset.resource; - material.init(data); - asset.off("change", onTextureAssetChanged, material); - asset.on("change", onTextureAssetChanged, material) - }); - assets.load(asset) - }) - }else { - if(pathMapping) { - assets.once("add:url:" + pc.path.join(dir, param.data), function(asset) { - asset.ready(function(asset) { - data.parameters[i].data = asset.resource; - material.init(data); - asset.off("change", onTextureAssetChanged, material); - asset.on("change", onTextureAssetChanged, material) - }); - assets.load(asset) - }) - } - } - } - }else { - if(param.type === "cubemap" && param.data && !(param.data instanceof pc.Texture)) { - if(pathMapping) { - asset = assets.getByUrl(pc.path.join(dir, param.data)) - }else { - id = param.data; - asset = assets.get(param.data) - } - if(asset) { - asset.ready(function(asset) { - param.data = asset.resource; - if(asset.resources.length > 1) { - data.parameters.push({name:"prefilteredCubeMap128", data:asset.resources[1]}); - data.parameters.push({name:"prefilteredCubeMap64", data:asset.resources[2]}); - data.parameters.push({name:"prefilteredCubeMap32", data:asset.resources[3]}); - data.parameters.push({name:"prefilteredCubeMap16", data:asset.resources[4]}); - data.parameters.push({name:"prefilteredCubeMap8", data:asset.resources[5]}); - data.parameters.push({name:"prefilteredCubeMap4", data:asset.resources[6]}) - } - material.init(data); - asset.off("change", onTextureAssetChanged, material); - asset.on("change", onTextureAssetChanged, material) - }); - assets.load(asset) - }else { - if(id) { - assets.once("add:" + id, function(asset) { - asset.ready(function(asset) { - param.data = asset.resource; - if(asset.resources.length > 1) { - data.parameters.push({name:"prefilteredCubeMap128", data:asset.resources[1]}); - data.parameters.push({name:"prefilteredCubeMap64", data:asset.resources[2]}); - data.parameters.push({name:"prefilteredCubeMap32", data:asset.resources[3]}); - data.parameters.push({name:"prefilteredCubeMap16", data:asset.resources[4]}); - data.parameters.push({name:"prefilteredCubeMap8", data:asset.resources[5]}); - data.parameters.push({name:"prefilteredCubeMap4", data:asset.resources[6]}) - } - material.init(data); - asset.off("change", onTextureAssetChanged, material); - asset.on("change", onTextureAssetChanged, material) - }); - assets.load(asset) - }) - }else { - if(pathMapping) { - assets.once("add:url:" + pc.path.join(dir, param.data), function(asset) { - asset.ready(function(asset) { - data.parameters[i].data = asset.resource; - material.init(data); - asset.off("change", onTextureAssetChanged, material); - asset.on("change", onTextureAssetChanged, material) - }); - assets.load(asset) - }) - } - } - } - } - } - }); - material.init(data) - }}; - return{MaterialHandler:MaterialHandler} -}()); -pc.extend(pc, function() { - var ModelHandler = function(device) { - this._device = device - }; - ModelHandler.DEFAULT_MATERIAL = new pc.PhongMaterial; - ModelHandler.prototype = {load:function(url, callback) { - pc.net.http.get(url, function(response) { - if(callback) { - callback(null, response) - } - }, {error:function(status, xhr, e) { - if(callback) { - callback(pc.string.format("Error loading model: {0} [{1}]", url, status)) - } - }}) - }, open:function(url, data) { - var model = null; - if(data.model.version <= 1) { - logERROR(pc.string.format("Asset: {0}, is an old model format. Upload source assets to re-import.", url)) - }else { - if(data.model.version >= 2) { - var parser = new pc.JsonModelParser(this._device); - model = parser.parse(data) - } - } - return model - }, patch:function(asset, assets) { - var resource = asset.resource; - var data = asset.data; - resource.meshInstances.forEach(function(meshInstance, i) { - if(data.mapping) { - if(data.mapping[i].material !== undefined) { - if(data.mapping[i].material === null) { - meshInstance.material = pc.ModelHandler.DEFAULT_MATERIAL - }else { - var material = assets.get(data.mapping[i].material); - if(material) { - material.ready(function(asset) { - meshInstance.material = asset.resource - }); - assets.load(material) - }else { - assets.on("add:" + data.mapping[i].material, function(material) { - material.ready(function(asset) { - meshInstance.material = asset.resource - }); - assets.load(material) - }) - } - } - }else { - if(data.mapping[i].path !== undefined) { - if(data.mapping[i].path) { - var url = asset.getFileUrl(); - var dir = pc.path.getDirectory(url); - var path = pc.path.join(dir, data.mapping[i].path); - var material = assets.getByUrl(path); - if(material) { - material.ready(function(asset) { - meshInstance.material = asset.resource - }); - assets.load(material) - }else { - assets.on("add:url:" + path, function(material) { - material.ready(function(asset) { - meshInstance.material = asset.resource - }); - assets.load(material) - }) - } - } - } - } - } - }) - }}; - return{ModelHandler:ModelHandler} -}()); -pc.extend(pc, function() { - var ScriptHandler = function(app) { - this._app = app; - this._scripts = {} - }; - ScriptHandler._types = []; - ScriptHandler._push = function(Type) { - if(ScriptHandler._types.length > 0) { - console.assert("Script Ordering Error. Contact support@playcanvas.com") - }else { - ScriptHandler._types.push(Type) - } - }; - ScriptHandler.prototype = {load:function(url, callback) { - pc.script.app = this._app; - this._loadScript(url, function(err, url) { - if(!err) { - var Type = null; - if(ScriptHandler._types.length) { - Type = ScriptHandler._types.pop() - } - if(Type) { - this._scripts[url] = Type - }else { - Type = null - } - callback(null, Type) - }else { - callback(err) - } - }.bind(this)) - }, open:function(url, data) { - return data - }, patch:function(asset, assets) { - }, _loadScript:function(url, callback) { - var self = this; - var head = document.getElementsByTagName("head")[0]; - var element = document.createElement("script"); - element.async = false; - element.addEventListener("error", function(e) { - callback(pc.string.format("Script: {0} failed to load", e.target.src)) - }); - var done = false; - element.onload = element.onreadystatechange = function() { - if(!done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) { - done = true; - callback(null, url) - } - }; - element.src = url; - head.appendChild(element) - }}; - return{ScriptHandler:ScriptHandler} -}()); -pc.extend(pc, function() { - var TextHandler = function() { - }; - TextHandler.prototype = {load:function(url, callback) { - pc.net.http.get(url, function(response) { - callback(null, response) - }, {error:function(status, xhr, e) { - callback(pc.string.format("Error loading text resource: {0} [{1}]", url, status)) - }}) - }, open:function(url, data) { - return data - }, patch:function(asset, assets) { - }}; - return{TextHandler:TextHandler} -}()); -pc.extend(pc, function() { - var JSON_ADDRESS_MODE = {"repeat":pc.ADDRESS_REPEAT, "clamp":pc.ADDRESS_CLAMP_TO_EDGE, "mirror":pc.ADDRESS_MIRRORED_REPEAT}; - var JSON_FILTER_MODE = {"nearest":pc.FILTER_NEAREST, "linear":pc.FILTER_LINEAR, "nearest_mip_nearest":pc.FILTER_NEAREST_MIPMAP_NEAREST, "linear_mip_nearest":pc.FILTER_LINEAR_MIPMAP_NEAREST, "nearest_mip_linear":pc.FILTER_NEAREST_MIPMAP_LINEAR, "linear_mip_linear":pc.FILTER_LINEAR_MIPMAP_LINEAR}; - function arrayBufferCopy(src, dst, dstByteOffset, numBytes) { - dst32Offset = dstByteOffset / 4; - var tail = numBytes % 4; - var src32 = new Uint32Array(src.buffer, 0, (numBytes - tail) / 4); - var dst32 = new Uint32Array(dst.buffer); - for(var i = 0;i < src32.length;i++) { - dst32[dst32Offset + i] = src32[i] - } - for(var i = numBytes - tail;i < numBytes;i++) { - dst[dstByteOffset + i] = src[i] - } - } - var TextureHandler = function(device, assets, loader) { - this._device = device; - this._assets = assets; - this._loader = loader; - this.crossOrigin = undefined - }; - TextureHandler.prototype = {load:function(url, callback) { - var self = this; - var urlWithoutParams = url.indexOf("?") >= 0 ? url.split("?")[0] : url; - var ext = pc.path.getExtension(urlWithoutParams).toLowerCase(); - if(ext === ".dds" || ext === ".crn") { - pc.net.http.get(url, function(response) { - callback(null, response) - }, {cache:true, responseType:"arraybuffer", error:function(status, xhr, e) { - callback(status) - }}) - }else { - if(ext === ".jpg" || ext === ".jpeg" || ext === ".gif" || ext === ".png") { - var image = new Image; - if(self.crossOrigin !== undefined) { - image.crossOrigin = self.crossOrigin - } - image.onload = function() { - callback(null, image) - }; - image.onerror = function(event) { - var element = event.srcElement; - callback(pc.string.format("Error loading Texture from: '{0}'", element.src)) - }; - image.src = url - } - } - }, open:function(url, data) { - var self = this; - var texture; - var ext = pc.path.getExtension(url).toLowerCase(); - if(data instanceof Image || data instanceof HTMLImageElement) { - var img = data; - var format = ext === ".jpg" || ext === ".jpeg" ? pc.PIXELFORMAT_R8_G8_B8 : pc.PIXELFORMAT_R8_G8_B8_A8; - texture = new pc.Texture(this._device, {width:img.width, height:img.height, format:format}); - texture.setSource(img) - }else { - if(data instanceof ArrayBuffer) { - if(ext === ".crn") { - var srcSize = data.byteLength; - var bytes = new Uint8Array(data); - var src = Module._malloc(srcSize); - arrayBufferCopy(bytes, Module.HEAPU8, src, srcSize); - var dst = Module._crn_decompress_get_data(src, srcSize); - var dstSize = Module._crn_decompress_get_size(src, srcSize); - data = Module.HEAPU8.buffer.slice(dst, dst + dstSize) - } - var header = new Uint32Array(data, 0, 128 / 4); - var width = header[4]; - var height = header[3]; - var mips = Math.max(header[7], 1); - var isFourCc = header[20] === 4; - var fcc = header[21]; - var bpp = header[22]; - var isCubemap = header[28] === 65024; - var FCC_DXT1 = 827611204; - var FCC_DXT5 = 894720068; - var FCC_FP32 = 116; - var FCC_ETC1 = 826496069; - var format = null; - var compressed = false; - var floating = false; - var etc1 = false; - if(isFourCc) { - if(fcc === FCC_DXT1) { - format = pc.PIXELFORMAT_DXT1; - compressed = true - }else { - if(fcc === FCC_DXT5) { - format = pc.PIXELFORMAT_DXT5; - compressed = true - }else { - if(fcc === FCC_FP32) { - format = pc.PIXELFORMAT_RGBA32F; - floating = true - }else { - if(fcc === FCC_ETC1) { - format = pc.PIXELFORMAT_ETC1; - compressed = true; - etc1 = true - } - } - } - } - }else { - if(bpp === 32) { - format = pc.PIXELFORMAT_R8_G8_B8_A8 - } - } - var requiredMips = Math.round(Math.log2(Math.max(width, height)) + 1); - var cantLoad = !format || mips !== requiredMips && compressed; - if(cantLoad) { - var errEnd = ". Empty texture will be created instead."; - if(!format) { - console.error("This DDS pixel format is currently unsupported" + errEnd) - }else { - console.error("DDS has " + mips + " mips, but engine requires " + requiredMips + " for DXT format. " + errEnd) - } - texture = new pc.Texture(this._device, {width:4, height:4, format:pc.PIXELFORMAT_R8_G8_B8}); - return texture - } - var texOptions = {width:width, height:height, format:format, cubemap:isCubemap}; - texture = new pc.Texture(this._device, texOptions); - if(isCubemap) { - texture.addressU = pc.ADDRESS_CLAMP_TO_EDGE; - texture.addressV = pc.ADDRESS_CLAMP_TO_EDGE - } - var offset = 128; - var faces = isCubemap ? 6 : 1; - var mipSize; - var DXT_BLOCK_WIDTH = 4; - var DXT_BLOCK_HEIGHT = 4; - var blockSize = fcc === FCC_DXT1 ? 8 : 16; - var numBlocksAcross, numBlocksDown; - for(var face = 0;face < faces;face++) { - var mipWidth = width; - var mipHeight = height; - for(var i = 0;i < mips;i++) { - if(compressed) { - if(etc1) { - mipSize = Math.floor((mipWidth + 3) / 4) * Math.floor((mipHeight + 3) / 4) * 8 - }else { - numBlocksAcross = Math.floor((mipWidth + DXT_BLOCK_WIDTH - 1) / DXT_BLOCK_WIDTH); - numBlocksDown = Math.floor((mipHeight + DXT_BLOCK_HEIGHT - 1) / DXT_BLOCK_HEIGHT); - numBlocks = numBlocksAcross * numBlocksDown; - mipSize = numBlocks * blockSize - } - }else { - mipSize = mipWidth * mipHeight * 4 - } - var mipBuff = floating ? new Float32Array(data, offset, mipSize) : new Uint8Array(data, offset, mipSize); - if(!isCubemap) { - texture._levels[i] = mipBuff - }else { - if(!texture._levels[i]) { - texture._levels[i] = [] - } - texture._levels[i][face] = mipBuff - } - offset += floating ? mipSize * 4 : mipSize; - mipWidth = Math.max(mipWidth * 0.5, 1); - mipHeight = Math.max(mipHeight * 0.5, 1) - } - } - texture.upload() - } - } - return texture - }, patch:function(asset, assets) { - this._updateTexture(asset.resource, asset.data); - if(asset.on) { - asset.off("change", this._onAssetChanged, this); - asset.on("change", this._onAssetChanged, this) - } - }, _onAssetChanged:function(asset, attribute, value, oldValue) { - if(attribute === "data") { - this._updateTexture(asset.resource, value) - }else { - if(attribute === "file") { - if(oldValue) { - this._loader.clearCache(oldValue.url, "texture") - } - if(value) { - asset.loaded = false; - this._assets.load(asset) - }else { - asset.unload() - } - } - } - }, _updateTexture:function(texture, data) { - if(data.name !== undefined) { - texture.name = data.name - } - if(data.addressu !== undefined) { - texture.addressU = JSON_ADDRESS_MODE[data.addressu] - } - if(data.addressV !== undefined) { - texture.addressV = JSON_ADDRESS_MODE[data.addressV] - } - if(data.magfilter !== undefined) { - texture.magFilter = JSON_FILTER_MODE[data.magfilter] - } - if(data.minfilter !== undefined) { - texture.minFilter = JSON_FILTER_MODE[data.minfilter] - } - if(data.anisotropy !== undefined) { - texture.anisotropy = data.anisotropy - } - if(data.rgbm !== undefined) { - texture.rgbm = data.rgbm - } - }}; - return{TextureHandler:TextureHandler} -}()); -pc.extend(pc, function() { - var SceneHandler = function(app) { - this._app = app - }; - SceneHandler.prototype = {load:function(url, callback) { - pc.net.http.get(url, function(response) { - callback(null, response) - }, {error:function(status, xhr, e) { - callback("Error requesting scene: " + url) - }}) - }, open:function(url, data) { - this._app.systems.script.preloading = true; - var scene = new pc.Scene; - this._app.scene = scene; - var parser = new pc.SceneParser(this._app); - var parent = parser.parse(data); - scene.root = parent; - scene.applySettings(data.settings); - this._app.systems.script.preloading = false; - return scene - }, patch:function(asset, assets) { - var scene = asset.resource; - var asset = assets.get(scene.skyboxAsset); - if(asset) { - asset.ready(function(asset) { - scene.attachSkyboxAsset(asset); - asset.on("change", this._onSkyBoxChanged, this); - asset.on("remove", this._onSkyBoxRemoved, this) - }) - }else { - assets.once("add:" + scene.skyboxAsset, function(asset) { - asset.ready(function(asset) { - scene.attachSkyboxAsset(asset) - }) - }) - } - }}; - return{SceneHandler:SceneHandler} -}()); -pc.extend(pc, function() { - var HierarchyHandler = function(app) { - this._app = app - }; - HierarchyHandler.prototype = {load:function(url, callback) { - pc.net.http.get(url, function(response) { - callback(null, response) - }, {error:function(status, xhr, e) { - callback("Error requesting scene: " + url) - }}) - }, open:function(url, data) { - this._app.systems.script.preloading = true; - var parser = new pc.SceneParser(this._app); - var parent = parser.parse(data); - this._app.systems.script.preloading = false; - return parent - }}; - return{HierarchyHandler:HierarchyHandler} -}()); -pc.extend(pc, function() { - var SceneSettingsHandler = function(app) { - this._app = app - }; - SceneSettingsHandler.prototype = {load:function(url, callback) { - pc.net.http.get(url, function(response) { - callback(null, response) - }, {error:function(status, xhr, e) { - callback("Error requesting scene: " + url) - }}) - }, open:function(url, data) { - return data.settings - }}; - return{SceneSettingsHandler:SceneSettingsHandler} -}()); -pc.extend(pc, function() { - var JSON_PRIMITIVE_TYPE = {"points":pc.PRIMITIVE_POINTS, "lines":pc.PRIMITIVE_LINES, "lineloop":pc.PRIMITIVE_LINELOOP, "linestrip":pc.PRIMITIVE_LINESTRIP, "triangles":pc.PRIMITIVE_TRIANGLES, "trianglestrip":pc.PRIMITIVE_TRISTRIP, "trianglefan":pc.PRIMITIVE_TRIFAN}; - var JSON_VERTEX_ELEMENT_TYPE = {"int8":pc.ELEMENTTYPE_INT8, "uint8":pc.ELEMENTTYPE_UINT8, "int16":pc.ELEMENTTYPE_INT16, "uint16":pc.ELEMENTTYPE_UINT16, "int32":pc.ELEMENTTYPE_INT32, "uint32":pc.ELEMENTTYPE_UINT32, "float32":pc.ELEMENTTYPE_FLOAT32}; - var JsonModelParser = function(device) { - this._device = device - }; - JsonModelParser.prototype = {parse:function(data) { - var modelData = data.model; - var nodes = this._parseNodes(data); - var skins = this._parseSkins(data, nodes); - var vertexBuffers = this._parseVertexBuffers(data); - var indices = this._parseIndexBuffers(data); - var meshes = this._parseMeshes(data, skins.skins, vertexBuffers, indices.buffer, indices.data); - var meshInstances = this._parseMeshInstances(data, nodes, meshes, skins.skins, skins.instances); - var model = new pc.Model; - model.graph = nodes[0]; - model.meshInstances = meshInstances; - model.skinInstances = skins.instances; - model.getGraph().syncHierarchy(); - return model - }, _parseNodes:function(data) { - var modelData = data.model; - var nodes = []; - var i; - for(i = 0;i < modelData.nodes.length;i++) { - var nodeData = modelData.nodes[i]; - var node = new pc.GraphNode; - node.setName(nodeData.name); - node.setLocalPosition(nodeData.position[0], nodeData.position[1], nodeData.position[2]); - node.setLocalEulerAngles(nodeData.rotation[0], nodeData.rotation[1], nodeData.rotation[2]); - node.setLocalScale(nodeData.scale[0], nodeData.scale[1], nodeData.scale[2]); - nodes.push(node) - } - for(i = 1;i < modelData.parents.length;i++) { - nodes[modelData.parents[i]].addChild(nodes[i]) - } - return nodes - }, _parseSkins:function(data, nodes) { - var modelData = data.model; - var skins = []; - var skinInstances = []; - var i, j; - if(!this._device.supportsBoneTextures && modelData.skins.length > 0) { - var boneLimit = this._device.getBoneLimit(); - pc.partitionSkin(modelData, null, boneLimit) - } - for(i = 0;i < modelData.skins.length;i++) { - var skinData = modelData.skins[i]; - var inverseBindMatrices = []; - for(j = 0;j < skinData.inverseBindMatrices.length;j++) { - var ibm = skinData.inverseBindMatrices[j]; - inverseBindMatrices[j] = new pc.Mat4(ibm[0], ibm[1], ibm[2], ibm[3], ibm[4], ibm[5], ibm[6], ibm[7], ibm[8], ibm[9], ibm[10], ibm[11], ibm[12], ibm[13], ibm[14], ibm[15]) - } - var skin = new pc.Skin(this._device, inverseBindMatrices, skinData.boneNames); - skins.push(skin); - var skinInstance = new pc.SkinInstance(skin); - var bones = []; - for(j = 0;j < skin.boneNames.length;j++) { - var boneName = skin.boneNames[j]; - var bone = nodes[0].findByName(boneName); - bones.push(bone) - } - skinInstance.bones = bones; - skinInstances.push(skinInstance) - } - return{skins:skins, instances:skinInstances} - }, _parseVertexBuffers:function(data) { - var modelData = data.model; - var vertexBuffers = []; - var attribute, attributeName; - var attributeMap = {position:pc.SEMANTIC_POSITION, normal:pc.SEMANTIC_NORMAL, tangent:pc.SEMANTIC_TANGENT, blendWeight:pc.SEMANTIC_BLENDWEIGHT, blendIndices:pc.SEMANTIC_BLENDINDICES, color:pc.SEMANTIC_COLOR, texCoord0:pc.SEMANTIC_TEXCOORD0, texCoord1:pc.SEMANTIC_TEXCOORD1, texCoord2:pc.SEMANTIC_TEXCOORD2, texCoord3:pc.SEMANTIC_TEXCOORD3, texCoord4:pc.SEMANTIC_TEXCOORD4, texCoord5:pc.SEMANTIC_TEXCOORD5, texCoord6:pc.SEMANTIC_TEXCOORD6, texCoord7:pc.SEMANTIC_TEXCOORD7}; - var i, j; - for(i = 0;i < modelData.vertices.length;i++) { - var vertexData = modelData.vertices[i]; - if(vertexData.position && vertexData.normal && vertexData.texCoord0) { - var indices = []; - for(j = 0;j < modelData.meshes.length;j++) { - if(modelData.meshes[j].vertices === i) { - indices = indices.concat(modelData.meshes[j].indices) - } - } - tangents = pc.calculateTangents(vertexData.position.data, vertexData.normal.data, vertexData.texCoord0.data, indices); - vertexData.tangent = {type:"float32", components:4, data:tangents} - } - var formatDesc = []; - for(attributeName in vertexData) { - attribute = vertexData[attributeName]; - var attribType = attribute.type; - if(!this._device.supportsUnsignedByte) { - if(attribType === "uint8") { - attribType = "float32" - } - if(attribType === "int8") { - attribType = "float32" - } - } - formatDesc.push({semantic:attributeMap[attributeName], components:attribute.components, type:JSON_VERTEX_ELEMENT_TYPE[attribType], normalize:attributeMap[attributeName] === pc.SEMANTIC_COLOR}) - } - var vertexFormat = new pc.VertexFormat(this._device, formatDesc); - var numVertices = vertexData.position.data.length / vertexData.position.components; - var vertexBuffer = new pc.VertexBuffer(this._device, vertexFormat, numVertices); - var iterator = new pc.VertexIterator(vertexBuffer); - for(j = 0;j < numVertices;j++) { - for(attributeName in vertexData) { - attribute = vertexData[attributeName]; - switch(attribute.components) { - case 1: - iterator.element[attributeMap[attributeName]].set(attribute.data[j]); - break; - case 2: - iterator.element[attributeMap[attributeName]].set(attribute.data[j * 2], attribute.data[j * 2 + 1]); - break; - case 3: - iterator.element[attributeMap[attributeName]].set(attribute.data[j * 3], attribute.data[j * 3 + 1], attribute.data[j * 3 + 2]); - break; - case 4: - iterator.element[attributeMap[attributeName]].set(attribute.data[j * 4], attribute.data[j * 4 + 1], attribute.data[j * 4 + 2], attribute.data[j * 4 + 3]); - break - } - } - iterator.next() - } - iterator.end(); - vertexBuffers.push(vertexBuffer) - } - return vertexBuffers - }, _parseIndexBuffers:function(data) { - var modelData = data.model; - var indexBuffer = null; - var indexData = null; - var i; - var numIndices = 0; - for(i = 0;i < modelData.meshes.length;i++) { - var meshData = modelData.meshes[i]; - if(meshData.indices !== undefined) { - numIndices += meshData.indices.length - } - } - if(numIndices > 0) { - indexBuffer = new pc.IndexBuffer(this._device, pc.INDEXFORMAT_UINT16, numIndices); - indexData = new Uint16Array(indexBuffer.lock()) - } - return{buffer:indexBuffer, data:indexData} - }, _parseMeshes:function(data, skins, vertexBuffers, indexBuffer, indexData) { - var modelData = data.model; - var meshes = []; - var indexBase = 0; - var i; - for(i = 0;i < modelData.meshes.length;i++) { - var meshData = modelData.meshes[i]; - var meshAabb = meshData.aabb; - var min = meshAabb.min; - var max = meshAabb.max; - var aabb = new pc.shape.Aabb(new pc.Vec3((max[0] + min[0]) * 0.5, (max[1] + min[1]) * 0.5, (max[2] + min[2]) * 0.5), new pc.Vec3((max[0] - min[0]) * 0.5, (max[1] - min[1]) * 0.5, (max[2] - min[2]) * 0.5)); - var indexed = meshData.indices !== undefined; - var mesh = new pc.Mesh; - mesh.vertexBuffer = vertexBuffers[meshData.vertices]; - mesh.indexBuffer[0] = indexed ? indexBuffer : null; - mesh.primitive[0].type = JSON_PRIMITIVE_TYPE[meshData.type]; - mesh.primitive[0].base = indexed ? meshData.base + indexBase : meshData.base; - mesh.primitive[0].count = meshData.count; - mesh.primitive[0].indexed = indexed; - mesh.skin = meshData.skin !== undefined ? skins[meshData.skin] : null; - mesh.aabb = aabb; - if(indexed) { - indexData.set(meshData.indices, indexBase); - indexBase += meshData.indices.length - } - meshes.push(mesh) - } - if(indexBuffer !== null) { - indexBuffer.unlock() - } - return meshes - }, _parseMeshInstances:function(data, nodes, meshes, skins, skinInstances) { - var modelData = data.model; - var meshInstances = []; - var i; - for(i = 0;i < modelData.meshInstances.length;i++) { - var meshInstanceData = modelData.meshInstances[i]; - var node = nodes[meshInstanceData.node]; - var mesh = meshes[meshInstanceData.mesh]; - var meshInstance = new pc.MeshInstance(node, mesh, pc.ModelHandler.DEFAULT_MATERIAL); - if(mesh.skin) { - var skinIndex = skins.indexOf(mesh.skin); - if(skinIndex === -1) { - throw new Error("Mesh's skin does not appear in skin array."); - } - meshInstance.skinInstance = skinInstances[skinIndex] - } - meshInstances.push(meshInstance) - } - return meshInstances - }}; - return{JsonModelParser:JsonModelParser} -}()); -pc.extend(pc, function() { - var SceneParser = function(app) { - this._app = app - }; - SceneParser.prototype = {parse:function(data) { - var entities = {}; - var id, i; - var parent = null; - for(id in data["entities"]) { - entities[id] = this._createEntity(data["entities"][id]); - if(data["entities"][id].parent === null) { - parent = entities[id] - } - } - for(id in data["entities"]) { - var entity = entities[id]; - var l = data["entities"][id]["children"].length; - for(i = 0;i < l;i++) { - var resource_id = data["entities"][id]["children"][i]; - if(entities[resource_id]) { - entities[id].addChild(entities[resource_id]) - } - } - } - this._openComponentData(parent, data.entities); - return parent - }, _createEntity:function(data) { - var entity = new pc.Entity; - var p = data.position; - var r = data.rotation; - var s = data.scale; - entity.setName(data.name); - entity.setGuid(data.resource_id); - entity.setLocalPosition(p[0], p[1], p[2]); - entity.setLocalEulerAngles(r[0], r[1], r[2]); - entity.setLocalScale(s[0], s[1], s[2]); - entity._enabled = data.enabled !== undefined ? data.enabled : true; - entity._enabledInHierarchy = entity._enabled; - entity.template = data.template; - if(data.labels) { - data.labels.forEach(function(label) { - entity.addLabel(label) - }) - } - return entity - }, _openComponentData:function(entity, entities) { - var systems = this._app.systems.list(); - var i, len = systems.length; - var edata = entities[entity.getGuid()]; - for(i = 0;i < len;i++) { - var componentData = edata.components[systems[i].id]; - if(componentData) { - this._app.systems[systems[i].id].addComponent(entity, componentData) - } - } - var child, length = edata.children.length; - var children = entity.getChildren(); - for(i = 0;i < length;i++) { - children[i] = this._openComponentData(children[i], entities) - } - return entity - }}; - return{SceneParser:SceneParser} -}()); -pc.extend(pc, function() { - var assetIdCounter = -1; - var Asset = function(name, type, file, data) { - var file, data; - this._id = ++assetIdCounter; - this.name = arguments[0]; - this.type = arguments[1]; - this.preload = false; - this._file = arguments[2] ? {filename:file.filename, size:file.size, hash:file.hash, url:file.url} : null; - this._data = arguments[3] || {}; - this._resources = []; - this.loaded = false; - pc.events.attach(this) - }; - Asset.prototype = {getFileUrl:function() { - if(!this.file) { - return null - } - return this.file.url - }, ready:function(callback) { - if(this.resource) { - callback(this) - }else { - this.once("load", function(asset) { - callback(asset) - }) - } - }, unload:function() { - this.resource = null; - this.loaded = false - }}; - Object.defineProperty(Asset.prototype, "id", {get:function() { - return this._id - }, set:function(value) { - this._id = value; - if(value > assetIdCounter) { - assetIdCounter = value - } - }}); - Object.defineProperty(Asset.prototype, "file", {get:function() { - return this._file - }, set:function(value) { - var old = this._file; - this._file = value; - if(value && !old || !value && old || value && old && value.hash !== old.hash) { - this.fire("change", this, "file", value, old) - } - }}); - Object.defineProperty(Asset.prototype, "data", {get:function() { - return this._data - }, set:function(value) { - var old = this._data; - this._data = value; - if(value !== old) { - this.fire("change", this, "data", value, old) - } - }}); - Object.defineProperty(Asset.prototype, "resource", {get:function() { - return this._resources[0] - }, set:function(value) { - var _old = this._resources[0]; - this._resources[0] = value; - this.fire("change", this, "resource", value, _old) - }}); - Object.defineProperty(Asset.prototype, "resources", {get:function() { - return this._resources - }, set:function(value) { - var _old = this._resources; - this._resources = value; - this.fire("change", this, "resources", value, _old) - }}); - return{Asset:Asset, ASSET_ANIMATION:"animation", ASSET_AUDIO:"audio", ASSET_IMAGE:"image", ASSET_JSON:"json", ASSET_MODEL:"model", ASSET_MATERIAL:"material", ASSET_TEXT:"text", ASSET_TEXTURE:"texture", ASSET_CUBEMAP:"cubemap"} -}()); -pc.extend(pc, function() { - var AssetRegistry = function(loader) { - this._loader = loader; - this._assets = []; - this._cache = {}; - this._names = {}; - this._urls = {}; - pc.extend(this, pc.events) - }; - AssetRegistry.prototype = {list:function(filters) { - filters = filters || {}; - return this._assets.filter(function(asset) { - var include = true; - if(filters.preload !== undefined) { - include = asset.preload === filters.preload - } - return include - }) - }, add:function(asset) { - var index = this._assets.push(asset) - 1; - var url; - this._cache[asset.id] = index; - if(!this._names[asset.name]) { - this._names[asset.name] = [] - } - this._names[asset.name].push(index); - if(asset.file) { - url = asset.getFileUrl(); - this._urls[url] = index - } - this.fire("add", asset); - this.fire("add:" + asset.id, asset); - if(url) { - this.fire("add:url:" + url, asset) - } - }, remove:function(asset) { - delete this._cache[asset.id]; - delete this._names[asset.name]; - var url = asset.getFileUrl(); - if(url) { - delete this._urls[url] - } - asset.fire("remove", asset); - this.fire("remove", asset); - this.fire("remove:" + asset.id, asset); - if(url) { - this.fire("remove:url:" + url, asset) - } - }, get:function(id) { - var idx = this._cache[id]; - return this._assets[idx] - }, getByUrl:function(url) { - var idx = this._urls[url]; - return this._assets[idx] - }, _compatibleLoad:function(assets) { - var self = this; - console.warn("DEPRECATED: Loading arrays of assets is deprecated. Call assets.load with single assets."); - var promise = new pc.promise.Promise(function(resolve, reject) { - var count = assets.length; - assets.forEach(function(a, index) { - a.ready(function(asset) { - count--; - if(count === 0) { - var resources = assets.map(function(asset) { - return asset.resource - }); - resolve(resources) - } - }); - self.load(a) - }) - }); - return promise - }, load:function(asset) { - if(asset instanceof Array) { - return this._compatibleLoad(asset) - } - var self = this; - if(asset.loaded) { - return - } - var load = !!asset.file; - var open = !load; - if(asset.file && asset.type === "cubemap") { - load = false; - open = false; - this._loader.load(asset.file.url, "texture", function(err, texture) { - if(!err) { - self._loader.patch({resource:texture, type:"texture", data:asset.data}, self); - asset.data.dds = texture; - _open() - }else { - self.fire("error", err, asset); - self.fire("error:" + asset.id, err, asset); - asset.fire("error", err, asset); - return - } - }) - } - var _load = function() { - var url = asset.file.url; - if(asset.type === "texture") { - url += "?t=" + asset.file.hash - } - self._loader.load(url, asset.type, function(err, resource) { - if(err) { - self.fire("error", err, asset); - self.fire("error:" + asset.id, err, asset); - asset.fire("error", err, asset); - return - } - if(resource instanceof Array) { - asset.resources = resource - }else { - asset.resource = resource - } - asset.loaded = true; - self._loader.patch(asset, self); - self.fire("load", asset); - self.fire("load:" + asset.id, asset); - asset.fire("load", asset) - }) - }; - var _open = function() { - var resource = self._loader.open(asset.type, asset.data); - if(resource instanceof Array) { - asset.resources = resource - }else { - asset.resource = resource - } - asset.loaded = true; - self._loader.patch(asset, self); - self.fire("load", asset); - self.fire("load:" + asset.id, asset); - asset.fire("load", asset) - }; - if(!asset.file) { - _open() - }else { - if(load) { - _load() - } - } - }, loadFromUrl:function(url, type, callback) { - var self = this; - var name = pc.path.getBasename(url); - var file = {url:url}; - var data = {}; - var asset = self.getByUrl(url); - if(!asset) { - asset = new pc.Asset(name, type, file, data) - } - self.add(asset); - if(type === "model") { - self._loadModel(asset, callback); - return - } - asset.once("load", function(asset) { - callback(null, asset) - }); - asset.once("error", function(err) { - callback(err) - }); - self.load(asset) - }, _loadModel:function(asset, callback) { - var self = this; - var url = asset.getFileUrl(); - var dir = pc.path.getDirectory(url); - var basename = pc.path.getBasename(url); - var name = basename.replace(".json", ""); - var mappingUrl = pc.path.join(dir, basename.replace(".json", ".mapping.json")); - this._loader.load(mappingUrl, "json", function(err, data) { - if(err) { - callback(err); - return - } - self._loadMaterials(dir, data, function(err, materials) { - asset.data = data; - asset.once("load", function(asset) { - callback(null, asset) - }); - asset.once("error", function(err) { - callback(err) - }); - self.load(asset) - }) - }) - }, _loadMaterials:function(dir, mapping, callback) { - var self = this; - var i; - var count = mapping.mapping.length; - var materials = []; - for(i = 0;i < mapping.mapping.length;i++) { - var path = mapping.mapping[i].path; - if(path) { - self.loadFromUrl(pc.path.join(dir, path), "material", function(err, asset) { - materials.push(asset); - count--; - if(count === 0) { - done(null, materials) - } - }) - } - } - var done = function(err, materials) { - self._loadTextures(materials, function(err, textures) { - callback(null, materials) - }) - } - }, _loadTextures:function(materials, callback) { - var self = this; - var i, j; - var urls = []; - var textures = []; - var count = 0; - for(i = 0;i < materials.length;i++) { - var params = materials[i].data.parameters; - for(j = 0;j < params.length;j++) { - if(params[j].type === "texture") { - var dir = pc.path.getDirectory(materials[i].getFileUrl()); - var url = pc.path.join(dir, params[j].data); - urls.push(url); - count++ - } - } - } - for(i = 0;i < urls.length;i++) { - self.loadFromUrl(urls[i], "texture", function(err, texture) { - textures.push(texture); - count--; - if(count === 0) { - callback(null, textures) - } - }) - } - }, findAll:function(name, type) { - var self = this; - var idxs = this._names[name]; - var assets; - if(idxs) { - assets = idxs.map(function(idx) { - return self._assets[idx] - }); - if(type) { - return assets.filter(function(asset) { - return asset.type === type - }) - }else { - return assets - } - }else { - return[] - } - }, find:function(name, type) { - var asset = this.findAll(name, type); - return asset ? asset[0] : null - }, getAssetById:function(id) { - console.warn("DEPRECATED: getAssetById() use get() instead"); - return this.get(id) - }}; - return{AssetRegistry:AssetRegistry} -}()); -!function(a) { - var b, c; - !function() { - var a = {}, d = {}; - b = function(b, c, d) { - a[b] = {deps:c, callback:d} - }, c = function(b) { - function e(a) { - if("." !== a.charAt(0)) { - return a - } - for(var c = a.split("/"), d = b.split("/").slice(0, -1), e = 0, f = c.length;f > e;e++) { - var g = c[e]; - if(".." === g) { - d.pop() - }else { - if("." === g) { - continue - } - d.push(g) - } - } - return d.join("/") - } - if(d[b]) { - return d[b] - } - if(d[b] = {}, !a[b]) { - throw new Error("Could not find module " + b); - } - for(var f, g = a[b], h = g.deps, i = g.callback, j = [], k = 0, l = h.length;l > k;k++) { - j.push("exports" === h[k] ? f = {} : c(e(h[k]))) - } - var m = i.apply(this, j); - return d[b] = f || m - }, c.entries = a - }(), b("rsvp/all-settled", ["./promise", "./utils", "exports"], function(a, b, c) { - function d(a) { - return{state:"fulfilled", value:a} - } - function e(a) { - return{state:"rejected", reason:a} - } - var f = a["default"], g = b.isArray, h = b.isNonThenable; - c["default"] = function(a, b) { - return new f(function(b) { - function c(a) { - return function(b) { - j(a, d(b)) - } - } - function i(a) { - return function(b) { - j(a, e(b)) - } - } - function j(a, c) { - m[a] = c, 0 === --l && b(m) - } - if(!g(a)) { - throw new TypeError("You must pass an array to allSettled."); - } - var k, l = a.length; - if(0 === l) { - return void b([]) - } - for(var m = new Array(l), n = 0;n < a.length;n++) { - k = a[n], h(k) ? j(n, d(k)) : f.resolve(k).then(c(n), i(n)) - } - }, b) - } - }), b("rsvp/all", ["./promise", "exports"], function(a, b) { - var c = a["default"]; - b["default"] = function(a, b) { - return c.all(a, b) - } - }), b("rsvp/asap", ["exports"], function(a) { - function b() { - return function() { - process.nextTick(e) - } - } - function c() { - var a = 0, b = new h(e), c = document.createTextNode(""); - return b.observe(c, {characterData:!0}), function() { - c.data = a = ++a % 2 - } - } - function d() { - return function() { - setTimeout(e, 1) - } - } - function e() { - for(var a = 0;a < i.length;a++) { - var b = i[a], c = b[0], d = b[1]; - c(d) - } - i.length = 0 - } - a["default"] = function(a, b) { - var c = i.push([a, b]); - 1 === c && f() - }; - var f, g = "undefined" != typeof window ? window : {}, h = g.MutationObserver || g.WebKitMutationObserver, i = []; - f = "undefined" != typeof process && "[object process]" === {}.toString.call(process) ? b() : h ? c() : d() - }), b("rsvp/config", ["./events", "exports"], function(a, b) { - function c(a, b) { - return"onerror" === a ? void e.on("error", b) : 2 !== arguments.length ? e[a] : void(e[a] = b) - } - var d = a["default"], e = {instrument:!1}; - d.mixin(e), b.config = e, b.configure = c - }), b("rsvp/defer", ["./promise", "exports"], function(a, b) { - var c = a["default"]; - b["default"] = function(a) { - var b = {}; - return b.promise = new c(function(a, c) { - b.resolve = a, b.reject = c - }, a), b - } - }), b("rsvp/events", ["exports"], function(a) { - function b(a, b) { - for(var c = 0, d = a.length;d > c;c++) { - if(a[c] === b) { - return c - } - } - return-1 - } - function c(a) { - var b = a._promiseCallbacks; - return b || (b = a._promiseCallbacks = {}), b - } - a["default"] = {mixin:function(a) { - return a.on = this.on, a.off = this.off, a.trigger = this.trigger, a._promiseCallbacks = void 0, a - }, on:function(a, d) { - var e, f = c(this); - e = f[a], e || (e = f[a] = []), -1 === b(e, d) && e.push(d) - }, off:function(a, d) { - var e, f, g = c(this); - return d ? (e = g[a], f = b(e, d), void(-1 !== f && e.splice(f, 1))) : void(g[a] = []) - }, trigger:function(a, b) { - var d, e, f = c(this); - if(d = f[a]) { - for(var g = 0;g < d.length;g++) { - (e = d[g])(b) - } - } - }} - }), b("rsvp/filter", ["./promise", "./utils", "exports"], function(a, b, c) { - var d = a["default"], e = b.isFunction; - c["default"] = function(a, b, c) { - return d.all(a, c).then(function(a) { - if(!e(b)) { - throw new TypeError("You must pass a function as filter's second argument."); - } - for(var f = a.length, g = new Array(f), h = 0;f > h;h++) { - g[h] = b(a[h]) - } - return d.all(g, c).then(function(b) { - for(var c = new Array(f), d = 0, e = 0;f > e;e++) { - b[e] === !0 && (c[d] = a[e], d++) - } - return c.length = d, c - }) - }) - } - }), b("rsvp/hash-settled", ["./promise", "./utils", "exports"], function(a, b, c) { - function d(a) { - return{state:"fulfilled", value:a} - } - function e(a) { - return{state:"rejected", reason:a} - } - var f = a["default"], g = b.isNonThenable, h = b.keysOf; - c["default"] = function(a) { - return new f(function(b) { - function c(a) { - return function(b) { - j(a, d(b)) - } - } - function i(a) { - return function(b) { - j(a, e(b)) - } - } - function j(a, c) { - m[a] = c, 0 === --o && b(m) - } - var k, l, m = {}, n = h(a), o = n.length; - if(0 === o) { - return void b(m) - } - for(var p = 0;p < n.length;p++) { - l = n[p], k = a[l], g(k) ? j(l, d(k)) : f.resolve(k).then(c(l), i(l)) - } - }) - } - }), b("rsvp/hash", ["./promise", "./utils", "exports"], function(a, b, c) { - var d = a["default"], e = b.isNonThenable, f = b.keysOf; - c["default"] = function(a) { - return new d(function(b, c) { - function g(a) { - return function(c) { - k[a] = c, 0 === --m && b(k) - } - } - function h(a) { - m = 0, c(a) - } - var i, j, k = {}, l = f(a), m = l.length; - if(0 === m) { - return void b(k) - } - for(var n = 0;n < l.length;n++) { - j = l[n], i = a[j], e(i) ? (k[j] = i, 0 === --m && b(k)) : d.resolve(i).then(g(j), h) - } - }) - } - }), b("rsvp/instrument", ["./config", "./utils", "exports"], function(a, b, c) { - var d = a.config, e = b.now; - c["default"] = function(a, b, c) { - try { - d.trigger(a, {guid:b._guidKey + b._id, eventName:a, detail:b._detail, childGuid:c && b._guidKey + c._id, label:b._label, timeStamp:e(), stack:(new Error(b._label)).stack}) - }catch(f) { - setTimeout(function() { - throw f; - }, 0) - } - } - }), b("rsvp/map", ["./promise", "./utils", "exports"], function(a, b, c) { - var d = a["default"], e = (b.isArray, b.isFunction); - c["default"] = function(a, b, c) { - return d.all(a, c).then(function(a) { - if(!e(b)) { - throw new TypeError("You must pass a function as map's second argument."); - } - for(var f = a.length, g = new Array(f), h = 0;f > h;h++) { - g[h] = b(a[h]) - } - return d.all(g, c) - }) - } - }), b("rsvp/node", ["./promise", "./utils", "exports"], function(a, b, c) { - var d = a["default"], e = b.isArray; - c["default"] = function(a, b) { - function c() { - for(var c = arguments.length, e = new Array(c), h = 0;c > h;h++) { - e[h] = arguments[h] - } - var i; - return f || g || !b ? i = this : (console.warn('Deprecation: RSVP.denodeify() doesn\'t allow setting the "this" binding anymore. Use yourFunction.bind(yourThis) instead.'), i = b), d.all(e).then(function(c) { - function e(d, e) { - function h() { - for(var a = arguments.length, c = new Array(a), h = 0;a > h;h++) { - c[h] = arguments[h] - } - var i = c[0], j = c[1]; - if(i) { - e(i) - }else { - if(f) { - d(c.slice(1)) - }else { - if(g) { - var k, l, m = {}, n = c.slice(1); - for(l = 0;l < b.length;l++) { - k = b[l], m[k] = n[l] - } - d(m) - }else { - d(j) - } - } - } - } - c.push(h), a.apply(i, c) - } - return new d(e) - }) - } - var f = b === !0, g = e(b); - return c.__proto__ = a, c - } - }), b("rsvp/promise", ["./config", "./events", "./instrument", "./utils", "./promise/cast", "./promise/all", "./promise/race", "./promise/resolve", "./promise/reject", "exports"], function(a, b, c, d, e, f, g, h, i, j) { - function k() { - } - function l(a, b) { - if(!z(a)) { - throw new TypeError("You must pass a resolver function as the first argument to the promise constructor"); - } - if(!(this instanceof l)) { - throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); - } - this._id = H++, this._label = b, this._subscribers = [], w.instrument && x("created", this), k !== a && m(a, this) - } - function m(a, b) { - function c(a) { - r(b, a) - } - function d(a) { - t(b, a) - } - try { - a(c, d) - }catch(e) { - d(e) - } - } - function n(a, b, c, d) { - var e = a._subscribers, f = e.length; - e[f] = b, e[f + K] = c, e[f + L] = d - } - function o(a, b) { - var c, d, e = a._subscribers, f = a._detail; - w.instrument && x(b === K ? "fulfilled" : "rejected", a); - for(var g = 0;g < e.length;g += 3) { - c = e[g], d = e[g + b], p(b, c, d, f) - } - a._subscribers = null - } - function p(a, b, c, d) { - var e, f, g, h, i = z(c); - if(i) { - try { - e = c(d), g = !0 - }catch(j) { - h = !0, f = j - } - }else { - e = d, g = !0 - } - q(b, e) || (i && g ? r(b, e) : h ? t(b, f) : a === K ? r(b, e) : a === L && t(b, e)) - } - function q(a, b) { - var c, d = null; - try { - if(a === b) { - throw new TypeError("A promises callback cannot return that same promise."); - } - if(y(b) && (d = b.then, z(d))) { - return d.call(b, function(d) { - return c ? !0 : (c = !0, void(b !== d ? r(a, d) : s(a, d))) - }, function(b) { - return c ? !0 : (c = !0, void t(a, b)) - }, "Settle: " + (a._label || " unknown promise")), !0 - } - }catch(e) { - return c ? !0 : (t(a, e), !0) - } - return!1 - } - function r(a, b) { - a === b ? s(a, b) : q(a, b) || s(a, b) - } - function s(a, b) { - a._state === I && (a._state = J, a._detail = b, w.async(u, a)) - } - function t(a, b) { - a._state === I && (a._state = J, a._detail = b, w.async(v, a)) - } - function u(a) { - o(a, a._state = K) - } - function v(a) { - a._onerror && a._onerror(a._detail), o(a, a._state = L) - } - var w = a.config, x = (b["default"], c["default"]), y = d.objectOrFunction, z = d.isFunction, A = d.now, B = e["default"], C = f["default"], D = g["default"], E = h["default"], F = i["default"], G = "rsvp_" + A() + "-", H = 0; - j["default"] = l, l.cast = B, l.all = C, l.race = D, l.resolve = E, l.reject = F; - var I = void 0, J = 0, K = 1, L = 2; - l.prototype = {constructor:l, _id:void 0, _guidKey:G, _label:void 0, _state:void 0, _detail:void 0, _subscribers:void 0, _onerror:function(a) { - w.trigger("error", a) - }, then:function(a, b, c) { - var d = this; - this._onerror = null; - var e = new this.constructor(k, c); - if(this._state) { - var f = arguments; - w.async(function() { - p(d._state, e, f[d._state - 1], d._detail) - }) - }else { - n(this, e, a, b) - } - return w.instrument && x("chained", d, e), e - }, "catch":function(a, b) { - return this.then(null, a, b) - }, "finally":function(a, b) { - var c = this.constructor; - return this.then(function(b) { - return c.resolve(a()).then(function() { - return b - }) - }, function(b) { - return c.resolve(a()).then(function() { - throw b; - }) - }, b) - }} - }), b("rsvp/promise/all", ["../utils", "exports"], function(a, b) { - var c = a.isArray, d = a.isNonThenable; - b["default"] = function(a, b) { - var e = this; - return new e(function(b, f) { - function g(a) { - return function(c) { - k[a] = c, 0 === --j && b(k) - } - } - function h(a) { - j = 0, f(a) - } - if(!c(a)) { - throw new TypeError("You must pass an array to all."); - } - var i, j = a.length, k = new Array(j); - if(0 === j) { - return void b(k) - } - for(var l = 0;l < a.length;l++) { - i = a[l], d(i) ? (k[l] = i, 0 === --j && b(k)) : e.resolve(i).then(g(l), h) - } - }, b) - } - }), b("rsvp/promise/cast", ["exports"], function(a) { - a["default"] = function(a, b) { - var c = this; - return a && "object" == typeof a && a.constructor === c ? a : new c(function(b) { - b(a) - }, b) - } - }), b("rsvp/promise/race", ["../utils", "exports"], function(a, b) { - var c = a.isArray, d = (a.isFunction, a.isNonThenable); - b["default"] = function(a, b) { - var e, f = this; - return new f(function(b, g) { - function h(a) { - j && (j = !1, b(a)) - } - function i(a) { - j && (j = !1, g(a)) - } - if(!c(a)) { - throw new TypeError("You must pass an array to race."); - } - for(var j = !0, k = 0;k < a.length;k++) { - if(e = a[k], d(e)) { - return j = !1, void b(e) - } - f.resolve(e).then(h, i) - } - }, b) - } - }), b("rsvp/promise/reject", ["exports"], function(a) { - a["default"] = function(a, b) { - var c = this; - return new c(function(b, c) { - c(a) - }, b) - } - }), b("rsvp/promise/resolve", ["exports"], function(a) { - a["default"] = function(a, b) { - var c = this; - return a && "object" == typeof a && a.constructor === c ? a : new c(function(b) { - b(a) - }, b) - } - }), b("rsvp/race", ["./promise", "exports"], function(a, b) { - var c = a["default"]; - b["default"] = function(a, b) { - return c.race(a, b) - } - }), b("rsvp/reject", ["./promise", "exports"], function(a, b) { - var c = a["default"]; - b["default"] = function(a, b) { - return c.reject(a, b) - } - }), b("rsvp/resolve", ["./promise", "exports"], function(a, b) { - var c = a["default"]; - b["default"] = function(a, b) { - return c.resolve(a, b) - } - }), b("rsvp/rethrow", ["exports"], function(a) { - a["default"] = function(a) { - throw setTimeout(function() { - throw a; - }), a; - } - }), b("rsvp/utils", ["exports"], function(a) { - function b(a) { - return"function" == typeof a || "object" == typeof a && null !== a - } - function c(a) { - return"function" == typeof a - } - function d(a) { - return!b(a) - } - a.objectOrFunction = b, a.isFunction = c, a.isNonThenable = d; - var e; - e = Array.isArray ? Array.isArray : function(a) { - return"[object Array]" === Object.prototype.toString.call(a) - }; - var f = e; - a.isArray = f; - var g = Date.now || function() { - return(new Date).getTime() - }; - a.now = g; - var h = Object.keys || function(a) { - var b = []; - for(var c in a) { - b.push(c) - } - return b - }; - a.keysOf = h - }), b("rsvp", ["./rsvp/promise", "./rsvp/events", "./rsvp/node", "./rsvp/all", "./rsvp/all-settled", "./rsvp/race", "./rsvp/hash", "./rsvp/hash-settled", "./rsvp/rethrow", "./rsvp/defer", "./rsvp/config", "./rsvp/map", "./rsvp/resolve", "./rsvp/reject", "./rsvp/filter", "./rsvp/asap", "exports"], function(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) { - function r(a, b) { - E.async(a, b) - } - function s() { - E.on.apply(E, arguments) - } - function t() { - E.off.apply(E, arguments) - } - var u = a["default"], v = b["default"], w = c["default"], x = d["default"], y = e["default"], z = f["default"], A = g["default"], B = h["default"], C = i["default"], D = j["default"], E = k.config, F = k.configure, G = l["default"], H = m["default"], I = n["default"], J = o["default"], K = p["default"]; - if(E.async = K, "undefined" != typeof window && "object" == typeof window.__PROMISE_INSTRUMENTATION__) { - var L = window.__PROMISE_INSTRUMENTATION__; - F("instrument", !0); - for(var M in L) { - L.hasOwnProperty(M) && s(M, L[M]) - } - } - q.Promise = u, q.EventTarget = v, q.all = x, q.allSettled = y, q.race = z, q.hash = A, q.hashSettled = B, q.rethrow = C, q.defer = D, q.denodeify = w, q.configure = F, q.on = s, q.off = t, q.resolve = H, q.reject = I, q.async = r, q.map = G, q.filter = J - }), a.RSVP = c("rsvp") -}(window); -pc.promise = {Promise:window.RSVP.Promise, all:window.RSVP.all}; -pc.anim = {Animation:pc.Animation, Key:pc.Key, Node:pc.Node, Skeleton:pc.Skeleton}; -pc.audio = {AudioManager:pc.AudioManager, Channel:pc.Channel, Channel3d:pc.Channel3d, Listener:pc.Listener, Sound:pc.Sound}; -pc.fw = {Application:pc.Application, Component:pc.Component, ComponentData:pc.ComponentData, ComponentSystem:pc.ComponentSystem, ContentFile:pc.ContentFile, Entity:pc.Entity, FillMode:{NONE:pc.FILLMODE_NONE, FILL_WINDOW:pc.FILLMODE_FILL_WINDOW, KEEP_ASPECT:pc.FILLMODE_KEEP_ASPECT}, Pack:pc.Pack, ResolutionMode:{AUTO:pc.RESOLUTION_AUTO, FIXED:pc.RESOLUTION_FIXED}}; -pc.extend(pc.gfx, {drawQuadWithShader:pc.drawQuadWithShader, precalculatedTangents:pc.precalculatedTangents, programlib:pc.programlib, shaderChunks:pc.shaderChunks, ContextCreationError:pc.ContextCreationError, Device:pc.GraphicsDevice, IndexBuffer:pc.IndexBuffer, ProgramLibrary:pc.ProgramLibrary, RenderTarget:pc.RenderTarget, ScopeId:pc.ScopeId, Shader:pc.Shader, ShaderInput:pc.ShaderInput, Texture:pc.Texture, UnsupportedBrowserError:pc.UnsupportedBrowserError, VertexBuffer:pc.VertexBuffer, VertexFormat:pc.VertexFormat, -VertexIterator:pc.VertexIterator}); -pc.extend(pc.input, {getTouchTargetCoords:pc.getTouchTargetCoords, Controller:pc.Controller, GamePads:pc.GamePads, Keyboard:pc.Keyboard, KeyboardEvent:pc.KeyboardEvent, Mouse:pc.Mouse, MouseEvent:pc.MouseEvent, Touch:pc.Touch, TouchDevice:pc.TouchDevice, TouchEvent:pc.TouchEvent}); -pc.posteffect = {createFullscreenQuad:pc.createFullscreenQuad, drawFullscreenQuad:pc.drawFullscreenQuad, PostEffect:pc.PostEffect, PostEffectQueue:pc.PostEffectQueue}; -pc.extend(pc.scene, {partitionSkin:pc.partitionSkin, BasicMaterial:pc.BasicMaterial, DepthMaterial:pc.DepthMaterial, ForwardRenderer:pc.ForwardRenderer, GraphNode:pc.GraphNode, Material:pc.Material, Command:pc.Command, Mesh:pc.Mesh, MeshInstance:pc.MeshInstance, Model:pc.Model, ParticleEmitter:pc.ParticleEmitter, PhongMaterial:pc.PhongMaterial, Picker:pc.Picker, PickMaterial:pc.PickMaterial, Scene:pc.Scene, Skin:pc.Skin, SkinInstance:pc.SkinInstance}); -pc.scene.procedural = {calculateTangents:pc.calculateTangents, createMesh:pc.createMesh, createTorus:pc.createTorus, createCylinder:pc.createCylinder, createCapsule:pc.createCapsule, createCone:pc.createCone, createSphere:pc.createSphere, createPlane:pc.createPlane, createBox:pc.createBox}; -pc.scene.Projection = {ORTHOGRAPHIC:pc.PROJECTION_ORTHOGRAPHIC, PERSPECTIVE:pc.PROJECTION_PERSPECTIVE}; -pc.asset = {ASSET_ANIMATION:"animation", ASSET_AUDIO:"audio", ASSET_IMAGE:"image", ASSET_JSON:"json", ASSET_MODEL:"model", ASSET_MATERIAL:"material", ASSET_TEXT:"text", ASSET_TEXTURE:"texture", ASSET_CUBEMAP:"cubemap"}; -pc.time = {now:pc.now, Timer:pc.Timer}; -pc.extend(pc.Application.prototype, function() { - var lineVertexFormat = null; - var lineBatches = []; - var quadMesh = null; - var cubeLocalPos = null; - var cubeWorldPos = null; - var lineBatch = function() { - this.numLinesAllocated = 128; - this.vb = null; - this.vbRam = null; - this.mesh = null; - this.linesUsed = 0; - this.material = null; - this.meshInstance = null - }; - lineBatch.prototype = {init:function(device, linesToAdd) { - if(!this.mesh) { - this.mesh = new pc.Mesh; - this.mesh.primitive[0].type = pc.PRIMITIVE_LINES; - this.mesh.primitive[0].base = 0; - this.mesh.primitive[0].indexed = false; - this.material = new pc.BasicMaterial; - this.material.vertexColors = true; - this.material.blend = true; - this.material.blendType = pc.BLEND_NORMAL; - this.material.update() - } - while(this.linesUsed + linesToAdd > this.numLinesAllocated) { - this.vb = null; - this.numLinesAllocated *= 2 - } - if(!this.vb) { - this.vb = new pc.VertexBuffer(device, lineVertexFormat, this.numLinesAllocated * 2, pc.BUFFER_DYNAMIC); - this.mesh.vertexBuffer = this.vb; - this.vbRam = new DataView(this.vb.lock()); - if(!this.meshInstance) { - var node = {worldTransform:pc.Mat4.IDENTITY}; - this.meshInstance = new pc.MeshInstance(node, this.mesh, this.material) - } - } - }, addLines:function(position, color) { - var multiColor = !!color.length; - var offset = this.linesUsed * 2 * lineVertexFormat.size; - var clr; - for(var i = 0;i < position.length;i++) { - this.vbRam.setFloat32(offset, position[i].x, true); - offset += 4; - this.vbRam.setFloat32(offset, position[i].y, true); - offset += 4; - this.vbRam.setFloat32(offset, position[i].z, true); - offset += 4; - clr = multiColor ? color[i] : color; - this.vbRam.setUint8(offset, clr.r * 255); - offset += 1; - this.vbRam.setUint8(offset, clr.g * 255); - offset += 1; - this.vbRam.setUint8(offset, clr.b * 255); - offset += 1; - this.vbRam.setUint8(offset, clr.a * 255); - offset += 1 - } - this.linesUsed += position.length / 2 - }, finalize:function(drawCalls) { - if(this.linesUsed > 0) { - this.vb.setData(this.vbRam.buffer); - this.mesh.primitive[0].count = this.linesUsed * 2; - drawCalls.push(this.meshInstance); - this.linesUsed = 0 - } - }}; - function _addLines(batchId, position, color) { - if(!lineVertexFormat) { - lineVertexFormat = new pc.VertexFormat(this.graphicsDevice, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}, {semantic:pc.SEMANTIC_COLOR, components:4, type:pc.ELEMENTTYPE_UINT8, normalize:true}]); - this.on("preRender", this._preRenderImmediate, this) - } - if(!lineBatches[batchId]) { - lineBatches[batchId] = new lineBatch; - lineBatches[batchId].init(this.graphicsDevice, position.length / 2); - if(batchId === pc.LINEBATCH_OVERLAY) { - lineBatches[batchId].material.depthTest = false; - lineBatches[batchId].meshInstance.layer = pc.LAYER_GIZMO - }else { - if(batchId === pc.LINEBATCH_GIZMO) { - lineBatches[batchId].meshInstance.layer = pc.LAYER_GIZMO - } - } - }else { - lineBatches[batchId].init(this.graphicsDevice, position.length / 2) - } - lineBatches[batchId].addLines(position, color) - } - function renderLine(start, end, color, arg3, arg4) { - var endColor = color; - var lineType = pc.LINEBATCH_WORLD; - if(arg3) { - if(typeof arg3 === "number") { - lineType = arg3 - }else { - endColor = arg3; - if(arg4) { - lineType = arg4 - } - } - } - this._addLines(lineType, [start, end], [color, endColor]) - } - function renderLines(position, color, lineType) { - if(lineType === undefined) { - lineType = pc.LINEBATCH_WORLD - } - var multiColor = !!color.length; - if(multiColor) { - if(position.length !== color.length) { - pc.log.error("renderLines: position/color arrays have different lengths"); - return - } - } - if(position.length % 2 !== 0) { - pc.log.error("renderLines: array length is not divisible by 2"); - return - } - this._addLines(lineType, position, color) - } - function renderWireCube(matrix, color, lineType) { - if(lineType === undefined) { - lineType = pc.LINEBATCH_WORLD - } - var i; - if(!cubeLocalPos) { - var x = 0.5; - cubeLocalPos = [new pc.Vec3(-x, -x, -x), new pc.Vec3(-x, x, -x), new pc.Vec3(x, x, -x), new pc.Vec3(x, -x, -x), new pc.Vec3(-x, -x, x), new pc.Vec3(-x, x, x), new pc.Vec3(x, x, x), new pc.Vec3(x, -x, x)]; - cubeWorldPos = [new pc.Vec3, new pc.Vec3, new pc.Vec3, new pc.Vec3, new pc.Vec3, new pc.Vec3, new pc.Vec3, new pc.Vec3] - } - for(i = 0;i < 8;i++) { - matrix.transformPoint(cubeLocalPos[i], cubeWorldPos[i]) - } - this.renderLines([cubeWorldPos[0], cubeWorldPos[1], cubeWorldPos[1], cubeWorldPos[2], cubeWorldPos[2], cubeWorldPos[3], cubeWorldPos[3], cubeWorldPos[0], cubeWorldPos[4], cubeWorldPos[5], cubeWorldPos[5], cubeWorldPos[6], cubeWorldPos[6], cubeWorldPos[7], cubeWorldPos[7], cubeWorldPos[4], cubeWorldPos[0], cubeWorldPos[4], cubeWorldPos[1], cubeWorldPos[5], cubeWorldPos[2], cubeWorldPos[6], cubeWorldPos[3], cubeWorldPos[7]], color, lineType) - } - function _preRenderImmediate() { - for(var i = 0;i < 3;i++) { - if(lineBatches[i]) { - lineBatches[i].finalize(this.scene.immediateDrawCalls) - } - } - } - function renderMeshInstance(meshInstance) { - this.scene.immediateDrawCalls.push(meshInstance) - } - function renderMesh(mesh, material, matrix) { - var node = {worldTransform:matrix}; - var instance = new pc.MeshInstance(node, mesh, material); - this.scene.immediateDrawCalls.push(instance) - } - function renderQuad(matrix, material, layer) { - if(!quadMesh) { - var format = new pc.VertexFormat(this.graphicsDevice, [{semantic:pc.SEMANTIC_POSITION, components:3, type:pc.ELEMENTTYPE_FLOAT32}]); - quadVb = new pc.VertexBuffer(this.graphicsDevice, format, 4); - var iterator = new pc.VertexIterator(quadVb); - iterator.element[pc.SEMANTIC_POSITION].set(-0.5, -0.5, 0); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(0.5, -0.5, 0); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(-0.5, 0.5, 0); - iterator.next(); - iterator.element[pc.SEMANTIC_POSITION].set(0.5, 0.5, 0); - iterator.end(); - quadMesh = new pc.Mesh; - quadMesh.vertexBuffer = quadVb; - quadMesh.primitive[0].type = pc.PRIMITIVE_TRISTRIP; - quadMesh.primitive[0].base = 0; - quadMesh.primitive[0].count = 4; - quadMesh.primitive[0].indexed = false - } - var node = {worldTransform:matrix}; - var quad = new pc.MeshInstance(node, quadMesh, material); - if(layer) { - quad.layer = layer - } - this.scene.immediateDrawCalls.push(quad) - } - return{renderMeshInstance:renderMeshInstance, renderMesh:renderMesh, renderLine:renderLine, renderLines:renderLines, renderQuad:renderQuad, renderWireCube:renderWireCube, _addLines:_addLines, _preRenderImmediate:_preRenderImmediate} -}()); - diff --git a/package.json b/package.json deleted file mode 100644 index b26dc186498..00000000000 --- a/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "author": "PlayCanvas ", - "description": "PlayCanvas Engine", - "engines": { - "node": ">= 0.6.12" - }, - "files": [ - "build/output/playcanvas-latest.js" - ], - "homepage": "https://playcanvas.com", - "main": "build/output/playcanvas-latest.js", - "name": "playcanvas", - "repository": "https://github.com/playcanvas/engine", - "version": "0.169.0-dev" -} \ No newline at end of file diff --git a/src/graphics/programlib/chunks/generated_shaderchunks.js b/src/graphics/programlib/chunks/generated_shaderchunks.js deleted file mode 100644 index ee79986928e..00000000000 --- a/src/graphics/programlib/chunks/generated_shaderchunks.js +++ /dev/null @@ -1,149 +0,0 @@ -// autogenerated at: 2015-06-12 23:42 -pc.shaderChunks.ambientConstantPS = "\nvoid addAmbient(inout psInternalData data) {\n data.diffuseLight = light_globalAmbient;\n}\n" -pc.shaderChunks.ambientPrefilteredCubePS = "void addAmbient(inout psInternalData data) {\n vec3 fixedReflDir = fixSeamsStatic(data.normalW, 1.0 - 1.0 / 4.0);\n fixedReflDir.x *= -1.0;\n data.diffuseLight = processEnvironment($DECODE(textureCube(texture_prefilteredCubeMap4, fixedReflDir)).rgb);\n}\n\n" -pc.shaderChunks.ambientPrefilteredCubeLodPS = "void addAmbient(inout psInternalData data) {\n vec3 fixedReflDir = fixSeamsStatic(data.normalW, 1.0 - 1.0 / 4.0);\n fixedReflDir.x *= -1.0;\n data.diffuseLight = processEnvironment($DECODE( textureCubeLodEXT(texture_prefilteredCubeMap128, fixedReflDir, 5.0) ).rgb);\n}\n\n" -pc.shaderChunks.ambientSHPS = "uniform vec3 ambientSH[9];\nvoid addAmbient(inout psInternalData data) {\n vec3 n = data.normalW;\n\n data.diffuseLight =\n ambientSH[0] +\n ambientSH[1] * n.x +\n ambientSH[2] * n.y +\n ambientSH[3] * n.z +\n ambientSH[4] * n.x * n.z +\n ambientSH[5] * n.z * n.y +\n ambientSH[6] * n.y * n.x +\n ambientSH[7] * (3.0 * n.z * n.z - 1.0) +\n ambientSH[8] * (n.x * n.x - n.y * n.y);\n\n data.diffuseLight = processEnvironment(max(data.diffuseLight, vec3(0.0)));\n}\n\n" -pc.shaderChunks.aoSpecOccPS = "uniform float material_occludeSpecularIntensity;\nvoid occludeSpecular(inout psInternalData data) {\n // approximated specular occlusion from AO\n float specPow = exp2(data.glossiness * 11.0);\n // http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx\n float specOcc = saturate(pow(dot(data.normalW, data.viewDirW) + data.ao, 0.01*specPow) - 1.0 + data.ao);\n specOcc = mix(1.0, specOcc, material_occludeSpecularIntensity);\n\n data.specularLight *= specOcc;\n data.reflection *= specOcc;\n}\n\n" -pc.shaderChunks.aoSpecOccConstPS = "void occludeSpecular(inout psInternalData data) {\n // approximated specular occlusion from AO\n float specPow = exp2(data.glossiness * 11.0);\n // http://research.tri-ace.com/Data/cedec2011_RealtimePBR_Implementation_e.pptx\n float specOcc = saturate(pow(dot(data.normalW, data.viewDirW) + data.ao, 0.01*specPow) - 1.0 + data.ao);\n\n data.specularLight *= specOcc;\n data.reflection *= specOcc;\n}\n\n" -pc.shaderChunks.aoTexPS = "uniform sampler2D texture_aoMap;\nvoid applyAO(inout psInternalData data) {\n data.ao = texture2D(texture_aoMap, $UV).$CH;\n data.diffuseLight *= data.ao;\n}\n\n" -pc.shaderChunks.aoVertPS = "void applyAO(inout psInternalData data) {\n data.ao = saturate(vVertexColor.$CH);\n data.diffuseLight *= data.ao;\n}\n\n" -pc.shaderChunks.basePS = "\nuniform vec3 view_position;\n\nuniform vec3 light_globalAmbient;\n\nstruct psInternalData {\n vec3 albedo;\n vec3 specularity;\n float glossiness;\n vec3 emission;\n vec3 normalW;\n mat3 TBN;\n vec3 viewDirW;\n vec3 reflDirW;\n vec3 diffuseLight;\n vec3 specularLight;\n vec4 reflection;\n float alpha;\n vec3 lightDirNormW;\n vec3 lightDirW;\n vec3 lightPosW;\n float atten;\n vec3 shadowCoord;\n vec2 uvOffset;\n vec3 normalMap;\n float ao;\n};\n\nvoid getViewDir(inout psInternalData data) {\n data.viewDirW = normalize(view_position - vPositionW);\n}\n\nvoid getReflDir(inout psInternalData data) {\n data.reflDirW = normalize(-reflect(data.viewDirW, data.normalW));\n}\n\nvoid getLightDirPoint(inout psInternalData data, vec3 lightPosW) {\n data.lightDirW = vPositionW - lightPosW;\n data.lightDirNormW = normalize(data.lightDirW);\n data.lightPosW = lightPosW;\n}\n\nfloat getFalloffLinear(inout psInternalData data, float lightRadius) {\n float d = length(data.lightDirW);\n return max(((lightRadius - d) / lightRadius), 0.0);\n}\n\nfloat square(float x) {\n return x*x;\n}\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 saturate(vec3 x) {\n return clamp(x, vec3(0.0), vec3(1.0));\n}\n\nfloat getFalloffInvSquared(inout psInternalData data, float lightRadius) {\n float sqrDist = dot(data.lightDirW, data.lightDirW);\n float falloff = 1.0 / (sqrDist + 1.0);\n float invRadius = 1.0 / lightRadius;\n\n falloff *= 16.0;\n falloff *= square( saturate( 1.0 - square( sqrDist * square(invRadius) ) ) );\n\n return falloff;\n}\n\nfloat getSpotEffect(inout psInternalData data, vec3 lightSpotDirW, float lightInnerConeAngle, float lightOuterConeAngle) {\n float cosAngle = dot(data.lightDirNormW, lightSpotDirW);\n return smoothstep(lightOuterConeAngle, lightInnerConeAngle, cosAngle);\n}\n\nvoid processMetalness(inout psInternalData data, float metalness) {\n const float dielectricF0 = 0.04;\n data.specularity = mix(vec3(dielectricF0), data.albedo, metalness);\n data.albedo *= 1.0 - metalness;\n}\n\n" -pc.shaderChunks.baseVS = "\nattribute vec3 vertex_position;\nattribute vec3 vertex_normal;\nattribute vec4 vertex_tangent;\nattribute vec2 vertex_texCoord0;\nattribute vec2 vertex_texCoord1;\nattribute vec4 vertex_color;\n\nuniform mat4 matrix_viewProjection;\nuniform mat4 matrix_model;\nuniform mat3 matrix_normal;\n\nstruct vsInternalData {\n vec3 positionW;\n mat4 modelMatrix;\n mat3 normalMatrix;\n vec3 lightPosW;\n vec3 lightDirNormW;\n vec3 normalW;\n};\n\n" -pc.shaderChunks.combineDiffusePS = "vec3 combineColor(inout psInternalData data) {\n return data.albedo * data.diffuseLight;\n}\n\n" -pc.shaderChunks.combineDiffuseSpecularPS = "vec3 combineColor(inout psInternalData data) {\n return mix(data.albedo * data.diffuseLight, data.specularLight + data.reflection.rgb * data.reflection.a, data.specularity);\n}\n\n" -pc.shaderChunks.combineDiffuseSpecularNoConservePS = "vec3 combineColor(inout psInternalData data) {\n return data.albedo * data.diffuseLight + (data.specularLight + data.reflection.rgb * data.reflection.a) * data.specularity;\n}\n\n" -pc.shaderChunks.combineDiffuseSpecularNoReflPS = "vec3 combineColor(inout psInternalData data) {\n return data.albedo * data.diffuseLight + data.specularLight * data.specularity;\n}\n\n" -pc.shaderChunks.combineDiffuseSpecularNoReflSeparateAmbientPS = "uniform vec3 material_ambient;\nvec3 combineColor(inout psInternalData data) {\n return (data.diffuseLight - light_globalAmbient) * data.albedo + data.specularLight * data.specularity + material_ambient * light_globalAmbient;\n}\n\n" -pc.shaderChunks.combineDiffuseSpecularOldPS = "vec3 combineColor(inout psInternalData data) {\n return mix(data.albedo * data.diffuseLight + data.specularLight * data.specularity, data.reflection.rgb, data.reflection.a);\n}\n\n" -pc.shaderChunks.cubeMapProjectBoxPS = "uniform vec3 envBoxMin, envBoxMax;\n\nvec3 cubeMapProject(vec3 nrdir) {\n vec3 rbmax = (envBoxMax - vPositionW) / nrdir;\n vec3 rbmin = (envBoxMin - vPositionW) / nrdir;\n\n vec3 rbminmax;\n rbminmax.x = nrdir.x>0.0? rbmax.x : rbmin.x;\n rbminmax.y = nrdir.y>0.0? rbmax.y : rbmin.y;\n rbminmax.z = nrdir.z>0.0? rbmax.z : rbmin.z;\n\n float fa = min(min(rbminmax.x, rbminmax.y), rbminmax.z);\n\n vec3 posonbox = vPositionW + nrdir * fa;\n vec3 envBoxPos = (envBoxMin + envBoxMax) * 0.5;\n return posonbox - envBoxPos;\n}\n\n" -pc.shaderChunks.cubeMapProjectNonePS = "vec3 cubeMapProject(vec3 dir) {\n return dir;\n}\n\n" -pc.shaderChunks.diffuseConstPS = "uniform vec3 material_diffuse;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = material_diffuse.rgb;\n}\n\n" -pc.shaderChunks.diffuseTexPS = "uniform sampler2D texture_diffuseMap;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = texture2DSRGB(texture_diffuseMap, $UV).$CH;\n}\n\n" -pc.shaderChunks.diffuseTexConstPS = "uniform sampler2D texture_diffuseMap;\nuniform vec3 material_diffuse;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = texture2DSRGB(texture_diffuseMap, $UV).$CH * material_diffuse;\n}\n\n" -pc.shaderChunks.diffuseVertPS = "void getAlbedo(inout psInternalData data) {\n data.albedo = gammaCorrectInput(saturate(vVertexColor.$CH));\n}\n\n" -pc.shaderChunks.diffuseVertConstPS = "uniform vec3 material_diffuse;\nvoid getAlbedo(inout psInternalData data) {\n data.albedo = gammaCorrectInput(saturate(vVertexColor.$CH)) * material_diffuse;\n}\n\n" -pc.shaderChunks.dpAtlasQuadPS = "varying vec2 vUv0;\nuniform sampler2D source;\nuniform vec4 params;\n\nvoid main(void) {\n vec2 uv = vUv0;\n uv = uv * 2.0 - vec2(1.0);\n uv *= params.xy;\n uv = uv * 0.5 + 0.5;\n gl_FragColor = texture2D(source, uv);\n}\n" -pc.shaderChunks.emissiveConstPS = "uniform vec3 material_emissive;\nvec3 getEmission(inout psInternalData data) {\n return material_emissive;\n}\n\n" -pc.shaderChunks.emissiveTexPS = "uniform sampler2D texture_emissiveMap;\nvec3 getEmission(inout psInternalData data) {\n return $texture2DSAMPLE(texture_emissiveMap, $UV).$CH;\n}\n\n" -pc.shaderChunks.emissiveTexConstPS = "uniform sampler2D texture_emissiveMap;\nuniform vec3 material_emissive;\nvec3 getEmission(inout psInternalData data) {\n return $texture2DSAMPLE(texture_emissiveMap, $UV).$CH * material_emissive;\n}\n\n" -pc.shaderChunks.emissiveVertPS = "vec3 getEmission(inout psInternalData data) {\n return gammaCorrectInput(saturate(vVertexColor.$CH));\n}\n\n" -pc.shaderChunks.emissiveVertConstPS = "uniform vec3 material_emissive;\nvec3 getEmission(inout psInternalData data) {\n return gammaCorrectInput(saturate(vVertexColor.$CH)) * material_emissive;\n}\n\n" -pc.shaderChunks.endPS = " gl_FragColor.rgb = combineColor(data);\n gl_FragColor.rgb += getEmission(data);\n gl_FragColor.rgb = addFog(data, gl_FragColor.rgb);\n gl_FragColor.rgb = toneMap(gl_FragColor.rgb);\n gl_FragColor.rgb = gammaCorrectOutput(gl_FragColor.rgb);\n" -pc.shaderChunks.envConstPS = "vec3 processEnvironment(vec3 color) {\n return color;\n}\n\n" -pc.shaderChunks.envMultiplyPS = "uniform float skyboxIntensity;\nvec3 processEnvironment(vec3 color) {\n return color * skyboxIntensity;\n}\n\n" -pc.shaderChunks.fixCubemapSeamsNonePS = "vec3 fixSeams(vec3 vec, float mipmapIndex) {\n return vec;\n}\n\nvec3 fixSeams(vec3 vec) {\n return vec;\n}\n\nvec3 fixSeamsStatic(vec3 vec, float invRecMipSize) {\n return vec;\n}\n" -pc.shaderChunks.fixCubemapSeamsStretchPS = "vec3 fixSeams(vec3 vec, float mipmapIndex) {\n float scale = 1.0 - exp2(mipmapIndex) / 128.0;\n float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));\n if (abs(vec.x) != M) vec.x *= scale;\n if (abs(vec.y) != M) vec.y *= scale;\n if (abs(vec.z) != M) vec.z *= scale;\n return vec;\n}\n\nvec3 fixSeams(vec3 vec) {\n float scale = 1.0 - 1.0 / 128.0;\n float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));\n if (abs(vec.x) != M) vec.x *= scale;\n if (abs(vec.y) != M) vec.y *= scale;\n if (abs(vec.z) != M) vec.z *= scale;\n return vec;\n}\n\nvec3 fixSeamsStatic(vec3 vec, float invRecMipSize) {\n float scale = invRecMipSize;\n float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));\n if (abs(vec.x) != M) vec.x *= scale;\n if (abs(vec.y) != M) vec.y *= scale;\n if (abs(vec.z) != M) vec.z *= scale;\n return vec;\n}\n\n" -pc.shaderChunks.fogExpPS = "uniform vec3 fog_color;\nuniform float fog_density;\nvec3 addFog(inout psInternalData data, vec3 color) {\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n float fogFactor = exp(-depth * fog_density);\n fogFactor = clamp(fogFactor, 0.0, 1.0);\n return mix(fog_color, color, fogFactor);\n}\n" -pc.shaderChunks.fogExp2PS = "uniform vec3 fog_color;\nuniform float fog_density;\nvec3 addFog(inout psInternalData data, vec3 color) {\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n float fogFactor = exp(-depth * depth * fog_density * fog_density);\n fogFactor = clamp(fogFactor, 0.0, 1.0);\n return mix(fog_color, color, fogFactor);\n}\n" -pc.shaderChunks.fogLinearPS = "uniform vec3 fog_color;\nuniform float fog_start;\nuniform float fog_end;\nvec3 addFog(inout psInternalData data, vec3 color) {\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n float fogFactor = (fog_end - depth) / (fog_end - fog_start);\n fogFactor = clamp(fogFactor, 0.0, 1.0);\n fogFactor = gammaCorrectInput(fogFactor);\n return mix(fog_color, color, fogFactor);\n}\n" -pc.shaderChunks.fogNonePS = "vec3 addFog(inout psInternalData data, vec3 color) {\n return color;\n}\n\n\n" -pc.shaderChunks.fresnelComplexPS = "// More physically-based Fresnel\nuniform float material_fresnelFactor; // should be IOR\nvoid getFresnel(inout psInternalData data) {\n float cosThetaI = max(dot(data.normalW, data.viewDirW), 0.0);\n float n = material_fresnelFactor;\n\n float cosThetaT = sqrt(max(0.0, 1.0 - (1.0 - cosThetaI * cosThetaI) / (n * n)));\n float nCosThetaT = n * cosThetaT;\n float nCosThetaI = n * cosThetaI;\n\n float rS = abs((cosThetaI - nCosThetaT) / (cosThetaI + nCosThetaT));\n float rP = abs((cosThetaT - nCosThetaI) / (cosThetaT + nCosThetaI));\n rS *= rS;\n rP *= rP;\n\n data.specularity *= (rS + rP) / 2.0;\n}\n\n" -pc.shaderChunks.fresnelSchlickPS = "// Schlick's approximation\nuniform float material_fresnelFactor; // unused\nvoid getFresnel(inout psInternalData data) {\n float fresnel = 1.0 - max(dot(data.normalW, data.viewDirW), 0.0);\n float fresnel2 = fresnel * fresnel;\n fresnel *= fresnel2 * fresnel2;\n fresnel *= data.glossiness * data.glossiness;\n data.specularity = data.specularity + (1.0 - data.specularity) * fresnel;\n}\n\n" -pc.shaderChunks.fresnelSimplePS = "// Easily tweakable but not very correct Fresnel\nuniform float material_fresnelFactor;\nvoid getFresnel(inout psInternalData data) {\n float fresnel = 1.0 - max(dot(data.normalW, data.viewDirW), 0.0);\n data.specularity *= pow(fresnel, material_fresnelFactor);\n}\n\n" -pc.shaderChunks.fullscreenQuadPS = "varying vec2 vUv0;\nuniform sampler2D source;\n\nvoid main(void) {\n gl_FragColor = texture2D(source, vUv0);\n}\n" -pc.shaderChunks.fullscreenQuadVS = "attribute vec2 aPosition;\n\nvarying vec2 vUv0;\n\nvoid main(void)\n{\n gl_Position = vec4(aPosition, 0.5, 1.0);\n vUv0 = aPosition.xy*0.5+0.5;\n}\n\n" -pc.shaderChunks.gamma1_0PS = "vec4 texture2DSRGB(sampler2D tex, vec2 uv) {\n return texture2D(tex, uv);\n}\n\nvec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {\n return textureCube(tex, uvw);\n}\n\nvec3 gammaCorrectOutput(vec3 color) {\n return color;\n}\n\nvec3 gammaCorrectInput(vec3 color) {\n return color;\n}\n\nfloat gammaCorrectInput(float color) {\n return color;\n}\n\nvec4 gammaCorrectInput(vec4 color) {\n return color;\n}\n\n" -pc.shaderChunks.gamma2_2PS = "vec3 gammaCorrectInput(vec3 color) {\n return pow(color, vec3(2.2));\n}\n\nfloat gammaCorrectInput(float color) {\n return pow(color, 2.2);\n}\n\nvec4 gammaCorrectInput(vec4 color) {\n return vec4(pow(color.rgb, vec3(2.2)), color.a);\n}\n\nvec4 texture2DSRGB(sampler2D tex, vec2 uv) {\n vec4 rgba = texture2D(tex, uv);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {\n vec4 rgba = textureCube(tex, uvw);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec3 gammaCorrectOutput(vec3 color) {\n color += vec3(0.0000001);\n return pow(color, vec3(0.45));\n}\n\n" -pc.shaderChunks.gamma2_2FastPS = "vec3 gammaCorrectInput(vec3 color) {\n return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878);\n}\n\nfloat gammaCorrectInput(float color) {\n return color * (color * (color * 0.305306011 + 0.682171111) + 0.012522878);\n}\n\nvec4 gammaCorrectInput(vec4 color) {\n return vec4(gammaCorrectInput(color.rgb), color.a);\n}\n\nvec4 texture2DSRGB(sampler2D tex, vec2 uv) {\n vec4 rgba = texture2D(tex, uv);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {\n vec4 rgba = textureCube(tex, uvw);\n rgba.rgb = gammaCorrectInput(rgba.rgb);\n return rgba;\n}\n\nvec3 gammaCorrectOutput(vec3 color) {\n color += vec3(0.0000001);\n return pow(color, vec3(0.45));\n}\n\n" -pc.shaderChunks.genParaboloidPS = "varying vec2 vUv0;\n\nuniform samplerCube source;\nuniform vec4 params; // x = mip\n\nvoid main(void) {\n\n vec2 uv = vUv0;\n\n float side = uv.x < 0.5? 1.0 : -1.0;\n vec2 tc;\n tc.x = fract(uv.x * 2.0) * 2.0 - 1.0;\n tc.y = uv.y * 2.0 - 1.0;\n\n // scale projection a bit to have a little overlap for filtering\n const float scale = 1.1;\n tc *= scale;\n\n vec3 dir;\n dir.y = (dot(tc, tc) - 1.0) * side; // from 1.0 center to 0.0 borders quadratically\n dir.xz = tc * -2.0;\n\n dir.x *= -side; // flip original cubemap x instead of doing it at runtime\n\n dir = fixSeams(dir, params.x);\n\n vec4 color = textureCube(source, dir, -100.0);\n gl_FragColor = color;\n}\n" -pc.shaderChunks.glossConstPS = "uniform float material_shininess;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = material_shininess;\n}\n\n" -pc.shaderChunks.glossTexPS = "uniform sampler2D texture_glossMap;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = texture2D(texture_glossMap, $UV).$CH;\n}\n\n" -pc.shaderChunks.glossTexConstPS = "uniform sampler2D texture_glossMap;\nuniform float material_shininess;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = material_shininess * texture2D(texture_glossMap, $UV).$CH;\n}\n\n" -pc.shaderChunks.glossVertPS = "void getGlossiness(inout psInternalData data) {\n data.glossiness = saturate(vVertexColor.$CH);\n}\n\n" -pc.shaderChunks.glossVertConstPS = "uniform float material_shininess;\nvoid getGlossiness(inout psInternalData data) {\n data.glossiness = material_shininess * saturate(vVertexColor.$CH);\n}\n\n" -pc.shaderChunks.instancingVS = "\nattribute vec4 instance_line1;\nattribute vec4 instance_line2;\nattribute vec4 instance_line3;\nattribute vec4 instance_line4;\n\n" -pc.shaderChunks.lightDiffuseLambertPS = "float getLightDiffuse(inout psInternalData data) {\n return max(dot(data.normalW, -data.lightDirNormW), 0.0);\n}\n\n" -pc.shaderChunks.lightmapSinglePS = "uniform sampler2D texture_lightMap;\nvoid addAmbient(inout psInternalData data) {\n data.diffuseLight = $texture2DSAMPLE(texture_lightMap, $UV).$CH;\n}\n\n" -pc.shaderChunks.lightmapSingleVertPS = "void addAmbient(inout psInternalData data) {\n data.diffuseLight = saturate(vVertexColor.$CH);\n}\n\n" -pc.shaderChunks.lightSpecularBlinnPS = "// Energy-conserving (hopefully) Blinn-Phong\nfloat getLightSpecular(inout psInternalData data) {\n vec3 h = normalize( -data.lightDirNormW + data.viewDirW );\n float nh = max( dot( h, data.normalW ), 0.0 );\n\n float specPow = exp2(data.glossiness * 11.0); // glossiness is linear, power is not; 0 - 2048\n specPow = antiAliasGlossiness(data, specPow);\n\n // Hack: On Mac OS X, calling pow with zero for the exponent generates hideous artifacts so bias up a little\n specPow = max(specPow, 0.0001);\n\n return pow(nh, specPow) * (specPow + 2.0) / 8.0;\n}\n\n" -pc.shaderChunks.lightSpecularPhongPS = "float getLightSpecular(inout psInternalData data) {\n float specPow = data.glossiness;\n\n specPow = antiAliasGlossiness(data, specPow);\n\n // Hack: On Mac OS X, calling pow with zero for the exponent generates hideous artifacts so bias up a little\n return pow(max(dot(data.reflDirW, -data.lightDirNormW), 0.0), specPow + 0.0001);\n}\n\n" -pc.shaderChunks.metalnessConstPS = "uniform float material_metalness;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, material_metalness);\n}\n\n" -pc.shaderChunks.metalnessTexPS = "uniform sampler2D texture_metalnessMap;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, texture2D(texture_metalnessMap, $UV).$CH);\n}\n\n" -pc.shaderChunks.metalnessTexConstPS = "uniform sampler2D texture_metalnessMap;\nuniform float material_metalness;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, texture2D(texture_metalnessMap, $UV).$CH * material_metalness);\n}\n\n" -pc.shaderChunks.metalnessVertPS = "void getSpecularity(inout psInternalData data) {\n processMetalness(data, saturate(vVertexColor.$CH));\n}\n\n" -pc.shaderChunks.metalnessVertConstPS = "uniform float material_metalness;\nvoid getSpecularity(inout psInternalData data) {\n processMetalness(data, saturate(vVertexColor.$CH) * material_metalness);\n}\n\n" -pc.shaderChunks.normalVS = "vec3 getNormal(inout vsInternalData data) {\n data.normalMatrix = matrix_normal;\n return normalize(data.normalMatrix * vertex_normal);\n}\n\n" -pc.shaderChunks.normalInstancedVS = "vec3 getNormal(inout vsInternalData data) {\n data.normalMatrix = mat3(instance_line1.xyz, instance_line2.xyz, instance_line3.xyz);\n return normalize(data.normalMatrix * vertex_normal);\n}\n\n" -pc.shaderChunks.normalMapPS = "uniform sampler2D texture_normalMap;\nuniform float material_bumpMapFactor;\nvoid getNormal(inout psInternalData data) {\n vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));\n data.normalMap = normalMap;\n data.normalW = data.TBN * normalMap;\n}\n\n" -pc.shaderChunks.normalMapFloatPS = "uniform sampler2D texture_normalMap;\nuniform float material_bumpMapFactor;\nvoid getNormal(inout psInternalData data) {\n vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));\n data.normalMap = normalMap;\n normalMap = normalize(mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpMapFactor));\n data.normalW = data.TBN * normalMap;\n}\n\n" -pc.shaderChunks.normalMapFloatTBNfastPS = "uniform sampler2D texture_normalMap;\nuniform float material_bumpMapFactor;\nvoid getNormal(inout psInternalData data) {\n vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV));\n data.normalMap = normalMap;\n normalMap = mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpMapFactor);\n data.normalW = normalize(data.TBN * normalMap);\n}\n\n" -pc.shaderChunks.normalSkinnedVS = "vec3 getNormal(inout vsInternalData data) {\n data.normalMatrix = mat3(data.modelMatrix[0].xyz, data.modelMatrix[1].xyz, data.modelMatrix[2].xyz);\n return normalize(data.normalMatrix * vertex_normal);\n}\n\n" -pc.shaderChunks.normalVertexPS = "void getNormal(inout psInternalData data) {\n data.normalW = normalize(vNormalW);\n}\n\n" -pc.shaderChunks.normalXYPS = "vec3 unpackNormal(vec4 nmap) {\n vec3 normal;\n normal.xy = nmap.wy * 2.0 - 1.0;\n normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));\n return normal;\n}\n\n" -pc.shaderChunks.normalXYZPS = "vec3 unpackNormal(vec4 nmap) {\n return nmap.xyz * 2.0 - 1.0;\n}\n\n" -pc.shaderChunks.opacityConstPS = "uniform float material_opacity;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = material_opacity;\n}\n\n" -pc.shaderChunks.opacityTexPS = "uniform sampler2D texture_opacityMap;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = texture2D(texture_opacityMap, $UV).$CH;\n}\n\n" -pc.shaderChunks.opacityTexConstPS = "uniform sampler2D texture_opacityMap;\nuniform float material_opacity;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = texture2D(texture_opacityMap, $UV).$CH * material_opacity;\n}\n\n" -pc.shaderChunks.opacityVertPS = "void getOpacity(inout psInternalData data) {\n data.alpha = saturate(vVertexColor.$CH);\n}\n\n" -pc.shaderChunks.opacityVertConstPS = "uniform float material_opacity;\nvoid getOpacity(inout psInternalData data) {\n data.alpha = saturate(vVertexColor.$CH) * material_opacity;\n}\n\n" -pc.shaderChunks.outputCubemapPS = "varying vec2 vUv0;\n\nuniform samplerCube source;\nuniform vec4 params;\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec4 encodeRGBM(vec4 color) { // modified RGBM\n color.rgb = pow(color.rgb, vec3(0.5));\n color.rgb *= 1.0 / 8.0;\n\n color.a = saturate( max( max( color.r, color.g ), max( color.b, 1.0 / 255.0 ) ) );\n color.a = ceil(color.a * 255.0) / 255.0;\n\n color.rgb /= color.a;\n return color;\n}\n\nvoid main(void) {\n\n vec2 st = vUv0 * 2.0 - 1.0;\n float face = params.x;\n\n vec3 vec;\n if (face==0.0) {\n vec = vec3(1, -st.y, -st.x);\n } else if (face==1.0) {\n vec = vec3(-1, -st.y, st.x);\n } else if (face==2.0) {\n vec = vec3(st.x, 1, st.y);\n } else if (face==3.0) {\n vec = vec3(st.x, -1, -st.y);\n } else if (face==4.0) {\n vec = vec3(st.x, -st.y, 1);\n } else {\n vec = vec3(-st.x, -st.y, -1);\n }\n\n gl_FragColor = textureCube(source, vec);\n if (params.w >= 2.0) gl_FragColor = encodeRGBM(gl_FragColor);\n}\n\n" -pc.shaderChunks.packDepthPS = "// Packing a float in GLSL with multiplication and mod\n// http://blog.gradientstudios.com/2012/08/23/shadow-map-improvement\nvec4 packFloat(float depth) {\n const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\n\n // combination of mod and multiplication and division works better\n vec4 res = mod(depth * bit_shift * vec4(255), vec4(256) ) / vec4(255);\n res -= res.xxyz * bit_mask;\n return res;\n}\n\n\n" -pc.shaderChunks.packDepthMaskPS = "vec4 packFloat(float depth) {\n const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);\n\n // combination of mod and multiplication and division works better\n vec4 res = mod(depth * bit_shift * vec4(255), vec4(256) ) / vec4(255);\n res.x = 0.0;\n res -= res.xxyz * bit_mask;\n return res;\n}\n\n" -pc.shaderChunks.parallaxPS = "uniform sampler2D texture_heightMap;\nuniform float material_heightMapFactor;\nvoid getParallax(inout psInternalData data) {\n float parallaxScale = material_heightMapFactor;\n const float parallaxBias = 0.01;\n\n float height = texture2D(texture_heightMap, $UV).$CH * parallaxScale - parallaxBias;\n vec3 viewDirT = data.viewDirW * data.TBN;\n\n data.uvOffset = min(height * viewDirT.xy, vec2(parallaxBias));\n}\n\n" -pc.shaderChunks.particlePS = "varying vec4 texCoordsAlphaLife;\n\nuniform sampler2D colorMap;\nuniform sampler2D internalTex3;\nuniform float graphSampleSize;\nuniform float graphNumSamples;\nuniform vec4 screenSize;\nuniform float camera_far;\nuniform float softening;\nuniform float colorMult;\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat unpackFloat(vec4 rgbaDepth) {\n const vec4 bitShift = vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0);\n float depth = dot(rgbaDepth, bitShift);\n return depth;\n}\n\nvoid main(void) {\n psInternalData data;\n vec4 tex = texture2DSRGB(colorMap, texCoordsAlphaLife.xy);\n vec4 ramp = texture2DSRGB(internalTex3, vec2(texCoordsAlphaLife.w, 0.0));\n ramp.rgb *= colorMult;\n\n ramp.a += texCoordsAlphaLife.z;\n\n vec3 rgb = tex.rgb * ramp.rgb;\n float a = tex.a * ramp.a;\n\n" -pc.shaderChunks.particleVS = "attribute vec4 particle_vertexData; // XYZ = particle position, W = particle ID + random factor\n\nuniform mat4 matrix_viewProjection;\nuniform mat4 matrix_model;\nuniform mat3 matrix_normal;\nuniform mat4 matrix_viewInverse;\nuniform mat4 matrix_view;\n\nuniform float numParticles, numParticlesPot;\nuniform float graphSampleSize;\nuniform float graphNumSamples;\nuniform float stretch;\nuniform vec3 wrapBounds;\nuniform vec3 emitterScale;\nuniform float rate, rateDiv, lifetime, deltaRandomnessStatic, scaleDivMult, alphaDivMult, seed;\nuniform sampler2D particleTexOUT, particleTexIN;\nuniform sampler2D internalTex0;\nuniform sampler2D internalTex1;\nuniform sampler2D internalTex2;\n\nvarying vec4 texCoordsAlphaLife;\n\nvec3 unpack3NFloats(float src) {\n float r = fract(src);\n float g = fract(src * 256.0);\n float b = fract(src * 65536.0);\n return vec3(r, g, b);\n}\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec4 tex1Dlod_lerp(sampler2D tex, vec2 tc) {\n return mix( texture2D(tex,tc), texture2D(tex,tc + graphSampleSize), fract(tc.x*graphNumSamples) );\n}\n\nvec4 tex1Dlod_lerp(sampler2D tex, vec2 tc, out vec3 w) {\n vec4 a = texture2D(tex,tc);\n vec4 b = texture2D(tex,tc + graphSampleSize);\n float c = fract(tc.x*graphNumSamples);\n\n vec3 unpackedA = unpack3NFloats(a.w);\n vec3 unpackedB = unpack3NFloats(b.w);\n w = mix(unpackedA, unpackedB, c);\n\n return mix(a, b, c);\n}\n\n\nvec2 rotate(vec2 quadXY, float pRotation, out mat2 rotMatrix) {\n float c = cos(pRotation);\n float s = sin(pRotation);\n\n mat2 m = mat2(c, -s, s, c);\n rotMatrix = m;\n\n return m * quadXY;\n}\n\nvec3 billboard(vec3 InstanceCoords, vec2 quadXY, out mat3 localMat) {\n vec3 viewUp = matrix_viewInverse[1].xyz;\n vec3 posCam = matrix_viewInverse[3].xyz;\n\n mat3 billMat;\n billMat[2] = normalize(InstanceCoords - posCam);\n billMat[0] = normalize(cross(viewUp, billMat[2]));\n billMat[1] = -viewUp;\n vec3 pos = billMat * vec3(quadXY, 0);\n\n localMat = billMat;\n\n return pos;\n}\n\nvoid main(void) {\n vec3 meshLocalPos = particle_vertexData.xyz;\n float id = floor(particle_vertexData.w);\n\n float rndFactor = fract(sin(id + 1.0 + seed));\n vec3 rndFactor3 = vec3(rndFactor, fract(rndFactor*10.0), fract(rndFactor*100.0));\n\n vec4 particleTex = texture2D(particleTexOUT, vec2(id / numParticlesPot, 0.125));\n vec3 pos = particleTex.xyz;\n float angle = (particleTex.w < 0.0? -particleTex.w : particleTex.w) - 1000.0;\n bool hide = particleTex.w < 0.0;\n\n vec4 particleTex2 = texture2D(particleTexOUT, vec2(id / numParticlesPot, 0.375));\n vec3 particleVelocity = particleTex2.xyz;\n vec2 velocityV = normalize((mat3(matrix_view) * particleVelocity).xy); // should be removed by compiler if align/stretch is not used\n float life = particleTex2.w;\n\n float particleLifetime = lifetime;\n\n if (life <= 0.0 || life > particleLifetime || hide) meshLocalPos = vec3(0.0);\n vec2 quadXY = meshLocalPos.xy;\n float nlife = clamp(life / particleLifetime, 0.0, 1.0);\n\n vec3 paramDiv;\n vec4 params = tex1Dlod_lerp(internalTex2, vec2(nlife, 0), paramDiv);\n float scale = params.y;\n float scaleDiv = paramDiv.x;\n float alphaDiv = paramDiv.z;\n\n scale += (scaleDiv * 2.0 - 1.0) * scaleDivMult * fract(rndFactor*10000.0);\n\n texCoordsAlphaLife = vec4(quadXY * -0.5 + 0.5, (alphaDiv * 2.0 - 1.0) * alphaDivMult * fract(rndFactor*1000.0), nlife);\n\n vec3 particlePos = pos;\n vec3 particlePosMoved = vec3(0.0);\n\n mat2 rotMatrix;\n mat3 localMat;\n\n\n" -pc.shaderChunks.particleUpdaterAABBPS = "uniform mat3 spawnBounds;\nvec3 calcSpawnPosition(vec3 inBounds, float rndFactor) {\n return emitterPos + spawnBounds * (inBounds - vec3(0.5));\n}\n\nvoid addInitialVelocity(inout vec3 localVelocity, vec3 inBounds) {\n localVelocity -= vec3(0, 0, initialVelocity);\n}\n\n" -pc.shaderChunks.particleUpdaterEndPS = "\n tex = vec4(outPosition, (outRotation + 1000.0) * visMode) * outMask0 +\n vec4(outVelocity, life) * outMask1 +\n texR * outMask2;\n\n gl_FragColor = tex;\n}\n\n" -pc.shaderChunks.particleUpdaterInitPS = "varying vec2 vUv0;\n\nuniform sampler2D particleTexIN;\nuniform sampler2D internalTex0;\nuniform sampler2D internalTex1;\nuniform sampler2D internalTex2;\n\nuniform mat3 emitterMatrix;\nuniform vec3 emitterScale;\n\nuniform vec3 emitterPos, frameRandom, localVelocityDivMult, velocityDivMult;\nuniform float delta, rate, rateDiv, lifetime, numParticles, rotSpeedDivMult, seed;\nuniform float startAngle, startAngle2;\nuniform float initialVelocity;\n\nuniform float graphSampleSize;\nuniform float graphNumSamples;\n\n" -pc.shaderChunks.particleUpdaterNoRespawnPS = " if (life >= particleLifetime) {\n life -= max(particleLifetime, (numParticles - 1.0) * particleRate);\n visMode = -1.0;\n }\n" -pc.shaderChunks.particleUpdaterOnStopPS = " visMode = life < 0.0? -1.0: visMode;\n\n" -pc.shaderChunks.particleUpdaterRespawnPS = " if (life >= particleLifetime) {\n life -= max(particleLifetime, (numParticles - 1.0) * particleRate);\n visMode = 1.0;\n }\n visMode = life < 0.0? 1.0: visMode;\n\n" -pc.shaderChunks.particleUpdaterSpherePS = "uniform float spawnBoundsSphere;\nvec3 calcSpawnPosition(vec3 inBounds, float rndFactor) {\n float rnd4 = fract(rndFactor * 1000.0);\n return emitterPos + normalize(inBounds.xyz - vec3(0.5)) * rnd4 * spawnBoundsSphere;\n}\n\nvoid addInitialVelocity(inout vec3 localVelocity, vec3 inBounds) {\n localVelocity += normalize(inBounds - vec3(0.5)) * initialVelocity;\n}\n\n" -pc.shaderChunks.particleUpdaterStartPS = "float saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 unpack3NFloats(float src) {\n float r = fract(src);\n float g = fract(src * 256.0);\n float b = fract(src * 65536.0);\n return vec3(r, g, b);\n}\n\nvec3 tex1Dlod_lerp(sampler2D tex, vec2 tc, out vec3 w) {\n vec4 a = texture2D(tex, tc);\n vec4 b = texture2D(tex, tc + graphSampleSize);\n float c = fract(tc.x * graphNumSamples);\n\n vec3 unpackedA = unpack3NFloats(a.w);\n vec3 unpackedB = unpack3NFloats(b.w);\n w = mix(unpackedA, unpackedB, c);\n\n return mix(a.xyz, b.xyz, c);\n}\n\nvoid main(void)\n{\n if (gl_FragCoord.x > numParticles) discard;\n float outMask0 = gl_FragCoord.y < 1.0? 1.0 : 0.0;\n float outMask1 = (gl_FragCoord.y < 2.0 && gl_FragCoord.y >= 1.0)? 1.0 : 0.0;\n float outMask2 = (gl_FragCoord.y < 3.0 && gl_FragCoord.y >= 2.0)? 1.0 : 0.0;\n\n vec4 tex = texture2D(particleTexIN, vec2(vUv0.x, 0.125));\n vec4 tex2 = texture2D(particleTexIN, vec2(vUv0.x, 0.375));\n vec4 texR = texture2D(particleTexIN, vec2(vUv0.x, 0.625));\n\n vec4 rndFactor = texR;\n float particleLifetime = lifetime;\n float life = tex2.w + delta;\n float particleRate = rate + rateDiv * rndFactor.x;\n\n float nlife = clamp(life / particleLifetime, 0.0, 1.0);\n vec3 localVelocityDiv;\n vec3 velocityDiv;\n vec3 paramDiv;\n vec3 localVelocity = tex1Dlod_lerp(internalTex0, vec2(nlife, 0), localVelocityDiv);\n vec3 velocity = tex1Dlod_lerp(internalTex1, vec2(nlife, 0), velocityDiv);\n vec3 params = tex1Dlod_lerp(internalTex2, vec2(nlife, 0), paramDiv);\n float rotSpeed = params.x;\n float rotSpeedDiv = paramDiv.y;\n float angle = (tex.w < 0.0? -tex.w : tex.w) - 1000.0;\n float visMode = tex.w < 0.0? -1.0 : 1.0;\n\n localVelocity += (localVelocityDiv * vec3(2.0) - vec3(1.0)) * localVelocityDivMult * rndFactor.xyz;\n velocity += (velocityDiv * vec3(2.0) - vec3(1.0)) * velocityDivMult * rndFactor.zxy;\n rotSpeed += (rotSpeedDiv * 2.0 - 1.0) * rotSpeedDivMult * rndFactor.y;\n\n addInitialVelocity(localVelocity, rndFactor.xyz);\n\n vec3 outVelocity = emitterMatrix * localVelocity.xyz + velocity.xyz * emitterScale;\n vec3 outPosition = tex.xyz + outVelocity * delta;\n float outRotation = angle + rotSpeed * delta;\n\n bool respawn = life <= 0.0 || life >= particleLifetime;\n outPosition = respawn? calcSpawnPosition(rndFactor.xyz, rndFactor.x) : outPosition;\n outRotation = respawn? mix(startAngle, startAngle2, rndFactor.x) : outRotation;\n outVelocity = respawn? vec3(0.0) : outVelocity;\n" -pc.shaderChunks.particle_billboardVS = "\n quadXY = rotate(quadXY, angle, rotMatrix);\n vec3 localPos = billboard(particlePos, quadXY, localMat);\n\n" -pc.shaderChunks.particle_blendAddPS = "\n rgb *= gammaCorrectInput(a);\n if ((rgb.r + rgb.g + rgb.b) < 0.000001) discard;\n\n" -pc.shaderChunks.particle_blendMultiplyPS = "\n rgb = mix(vec3(1.0), rgb, vec3(a));\n if (rgb.r + rgb.g + rgb.b > 2.99) discard;\n\n" -pc.shaderChunks.particle_blendNormalPS = "\n if (a < 0.01) discard;\n" -pc.shaderChunks.particle_cpuVS = "attribute vec4 particle_vertexData; // XYZ = world pos, W = life\nattribute vec4 particle_vertexData2; // X = angle, Y = scale, Z = alpha, W = velocity.x\nattribute vec4 particle_vertexData3; // XYZ = particle local pos, W = velocity.y\nattribute vec2 particle_vertexData4; // X = velocity.z, W = particle ID\n\nuniform mat4 matrix_viewProjection;\nuniform mat4 matrix_model;\nuniform mat4 matrix_view;\nuniform mat3 matrix_normal;\nuniform mat4 matrix_viewInverse;\n\nuniform float numParticles;\nuniform float lifetime;\nuniform float stretch;\n//uniform float graphSampleSize;\n//uniform float graphNumSamples;\nuniform vec3 wrapBounds, emitterScale;\nuniform sampler2D texLifeAndSourcePosOUT;\nuniform sampler2D internalTex0;\nuniform sampler2D internalTex1;\nuniform sampler2D internalTex2;\n\nvarying vec4 texCoordsAlphaLife;\n\n\nvec2 rotate(vec2 quadXY, float pRotation, out mat2 rotMatrix)\n{\n float c = cos(pRotation);\n float s = sin(pRotation);\n //vec4 rotationMatrix = vec4(c, -s, s, c);\n\n mat2 m = mat2(c, -s, s, c);\n rotMatrix = m;\n\n return m * quadXY;\n}\n\nvec3 billboard(vec3 InstanceCoords, vec2 quadXY, out mat3 localMat)\n{\n vec3 viewUp = matrix_viewInverse[1].xyz;\n vec3 posCam = matrix_viewInverse[3].xyz;\n\n mat3 billMat;\n billMat[2] = normalize(InstanceCoords - posCam);\n billMat[0] = normalize(cross(viewUp, billMat[2]));\n billMat[1] = -viewUp;\n vec3 pos = billMat * vec3(quadXY, 0);\n\n localMat = billMat;\n\n return pos;\n}\n\n\nvoid main(void)\n{\n vec3 particlePos = particle_vertexData.xyz;\n vec3 pos = particlePos;\n vec3 vertPos = particle_vertexData3.xyz;\n vec3 particleVelocity = vec3(particle_vertexData2.w, particle_vertexData3.w, particle_vertexData4.x);\n vec2 velocityV = normalize((mat3(matrix_view) * particleVelocity).xy); // should be removed by compiler if align/stretch is not used\n\n vec2 quadXY = vertPos.xy;\n texCoordsAlphaLife = vec4(quadXY * -0.5 + 0.5, particle_vertexData2.z, particle_vertexData.w);\n\n mat2 rotMatrix;\n mat3 localMat;\n\n float angle = particle_vertexData2.x;\n vec3 particlePosMoved = vec3(0.0);\n vec3 meshLocalPos = particle_vertexData3.xyz;\n\n" -pc.shaderChunks.particle_cpu_endVS = "\n localPos *= particle_vertexData2.y * emitterScale;\n localPos += particlePos;\n\n gl_Position = matrix_viewProjection * vec4(localPos, 1.0);\n}\n\n" -pc.shaderChunks.particle_endPS = " rgb = addFog(data, rgb);\n rgb = toneMap(rgb);\n rgb = gammaCorrectOutput(rgb);\n gl_FragColor = vec4(rgb, a);\n}\n" -pc.shaderChunks.particle_endVS = "\n localPos *= scale * emitterScale;\n localPos += particlePos;\n\n gl_Position = matrix_viewProjection * vec4(localPos.xyz, 1.0);\n}\n" -pc.shaderChunks.particle_halflambertPS = "\n vec3 negNormal = normal*0.5+0.5;\n vec3 posNormal = -normal*0.5+0.5;\n negNormal *= negNormal;\n posNormal *= posNormal;\n\n\n" -pc.shaderChunks.particle_lambertPS = "\n vec3 negNormal = max(normal, vec3(0.0));\n vec3 posNormal = max(-normal, vec3(0.0));\n\n\n" -pc.shaderChunks.particle_lightingPS = "\n vec3 light = negNormal.x*lightCube[0] + posNormal.x*lightCube[1] +\n negNormal.y*lightCube[2] + posNormal.y*lightCube[3] +\n negNormal.z*lightCube[4] + posNormal.z*lightCube[5];\n\n\n rgb *= light;\n\n\n" -pc.shaderChunks.particle_meshVS = "\n vec3 localPos = meshLocalPos;\n localPos.xy = rotate(localPos.xy, angle, rotMatrix);\n localPos.yz = rotate(localPos.yz, angle, rotMatrix);\n\n billboard(particlePos, quadXY, localMat);\n\n\n" -pc.shaderChunks.particle_normalVS = "\n Normal = normalize(localPos - localMat[2]);\n\n\n" -pc.shaderChunks.particle_normalMapPS = "\n vec3 normalMap = normalize( texture2D(normalMap, texCoordsAlphaLife.xy).xyz * 2.0 - 1.0 );\n vec3 normal = ParticleMat * normalMap;\n\n\n\n\n" -pc.shaderChunks.particle_pointAlongVS = " angle = atan(velocityV.x, velocityV.y); // not the fastest way, but easier to plug in; TODO: create rot matrix right from vectors\n\n" -pc.shaderChunks.particle_softPS = "\n vec2 screenTC = gl_FragCoord.xy / screenSize.xy;\n float depth = unpackFloat( texture2D(uDepthMap, screenTC) ) * camera_far;\n float particleDepth = gl_FragCoord.z / gl_FragCoord.w;\n float depthDiff = saturate(abs(particleDepth - depth) * softening);\n a *= depthDiff;\n\n" -pc.shaderChunks.particle_stretchVS = " vec3 moveDir = particleVelocity * stretch;\n vec3 posPrev = pos - moveDir;\n posPrev += particlePosMoved;\n\n vec2 centerToVertexV = normalize((mat3(matrix_view) * localPos).xy);\n\n float interpolation = dot(-velocityV, centerToVertexV) * 0.5 + 0.5;\n\n particlePos = mix(particlePos, posPrev, interpolation);\n\n" -pc.shaderChunks.particle_TBNVS = "\n mat3 rot3 = mat3(rotMatrix[0][0], rotMatrix[0][1], 0.0, rotMatrix[1][0], rotMatrix[1][1], 0.0, 0.0, 0.0, 1.0);\n localMat[2] *= -1.0;\n ParticleMat = localMat * rot3;\n\n\n\n\n" -pc.shaderChunks.particle_wrapVS = "\n vec3 origParticlePos = particlePos;\n particlePos -= matrix_model[3].xyz;\n particlePos = mod(particlePos, wrapBounds) - wrapBounds * 0.5;\n particlePos += matrix_model[3].xyz;\n particlePosMoved = particlePos - origParticlePos;\n\n\n" -pc.shaderChunks.prefilterCubemapPS = "varying vec2 vUv0;\n\nuniform samplerCube source;\nuniform vec4 params;\n\nfloat saturate(float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nfloat rnd(vec2 uv) {\n return fract(sin(dot(uv, vec2(12.9898, 78.233) * 2.0)) * 43758.5453);\n}\n\nconst float PI = 3.14159265358979;\nvec3 hemisphereSample_cos(vec2 uv, mat3 vecSpace, vec3 cubeDir, float gloss) { // cos + lerped cone size (better than just lerped)\n float phi = uv.y * 2.0 * PI;\n float cosTheta = sqrt(1.0 - uv.x);\n float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);\n return normalize(mix(vecSpace * sampleDir, cubeDir, params.y));\n}\n\nvec3 hemisphereSample_phong(vec2 uv, mat3 vecSpace, vec3 cubeDir, float specPow) {\n float phi = uv.y * 2.0 * PI;\n float cosTheta = pow(1.0 - uv.x, 1.0 / (specPow + 1.0));\n float sinTheta = sqrt(1.0 - cosTheta * cosTheta);\n vec3 sampleDir = vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);\n return vecSpace * sampleDir;\n}\n\nmat3 matrixFromVector(vec3 n) { // frisvad\n float a = 1.0 / (1.0 + n.z);\n float b = -n.x * n.y * a;\n vec3 b1 = vec3(1.0 - n.x * n.x * a, b, -n.x);\n vec3 b2 = vec3(b, 1.0 - n.y * n.y * a, -n.y);\n return mat3(b1, b2, n);\n}\n\nvec4 encodeRGBM(vec4 color) { // modified RGBM\n color.rgb = pow(color.rgb, vec3(0.5));\n color.rgb *= 1.0 / 8.0;\n\n color.a = saturate( max( max( color.r, color.g ), max( color.b, 1.0 / 255.0 ) ) );\n color.a = ceil(color.a * 255.0) / 255.0;\n\n color.rgb /= color.a;\n return color;\n}\n\nvoid main(void) {\n\n vec2 st = vUv0 * 2.0 - 1.0;\n\n if (params.w==1.0 || params.w==3.0) {\n st = 2.0 * floor(gl_FragCoord.xy) / (params.z - 1.0) - 1.0;\n }\n\n float face = params.x;\n\n vec3 vec;\n if (face==0.0) {\n vec = vec3(1, -st.y, -st.x);\n } else if (face==1.0) {\n vec = vec3(-1, -st.y, st.x);\n } else if (face==2.0) {\n vec = vec3(st.x, 1, st.y);\n } else if (face==3.0) {\n vec = vec3(st.x, -1, -st.y);\n } else if (face==4.0) {\n vec = vec3(st.x, -st.y, 1);\n } else {\n vec = vec3(-st.x, -st.y, -1);\n }\n\n mat3 vecSpace = matrixFromVector(normalize(vec));\n\n vec4 color = vec4(0.0);\n const int samples = $NUMSAMPLES;\n vec3 vect;\n for(int i=0; i