Spaces:
Running
Running
| (function () { | |
| // Shared Lib | |
| var CANVAS_ID = 'application-canvas'; | |
| // Needed as we will have edge cases for particular versions of iOS | |
| // returns null if not iOS | |
| var getIosVersion = function () { | |
| if (/iP(hone|od|ad)/.test(navigator.platform)) { | |
| var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/); | |
| var version = [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; | |
| return version; | |
| } | |
| return null; | |
| }; | |
| var lastWindowHeight = window.innerHeight; | |
| var lastWindowWidth = window.innerWidth; | |
| var windowSizeChangeIntervalHandler = null; | |
| var pcBootstrap = { | |
| reflowHandler: null, | |
| iosVersion: getIosVersion(), | |
| createCanvas: function () { | |
| var canvas = document.createElement('canvas'); | |
| canvas.setAttribute('id', CANVAS_ID); | |
| canvas.setAttribute('tabindex', 0); | |
| // Disable I-bar cursor on click+drag | |
| canvas.onselectstart = function () { return false; }; | |
| // Disable long-touch select on iOS devices | |
| canvas.style['-webkit-user-select'] = 'none'; | |
| document.body.appendChild(canvas); | |
| return canvas; | |
| }, | |
| resizeCanvas: function (app, canvas) { | |
| canvas.style.width = ''; | |
| canvas.style.height = ''; | |
| app.resizeCanvas(canvas.width, canvas.height); | |
| var fillMode = app._fillMode; | |
| if (fillMode === pc.FILLMODE_NONE || fillMode === pc.FILLMODE_KEEP_ASPECT) { | |
| if ((fillMode === pc.FILLMODE_NONE && canvas.clientHeight < window.innerHeight) || (canvas.clientWidth / canvas.clientHeight >= window.innerWidth / window.innerHeight)) { | |
| canvas.style.marginTop = Math.floor((window.innerHeight - canvas.clientHeight) / 2) + 'px'; | |
| } else { | |
| canvas.style.marginTop = ''; | |
| } | |
| } | |
| lastWindowHeight = window.innerHeight; | |
| lastWindowWidth = window.innerWidth; | |
| // Work around when in landscape to work on iOS 12 otherwise | |
| // the content is under the URL bar at the top | |
| if (this.iosVersion && this.iosVersion[0] <= 12) { | |
| window.scrollTo(0, 0); | |
| } | |
| }, | |
| reflow: function (app, canvas) { | |
| this.resizeCanvas(app, canvas); | |
| // Poll for size changes as the window inner height can change after the resize event for iOS | |
| // Have one tab only, and rotate from portrait -> landscape -> portrait | |
| if (windowSizeChangeIntervalHandler === null) { | |
| windowSizeChangeIntervalHandler = setInterval(function () { | |
| if (lastWindowHeight !== window.innerHeight || lastWindowWidth !== window.innerWidth) { | |
| this.resizeCanvas(app, canvas); | |
| } | |
| }.bind(this), 100); | |
| // Don't want to do this all the time so stop polling after some short time | |
| setTimeout(function () { | |
| if (!!windowSizeChangeIntervalHandler) { | |
| clearInterval(windowSizeChangeIntervalHandler); | |
| windowSizeChangeIntervalHandler = null; | |
| } | |
| }, 2000); | |
| } | |
| } | |
| }; | |
| // Expose the reflow to users so that they can override the existing | |
| // reflow logic if need be | |
| window.pcBootstrap = pcBootstrap; | |
| })(); | |
| (function () { | |
| // template varants | |
| var LTC_MAT_1 = []; | |
| var LTC_MAT_2 = []; | |
| // varants | |
| var canvas = pcBootstrap.createCanvas(); | |
| var app = new pc.AppBase(canvas); | |
| function initCSS() { | |
| if (document.head.querySelector) { | |
| // css media query for aspect ratio changes | |
| // TODO: Change these from private properties | |
| var css = `@media screen and (min-aspect-ratio: ${app._width}/${app._height}) { | |
| #application-canvas.fill-mode-KEEP_ASPECT { | |
| width: auto; | |
| height: 100%; | |
| margin: 0 auto; | |
| } | |
| }`; | |
| document.head.querySelector('style').innerHTML += css; | |
| } | |
| // Configure resolution and resize event | |
| if (canvas.classList) { | |
| canvas.classList.add(`fill-mode-${app.fillMode}`); | |
| } | |
| } | |
| function displayError(html) { | |
| var div = document.createElement('div'); | |
| div.innerHTML = `<table style="background-color: #8CE; width: 100%; height: 100%;"> | |
| <tr> | |
| <td align="center"> | |
| <div style="display: table-cell; vertical-align: middle;"> | |
| <div style="">${html}</div> | |
| </div> | |
| </td> | |
| </tr> | |
| </table>`; | |
| document.body.appendChild(div); | |
| } | |
| function createGraphicsDevice(callback) { | |
| var deviceOptions = window.CONTEXT_OPTIONS ? window.CONTEXT_OPTIONS : {}; | |
| if (typeof window.Promise === 'function') { | |
| var LEGACY_WEBGL = 'webgl'; | |
| var deviceTypes = [...deviceOptions.deviceTypes, LEGACY_WEBGL]; | |
| var gpuLibPath = window.ASSET_PREFIX ? (window.ASSET_PREFIX.replace(/\/$/g, '') + '/') : ''; | |
| // new graphics device creation function with promises | |
| var gfxOptions = { | |
| deviceTypes: deviceTypes, | |
| glslangUrl: gpuLibPath + 'glslang.js', | |
| twgslUrl: gpuLibPath + 'twgsl.js', | |
| powerPreference: deviceOptions.powerPreference, | |
| antialias: deviceOptions.antialias !== false, | |
| alpha: deviceOptions.alpha === true, | |
| preserveDrawingBuffer: !!deviceOptions.preserveDrawingBuffer | |
| }; | |
| pc.createGraphicsDevice(canvas, gfxOptions).then((device) => { | |
| callback(device); | |
| }).catch((e) => { | |
| console.error('Device creation error:', e); | |
| callback(null); | |
| }) | |
| } else { | |
| var igl1 = deviceOptions.deviceTypes.indexOf('webgl1'); | |
| var igl2 = deviceOptions.deviceTypes.indexOf('webgl2'); | |
| // old webgl graphics device creation | |
| var options = { | |
| powerPreference: deviceOptions.powerPreference, | |
| antialias: deviceOptions.antialias !== false, | |
| alpha: deviceOptions.transparentCanvas !== false, | |
| preserveDrawingBuffer: !!deviceOptions.preserveDrawingBuffer, | |
| preferWebGl2: igl2 > igl1 | |
| }; | |
| if (pc.platform.browser && !!navigator.xr) { | |
| options.xrCompatible = true; | |
| } | |
| callback(new pc.WebglGraphicsDevice(canvas, options)); | |
| } | |
| } | |
| function initApp(device) { | |
| try { | |
| var createOptions = new pc.AppOptions(); | |
| createOptions.graphicsDevice = device; | |
| createOptions.componentSystems = [ | |
| pc.RigidBodyComponentSystem, | |
| pc.CollisionComponentSystem, | |
| pc.JointComponentSystem, | |
| pc.AnimationComponentSystem, | |
| pc.AnimComponentSystem, | |
| pc.ModelComponentSystem, | |
| pc.RenderComponentSystem, | |
| pc.CameraComponentSystem, | |
| pc.LightComponentSystem, | |
| pc.script.legacy ? pc.ScriptLegacyComponentSystem : pc.ScriptComponentSystem, | |
| pc.AudioSourceComponentSystem, | |
| pc.SoundComponentSystem, | |
| pc.AudioListenerComponentSystem, | |
| pc.ParticleSystemComponentSystem, | |
| pc.ScreenComponentSystem, | |
| pc.ElementComponentSystem, | |
| pc.ButtonComponentSystem, | |
| pc.ScrollViewComponentSystem, | |
| pc.ScrollbarComponentSystem, | |
| pc.SpriteComponentSystem, | |
| pc.LayoutGroupComponentSystem, | |
| pc.LayoutChildComponentSystem, | |
| pc.ZoneComponentSystem, | |
| pc.GSplatComponentSystem, | |
| ].filter(Boolean); | |
| createOptions.resourceHandlers = [ | |
| pc.RenderHandler, | |
| pc.AnimationHandler, | |
| pc.AnimClipHandler, | |
| pc.AnimStateGraphHandler, | |
| pc.ModelHandler, | |
| pc.MaterialHandler, | |
| pc.TextureHandler, | |
| pc.TextHandler, | |
| pc.JsonHandler, | |
| pc.AudioHandler, | |
| pc.ScriptHandler, | |
| pc.SceneHandler, | |
| pc.CubemapHandler, | |
| pc.HtmlHandler, | |
| pc.CssHandler, | |
| pc.ShaderHandler, | |
| pc.HierarchyHandler, | |
| pc.FolderHandler, | |
| pc.FontHandler, | |
| pc.BinaryHandler, | |
| pc.TextureAtlasHandler, | |
| pc.SpriteHandler, | |
| pc.TemplateHandler, | |
| pc.ContainerHandler, | |
| pc.GSplatHandler | |
| ].filter(Boolean); | |
| createOptions.elementInput = new pc.ElementInput(canvas, { | |
| useMouse: INPUT_SETTINGS.useMouse, | |
| useTouch: INPUT_SETTINGS.useTouch | |
| }); | |
| createOptions.keyboard = INPUT_SETTINGS.useKeyboard ? new pc.Keyboard(window) : null; | |
| createOptions.mouse = INPUT_SETTINGS.useMouse ? new pc.Mouse(canvas) : null; | |
| createOptions.gamepads = INPUT_SETTINGS.useGamepads ? new pc.GamePads() : null; | |
| createOptions.touch = INPUT_SETTINGS.useTouch && pc.platform.touch ? new pc.TouchDevice(canvas) : null; | |
| createOptions.assetPrefix = window.ASSET_PREFIX || ''; | |
| createOptions.scriptPrefix = window.SCRIPT_PREFIX || ''; | |
| createOptions.scriptsOrder = window.SCRIPTS || []; | |
| createOptions.soundManager = new pc.SoundManager(); | |
| createOptions.lightmapper = pc.Lightmapper; | |
| createOptions.batchManager = pc.BatchManager; | |
| createOptions.xr = pc.XrManager; | |
| app.init(createOptions); | |
| return true; | |
| } catch (e) { | |
| displayError('Could not initialize application. Error: ' + e); | |
| console.error(e); | |
| return false; | |
| } | |
| } | |
| function configure() { | |
| app.configure(window.CONFIG_FILENAME, (err) => { | |
| if (err) { | |
| console.error(err); | |
| return; | |
| } | |
| initCSS(canvas, app._fillMode, app._width, app._height); | |
| if (LTC_MAT_1.length && LTC_MAT_2.length && app.setAreaLightLuts.length === 2) { | |
| app.setAreaLightLuts(LTC_MAT_1, LTC_MAT_2); | |
| } | |
| // do the first reflow after a timeout because of | |
| // iOS showing a squished iframe sometimes | |
| setTimeout(() => { | |
| pcBootstrap.reflow(app, canvas); | |
| pcBootstrap.reflowHandler = function () { | |
| pcBootstrap.reflow(app, canvas); | |
| }; | |
| window.addEventListener('resize', pcBootstrap.reflowHandler, false); | |
| window.addEventListener('orientationchange', pcBootstrap.reflowHandler, false); | |
| app.preload(() => { | |
| app.scenes.loadScene(window.SCENE_PATH, (err) => { | |
| if (err) { | |
| console.error(err); | |
| return; | |
| } | |
| app.start(); | |
| }) | |
| }) | |
| }); | |
| }); | |
| } | |
| function main() { | |
| createGraphicsDevice((device) => { | |
| if (!device) { | |
| return; | |
| } | |
| if (!initApp(device)) { | |
| return; | |
| } | |
| if (window.PRELOAD_MODULES.length) { | |
| loadModules(window.PRELOAD_MODULES, window.ASSET_PREFIX, () => { | |
| configure(() => { | |
| console.timeEnd('start'); | |
| }); | |
| }) | |
| } else { | |
| configure(); | |
| } | |
| }); | |
| } | |
| main(); | |
| })(); // Add scope to avoid polluting window scope | |