UNPKG

@plattar/plattar-ar-adapter

Version:

Plattar AR Adapter for interfacing with Google & Apple WebAR

214 lines (211 loc) 10.7 kB
"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;