@plattar/plattar-ar-adapter
Version:
Plattar AR Adapter for interfacing with Google & Apple WebAR
1,041 lines (1,032 loc) • 469 kB
JavaScript
(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