UNPKG

@plattar/plattar-ar-adapter

Version:

Plattar AR Adapter for interfacing with Google & Apple WebAR

1,041 lines (1,032 loc) 469 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PlattarARAdapter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfiguratorAR = void 0; const plattar_analytics_1 = require("@plattar/plattar-analytics"); const plattar_api_1 = require("@plattar/plattar-api"); const plattar_services_1 = require("@plattar/plattar-services"); const util_1 = require("../util/util"); const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer")); const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer")); const launcher_ar_1 = require("./launcher-ar"); const version_1 = __importDefault(require("../version")); /** * Performs AR functionality related to Plattar Scenes */ class ConfiguratorAR extends launcher_ar_1.LauncherAR { constructor(options) { super(); // analytics instance this._analytics = null; if (!options.state) { throw new Error("ConfiguratorAR.constructor(state) - state must be defined"); } this._options = options; this._ar = null; } _SetupAnalytics() { const scene = this._options.state.scene; let analytics = null; // setup scene stuff (if any) if (scene) { analytics = new plattar_analytics_1.Analytics(scene.attributes.application_id); analytics.origin = plattar_api_1.Server.location().type; this._analytics = analytics; analytics.data.push("type", "scene-ar"); analytics.data.push("sdkVersion", version_1.default); analytics.data.push("sceneId", scene.id); analytics.data.push("sceneTitle", scene.attributes.title); const application = scene.relationships.find(plattar_api_1.Project); // setup application stuff (if any) if (application) { analytics.data.push("applicationId", application.id); analytics.data.push("applicationTitle", application.attributes.title); if (this._options.useARBanner) { this.options.banner = { title: application.attributes.title, subtitle: scene.attributes.title, button: 'Visit' }; } } } } /** * Composes a Scene into an AR Model (remote operation) that can be used to launch * an AR File */ async _Compose(output) { const objects = this._options.state.state.array(); if (objects.length <= 0) { throw new Error("ConfiguratorAR.Compose() - cannot proceed as scene does not contain AR components"); } // define our configurator const configurator = new plattar_services_1.Configurator(); configurator.server = plattar_api_1.Server.location().type; configurator.output = output; let totalARObjectCount = 0; objects.forEach((object) => { if (object.meta_data.augment) { if (object.meta_data.type === "scenemodel") { configurator.addModel(object.scene_product_id); } else { configurator.addSceneProduct(object.scene_product_id, object.product_variation_id); } totalARObjectCount++; } }); if (totalARObjectCount <= 0) { throw new Error("ConfiguratorAR.Compose() - cannot proceed as scene does not contain any enabled AR components"); } const results = await configurator.get(); return results.filename; } /** * Initialise the SceneAR instance. This returns a Promise that resolves * successfully if initialisation is successful, otherwise it will fail. * * filure can occur for a number of reasons but it generally means that AR * cannot be performed. */ async init() { if (!util_1.Util.canAugment()) { throw new Error("ConfiguratorAR.init() - cannot proceed as AR not available in context"); } const scene = this._options.state.scene; this._SetupAnalytics(); const sceneOpt = scene.attributes.custom_json || {}; // we need to define our AR module here // we are in Safari/Quicklook mode here if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) { // we need to launch a VTO experience here // VTO requires Reality Support if (sceneOpt.anchor === "face") { if (util_1.Util.canRealityViewer()) { const modelUrl = await this._Compose("vto"); this._ar = new quicklook_viewer_1.default(); this._ar.modelUrl = modelUrl; this._ar.banner = this.options.banner; return this; } else { throw new Error("ConfiguratorAR.init() - cannot proceed as VTO AR requires Reality Viewer support"); } } // otherwise, load the USDZ stuff second if available if (util_1.Util.canQuicklook()) { const modelUrl = await this._Compose("usdz"); this._ar = new quicklook_viewer_1.default(); this._ar.modelUrl = modelUrl; this._ar.banner = this.options.banner; return this; } throw new Error("ConfiguratorAR.init() - cannot proceed as IOS device does not support AR Mode"); } // check android if (util_1.Util.canSceneViewer()) { const modelUrl = await this._Compose("glb"); const arviewer = new scene_viewer_1.default(); arviewer.modelUrl = modelUrl; arviewer.isVertical = this.options.anchor === "vertical" ? true : false; arviewer.banner = this.options.banner; if (sceneOpt.anchor === "vertical") { arviewer.isVertical = true; } this._ar = arviewer; return this; } // otherwise, we didn't have AR available - it should never really reach this stage as this should be caught // earlier in the process throw new Error("ConfiguratorAR.init() - could not initialise AR correctly, check values"); } start() { if (!this._ar) { throw new Error("SceneAR.start() - cannot proceed as AR instance is null"); } const analytics = this._analytics; if (analytics) { analytics.data.push("device", this._ar.device); analytics.data.push("eventCategory", this._ar.nodeType); analytics.data.push("eventAction", "Start Scene Augment"); analytics.write(); analytics.startRecordEngagement(); } // this was initialised via the init() function this._ar.start(); } canQuicklook() { return this._ar && this._ar.nodeType === "Quick Look" ? true : false; } canRealityViewer() { return this._ar && this._ar.nodeType === "Reality Viewer" ? true : false; } canSceneViewer() { return this._ar && this._ar.nodeType === "Scene Viewer" ? true : false; } } exports.ConfiguratorAR = ConfiguratorAR; },{"../util/util":18,"../version":19,"../viewers/quicklook-viewer":21,"../viewers/scene-viewer":23,"./launcher-ar":2,"@plattar/plattar-analytics":43,"@plattar/plattar-api":47,"@plattar/plattar-services":121}],2:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LauncherAR = void 0; class LauncherAR { constructor() { this._opt = { anchor: "horizontal_vertical", banner: null }; } /** * Initialise and launch with a single function call. this is mostly for convenience. * Use .init() and .start() separately for fine-grained control */ async launch() { const value = await this.init(); return value.start(); } /** * AR Options used for launching AR */ get options() { return this._opt; } } exports.LauncherAR = LauncherAR; },{}],3:[function(require,module,exports){ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ModelAR = void 0; const plattar_api_1 = require("@plattar/plattar-api"); const plattar_analytics_1 = require("@plattar/plattar-analytics"); const util_1 = require("../util/util"); const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer")); const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer")); const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer")); const launcher_ar_1 = require("./launcher-ar"); const version_1 = __importDefault(require("../version")); /** * Performs AT Functionality using Plattar FileModel types */ class ModelAR extends launcher_ar_1.LauncherAR { constructor(options) { super(); // analytics instance this._analytics = null; if (!options.modelID) { throw new Error("ModelAR.constructor(modelID) - modelID must be defined"); } this._options = options; this._ar = null; } get modelID() { return this._options.modelID; } _SetupAnalytics(model) { let analytics = null; const project = model.relationships.find(plattar_api_1.Project); // setup scene stuff (if any) if (project) { analytics = new plattar_analytics_1.Analytics(project.id); analytics.origin = plattar_api_1.Server.location().type; analytics.data.push("type", "model-ar"); analytics.data.push("sdkVersion", version_1.default); analytics.data.push("applicationId", project.id); analytics.data.push("applicationTitle", project.attributes.title); analytics.data.push("modelId", model.id); analytics.data.push("modelTitle", model.attributes.title); this._analytics = analytics; if (this._options.useARBanner) { this.options.banner = { title: project.attributes.title, subtitle: model.attributes.title, button: 'Visit' }; } } } /** * Initialise the ModelAR instance. This returns a Promise that resolves * successfully if initialisation is successful, otherwise it will fail. * * filure can occur for a number of reasons but it generally means that AR * cannot be performed. */ init() { return new Promise((accept, reject) => { if (!util_1.Util.canAugment()) { return reject(new Error("ModelAR.init() - cannot proceed as AR not available in context")); } const model = new plattar_api_1.FileModel(this.modelID); model.include(plattar_api_1.Project); model.get().then((model) => { // setup the analytics data this._SetupAnalytics(model); // we need to define our AR module here // we are in Safari/Quicklook mode here if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) { // model needs to have either USDZ or REALITY files defined // we load REALITY stuff first if available if (model.attributes.reality_filename && util_1.Util.canRealityViewer()) { this._ar = new reality_viewer_1.default(); this._ar.modelUrl = plattar_api_1.Server.location().cdn + model.attributes.path + model.attributes.reality_filename; this._ar.banner = this.options.banner; return accept(this); } // otherwise, load the USDZ stuff second if available if (model.attributes.usdz_filename && util_1.Util.canQuicklook()) { this._ar = new quicklook_viewer_1.default(); this._ar.modelUrl = plattar_api_1.Server.location().cdn + model.attributes.path + model.attributes.usdz_filename; this._ar.banner = this.options.banner; return accept(this); } return reject(new Error("ModelAR.init() - cannot proceed as ModelFile does not have a defined .usdz or .reality file")); } // check android if (util_1.Util.canSceneViewer()) { const arviewer = new scene_viewer_1.default(); arviewer.modelUrl = plattar_api_1.Server.location().cdn + model.attributes.path + model.attributes.original_filename; arviewer.isVertical = this.options.anchor === "vertical" ? true : false; arviewer.banner = this.options.banner; this._ar = arviewer; return accept(this); } // otherwise, we didn't have AR available - it should never really reach this stage as this should be caught // earlier in the process return reject(new Error("ModelAR.init() - could not initialise AR correctly, check values")); }).catch(reject); }); } /** * Launches the internal AR instance using an appropriate version of AR Viewers */ start() { if (!this._ar) { throw new Error("ModelAR.start() - cannot proceed as AR instance is null"); } const analytics = this._analytics; if (analytics) { analytics.data.push("device", this._ar.device); analytics.data.push("eventCategory", this._ar.nodeType); analytics.data.push("eventAction", "Start Model Augment"); analytics.write(); analytics.startRecordEngagement(); } // this was initialised via the init() function this._ar.start(); } canQuicklook() { return this._ar && this._ar.nodeType === "Quick Look" ? true : false; } canRealityViewer() { return this._ar && this._ar.nodeType === "Reality Viewer" ? true : false; } canSceneViewer() { return this._ar && this._ar.nodeType === "Scene Viewer" ? true : false; } } exports.ModelAR = ModelAR; },{"../util/util":18,"../version":19,"../viewers/quicklook-viewer":21,"../viewers/reality-viewer":22,"../viewers/scene-viewer":23,"./launcher-ar":2,"@plattar/plattar-analytics":43,"@plattar/plattar-api":47}],4:[function(require,module,exports){ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProductAR = void 0; const plattar_api_1 = require("@plattar/plattar-api"); const plattar_analytics_1 = require("@plattar/plattar-analytics"); const util_1 = require("../util/util"); const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer")); const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer")); const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer")); const launcher_ar_1 = require("./launcher-ar"); const version_1 = __importDefault(require("../version")); /** * Performs AR functionality related to Plattar Products and Variation types */ class ProductAR extends launcher_ar_1.LauncherAR { /* constructor(productID: string | undefined | null = null, variationID: string | undefined | null = null, variationSKU: string | undefined | null = null) { super(); if (!productID) { throw new Error("ProductAR.constructor(productID, variationID) - productID must be defined"); } this._productID = productID; this._variationSKU = variationSKU; this._variationID = variationID ? variationID : (variationSKU ? null : "default"); this._ar = null; } */ constructor(options) { super(); // analytics instance this._analytics = null; if (!options.productID) { throw new Error("ProductAR.constructor(productID, variationID) - productID must be defined"); } this._options = options; this._ar = null; } get productID() { return this._options.productID; } get variationID() { return this._options.variationID; } get variationSKU() { return this._options.variationSKU; } _SetupAnalytics(product, variation) { let analytics = null; const scene = product.relationships.find(plattar_api_1.Scene); // setup scene stuff (if any) if (scene) { analytics = new plattar_analytics_1.Analytics(scene.attributes.application_id); analytics.origin = plattar_api_1.Server.location().type; this._analytics = analytics; analytics.data.push("type", "product-ar"); analytics.data.push("sdkVersion", version_1.default); analytics.data.push("sceneId", scene.id); analytics.data.push("sceneTitle", scene.attributes.title); const application = scene.relationships.find(plattar_api_1.Project); // setup application stuff (if any) if (application) { analytics.data.push("applicationId", application.id); analytics.data.push("applicationTitle", application.attributes.title); if (this._options.useARBanner) { this.options.banner = { title: product.attributes.title, subtitle: variation.attributes.title, button: 'Visit' }; } } } if (analytics) { // set product stuff analytics.data.push("productId", product.id); analytics.data.push("productTitle", product.attributes.title); analytics.data.push("productSKU", product.attributes.sku); // set variation stuff analytics.data.push("variationId", variation.id); analytics.data.push("variationTitle", variation.attributes.title); analytics.data.push("variationSKU", variation.attributes.sku); } } /** * Initialise the ProductAR instance. This returns a Promise that resolves * successfully if initialisation is successful, otherwise it will fail. * * filure can occur for a number of reasons but it generally means that AR * cannot be performed. */ init() { return new Promise((accept, reject) => { if (!util_1.Util.canAugment()) { return reject(new Error("ProductAR.init() - cannot proceed as AR not available in context")); } const product = new plattar_api_1.Product(this.productID); product.include(plattar_api_1.ProductVariation); product.include(plattar_api_1.ProductVariation.include(plattar_api_1.FileModel)); product.include(plattar_api_1.Scene); product.include(plattar_api_1.Scene.include(plattar_api_1.Project)); product.get().then((product) => { // find the required variation from our product const variationID = this.variationID ? (this.variationID === "default" ? product.attributes.product_variation_id : this.variationID) : null; const variationSKU = this.variationSKU; if (!variationID && !variationSKU) { return reject(new Error("ProductAR.init() - cannot proceed as variation-id or variation-sku was not set correctly")); } let variation = undefined; if (variationID) { variation = product.relationships.find(plattar_api_1.ProductVariation, variationID); } // if no variation was found with variationID - try searching variation sku if (!variation && variationSKU) { const variations = product.relationships.filter(plattar_api_1.ProductVariation); if (variations) { variation = variations.find((element) => { return element.attributes.sku === variationSKU; }); } } // make sure our variation is actually available before moving forward if (!variation) { return reject(new Error("ProductAR.init() - cannot proceed as variation with id " + variationID + " or sku " + variationSKU + " cannot be found")); } // otherwise both the product and variation are available // we need to figure out if we can actually do AR though // check if variation has a model file defined const modelID = variation.attributes.file_model_id; if (!modelID) { return reject(new Error("ProductAR.init() - cannot proceed as variation does not have a defined file")); } // find the actual FileModel from Variation const model = variation.relationships.find(plattar_api_1.FileModel, modelID); if (!model) { return reject(new Error("ProductAR.init() - cannot proceed as ModelFile for selected variation is corrupt")); } this._SetupAnalytics(product, variation); // we need to define our AR module here // we are in Safari/Quicklook mode here if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) { // model needs to have either USDZ or REALITY files defined // we load REALITY stuff first if available if (model.attributes.reality_filename && util_1.Util.canRealityViewer()) { this._ar = new reality_viewer_1.default(); this._ar.modelUrl = plattar_api_1.Server.location().cdn + model.attributes.path + model.attributes.reality_filename; this._ar.banner = this.options.banner; return accept(this); } // otherwise, load the USDZ stuff second if available if (model.attributes.usdz_filename && util_1.Util.canQuicklook()) { this._ar = new quicklook_viewer_1.default(); this._ar.modelUrl = plattar_api_1.Server.location().cdn + model.attributes.path + model.attributes.usdz_filename; this._ar.banner = this.options.banner; return accept(this); } return reject(new Error("ProductAR.init() - cannot proceed as ModelFile does not have a defined .usdz or .reality file")); } // check android if (util_1.Util.canSceneViewer()) { const arviewer = new scene_viewer_1.default(); arviewer.modelUrl = plattar_api_1.Server.location().cdn + model.attributes.path + model.attributes.original_filename; arviewer.isVertical = this.options.anchor === "vertical" ? true : false; arviewer.banner = this.options.banner; const scene = product.relationships.find(plattar_api_1.Scene); if (scene) { const sceneOpt = scene.attributes.custom_json || {}; if (sceneOpt.anchor === "vertical") { arviewer.isVertical = true; } } this._ar = arviewer; return accept(this); } // otherwise, we didn't have AR available - it should never really reach this stage as this should be caught // earlier in the process return reject(new Error("ProductAR.init() - could not initialise AR correctly, check values")); }).catch(reject); }); } /** * Launches the internal AR instance using an appropriate version of AR Viewers */ start() { if (!this._ar) { throw new Error("ProductAR.start() - cannot proceed as AR instance is null"); } const analytics = this._analytics; if (analytics) { analytics.data.push("device", this._ar.device); analytics.data.push("eventCategory", this._ar.nodeType); analytics.data.push("eventAction", "Start Augment"); analytics.write(); analytics.startRecordEngagement(); } // this was initialised via the init() function this._ar.start(); } canQuicklook() { return this._ar && this._ar.nodeType === "Quick Look" ? true : false; } canRealityViewer() { return this._ar && this._ar.nodeType === "Reality Viewer" ? true : false; } canSceneViewer() { return this._ar && this._ar.nodeType === "Scene Viewer" ? true : false; } } exports.ProductAR = ProductAR; },{"../util/util":18,"../version":19,"../viewers/quicklook-viewer":21,"../viewers/reality-viewer":22,"../viewers/scene-viewer":23,"./launcher-ar":2,"@plattar/plattar-analytics":43,"@plattar/plattar-api":47}],5:[function(require,module,exports){ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RawAR = void 0; const plattar_analytics_1 = require("@plattar/plattar-analytics"); const plattar_api_1 = require("@plattar/plattar-api"); const util_1 = require("../util/util"); const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer")); const reality_viewer_1 = __importDefault(require("../viewers/reality-viewer")); const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer")); const launcher_ar_1 = require("./launcher-ar"); const version_1 = __importDefault(require("../version")); /** * Allows launching AR Experiences provided a single remote 3D Model file */ class RawAR extends launcher_ar_1.LauncherAR { constructor(options) { super(); // analytics instance this._analytics = null; if (!options.modelLocation) { throw new Error("RawAR.constructor(modelLocation) - modelLocation must be defined"); } const lowerLoc = options.modelLocation.toLowerCase(); if (lowerLoc.endsWith("usdz") || lowerLoc.endsWith("glb") || lowerLoc.endsWith("gltf") || lowerLoc.endsWith("reality")) { this._options = options; this._ar = null; } else { throw new Error("RawAR.constructor(modelLocation) - modelLocation must be one of gltf, glb, usdz or reality"); } } get modelLocation() { return this._options.modelLocation; } _SetupAnalytics() { return new Promise((accept, _reject) => { const sceneID = this._options.sceneID; if (!sceneID) { return accept(); } const scene = new plattar_api_1.Scene(sceneID); scene.include(plattar_api_1.Project); scene.get().then((scene) => { const analytics = new plattar_analytics_1.Analytics(scene.attributes.application_id); analytics.origin = plattar_api_1.Server.location().type; this._analytics = analytics; analytics.data.push("type", "scene-ar"); analytics.data.push("sdkVersion", version_1.default); analytics.data.push("sceneId", scene.id); analytics.data.push("sceneTitle", scene.attributes.title); const application = scene.relationships.find(plattar_api_1.Project); // setup application stuff (if any) if (application) { analytics.data.push("applicationId", application.id); analytics.data.push("applicationTitle", application.attributes.title); if (this._options.useARBanner) { this.options.banner = { title: application.attributes.title, subtitle: scene.attributes.title, button: 'Visit' }; } } accept(); }).catch((_err) => { accept(); }); }); } /** * Initialise the RawAR instance. This returns a Promise that resolves * successfully if initialisation is successful, otherwise it will fail. * * filure can occur for a number of reasons but it generally means that AR * cannot be performed. */ init() { return new Promise((accept, reject) => { if (!util_1.Util.canAugment()) { return reject(new Error("RawAR.init() - cannot proceed as AR not available in context")); } // send the analytics (if any) this._SetupAnalytics().then(() => { const modelLocation = this._options.modelLocation; const lowerLoc = modelLocation.toLowerCase(); // we need to define our AR module here // we are in Safari/Quicklook mode here if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) { // load the reality experience if dealing with reality file if (lowerLoc.endsWith("reality") && util_1.Util.canRealityViewer()) { this._ar = new reality_viewer_1.default(); this._ar.modelUrl = modelLocation; this._ar.banner = this.options.banner; return accept(this); } // load the usdz experience if dealing with usdz file if (lowerLoc.endsWith("usdz") && util_1.Util.canQuicklook()) { this._ar = new quicklook_viewer_1.default(); this._ar.modelUrl = modelLocation; return accept(this); } return reject(new Error("RawAR.init() - cannot proceed as model is not a .usdz or .reality file")); } // check android if (util_1.Util.canSceneViewer()) { if (lowerLoc.endsWith("glb") || lowerLoc.endsWith("gltf")) { const arviewer = new scene_viewer_1.default(); arviewer.modelUrl = modelLocation; arviewer.isVertical = this.options.anchor === "vertical" ? true : false; arviewer.banner = this.options.banner; this._ar = arviewer; return accept(this); } return reject(new Error("RawAR.init() - cannot proceed as model is not a .glb or .gltf file")); } // otherwise, we didn't have AR available - it should never really reach this stage as this should be caught // earlier in the process return reject(new Error("RawAR.init() - could not initialise AR correctly, check values")); }); }); } /** * Launches the internal AR instance using an appropriate version of AR Viewers */ start() { if (!this._ar) { throw new Error("RawAR.start() - cannot proceed as AR instance is null"); } const analytics = this._analytics; if (analytics) { analytics.data.push("device", this._ar.device); analytics.data.push("eventCategory", this._ar.nodeType); analytics.data.push("eventAction", "Start Scene Augment"); analytics.write(); analytics.startRecordEngagement(); } // this was initialised via the init() function this._ar.start(); } canQuicklook() { return this._ar && this._ar.nodeType === "Quick Look" ? true : false; } canRealityViewer() { return this._ar && this._ar.nodeType === "Reality Viewer" ? true : false; } canSceneViewer() { return this._ar && this._ar.nodeType === "Scene Viewer" ? true : false; } } exports.RawAR = RawAR; },{"../util/util":18,"../version":19,"../viewers/quicklook-viewer":21,"../viewers/reality-viewer":22,"../viewers/scene-viewer":23,"./launcher-ar":2,"@plattar/plattar-analytics":43,"@plattar/plattar-api":47}],6:[function(require,module,exports){ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SceneAR = void 0; const plattar_analytics_1 = require("@plattar/plattar-analytics"); const plattar_api_1 = require("@plattar/plattar-api"); const plattar_services_1 = require("@plattar/plattar-services"); const util_1 = require("../util/util"); const quicklook_viewer_1 = __importDefault(require("../viewers/quicklook-viewer")); const scene_viewer_1 = __importDefault(require("../viewers/scene-viewer")); const launcher_ar_1 = require("./launcher-ar"); const version_1 = __importDefault(require("../version")); /** * Performs AR functionality related to Plattar Scenes */ class SceneAR extends launcher_ar_1.LauncherAR { constructor(options) { super(); // analytics instance this._analytics = null; if (!options.sceneID) { throw new Error("SceneAR.constructor(sceneID) - sceneID must be defined"); } this._options = options; this._ar = null; } get sceneID() { return this._options.sceneID; } _SetupAnalytics(scene) { let analytics = null; // setup scene stuff (if any) if (scene) { analytics = new plattar_analytics_1.Analytics(scene.attributes.application_id); analytics.origin = plattar_api_1.Server.location().type; this._analytics = analytics; analytics.data.push("type", "scene-ar"); analytics.data.push("sdkVersion", version_1.default); analytics.data.push("sceneId", scene.id); analytics.data.push("sceneTitle", scene.attributes.title); const application = scene.relationships.find(plattar_api_1.Project); // setup application stuff (if any) if (application) { analytics.data.push("applicationId", application.id); analytics.data.push("applicationTitle", application.attributes.title); if (this._options.useARBanner) { this.options.banner = { title: application.attributes.title, subtitle: scene.attributes.title, button: 'Visit' }; } } } } /** * Composes a Scene into an AR Model (remote operation) that can be used to launch * an AR File */ _ComposeScene(scene, output) { return new Promise((accept, reject) => { const sceneProducts = scene.relationships.filter(plattar_api_1.SceneProduct); const sceneModels = scene.relationships.filter(plattar_api_1.SceneModel); // nothing to do if no AR components can be found if ((sceneProducts.length + sceneModels.length) <= 0) { return reject(new Error("SceneAR.ComposeScene() - cannot proceed as scene does not contain AR components")); } // define our configurator const configurator = new plattar_services_1.Configurator(); configurator.server = plattar_api_1.Server.location().type; configurator.output = output; let totalARObjectCount = 0; // add our scene products sceneProducts.forEach((sceneProduct) => { const product = sceneProduct.relationships.find(plattar_api_1.Product); const selection = this._options.variationSelection; // we have a specific product selection if (sceneProduct.attributes.include_in_augment) { // check if this product is the one we want (from selection optionally) if (product && (product.id === selection.productID) && selection.variationID) { configurator.addSceneProduct(sceneProduct.id, selection.variationID); totalARObjectCount++; } else if (product) { // check if this scene-product is the one we want (from selection) if ((sceneProduct.id === selection.sceneProductID) && selection.variationID) { configurator.addSceneProduct(sceneProduct.id, selection.variationID); totalARObjectCount++; } else if (product.attributes.product_variation_id) { configurator.addSceneProduct(sceneProduct.id, product.attributes.product_variation_id); totalARObjectCount++; } } } }); // add our scene models sceneModels.forEach((sceneModel) => { if (sceneModel.attributes.include_in_augment) { configurator.addModel(sceneModel.id); totalARObjectCount++; } }); // ensure we have actually added AR objects if (totalARObjectCount <= 0) { return reject(new Error("SceneAR.ComposeScene() - cannot proceed as scene does not contain any enabled AR components")); } return configurator.get().then((result) => { accept(result.filename); }).catch(reject); }); } /** * Initialise the SceneAR instance. This returns a Promise that resolves * successfully if initialisation is successful, otherwise it will fail. * * filure can occur for a number of reasons but it generally means that AR * cannot be performed. */ init() { return new Promise((accept, reject) => { if (!util_1.Util.canAugment()) { return reject(new Error("SceneAR.init() - cannot proceed as AR not available in context")); } const scene = new plattar_api_1.Scene(this.sceneID); scene.include(plattar_api_1.Project); scene.include(plattar_api_1.SceneProduct); scene.include(plattar_api_1.SceneProduct.include(plattar_api_1.Product)); scene.include(plattar_api_1.SceneModel); scene.get().then((scene) => { this._SetupAnalytics(scene); const sceneOpt = scene.attributes.custom_json || {}; // we need to define our AR module here // we are in Safari/Quicklook mode here if (util_1.Util.isSafari() || util_1.Util.isChromeOnIOS()) { // we need to launch a VTO experience here // VTO requires Reality Support if (sceneOpt.anchor === "face") { if (util_1.Util.canRealityViewer()) { return this._ComposeScene(scene, "vto").then((modelUrl) => { this._ar = new quicklook_viewer_1.default(); this._ar.modelUrl = modelUrl; this._ar.banner = this.options.banner; return accept(this); }).catch(reject); } else { return reject(new Error("SceneAR.init() - cannot proceed as VTO AR requires Reality Viewer support")); } } // otherwise, load the USDZ stuff second if available if (util_1.Util.canQuicklook()) { return this._ComposeScene(scene, "usdz").then((modelUrl) => { this._ar = new quicklook_viewer_1.default(); this._ar.modelUrl = modelUrl; this._ar.banner = this.options.banner; return accept(this); }).catch(reject); } return reject(new Error("SceneAR.init() - cannot proceed as IOS device does not support AR Mode")); } // check android if (util_1.Util.canSceneViewer()) { return this._ComposeScene(scene, "glb").then((modelUrl) => { const arviewer = new scene_viewer_1.default(); arviewer.modelUrl = modelUrl; arviewer.isVertical = this.options.anchor === "vertical" ? true : false; arviewer.banner = this.options.banner; if (sceneOpt.anchor === "vertical") { arviewer.isVertical = true; } this._ar = arviewer; return accept(this); }).catch(reject); } // otherwise, we didn't have AR available - it should never really reach this stage as this should be caught // earlier in the process return reject(new Error("SceneAR.init() - could not initialise AR correctly, check values")); }).catch(reject); }); } start() { if (!this._ar) { throw new Error("SceneAR.start() - cannot proceed as AR instance is null"); } const analytics = this._analytics; if (analytics) { analytics.data.push("device", this._ar.device); analytics.data.push("eventCategory", this._ar.nodeType); analytics.data.push("eventAction", "Start Scene Augment"); analytics.write(); analytics.startRecordEngagement(); } // this was initialised via the init() function this._ar.start(); } canQuicklook() { return this._ar && this._ar.nodeType === "Quick Look" ? true : false; } canRealityViewer() { return this._ar && this._ar.nodeType === "Reality Viewer" ? true : false; } canSceneViewer() { return this._ar && this._ar.nodeType === "Scene Viewer" ? true : false; } } exports.SceneAR = SceneAR; },{"../util/util":18,"../version":19,"../viewers/quicklook-viewer":21,"../viewers/scene-viewer":23,"./launcher-ar":2,"@plattar/plattar-analytics":43,"@plattar/plattar-api":47,"@plattar/plattar-services":121}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SceneProductAR = void 0; const product_ar_1 = require("./product-ar"); const plattar_api_1 = require("@plattar/plattar-api"); const util_1 = require("../util/util"); /** * Allows launching Product AR by providing a SceneProduct ID instead. * SceneProducts are much more convenient to grab from the Plattar CMS */ class SceneProductAR extends product_ar_1.ProductAR { constructor(options) { //super(sceneProductID, variationID, variationSKU); super(options); // this is evaluated in the init() function this._attachedProductID = null; if (!options.productID) { throw new Error("SceneProductAR.constructor(sceneProductID, variationID) - sceneProductID must be defined"); } this._sceneProductID = options.productID; } get sceneProductID() { return this._sceneProductID; } get productID() { if (!this._attachedProductID) { throw new Error("SceneProductAR.productID() - product id was not defined, did you call init()?"); } return this._attachedProductID; } init() { return new Promise((accept, reject) => { if (!util_1.Util.canAugment()) { return reject(new Error("SceneProductAR.init() - cannot proceed as AR not available in context")); } const sceneProduct = new plattar_api_1.SceneProduct(this.sceneProductID); sceneProduct.get().then((sceneProduct) => { const productID = sceneProduct.attributes.product_id; if (!productID) { return reject("SceneProductAR.init() - Scene Product does not have an attached Product instance"); } this._attachedProductID = productID; // execute the standard Product AR functionality return super.init().then(accept).catch(reject); }).catch(reject); }); } } exports.SceneProductAR = SceneProductAR; },{"../util/util":18,"./product-ar":4,"@plattar/plattar-api":47}],8:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfiguratorController = void 0; const plattar_api_1 = require("@plattar/plattar-api"); const scene_product_ar_1 = require("../../ar/scene-product-ar"); const util_1 = require("../../util/util"); const plattar_controller_1 = require("./plattar-controller"); const configurator_ar_1 = require("../../ar/configurator-ar"); /** * Manages an instance of the <plattar-configurator> HTML Element */ class ConfiguratorController extends plattar_controller_1.PlattarController { constructor() { super(...arguments); this._cachedConfigState = null; } async getConfiguratorState() { if (this._cachedConfigState) { return this._cachedConfigState; } this._cachedConfigState = this.createConfiguratorState(); return this._cachedConfigState; } async onAttributesUpdated(attributeName) { const state = this._state; if (state === plattar_controller_1.ControllerState.Renderer) { const viewer = this.element; if (viewer) { if (attributeName === "variation-id") { const variationIDs = this.getAttribute("variation-id"); const variationIDsList = variationIDs ? variationIDs.split(",") : []; if (variationIDsList.length > 0) { await viewer.messenger.selectVariationID(variationIDsList); } } if (attributeName === "variation-sku") { const variationSKUs = this.getAttribute("variation-sku"); const variationSKUList = variationSKUs ? variationSKUs.split(",") : []; if (variationSKUList.length > 0) { await viewer.messenger.selectVariationSKU(variationSKUList); } } } return; } // re-render the QR Code when attributes have changed if (state === plattar_controller_1.ControllerState.QRCode) { if (attributeName === "variation-id") { const configState = await this.getConfiguratorState(); const variationIDs = this.getAttribute("variation-id"); const variationIDsList = variationIDs ? variationIDs.split(",") : []; variationIDsList.forEach((variationID) => { configState.state.setVariationID(variationID); }); } if (attributeName === "variation-sku") { const configState = await this.getConfiguratorState(); const variationSKUs = this.getAttribute("variation-sku"); const variationSKUList = variationSKUs ? variationSKUs.split(",") : []; variationSKUList.forEach((variationSKU) => { configState.state.setVariationSKU(variationSKU); }); } this.startQRCode(this._prevQROpt); return; } } async startARQRCode(options) { try { const dState = await this.getConfiguratorState(); // if this is declared, we have a furniture scene that we n