import { Utils } from '../common/Utils';
import { MathUtils } from '../math/MathUtils';
import { Relationship } from '../relationship/Relationship';
import { EventType, RelationshipDirection } from '../const';
import { CubeTexture } from '../resources/CubeTexture';
import { TSFResolver } from '../resolvers/TSFResolver';
import { PathResolver } from '../resolvers/PathResolver';
import { Selector } from '../selector/Selector';
const cStyleTextureKeys = [
'map'
];
const cCanIgnoreKeys = {
'relationships': false,
'blueprints': false,
'selections': false,
'plugins': false,
'files': false,
'predownloads': false,
'rendersettings': true
};
const __ = {
private: Symbol('private'),
}
function _initPrivateMembers(that) {
that[__.private] = {};
const _private = that[__.private];
_private.checkIgnore = (key) => {
if (!cCanIgnoreKeys.hasOwnProperty(key)) {
return false;
}
if (_private.ignore.hasOwnProperty(key)) {
return _private.ignore[key];
}
else {
return cCanIgnoreKeys[key];
}
}
_private.getPathFromURL = (url) => {
if (!url) {
return '';
}
let end = url.lastIndexOf('/');
if (end < 0) {
end = url.lastIndexOf('\\');
}
let path = url.substr(0, end);
return path;
}
_private.processOptions = (options) => {
_private.options = Object.assign(_private.options, options);
_private.dynamic = Utils.parseValue(options['dynamic'], false);
_private.hidden = Utils.parseValue(options['hidden'], false);
_private.isEditor = Utils.parseValue(options['isEditor'], false);
_private.useLatestModel = Utils.parseValue(options['useLatestModel'], true);
_private.customObjectProcessCallback = Utils.parseValue(options['CustomObjectProcess'], null);
const loadIndex = options['_index_'];
if (Utils.isValid(loadIndex)) {
_private.progressParam.index = loadIndex;
}
_private.currentPath = _private.getPathFromURL(options.url);
_private.root = options['root'];
_private.onProgress = options['onProgress'];
_private.onComplete = options['onComplete'];
_private.onError = options['onError'];
_private.onCreateObject = options['onCreateObject'];
let ignore = options['ignore'];
if (ignore) {
_private.ignore = ignore;
}
}
// #region parse
_private.checkAndParse = (data, parseKey, parseCallback) => {
let parseData = data[parseKey];
let ignore = _private.checkIgnore(parseKey);
if (!ignore && parseData && parseCallback) {
parseCallback(parseData);
}
}
_private.parseBaseURL = (baseURL) => {
_private.baseURL = baseURL;
if (!_private.baseURL._endsWith('/')) {
_private.baseURL += '/';
}
}
_private.parseTags = (tags) => {
_private.tags = tags;
}
_private.parseURIs = (URIs) => {
_private.URIs = URIs;
}
_private.parseStyles = (styles) => {
_private.styles = styles;
_private.styles.forEach((style) => {
if (!style) {
return;
}
for (let key in style) {
if (cStyleTextureKeys.includes(key)) {
let styleTexture = style[key];
if (Array.isArray(styleTexture)) {
styleTexture.forEach((data, index) => {
styleTexture[index] = _private.URIs[data];
});
_private.info.totalNumber += 6;
}
else {
style[key] = _private.URIs[styleTexture];
_private.info.totalNumber++;
}
}
}
});
}
_private.parseScripts = (scripts) => {
scripts.forEach(script => {
let url = _private.toolkit.pathResolver.resolveURL(script);
_private.scripts.push(url);
_private.info.totalNumber++;
});
}
_private.parseFiles = (files) => {
files.forEach(file => {
_private.files.push(file);
_private.info.totalNumber++;
});
}
_private.parsePredownloads = (predownloads) => {
predownloads.forEach(predownload => {
let url = _private.toolkit.pathResolver.resolveURL(predownload);
_private.predownloads.push(url);
_private.info.totalNumber++;
});
}
_private.parseResolvers = (resolvers) => {
resolvers.forEach(resolver => {
_private.resolvers.set(resolver.type, resolver.data);
_private.info.totalNumber++;
})
}
_private.getObjectClassType = (object) => {
// Get the class type
let classType = Utils.getRegisteredClasses()[object.type];
// Try to get class type from outside
let onGetClassType = _private.options['onGetClassType'];
if (onGetClassType) {
classType = onGetClassType(object) || classType;
}
return classType;
}
_private.parseObjectRes = (index) => {
let uri, nodeName, version;
let url = _private.URIs[index];
if (!url) {
return null;
}
uri = _private.toolkit.pathResolver.resolveModelURL(url);
if (uri.indexOf('?') != -1) {
let uriContent = uri.split('?');
uri = uriContent[0];
let params = uriContent[1].split('&');
for (let i = 0; i < params.length; i++) {
let param = params[i].split('=');
if (param[0] == 'nodename') {
nodeName = param[1];
}
else if (param[0] == 'version') {
version = param[1];
}
}
}
return { uri, nodeName, version };
}
_private.parseObjectSize = (size) => {
if (!size) {
return null;
}
MathUtils.fixScaleFactor(size);
let initialLocalBoundingBox = {
// object center are at the foot,however the boundingbox center in the center of box
// so we up the bounding half of y,make the two center coinside
center: [0, size[1] / 2, 0],
halfSize: MathUtils.divideVector(size, 2)
};
return { size, initialLocalBoundingBox };
}
_private.parseObject = (object) => {
let data = {};
// extras
let extras = object.extras;
if (extras) {
data.extras = extras;
}
// postion
let position = object.position;
if (position) {
data.position = position;
}
// scale
let scale = object.scale;
if (scale) {
MathUtils.fixScaleFactor(scale);
data.scale = scale;
}
// rotation
let rotation = object.rotation;
if (rotation) {
if (rotation.length == 3) {
data.quaternion = MathUtils.getQuatFromAngles(rotation);
}
else {
data.quaternion = rotation;
}
}
// tags
let tags = [];
if (object.tags) {
tags = object.tags.map(index => {
return _private.tags[index];
});
data.tags = tags;
}
data.res = _private.parseObjectRes(object.uri);
// TODO:
// data.size = _private.parseObjectSize(object.size);
Utils.setAttributeIfExist(data, 'id', object, (v) => { return v != ''; });
Utils.setAttributeIfExist(data, 'name', object, (v) => { return v != ''; });
Utils.setAttributeIfExist(data, 'type', object);
Utils.setAttributeIfExist(data, 'parent', object);
Utils.setAttributeIfExist(data, 'uuid', object);
Utils.setAttributeIfExist(data, 'active', object);
Utils.setAttributeIfExist(data, 'visible', object);
Utils.setAttributeIfExist(data, 'style', object);
Utils.setAttributeIfExist(data, 'components', object);
Utils.setAttributeIfExist(data, 'children', object);
Utils.setAttributeIfExist(data, 'userData', object);
return data;
}
_private.parseObjects = (objects) => {
objects.forEach(object => {
let data = _private.parseObject(object);
if (data) {
_private.info.totalNumber++;
if (data.hasOwnProperty('parent')) {
_private.rootObjectIndices.push(_private.objects.length);
}
_private.objects.push(data);
}
});
}
_private.parseComponents = (components) => {
for (let i = 0; i < components.length; i++) {
let element = components[i];
const classType = _private.getComponentClassType(element);
element['classType'] = classType;
}
}
_private.parseRelationship = (relationship) => {
if (!relationship.type) {
return null;
}
let data = Object.assign({}, relationship);
if (!data.name) {
data.name = "";
}
if (!data.queryDirection) {
data.queryDirection = RelationshipDirection.Out;
}
return data;
};
_private.parseRelationships = (relationships) => {
if (!relationships || relationships.length <= 0) {
return;
}
relationships.forEach(relationship => {
let data = _private.parseRelationship(relationship);
if (data) {
_private.relationships.push(data);
}
})
_private.info.totalNumber++;
};
_private.parseBlueprints = (blueprints) => {
_private.blueprints = blueprints;
_private.info.totalNumber += blueprints.length;
}
_private.parseSelections = (selections) => {
_private.selections = selections;
_private.info.totalNumber += selections.length;
}
_private.parsePlugins = (plugins) => {
_private.plugins = plugins;
_private.info.totalNumber += plugins.length;
}
_private.parseTexture = (object, key) => {
if (!object || !object[key]) {
return;
}
let value = object[key];
if (Array.isArray(value)) {
object[key] = [];
value.forEach(index => {
object[key].push(_private.URIs[index]);
})
_private.info.totalNumber += 6;
}
else if (value instanceof Number) {
object[key] = _private.URIs[value];
_private.info.totalNumber++;
}
}
_private.parseRenderSettings = (renderSettings) => {
if (!renderSettings) {
return;
}
_private.renderSettings = renderSettings;
_private.parseTexture(_private.renderSettings, 'background');
let environment = _private.renderSettings.environment;
_private.parseTexture(environment, 'envMap');
}
_private.parseExtensions = (extensions) => {
for (let key in extensions) {
_private.extensions[key] = extensions[key];
}
}
_private.parseViewpoint = (viewpoint) => {
for (let key in viewpoint) {
_private.viewpoint[key] = viewpoint[key];
}
}
// #endregion
// #region load
_private.checkAndLoad = (loadKey, loadCallback) => {
let ignore = _private.checkIgnore(loadKey);
if (!ignore && loadCallback) {
loadCallback();
}
}
_private.getLoadResult = () => {
let result = {};
if (_private.info.objects.length > 0) {
result.root = _private.root;
result.objects = _private.info.objects;
}
if (_private.info.images.length > 0) {
result.images = _private.info.images;
}
if (_private.selections.length > 0) {
result.selections = _private.selections;
}
if (_private.blueprints.length > 0) {
result.blueprints = _private.blueprints;
}
if (_private.files.length > 0) {
result.files = _private.files;
}
if (_private.scripts.length > 0) {
result.scripts = _private.scripts;
}
if (_private.extractClasses && !Utils.isEmptyObject(_private.extractClasses)) {
result.extractClasses = _private.extractClasses;
}
if (_private.predownloads.length > 0) {
result.predownloads = _private.predownloads;
}
if (_private.plugins.length > 0) {
result.plugins = _private.plugins;
}
if (_private.relationships.length > 0) {
result.relationships = _private.relationships;
}
if (_private.renderSettings && !Utils.isEmptyObject(_private.renderSettings)) {
result.renderSettings = _private.renderSettings;
}
if (_private.extensions && !Utils.isEmptyObject(_private.extensions)) {
result.extensions = _private.extensions;
}
if (_private.viewpoint && !Utils.isEmptyObject(_private.viewpoint)) {
result.viewpoint = _private.viewpoint;
}
return result;
}
_private.updateProgress = (count = 1) => {
let info = _private.info;
info.number += count;
// Notify loading progress
if (_private.onProgress) {
let progress = info.progress();
if (Utils.isValid(_private.progressParam.index)) {
_private.progressParam.progress = progress;
_private.onProgress(_private.progressParam);
}
else {
_private.onProgress(progress);
}
}
// Check whether load completed
if (_private.info.isComplete()) {
let result = _private.getLoadResult();
if (_private.onComplete) {
_private.onComplete(result, _private.toolkit);
}
_private.resolve(result);
}
}
_private.loadImage = (data) => {
let imageTexture = null;
if (Array.isArray(data)) {
imageTexture = new CubeTexture({
url: data,
onLoad: function () {
_private.updateProgress(6);
}
});
}
else {
let app = Utils.getCurrentApp();
let textureManager = app.resourceManager.getTextureManager();
let url = _private.toolkit.pathResolver.resolveTextureURL(data);
let flipY = false;
let uri = url;
if (uri.indexOf('?') != -1) {
let uriContent = uri.split('?');
uri = uriContent[0];
let params = uriContent[1].split('&');
for (let i = 0; i < params.length; i++) {
let param = params[i].split('=');
if (param[0] == 'flipy') {
flipY = Utils.parseBoolean(param[1], false);
}
}
}
imageTexture = textureManager.load(uri, undefined, { flipY: flipY });
_private.updateProgress();
}
_private.info.images.push(imageTexture);
return imageTexture;
}
_private.processStyles = () => {
_private.styles.forEach((style) => {
if (!style) {
return;
}
for (let key in style) {
if (cStyleTextureKeys.includes(key)) {
let data = style[key];
let image = _private.loadImage(data);
if (!image) {
continue;
}
style[key] = image;
}
}
});
}
_private.loadScripts = () => {
let useExport = (txt) => {
const exportTxt = txt.replaceAll(' ', '');
return exportTxt.includes('export*') || exportTxt.includes('exportdefault') || exportTxt.includes('export{');
}
return new Promise((resolve, reject) => {
let current = 0;
let total = _private.scripts.length;
// check empty
if (total == 0) {
resolve();
}
let checkComplete = () => {
current++;
if (current >= total) {
resolve();
}
}
_private.scripts.forEach(script => {
Utils.loadTextFile(script).then(txt => {
if (useExport(txt)) {
Utils.extractClassesFromScript(script).then((classes) => {
for (const [key, value] of classes.componentClasses) {
_private.extractClasses.componentClasses.set(key, value);
}
for (const [key, value] of classes.bpnodeClasses) {
_private.extractClasses.bpnodeClasses.set(key, value);
}
for (const [key, value] of classes.objectClasses) {
_private.extractClasses.objectClasses.set(key, value);
}
for (const [key, value] of classes.unknownClasses) {
_private.extractClasses.unknownClasses.set(key, value);
}
_private.updateProgress();
checkComplete();
});
}
else {
Utils.loadFile(script, {
onLoad: function () {
_private.updateProgress();
checkComplete();
},
onError: function () {
_private.updateProgress();
reject();
}
})
}
});
})
})
}
_private.loadFiles = () => {
_private.files.forEach(file => {
that.load(file).then(() => {
_private.updateProgress();
});
});
}
_private.loadPredownloads = () => {
_private.predownloads.forEach(predownload => {
// todo: download
_private.updateProgress();
});
}
_private.loadViewpoint = () => {
if (!_private.options.useDefaultViewpoint) {
return;
}
let app = Utils.getCurrentApp();
if (_private.viewpoint.position) {
app.camera.position = _private.viewpoint.position;
}
if (_private.viewpoint.target) {
app.camera.target = _private.viewpoint.target;
}
}
_private.loadResolver = (key, data) => {
let classType = Utils.getRegisteredClass(key);
let resolver = classType ? new classType({ data: data }) : null;
return resolver;
}
_private.loadResolvers = () => {
let app = Utils.getCurrentApp();
app.trigger(EventType.BeforeLoadResolvers, { loader: that });
const keys = Array.from(_private.resolvers.keys());
keys.forEach(key => {
let data = _private.resolvers.get(key);
let resolver = _private.loadResolver(key, data);
_private.resolvers.set(key, resolver);
_private.updateProgress();
})
}
_private.onUpdateCreateOptions = (classType, createOptions, options) => {
if (classType.onParseCreateOptions) {
classType.onParseCreateOptions(createOptions, options);
}
let onUpdateCreateOptions = options['onUpdateCreateOptions'];
if (onUpdateCreateOptions) {
let _private = that[__.private];
onUpdateCreateOptions(_private.root, classType, createOptions);
}
}
_private.getComponentClassType = (component) => {
let componentClassType = null;
// Try to get component type from outside
let onGetComponentClassType = _private.options['onGetComponentClassType'];
if (onGetComponentClassType) {
componentClassType = onGetComponentClassType(component) || componentClassType;
}
// Try to get the component type form scripts of tsf
if (!componentClassType && _private.extractClasses.componentClasses) {
componentClassType = _private.extractClasses.componentClasses.get(component.type);
}
// Try to get the component type form register classes
if (!componentClassType) {
componentClassType = Utils.getRegisteredClasses()[component.type];
}
return componentClassType;
}
_private.loadComponents = (object, components) => {
const {
url,
data,
root,
parent,
onComplete,
complete,
onProgress,
progress,
position,
localPosition,
rotation,
localRotation,
angles,
localAngles,
quaternion,
localQuaternion,
scale,
localScale,
...filteredOptions } = _private.options;
let options = Object.assign(_private.toolkit, filteredOptions);
object.onImportComponents(components, options);
}
_private.generateObject = (objectdata, createOptions) => {
const {
url,
data,
onComplete,
complete,
onProgress,
progress,
position,
localPosition,
rotation,
localRotation,
angles,
localAngles,
quaternion,
localQuaternion,
scale,
localScale,
...filteredOptions } = _private.options;
let params = Object.assign(createOptions, filteredOptions);
let object = new objectdata.classType(params);
return object;
}
_private.processObjectData = (data) => {
if (_private.customObjectProcessCallback) {
data = _private.customObjectProcessCallback(data);
}
return data;
}
_private.loadObjectByIndex = (index, parent) => {
let data = _private.objects[index];
if (!data) {
return null;
}
data = _private.processObjectData(data);
// Build create options
let createOptions = {
id: data.id,
name: data.name,
parent: parent,
style: _private.styles[data.style],
visible: data.visible,
active: data.active,
localPosition: data.position,
localQuaternion: data.quaternion,
localScale: data.scale,
userData: data.userData,
tags: data.tags,
dynamic: _private.dynamic,
components: data.components,
extras: data.extras,
toolkit: _private.toolkit,
error: () => {
// Need to update progress even it's error ...
_private.updateProgress();
},
syncComplete: () => {
_private.updateProgress();
}
};
if (data.res) {
if (data.res.nodeName) {
createOptions.nodeName = data.res.nodeName;
}
if (data.res.uri) {
createOptions.url = data.res.uri;
}
}
// process uuid;
let app = Utils.getCurrentApp();
let baseObject = app.objectManager.getBaseObjectFromUUID(data.uuid)
if (!baseObject) {
createOptions.uuid = data.uuid;
}
// classType
let classType = _private.getObjectClassType(data);
if (!classType) {
if (_private.onError) {
_private.onError({ err: `can not get the object class type, due to 'THING[${data.type}]' is not existing` });
}
return null;
}
data.classType = classType;
// Update create options
_private.onUpdateCreateOptions(data.classType, createOptions, _private.options);
// Create object
let object = _private.generateObject(data, createOptions);
// set visible
if (_private.hidden) {
object.visible = false;
}
// Set the initial bound size to calculate bounding box
// If object had been loaded then skip to set initial local bounding box
if (!object.loaded && data.size) {
object.initialLocalBoundingBox = data.size.initialLocalBoundingBox;
}
// onCreateObject
// todo:
if (_private.onCreateObject) {
_private.onCreateObject(_private.root, object, createOptions);
}
// load children
if (data.children) {
data.children.forEach(index => {
_private.loadObjectByIndex(index, object);
});
}
_private.info.objects.push(object);
_private.objects[index] = object;
return object;
}
_private.loadPrefabByIndex = (index) => {
let _private = that[__.private];
let data = _private.objects[index];
if (!data) {
return;
}
let prefab = _private.root;
if (data.tags) {
if (_private.options.tags) {
prefab.tags = _private.options.tags;
}
else if (prefab.tags) {
prefab.tags = new Set([...prefab.tags, ...data.tags]);
}
else {
prefab.tags = data.tags;
}
}
if (data.id) {
if (_private.options.id) {
prefab.id = _private.options.id;
}
else {
prefab.id = data.id;
}
}
if (data.name) {
if (_private.options.name) {
prefab.name = _private.options.name;
}
else {
prefab.name = data.name;
}
}
if (data.extras) {
let extras = _private.options.extras || _private.options.external;
if (extras) {
prefab.external = extras;
}
else {
prefab.external = Object.assign(prefab.external, data.extras);
}
}
let hasComponent = (name) => {
for (let i = 0; i < _private.options.components.length; i++) {
const element = _private.options.components[i];
if (element.name === name) {
return false;
}
}
return true;
}
// Start to load components of prefab
let components = data.components;
if (components) {
if (_private.options.components) {
components = components.filter(component =>
hasComponent(component.name)
);
}
_private.loadComponents(prefab, components);
}
// Load body resource
let url = data.res ? data.res.uri : null;
if (url) {
let resourceManager = Utils.getCurrentApp().resourceManager;
resourceManager.loadModelAsync(url).then((ev) => {
prefab.setBodyNode(ev.node);
_private.updateProgress();
}).catch((ev) => {
_private.reject(ev);
});
}
else {
_private.updateProgress();
}
// load children
if (data.children) {
data.children.forEach(index => {
let child = _private.loadObjectByIndex(index);
prefab.add(child);
})
}
// set visible
if (_private.hidden) {
prefab.visible = false;
}
_private.objects[index] = prefab;
}
_private.loadRootObjectByIndex = (index) => {
let data = _private.objects[index];
if (!data) {
return;
}
let parent = _private.root;
if (data.parent) {
let uuid = data.parent.uuid;
let result = _private.root.query('[uuid==' + uuid + ']')[0];
if (result) {
parent = result;
}
}
let object = _private.loadObjectByIndex(index, parent);
_private.objects[index] = object;
}
_private.loadRootObjects = () => {
if (!_private.rootObjectIndices) {
return;
}
let isPrefab = _private.extensions && _private.extensions.isPrefab;
let count = _private.rootObjectIndices.length;
if (isPrefab && count == 1) {
let index = _private.rootObjectIndices[0];
_private.loadPrefabByIndex(index);
}
else {
_private.rootObjectIndices.forEach(index => {
_private.loadRootObjectByIndex(index);
})
}
}
_private.makeInstancedDrawing = () => {
if (_private.extensions && !_private.extensions.instances) {
return;
}
_private.extensions.instances.forEach(index => {
_private.objects[index].makeInstancedDrawing(true);
})
}
_private.mapFromArray = (data, arr, callback) => {
let ret;
if (Utils.isArray(data)) {
ret = [];
data.forEach(item => {
ret[i] = callback(item, arr);
})
}
else {
ret = callback(data, arr);
}
return ret;
}
_private.loadRelationship = (relationship) => {
let app = Utils.getCurrentApp();
let data = app.queryRelationships({ uuid: relationship.uuid });
if (data && data.length > 0) {
return;
}
let callback = (index, arr) => {
if (typeof index == 'number') {
return arr[index];
}
let object = _private.root.query('[uuid==' + index.uuid + ']')[0];
return object;
}
if (relationship.source) {
relationship.source = _private.mapFromArray(relationship.source, _private.objects, callback);
}
if (relationship.target) {
relationship.target = _private.mapFromArray(relationship.target, _private.objects, callback);
}
let item = new Relationship({
uuid: relationship.uuid,
type: relationship.type,
source: relationship.source,
target: relationship.target,
name: relationship.name,
queryDirection: relationship.queryDirection
});
return item;
}
_private.loadRelationships = () => {
if (!_private.relationships || _private.relationships.length <= 0) {
return;
}
_private.relationships.forEach((data, index) => {
let relationship = _private.loadRelationship(data);
_private.relationships[index] = relationship;
})
_private.updateProgress();
}
_private.loadBlueprints = () => {
if (!_private.blueprints.length) {
return;
}
_private.blueprints.forEach((data, index) => {
_private.root.blueprint.load({ data: data }).then(blueprint => {
_private.blueprints[index] = blueprint[0];
});
_private.updateProgress();
});
_private.root.blueprint.run();
}
_private.loadSelections = () => {
_private.selections.forEach((data, index) => {
let selector = null;
if (data.condition) {
selector = new Selector();
selector.select(data.condition, _private.objects);
}
else if (data.objects) {
data.objects.forEach((objIndex, index) => {
data.objects[index] = _private.objects[objIndex];
})
selector = new Selector(data.objects);
}
selector.forEach(object => {
if (data.hasOwnProperty('visible')) {
object.setVisible(data.visible, true);
}
if (data.style) {
object.style.copyFromProperties(data.style);
}
})
_private.selections[index] = selector;
_private.updateProgress();
})
}
_private.loadPlugins = () => {
let app = Utils.getCurrentApp();
_private.plugins.forEach((data, index) => {
let url = data.url;
let params = data.params;
app.loadPlugin(url, params).then(plugin => {
_private.plugins[index] = plugin;
_private.updateProgress();
});
})
}
_private.loadTexture = (object, key) => {
if (!object || !object[key]) {
return;
}
let index = object[key];
let uri = _private.URIs[index];
object[key] = _private.loadImage(uri);
}
_private.loadRenderSettings = () => {
if (!_private.renderSettings || Utils.isEmptyObject(_private.renderSettings)) {
return;
}
_private.loadTexture(_private.renderSettings, 'background');
let environment = _private.renderSettings.environment;
_private.loadTexture(environment, 'envMap');
let app = Utils.getCurrentApp();
app.renderSettings = _private.renderSettings;
}
// #endregion
_private.load = (options) => {
_private.reset();
_private.processOptions(options);
return new Promise((resolve, reject) => {
_private.resolve = resolve;
_private.reject = reject;
_private.checkAndParse(options.data, 'extensions', _private.parseExtensions);
_private.checkAndParse(options.data, 'viewpoint', _private.parseViewpoint);
_private.checkAndParse(options.data, 'baseURL', _private.parseBaseURL);
_private.checkAndParse(options.data, 'tags', _private.parseTags);
_private.checkAndParse(options.data, 'URIs', _private.parseURIs);
_private.checkAndParse(options.data, 'styles', _private.parseStyles);
_private.checkAndParse(options.data, 'objects', _private.parseObjects);
_private.checkAndParse(options.data, 'components', _private.parseComponents);
_private.checkAndParse(options.data, 'relationships', _private.parseRelationships);
_private.checkAndParse(options.data, 'blueprints', _private.parseBlueprints);
_private.checkAndParse(options.data, 'selections', _private.parseSelections);
_private.checkAndParse(options.data, 'plugins', _private.parsePlugins);
_private.checkAndParse(options.data, 'files', _private.parseFiles);
_private.checkAndParse(options.data, 'predownloads', _private.parsePredownloads);
_private.checkAndParse(options.data, 'renderSettings', _private.parseRenderSettings);
_private.checkAndParse(options.data, 'scripts', _private.parseScripts);
_private.checkAndParse(options.data, 'resolvers', _private.parseResolvers);
_private.processStyles();
_private.loadScripts().then(() => {
_private.loadViewpoint();
_private.loadResolvers();
_private.loadRootObjects();
_private.makeInstancedDrawing();
_private.checkAndLoad('relationships', _private.loadRelationships);
_private.checkAndLoad('blueprints', _private.loadBlueprints);
_private.checkAndLoad('selections', _private.loadSelections);
_private.checkAndLoad('plugins', _private.loadPlugins);
_private.checkAndLoad('files', _private.loadFiles);
_private.checkAndLoad('predownloads', _private.loadPredownloads);
_private.checkAndLoad('renderSettings', _private.loadRenderSettings);
});
// check complete; because the loader maybe do nothing
_private.updateProgress(0);
}).catch((ev) => {
if (_private.onError) {
_private.onError(ev);
_private.reject(ev);
}
})
}
_private.reset = () => {
_private.baseURL = '';
_private.currentPath = '';
_private.tags.length = 0;
_private.URIs.length = 0;
_private.rootObjectIndices.length = 0;
_private.objects.length = 0;
_private.styles.length = 0;
_private.relationships.length = 0;
_private.blueprints.length = 0;
_private.selections.length = 0;
_private.plugins.length = 0;
_private.renderSettings = {};
_private.extensions = {};
_private.viewpoint = {};
_private.options = {};
_private.scripts.length = 0;
_private.extractClasses.reset();
_private.files.length = 0;
_private.predownloads.length = 0;
_private.resolvers.clear();
_private.info.reset();
_private.ignore = {};
_private.progressParam.index = null;
_private.progressParam.progress = 0;
}
_private.init = () => {
_private.baseURL = '';
_private.currentPath = '';
_private.tags = [];
_private.URIs = [];
_private.rootObjectIndices = [];
_private.objects = [];
_private.styles = [];
_private.relationships = [];
_private.blueprints = [];
_private.selections = [];
_private.plugins = [];
_private.renderSettings = {};
_private.extensions = {};
_private.viewpoint = {};
_private.scripts = [];
_private.extractClasses = {
componentClasses: new Map(),
bpnodeClasses: new Map(),
objectClasses: new Map(),
unknownClasses: new Map(),
reset: function () {
this.componentClasses.clear();
this.bpnodeClasses.clear();
this.objectClasses.clear();
this.unknownClasses.clear();
}
};
_private.files = [];
_private.predownloads = [];
_private.resolvers = new Map();
_private.options = {};
_private.ignore = {};
_private.progressParam = {
index: null,
progress: 0
};
_private.info = {
number: 0,
totalNumber: 0,
objects: [],
images: [],
progress: function () {
if (this.number >= this.totalNumber || this.totalNumber <= 0) {
return 1;
}
return this.number / this.totalNumber;
},
isComplete: function () {
return this.number >= this.totalNumber;
},
reset: function () {
this.number = 0;
this.totalNumber = 0;
this.objects.length = 0;
this.images.length = 0;
}
};
_private.toolkit = {
tsfResolver: new TSFResolver({
getURIs: function () {
return _private.URIs;
}
}),
pathResolver: new PathResolver({
getOptions: function () {
return _private.options;
},
// this is the url which will be attached by XXXX
getBaseURL: function () {
return _private.baseURL;
},
// this is the path which will be attached by ./ or ../
getCurrentPath: function () {
return _private.currentPath;
}
}),
getResolver: function (type) {
return _private.resolvers.get(type);
},
args: {
isTemporary: true,
isEditor: _private.isEditor
},
onGetObjectClassType: (component) => {
return _private.getComponentClassType(component);
},
onGetComponentExternalData: _private.options['onGetComponentExternalData'],
onError: _private.onError
}
}
_private.init();
}
/**
* @class SceneLoader
* The scene object loader.
* @memberof THING.EXTEND
*/
class SceneLoader {
/**
* The loader of scene
*/
constructor() {
_initPrivateMembers(this);
}
reset() {
let _private = this[__.private];
_private.reset();
}
load(options = {}) {
let _private = this[__.private];
_private.load(options);
}
}
export { SceneLoader }