mirror of
				https://github.com/jiawanlong/Cesium-Examples.git
				synced 2025-11-04 01:04:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1669 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1669 lines
		
	
	
		
			57 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
(function webpackUniversalModuleDefinition(root, factory) {
 | 
						|
	if(typeof exports === 'object' && typeof module === 'object')
 | 
						|
		module.exports = factory(require("three-wtm"), require("three"));
 | 
						|
	else if(typeof define === 'function' && define.amd)
 | 
						|
		define(["three-wtm", "three"], factory);
 | 
						|
	else if(typeof exports === 'object')
 | 
						|
		exports["wwobjloader2"] = factory(require("threeWtm"), require("three"));
 | 
						|
	else
 | 
						|
		root["wwobjloader2"] = factory(root["threeWtm"], root["THREE"]);
 | 
						|
})(window, function(__WEBPACK_EXTERNAL_MODULE__0__, __WEBPACK_EXTERNAL_MODULE__1__) {
 | 
						|
return /******/ (function(modules) { // webpackBootstrap
 | 
						|
/******/ 	// The module cache
 | 
						|
/******/ 	var installedModules = {};
 | 
						|
/******/
 | 
						|
/******/ 	// The require function
 | 
						|
/******/ 	function __webpack_require__(moduleId) {
 | 
						|
/******/
 | 
						|
/******/ 		// Check if module is in cache
 | 
						|
/******/ 		if(installedModules[moduleId]) {
 | 
						|
/******/ 			return installedModules[moduleId].exports;
 | 
						|
/******/ 		}
 | 
						|
/******/ 		// Create a new module (and put it into the cache)
 | 
						|
/******/ 		var module = installedModules[moduleId] = {
 | 
						|
/******/ 			i: moduleId,
 | 
						|
/******/ 			l: false,
 | 
						|
/******/ 			exports: {}
 | 
						|
/******/ 		};
 | 
						|
/******/
 | 
						|
/******/ 		// Execute the module function
 | 
						|
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
 | 
						|
/******/
 | 
						|
/******/ 		// Flag the module as loaded
 | 
						|
/******/ 		module.l = true;
 | 
						|
/******/
 | 
						|
/******/ 		// Return the exports of the module
 | 
						|
/******/ 		return module.exports;
 | 
						|
/******/ 	}
 | 
						|
/******/
 | 
						|
/******/
 | 
						|
/******/ 	// expose the modules object (__webpack_modules__)
 | 
						|
/******/ 	__webpack_require__.m = modules;
 | 
						|
/******/
 | 
						|
/******/ 	// expose the module cache
 | 
						|
/******/ 	__webpack_require__.c = installedModules;
 | 
						|
/******/
 | 
						|
/******/ 	// define getter function for harmony exports
 | 
						|
/******/ 	__webpack_require__.d = function(exports, name, getter) {
 | 
						|
/******/ 		if(!__webpack_require__.o(exports, name)) {
 | 
						|
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
 | 
						|
/******/ 		}
 | 
						|
/******/ 	};
 | 
						|
/******/
 | 
						|
/******/ 	// define __esModule on exports
 | 
						|
/******/ 	__webpack_require__.r = function(exports) {
 | 
						|
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
 | 
						|
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
 | 
						|
/******/ 		}
 | 
						|
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
 | 
						|
/******/ 	};
 | 
						|
/******/
 | 
						|
/******/ 	// create a fake namespace object
 | 
						|
/******/ 	// mode & 1: value is a module id, require it
 | 
						|
/******/ 	// mode & 2: merge all properties of value into the ns
 | 
						|
/******/ 	// mode & 4: return value when already ns object
 | 
						|
/******/ 	// mode & 8|1: behave like require
 | 
						|
/******/ 	__webpack_require__.t = function(value, mode) {
 | 
						|
/******/ 		if(mode & 1) value = __webpack_require__(value);
 | 
						|
/******/ 		if(mode & 8) return value;
 | 
						|
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
 | 
						|
/******/ 		var ns = Object.create(null);
 | 
						|
/******/ 		__webpack_require__.r(ns);
 | 
						|
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
 | 
						|
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
 | 
						|
/******/ 		return ns;
 | 
						|
/******/ 	};
 | 
						|
/******/
 | 
						|
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
 | 
						|
/******/ 	__webpack_require__.n = function(module) {
 | 
						|
/******/ 		var getter = module && module.__esModule ?
 | 
						|
/******/ 			function getDefault() { return module['default']; } :
 | 
						|
/******/ 			function getModuleExports() { return module; };
 | 
						|
/******/ 		__webpack_require__.d(getter, 'a', getter);
 | 
						|
/******/ 		return getter;
 | 
						|
/******/ 	};
 | 
						|
/******/
 | 
						|
/******/ 	// Object.prototype.hasOwnProperty.call
 | 
						|
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
 | 
						|
/******/
 | 
						|
/******/ 	// __webpack_public_path__
 | 
						|
/******/ 	__webpack_require__.p = "";
 | 
						|
/******/
 | 
						|
/******/
 | 
						|
/******/ 	// Load entry module and return exports
 | 
						|
/******/ 	return __webpack_require__(__webpack_require__.s = 2);
 | 
						|
/******/ })
 | 
						|
/************************************************************************/
 | 
						|
/******/ ([
 | 
						|
/* 0 */
 | 
						|
/***/ (function(module, exports) {
 | 
						|
 | 
						|
module.exports = __WEBPACK_EXTERNAL_MODULE__0__;
 | 
						|
 | 
						|
/***/ }),
 | 
						|
/* 1 */
 | 
						|
/***/ (function(module, exports) {
 | 
						|
 | 
						|
module.exports = __WEBPACK_EXTERNAL_MODULE__1__;
 | 
						|
 | 
						|
/***/ }),
 | 
						|
/* 2 */
 | 
						|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
 | 
						|
 | 
						|
"use strict";
 | 
						|
__webpack_require__.r(__webpack_exports__);
 | 
						|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MtlObjBridge", function() { return MtlObjBridge; });
 | 
						|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJLoader2", function() { return OBJLoader2; });
 | 
						|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJLoader2Parallel", function() { return OBJLoader2Parallel; });
 | 
						|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJLoader2Parser", function() { return OBJLoader2Parser; });
 | 
						|
/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
 | 
						|
/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(three__WEBPACK_IMPORTED_MODULE_0__);
 | 
						|
/* harmony import */ var three_wtm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
 | 
						|
/* harmony import */ var three_wtm__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(three_wtm__WEBPACK_IMPORTED_MODULE_1__);
 | 
						|
 | 
						|
 | 
						|
 | 
						|
function _defineProperty(obj, key, value) {
 | 
						|
  if (key in obj) {
 | 
						|
    Object.defineProperty(obj, key, {
 | 
						|
      value: value,
 | 
						|
      enumerable: true,
 | 
						|
      configurable: true,
 | 
						|
      writable: true
 | 
						|
    });
 | 
						|
  } else {
 | 
						|
    obj[key] = value;
 | 
						|
  }
 | 
						|
 | 
						|
  return obj;
 | 
						|
}
 | 
						|
/**
 | 
						|
 * Creates a new OBJLoader2. Use it to load OBJ data from files or to parse OBJ data from arraybuffer or text.
 | 
						|
 *
 | 
						|
 * @param {LoadingManager} [manager] The loadingManager for the loader to use. Default is {@link LoadingManager}
 | 
						|
 * @constructor
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
class OBJLoader2 extends three__WEBPACK_IMPORTED_MODULE_0__["Loader"] {
 | 
						|
  /**
 | 
						|
   *
 | 
						|
   * @param {LoadingManager} [manager]
 | 
						|
   */
 | 
						|
  constructor(manager) {
 | 
						|
    super(manager);
 | 
						|
    this.parser = new OBJLoader2Parser();
 | 
						|
    this.materialStore = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialStore"](true);
 | 
						|
    this.parser.materials = this.materialStore.getMaterials();
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
 | 
						|
   *
 | 
						|
   * @param {boolean} enabled True or false.
 | 
						|
   * @param {boolean} debug True or false.
 | 
						|
   *
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setLogging(enabled, debug) {
 | 
						|
    this.parser.logging.enabled = enabled === true;
 | 
						|
    this.parser.logging.debug = debug === true;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Tells whether a material shall be created per smoothing group.
 | 
						|
   *
 | 
						|
   * @param {boolean} materialPerSmoothingGroup=false
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setMaterialPerSmoothingGroup(materialPerSmoothingGroup) {
 | 
						|
    this.parser.aterialPerSmoothingGroup = materialPerSmoothingGroup === true;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Usually 'o' is meta-information and does not result in creation of new meshes, but mesh creation on occurrence of "o" can be enforced.
 | 
						|
   *
 | 
						|
   * @param {boolean} useOAsMesh=false
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setUseOAsMesh(useOAsMesh) {
 | 
						|
    this.parser.useOAsMesh = useOAsMesh === true;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Instructs loaders to create indexed {@link BufferGeometry}.
 | 
						|
   *
 | 
						|
   * @param {boolean} useIndices=false
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setUseIndices(useIndices) {
 | 
						|
    this.parser.useIndices = useIndices === true;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Tells whether normals should be completely disregarded and regenerated.
 | 
						|
   *
 | 
						|
   * @param {boolean} disregardNormals=false
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setDisregardNormals(disregardNormals) {
 | 
						|
    this.parser.disregardNormals = disregardNormals === true;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Set the name of the model.
 | 
						|
   *
 | 
						|
   * @param {string} modelName
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setModelName(modelName) {
 | 
						|
    if (modelName) {
 | 
						|
      this.parser.modelName = modelName;
 | 
						|
    }
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Returns the name of the models
 | 
						|
   * @return {String}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  getModelName() {
 | 
						|
    return this.parser.modelName;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Set the node where the loaded objects will be attached directly.
 | 
						|
   *
 | 
						|
   * @param {Object3D} baseObject3d Object already attached to scenegraph where new meshes will be attached to
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setBaseObject3d(baseObject3d) {
 | 
						|
    this.parser.baseObject3d = baseObject3d === undefined || baseObject3d === null ? this.parser.baseObject3d : baseObject3d;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Clears materials object and sets the new ones.
 | 
						|
   *
 | 
						|
   * @param {Object} materials Object with named materials
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setMaterials(materials) {
 | 
						|
    this.materialStore.addMaterials(materials, false);
 | 
						|
    this.parser.materials = this.materialStore.getMaterials();
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Register a function that is used to report overall processing progress.
 | 
						|
   *
 | 
						|
   * @param {Function} onProgress
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setCallbackOnProgress(onProgress) {
 | 
						|
    if (onProgress !== null && onProgress !== undefined && onProgress instanceof Function) {
 | 
						|
      this.parser.callbacks.onProgress = onProgress;
 | 
						|
    }
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Register an error handler function that is called if errors occur. It can decide to just log or to throw an exception.
 | 
						|
   *
 | 
						|
   * @param {Function} onError
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setCallbackOnError(onError) {
 | 
						|
    if (onError !== null && onError !== undefined && onError instanceof Function) {
 | 
						|
      this.parser.callbacks.onError = onError;
 | 
						|
    }
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Register a function that is called when parsing was completed.
 | 
						|
   *
 | 
						|
   * @param {Function} onLoad
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setCallbackOnLoad(onLoad) {
 | 
						|
    if (onLoad !== null && onLoad !== undefined && onLoad instanceof Function) {
 | 
						|
      this.parser.callbacks.onLoad = onLoad;
 | 
						|
    }
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Register a function that is called once a single mesh is available and it could be altered by the supplied function.
 | 
						|
   *
 | 
						|
   * @param {Function} [onMeshAlter]
 | 
						|
   * @return {OBJLoader2}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setCallbackOnMeshAlter(onMeshAlter) {
 | 
						|
    if (onMeshAlter !== null && onMeshAlter !== undefined && onMeshAlter instanceof Function) {
 | 
						|
      this.parser.callbacks.onMeshAlter = onMeshAlter;
 | 
						|
    }
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Use this convenient method to load a file at the given URL. By default the fileLoader uses an ArrayBuffer.
 | 
						|
   *
 | 
						|
   * @param {string}  url A string containing the path/URL of the file to be loaded.
 | 
						|
   * @param {Function} onLoad A function to be called after loading is successfully completed. The function receives loaded Object3D as an argument.
 | 
						|
   * @param {Function} [onFileLoadProgress] A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, which contains total and Integer bytes.
 | 
						|
   * @param {Function} [onError] A function to be called if an error occurs during loading. The function receives the error as an argument.
 | 
						|
   * @param {Function} [onMeshAlter] Called after every single mesh is made available by the parser
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  load(url, onLoad, onFileLoadProgress, onError, onMeshAlter) {
 | 
						|
    if (onLoad === null || onLoad === undefined || !(onLoad instanceof Function)) {
 | 
						|
      const errorMessage = 'onLoad is not a function! Aborting...';
 | 
						|
 | 
						|
      this.parser._onError(errorMessage);
 | 
						|
 | 
						|
      throw errorMessage;
 | 
						|
    } else {
 | 
						|
      this.setCallbackOnLoad(onLoad);
 | 
						|
    }
 | 
						|
 | 
						|
    const scope = this;
 | 
						|
 | 
						|
    if (onError === null || onError === undefined || !(onError instanceof Function)) {
 | 
						|
      onError = function (event) {
 | 
						|
        let errorMessage = event;
 | 
						|
 | 
						|
        if (event.currentTarget && event.currentTarget.statusText !== null) {
 | 
						|
          errorMessage = 'Error occurred while downloading!\nurl: ' + event.currentTarget.responseURL + '\nstatus: ' + event.currentTarget.statusText;
 | 
						|
        }
 | 
						|
 | 
						|
        scope.parser._onError(errorMessage);
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
    if (!url) {
 | 
						|
      onError('An invalid url was provided. Unable to continue!');
 | 
						|
    }
 | 
						|
 | 
						|
    const urlFull = new URL(url, window.location.href).href;
 | 
						|
    let filename = urlFull;
 | 
						|
    const urlParts = urlFull.split('/');
 | 
						|
 | 
						|
    if (urlParts.length > 2) {
 | 
						|
      filename = urlParts[urlParts.length - 1];
 | 
						|
      let urlPartsPath = urlParts.slice(0, urlParts.length - 1).join('/') + '/';
 | 
						|
      if (urlPartsPath !== undefined) this.path = urlPartsPath;
 | 
						|
    }
 | 
						|
 | 
						|
    if (onFileLoadProgress === null || onFileLoadProgress === undefined || !(onFileLoadProgress instanceof Function)) {
 | 
						|
      let numericalValueRef = 0;
 | 
						|
      let numericalValue = 0;
 | 
						|
 | 
						|
      onFileLoadProgress = function (event) {
 | 
						|
        if (!event.lengthComputable) return;
 | 
						|
        numericalValue = event.loaded / event.total;
 | 
						|
 | 
						|
        if (numericalValue > numericalValueRef) {
 | 
						|
          numericalValueRef = numericalValue;
 | 
						|
          const output = 'Download of "' + url + '": ' + (numericalValue * 100).toFixed(2) + '%';
 | 
						|
 | 
						|
          scope.parser._onProgress('progressLoad', output, numericalValue);
 | 
						|
        }
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
    this.setCallbackOnMeshAlter(onMeshAlter);
 | 
						|
 | 
						|
    const fileLoaderOnLoad = function (content) {
 | 
						|
      scope.parse(content);
 | 
						|
    };
 | 
						|
 | 
						|
    const fileLoader = new three__WEBPACK_IMPORTED_MODULE_0__["FileLoader"](this.manager);
 | 
						|
    fileLoader.setPath(this.path || this.resourcePath);
 | 
						|
    fileLoader.setResponseType('arraybuffer');
 | 
						|
    fileLoader.load(filename, fileLoaderOnLoad, onFileLoadProgress, onError);
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Parses OBJ data synchronously from arraybuffer or string and returns the {@link Object3D}.
 | 
						|
   *
 | 
						|
   * @param {arraybuffer|string} content OBJ data as Uint8Array or String
 | 
						|
   * @return {Object3D}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  parse(content) {
 | 
						|
    if (this.parser.logging.enabled) {
 | 
						|
      console.info('Using OBJLoader2 version: ' + OBJLoader2.OBJLOADER2_VERSION);
 | 
						|
    } // fast-fail in case of illegal data
 | 
						|
 | 
						|
 | 
						|
    if (content === null || content === undefined) {
 | 
						|
      throw 'Provided content is not a valid ArrayBuffer or String. Unable to continue parsing';
 | 
						|
    }
 | 
						|
 | 
						|
    if (this.parser.logging.enabled) {
 | 
						|
      console.time('OBJLoader parse: ' + this.modelName);
 | 
						|
    }
 | 
						|
 | 
						|
    if (content instanceof ArrayBuffer || content instanceof Uint8Array) {
 | 
						|
      if (this.parser.logging.enabled) console.info('Parsing arrayBuffer...');
 | 
						|
 | 
						|
      this.parser._execute(content);
 | 
						|
    } else if (typeof content === 'string' || content instanceof String) {
 | 
						|
      if (this.parser.logging.enabled) console.info('Parsing text...');
 | 
						|
 | 
						|
      this.parser._executeLegacy(content);
 | 
						|
    } else {
 | 
						|
      this.parser._onError('Provided content was neither of type String nor Uint8Array! Aborting...');
 | 
						|
    }
 | 
						|
 | 
						|
    if (this.parser.logging.enabled) {
 | 
						|
      console.timeEnd('OBJLoader parse: ' + this.modelName);
 | 
						|
    }
 | 
						|
 | 
						|
    return this.parser.baseObject3d;
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
_defineProperty(OBJLoader2, "OBJLOADER2_VERSION", '4.0.0-dev');
 | 
						|
 | 
						|
class OBJLoader2Parser {
 | 
						|
  constructor() {
 | 
						|
    this.logging = {
 | 
						|
      enabled: false,
 | 
						|
      debug: false
 | 
						|
    };
 | 
						|
    this.usedBefore = false;
 | 
						|
 | 
						|
    this._init();
 | 
						|
 | 
						|
    this.callbacks = {
 | 
						|
      onLoad: null,
 | 
						|
      onError: null,
 | 
						|
      onProgress: null,
 | 
						|
      onMeshAlter: null
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  _init() {
 | 
						|
    this.contentRef = null;
 | 
						|
    this.legacyMode = false;
 | 
						|
    this.materials = {};
 | 
						|
    this.baseObject3d = new three__WEBPACK_IMPORTED_MODULE_0__["Object3D"]();
 | 
						|
    this.modelName = 'noname';
 | 
						|
    this.materialPerSmoothingGroup = false;
 | 
						|
    this.useOAsMesh = false;
 | 
						|
    this.useIndices = false;
 | 
						|
    this.disregardNormals = false;
 | 
						|
    this.vertices = [];
 | 
						|
    this.colors = [];
 | 
						|
    this.normals = [];
 | 
						|
    this.uvs = [];
 | 
						|
    this.objectId = 0;
 | 
						|
    this.rawMesh = {
 | 
						|
      objectName: '',
 | 
						|
      groupName: '',
 | 
						|
      activeMtlName: '',
 | 
						|
      mtllibName: '',
 | 
						|
      // reset with new mesh
 | 
						|
      faceType: -1,
 | 
						|
      subGroups: [],
 | 
						|
      subGroupInUse: null,
 | 
						|
      smoothingGroup: {
 | 
						|
        splitMaterials: false,
 | 
						|
        normalized: -1,
 | 
						|
        real: -1
 | 
						|
      },
 | 
						|
      counts: {
 | 
						|
        doubleIndicesCount: 0,
 | 
						|
        faceCount: 0,
 | 
						|
        mtlCount: 0,
 | 
						|
        smoothingGroupCount: 0
 | 
						|
      }
 | 
						|
    };
 | 
						|
    this.inputObjectCount = 1;
 | 
						|
    this.outputObjectCount = 1;
 | 
						|
    this.globalCounts = {
 | 
						|
      vertices: 0,
 | 
						|
      faces: 0,
 | 
						|
      doubleIndicesCount: 0,
 | 
						|
      lineByte: 0,
 | 
						|
      currentByte: 0,
 | 
						|
      totalBytes: 0
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  _resetRawMesh() {
 | 
						|
    // faces are stored according combined index of group, material and smoothingGroup (0 or not)
 | 
						|
    this.rawMesh.subGroups = [];
 | 
						|
    this.rawMesh.subGroupInUse = null;
 | 
						|
    this.rawMesh.smoothingGroup.normalized = -1;
 | 
						|
    this.rawMesh.smoothingGroup.real = -1; // this default index is required as it is possible to define faces without 'g' or 'usemtl'
 | 
						|
 | 
						|
    this._pushSmoothingGroup(1);
 | 
						|
 | 
						|
    this.rawMesh.counts.doubleIndicesCount = 0;
 | 
						|
    this.rawMesh.counts.faceCount = 0;
 | 
						|
    this.rawMesh.counts.mtlCount = 0;
 | 
						|
    this.rawMesh.counts.smoothingGroupCount = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  _configure() {
 | 
						|
    this.usedBefore = true;
 | 
						|
 | 
						|
    this._pushSmoothingGroup(1);
 | 
						|
 | 
						|
    if (this.logging.enabled) {
 | 
						|
      const matKeys = Object.keys(this.materials);
 | 
						|
      const matNames = matKeys.length > 0 ? '\n\tmaterialNames:\n\t\t- ' + matKeys.join('\n\t\t- ') : '\n\tmaterialNames: None';
 | 
						|
      let printedConfig = 'OBJLoader2 Parser configuration:' + matNames + '\n\tmaterialPerSmoothingGroup: ' + this.materialPerSmoothingGroup + '\n\tuseOAsMesh: ' + this.useOAsMesh + '\n\tuseIndices: ' + this.useIndices + '\n\tdisregardNormals: ' + this.disregardNormals;
 | 
						|
      if (this.callbacks.onProgress !== null) printedConfig += '\n\tcallbacks.onProgress: ' + this.callbacks.onProgress.name;
 | 
						|
      if (this.callbacks.onError !== null) printedConfig += '\n\tcallbacks.onError: ' + this.callbacks.onError.name;
 | 
						|
      if (this.callbacks.onMeshAlter !== null) printedConfig += '\n\tcallbacks.onMeshAlter: ' + this.callbacks.onMeshAlter.name;
 | 
						|
      if (this.callbacks.onLoad !== null) printedConfig += '\n\tcallbacks.onLoad: ' + this.callbacks.onLoad.name;
 | 
						|
      console.info(printedConfig);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Parse the provided arraybuffer
 | 
						|
   *
 | 
						|
   * @param {Uint8Array} arrayBuffer OBJ data as Uint8Array
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _execute(arrayBuffer) {
 | 
						|
    if (this.logging.enabled) console.time('OBJLoader2Parser.execute');
 | 
						|
 | 
						|
    this._configure();
 | 
						|
 | 
						|
    const arrayBufferView = new Uint8Array(arrayBuffer);
 | 
						|
    this.contentRef = arrayBufferView;
 | 
						|
    const length = arrayBufferView.byteLength;
 | 
						|
    this.globalCounts.totalBytes = length;
 | 
						|
    const buffer = new Array(128);
 | 
						|
    let bufferPointer = 0;
 | 
						|
    let slashesCount = 0;
 | 
						|
    let word = '';
 | 
						|
    let currentByte = 0;
 | 
						|
 | 
						|
    for (let code; currentByte < length; currentByte++) {
 | 
						|
      code = arrayBufferView[currentByte];
 | 
						|
 | 
						|
      switch (code) {
 | 
						|
        // space
 | 
						|
        case 32:
 | 
						|
          if (word.length > 0) buffer[bufferPointer++] = word;
 | 
						|
          word = '';
 | 
						|
          break;
 | 
						|
        // slash
 | 
						|
 | 
						|
        case 47:
 | 
						|
          if (word.length > 0) buffer[bufferPointer++] = word;
 | 
						|
          slashesCount++;
 | 
						|
          word = '';
 | 
						|
          break;
 | 
						|
        // LF
 | 
						|
 | 
						|
        case 10:
 | 
						|
          this._processLine(buffer, bufferPointer, slashesCount, word, currentByte);
 | 
						|
 | 
						|
          word = '';
 | 
						|
          bufferPointer = 0;
 | 
						|
          slashesCount = 0;
 | 
						|
          break;
 | 
						|
        // CR
 | 
						|
 | 
						|
        case 13:
 | 
						|
          break;
 | 
						|
 | 
						|
        default:
 | 
						|
          word += String.fromCharCode(code);
 | 
						|
          break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    this._processLine(buffer, bufferPointer, slashesCount, word, currentByte);
 | 
						|
 | 
						|
    this._finalizeParsing();
 | 
						|
 | 
						|
    if (this.logging.enabled) console.timeEnd('OBJLoader2Parser.execute');
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Parse the provided text
 | 
						|
   *
 | 
						|
   * @param {string} text OBJ data as string
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _executeLegacy(text) {
 | 
						|
    if (this.logging.enabled) console.time('OBJLoader2Parser.executeLegacy');
 | 
						|
 | 
						|
    this._configure();
 | 
						|
 | 
						|
    this.legacyMode = true;
 | 
						|
    this.contentRef = text;
 | 
						|
    const length = text.length;
 | 
						|
    this.globalCounts.totalBytes = length;
 | 
						|
    const buffer = new Array(128);
 | 
						|
    let bufferPointer = 0;
 | 
						|
    let slashesCount = 0;
 | 
						|
    let word = '';
 | 
						|
    let currentByte = 0;
 | 
						|
 | 
						|
    for (let char; currentByte < length; currentByte++) {
 | 
						|
      char = text[currentByte];
 | 
						|
 | 
						|
      switch (char) {
 | 
						|
        case ' ':
 | 
						|
          if (word.length > 0) buffer[bufferPointer++] = word;
 | 
						|
          word = '';
 | 
						|
          break;
 | 
						|
 | 
						|
        case '/':
 | 
						|
          if (word.length > 0) buffer[bufferPointer++] = word;
 | 
						|
          slashesCount++;
 | 
						|
          word = '';
 | 
						|
          break;
 | 
						|
 | 
						|
        case '\n':
 | 
						|
          this._processLine(buffer, bufferPointer, slashesCount, word, currentByte);
 | 
						|
 | 
						|
          word = '';
 | 
						|
          bufferPointer = 0;
 | 
						|
          slashesCount = 0;
 | 
						|
          break;
 | 
						|
 | 
						|
        case '\r':
 | 
						|
          break;
 | 
						|
 | 
						|
        default:
 | 
						|
          word += char;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    this._processLine(buffer, bufferPointer, word, slashesCount);
 | 
						|
 | 
						|
    this._finalizeParsing();
 | 
						|
 | 
						|
    if (this.logging.enabled) console.timeEnd('OBJLoader2Parser.executeLegacy');
 | 
						|
  }
 | 
						|
 | 
						|
  _processLine(buffer, bufferPointer, slashesCount, word, currentByte) {
 | 
						|
    this.globalCounts.lineByte = this.globalCounts.currentByte;
 | 
						|
    this.globalCounts.currentByte = currentByte;
 | 
						|
    if (bufferPointer < 1) return;
 | 
						|
    if (word.length > 0) buffer[bufferPointer++] = word;
 | 
						|
 | 
						|
    const reconstructString = function (content, legacyMode, start, stop) {
 | 
						|
      let line = '';
 | 
						|
 | 
						|
      if (stop > start) {
 | 
						|
        let i;
 | 
						|
 | 
						|
        if (legacyMode) {
 | 
						|
          for (i = start; i < stop; i++) line += content[i];
 | 
						|
        } else {
 | 
						|
          for (i = start; i < stop; i++) line += String.fromCharCode(content[i]);
 | 
						|
        }
 | 
						|
 | 
						|
        line = line.trim();
 | 
						|
      }
 | 
						|
 | 
						|
      return line;
 | 
						|
    };
 | 
						|
 | 
						|
    let bufferLength, length, i;
 | 
						|
    const lineDesignation = buffer[0];
 | 
						|
 | 
						|
    switch (lineDesignation) {
 | 
						|
      case 'v':
 | 
						|
        this.vertices.push(parseFloat(buffer[1]));
 | 
						|
        this.vertices.push(parseFloat(buffer[2]));
 | 
						|
        this.vertices.push(parseFloat(buffer[3]));
 | 
						|
 | 
						|
        if (bufferPointer > 4) {
 | 
						|
          this.colors.push(parseFloat(buffer[4]));
 | 
						|
          this.colors.push(parseFloat(buffer[5]));
 | 
						|
          this.colors.push(parseFloat(buffer[6]));
 | 
						|
        }
 | 
						|
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'vt':
 | 
						|
        this.uvs.push(parseFloat(buffer[1]));
 | 
						|
        this.uvs.push(parseFloat(buffer[2]));
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'vn':
 | 
						|
        this.normals.push(parseFloat(buffer[1]));
 | 
						|
        this.normals.push(parseFloat(buffer[2]));
 | 
						|
        this.normals.push(parseFloat(buffer[3]));
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'f':
 | 
						|
        bufferLength = bufferPointer - 1; // "f vertex ..."
 | 
						|
 | 
						|
        if (slashesCount === 0) {
 | 
						|
          this._checkFaceType(0);
 | 
						|
 | 
						|
          for (i = 2, length = bufferLength; i < length; i++) {
 | 
						|
            this._buildFace(buffer[1]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i + 1]);
 | 
						|
          } // "f vertex/uv ..."
 | 
						|
 | 
						|
        } else if (bufferLength === slashesCount * 2) {
 | 
						|
          this._checkFaceType(1);
 | 
						|
 | 
						|
          for (i = 3, length = bufferLength - 2; i < length; i += 2) {
 | 
						|
            this._buildFace(buffer[1], buffer[2]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i], buffer[i + 1]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i + 2], buffer[i + 3]);
 | 
						|
          } // "f vertex/uv/normal ..."
 | 
						|
 | 
						|
        } else if (bufferLength * 2 === slashesCount * 3) {
 | 
						|
          this._checkFaceType(2);
 | 
						|
 | 
						|
          for (i = 4, length = bufferLength - 3; i < length; i += 3) {
 | 
						|
            this._buildFace(buffer[1], buffer[2], buffer[3]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i], buffer[i + 1], buffer[i + 2]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i + 3], buffer[i + 4], buffer[i + 5]);
 | 
						|
          } // "f vertex//normal ..."
 | 
						|
 | 
						|
        } else {
 | 
						|
          this._checkFaceType(3);
 | 
						|
 | 
						|
          for (i = 3, length = bufferLength - 2; i < length; i += 2) {
 | 
						|
            this._buildFace(buffer[1], undefined, buffer[2]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i], undefined, buffer[i + 1]);
 | 
						|
 | 
						|
            this._buildFace(buffer[i + 2], undefined, buffer[i + 3]);
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'l':
 | 
						|
      case 'p':
 | 
						|
        bufferLength = bufferPointer - 1;
 | 
						|
 | 
						|
        if (bufferLength === slashesCount * 2) {
 | 
						|
          this._checkFaceType(4);
 | 
						|
 | 
						|
          for (i = 1, length = bufferLength + 1; i < length; i += 2) this._buildFace(buffer[i], buffer[i + 1]);
 | 
						|
        } else {
 | 
						|
          this._checkFaceType(lineDesignation === 'l' ? 5 : 6);
 | 
						|
 | 
						|
          for (i = 1, length = bufferLength + 1; i < length; i++) this._buildFace(buffer[i]);
 | 
						|
        }
 | 
						|
 | 
						|
        break;
 | 
						|
 | 
						|
      case 's':
 | 
						|
        this._pushSmoothingGroup(buffer[1]);
 | 
						|
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'g':
 | 
						|
        // 'g' leads to creation of mesh if valid data (faces declaration was done before), otherwise only groupName gets set
 | 
						|
        this._processCompletedMesh();
 | 
						|
 | 
						|
        this.rawMesh.groupName = reconstructString(this.contentRef, this.legacyMode, this.globalCounts.lineByte + 2, this.globalCounts.currentByte);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'o':
 | 
						|
        // 'o' is meta-information and usually does not result in creation of new meshes, but can be enforced with "useOAsMesh"
 | 
						|
        if (this.useOAsMesh) this._processCompletedMesh();
 | 
						|
        this.rawMesh.objectName = reconstructString(this.contentRef, this.legacyMode, this.globalCounts.lineByte + 2, this.globalCounts.currentByte);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'mtllib':
 | 
						|
        this.rawMesh.mtllibName = reconstructString(this.contentRef, this.legacyMode, this.globalCounts.lineByte + 7, this.globalCounts.currentByte);
 | 
						|
        break;
 | 
						|
 | 
						|
      case 'usemtl':
 | 
						|
        const mtlName = reconstructString(this.contentRef, this.legacyMode, this.globalCounts.lineByte + 7, this.globalCounts.currentByte);
 | 
						|
 | 
						|
        if (mtlName !== '' && this.rawMesh.activeMtlName !== mtlName) {
 | 
						|
          this.rawMesh.activeMtlName = mtlName;
 | 
						|
          this.rawMesh.counts.mtlCount++;
 | 
						|
 | 
						|
          this._checkSubGroup();
 | 
						|
        }
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  _pushSmoothingGroup(smoothingGroup) {
 | 
						|
    let smoothingGroupInt = parseInt(smoothingGroup);
 | 
						|
 | 
						|
    if (isNaN(smoothingGroupInt)) {
 | 
						|
      smoothingGroupInt = smoothingGroup === 'off' ? 0 : 1;
 | 
						|
    }
 | 
						|
 | 
						|
    const smoothCheck = this.rawMesh.smoothingGroup.normalized;
 | 
						|
    this.rawMesh.smoothingGroup.normalized = this.rawMesh.smoothingGroup.splitMaterials ? smoothingGroupInt : smoothingGroupInt === 0 ? 0 : 1;
 | 
						|
    this.rawMesh.smoothingGroup.real = smoothingGroupInt;
 | 
						|
 | 
						|
    if (smoothCheck !== smoothingGroupInt) {
 | 
						|
      this.rawMesh.counts.smoothingGroupCount++;
 | 
						|
 | 
						|
      this._checkSubGroup();
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Expanded faceTypes include all four face types, both line types and the point type
 | 
						|
   * faceType = 0: "f vertex ..."
 | 
						|
   * faceType = 1: "f vertex/uv ..."
 | 
						|
   * faceType = 2: "f vertex/uv/normal ..."
 | 
						|
   * faceType = 3: "f vertex//normal ..."
 | 
						|
   * faceType = 4: "l vertex/uv ..." or "l vertex ..."
 | 
						|
   * faceType = 5: "l vertex ..."
 | 
						|
   * faceType = 6: "p vertex ..."
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _checkFaceType(faceType) {
 | 
						|
    if (this.rawMesh.faceType !== faceType) {
 | 
						|
      this._processCompletedMesh();
 | 
						|
 | 
						|
      this.rawMesh.faceType = faceType;
 | 
						|
 | 
						|
      this._checkSubGroup();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  _checkSubGroup() {
 | 
						|
    const index = this.rawMesh.activeMtlName + '|' + this.rawMesh.smoothingGroup.normalized;
 | 
						|
    this.rawMesh.subGroupInUse = this.rawMesh.subGroups[index];
 | 
						|
 | 
						|
    if (this.rawMesh.subGroupInUse === undefined || this.rawMesh.subGroupInUse === null) {
 | 
						|
      this.rawMesh.subGroupInUse = {
 | 
						|
        index: index,
 | 
						|
        objectName: this.rawMesh.objectName,
 | 
						|
        groupName: this.rawMesh.groupName,
 | 
						|
        materialName: this.rawMesh.activeMtlName,
 | 
						|
        smoothingGroup: this.rawMesh.smoothingGroup.normalized,
 | 
						|
        vertices: [],
 | 
						|
        indexMappingsCount: 0,
 | 
						|
        indexMappings: [],
 | 
						|
        indices: [],
 | 
						|
        colors: [],
 | 
						|
        uvs: [],
 | 
						|
        normals: []
 | 
						|
      };
 | 
						|
      this.rawMesh.subGroups[index] = this.rawMesh.subGroupInUse;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  _buildFace(faceIndexV, faceIndexU, faceIndexN) {
 | 
						|
    const subGroupInUse = this.rawMesh.subGroupInUse;
 | 
						|
    const scope = this;
 | 
						|
 | 
						|
    const updateSubGroupInUse = function () {
 | 
						|
      const faceIndexVi = parseInt(faceIndexV);
 | 
						|
      let indexPointerV = 3 * (faceIndexVi > 0 ? faceIndexVi - 1 : faceIndexVi + scope.vertices.length / 3);
 | 
						|
      let indexPointerC = scope.colors.length > 0 ? indexPointerV : null;
 | 
						|
      const vertices = subGroupInUse.vertices;
 | 
						|
      vertices.push(scope.vertices[indexPointerV++]);
 | 
						|
      vertices.push(scope.vertices[indexPointerV++]);
 | 
						|
      vertices.push(scope.vertices[indexPointerV]);
 | 
						|
 | 
						|
      if (indexPointerC !== null) {
 | 
						|
        const colors = subGroupInUse.colors;
 | 
						|
        colors.push(scope.colors[indexPointerC++]);
 | 
						|
        colors.push(scope.colors[indexPointerC++]);
 | 
						|
        colors.push(scope.colors[indexPointerC]);
 | 
						|
      }
 | 
						|
 | 
						|
      if (faceIndexU) {
 | 
						|
        const faceIndexUi = parseInt(faceIndexU);
 | 
						|
        let indexPointerU = 2 * (faceIndexUi > 0 ? faceIndexUi - 1 : faceIndexUi + scope.uvs.length / 2);
 | 
						|
        const uvs = subGroupInUse.uvs;
 | 
						|
        uvs.push(scope.uvs[indexPointerU++]);
 | 
						|
        uvs.push(scope.uvs[indexPointerU]);
 | 
						|
      }
 | 
						|
 | 
						|
      if (faceIndexN && !scope.disregardNormals) {
 | 
						|
        const faceIndexNi = parseInt(faceIndexN);
 | 
						|
        let indexPointerN = 3 * (faceIndexNi > 0 ? faceIndexNi - 1 : faceIndexNi + scope.normals.length / 3);
 | 
						|
        const normals = subGroupInUse.normals;
 | 
						|
        normals.push(scope.normals[indexPointerN++]);
 | 
						|
        normals.push(scope.normals[indexPointerN++]);
 | 
						|
        normals.push(scope.normals[indexPointerN]);
 | 
						|
      }
 | 
						|
    };
 | 
						|
 | 
						|
    if (this.useIndices) {
 | 
						|
      if (this.disregardNormals) faceIndexN = undefined;
 | 
						|
      const mappingName = faceIndexV + (faceIndexU ? '_' + faceIndexU : '_n') + (faceIndexN ? '_' + faceIndexN : '_n');
 | 
						|
      let indicesPointer = subGroupInUse.indexMappings[mappingName];
 | 
						|
 | 
						|
      if (indicesPointer === undefined || indicesPointer === null) {
 | 
						|
        indicesPointer = this.rawMesh.subGroupInUse.vertices.length / 3;
 | 
						|
        updateSubGroupInUse();
 | 
						|
        subGroupInUse.indexMappings[mappingName] = indicesPointer;
 | 
						|
        subGroupInUse.indexMappingsCount++;
 | 
						|
      } else {
 | 
						|
        this.rawMesh.counts.doubleIndicesCount++;
 | 
						|
      }
 | 
						|
 | 
						|
      subGroupInUse.indices.push(indicesPointer);
 | 
						|
    } else {
 | 
						|
      updateSubGroupInUse();
 | 
						|
    }
 | 
						|
 | 
						|
    this.rawMesh.counts.faceCount++;
 | 
						|
  }
 | 
						|
 | 
						|
  _createRawMeshReport(inputObjectCount) {
 | 
						|
    return 'Input Object number: ' + inputObjectCount + '\n\tObject name: ' + this.rawMesh.objectName + '\n\tGroup name: ' + this.rawMesh.groupName + '\n\tMtllib name: ' + this.rawMesh.mtllibName + '\n\tVertex count: ' + this.vertices.length / 3 + '\n\tNormal count: ' + this.normals.length / 3 + '\n\tUV count: ' + this.uvs.length / 2 + '\n\tSmoothingGroup count: ' + this.rawMesh.counts.smoothingGroupCount + '\n\tMaterial count: ' + this.rawMesh.counts.mtlCount + '\n\tReal MeshOutputGroup count: ' + this.rawMesh.subGroups.length;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Clear any empty subGroup and calculate absolute vertex, normal and uv counts
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _finalizeRawMesh() {
 | 
						|
    const meshOutputGroupTemp = [];
 | 
						|
    let meshOutputGroup;
 | 
						|
    let absoluteVertexCount = 0;
 | 
						|
    let absoluteIndexMappingsCount = 0;
 | 
						|
    let absoluteIndexCount = 0;
 | 
						|
    let absoluteColorCount = 0;
 | 
						|
    let absoluteNormalCount = 0;
 | 
						|
    let absoluteUvCount = 0;
 | 
						|
    let indices;
 | 
						|
 | 
						|
    for (const name in this.rawMesh.subGroups) {
 | 
						|
      meshOutputGroup = this.rawMesh.subGroups[name];
 | 
						|
 | 
						|
      if (meshOutputGroup.vertices.length > 0) {
 | 
						|
        indices = meshOutputGroup.indices;
 | 
						|
 | 
						|
        if (indices.length > 0 && absoluteIndexMappingsCount > 0) {
 | 
						|
          for (let i = 0; i < indices.length; i++) {
 | 
						|
            indices[i] = indices[i] + absoluteIndexMappingsCount;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        meshOutputGroupTemp.push(meshOutputGroup);
 | 
						|
        absoluteVertexCount += meshOutputGroup.vertices.length;
 | 
						|
        absoluteIndexMappingsCount += meshOutputGroup.indexMappingsCount;
 | 
						|
        absoluteIndexCount += meshOutputGroup.indices.length;
 | 
						|
        absoluteColorCount += meshOutputGroup.colors.length;
 | 
						|
        absoluteUvCount += meshOutputGroup.uvs.length;
 | 
						|
        absoluteNormalCount += meshOutputGroup.normals.length;
 | 
						|
      }
 | 
						|
    } // do not continue if no result
 | 
						|
 | 
						|
 | 
						|
    let result = null;
 | 
						|
 | 
						|
    if (meshOutputGroupTemp.length > 0) {
 | 
						|
      result = {
 | 
						|
        name: this.rawMesh.groupName !== '' ? this.rawMesh.groupName : this.rawMesh.objectName,
 | 
						|
        subGroups: meshOutputGroupTemp,
 | 
						|
        absoluteVertexCount: absoluteVertexCount,
 | 
						|
        absoluteIndexCount: absoluteIndexCount,
 | 
						|
        absoluteColorCount: absoluteColorCount,
 | 
						|
        absoluteNormalCount: absoluteNormalCount,
 | 
						|
        absoluteUvCount: absoluteUvCount,
 | 
						|
        faceCount: this.rawMesh.counts.faceCount,
 | 
						|
        doubleIndicesCount: this.rawMesh.counts.doubleIndicesCount
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
 | 
						|
  _processCompletedMesh() {
 | 
						|
    const result = this._finalizeRawMesh();
 | 
						|
 | 
						|
    const haveMesh = result !== null;
 | 
						|
 | 
						|
    if (haveMesh) {
 | 
						|
      if (this.colors.length > 0 && this.colors.length !== this.vertices.length) {
 | 
						|
        this._onError('Vertex Colors were detected, but vertex count and color count do not match!');
 | 
						|
      }
 | 
						|
 | 
						|
      if (this.logging.enabled && this.logging.debug) console.debug(this._createRawMeshReport(this.inputObjectCount));
 | 
						|
      this.inputObjectCount++;
 | 
						|
 | 
						|
      this._buildMesh(result);
 | 
						|
 | 
						|
      const progressBytesPercent = this.globalCounts.currentByte / this.globalCounts.totalBytes;
 | 
						|
 | 
						|
      this._onProgress('Completed [o: ' + this.rawMesh.objectName + ' g:' + this.rawMesh.groupName + '' + '] Total progress: ' + (progressBytesPercent * 100).toFixed(2) + '%');
 | 
						|
 | 
						|
      this._resetRawMesh();
 | 
						|
    }
 | 
						|
 | 
						|
    return haveMesh;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * SubGroups are transformed to too intermediate format that is forwarded to the MeshReceiver.
 | 
						|
   * It is ensured that SubGroups only contain objects with vertices (no need to check).
 | 
						|
   *
 | 
						|
   * @param result
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _buildMesh(result) {
 | 
						|
    const meshOutputGroups = result.subGroups;
 | 
						|
    this.globalCounts.vertices += result.absoluteVertexCount / 3;
 | 
						|
    this.globalCounts.faces += result.faceCount;
 | 
						|
    this.globalCounts.doubleIndicesCount += result.doubleIndicesCount;
 | 
						|
    const geometry = new three__WEBPACK_IMPORTED_MODULE_0__["BufferGeometry"]();
 | 
						|
    const vertexFA = new Float32Array(result.absoluteVertexCount);
 | 
						|
    const indexUA = result.absoluteIndexCount > 0 ? new Uint32Array(result.absoluteIndexCount) : null;
 | 
						|
    const colorFA = result.absoluteColorCount > 0 ? new Float32Array(result.absoluteColorCount) : null;
 | 
						|
    const normalFA = result.absoluteNormalCount > 0 ? new Float32Array(result.absoluteNormalCount) : null;
 | 
						|
    const uvFA = result.absoluteUvCount > 0 ? new Float32Array(result.absoluteUvCount) : null;
 | 
						|
    geometry.setAttribute('position', new three__WEBPACK_IMPORTED_MODULE_0__["BufferAttribute"](vertexFA, 3, false));
 | 
						|
    if (normalFA != null) geometry.setAttribute('normal', new three__WEBPACK_IMPORTED_MODULE_0__["BufferAttribute"](normalFA, 3, false));
 | 
						|
    if (uvFA != null) geometry.setAttribute('uv', new three__WEBPACK_IMPORTED_MODULE_0__["BufferAttribute"](uvFA, 2, false));
 | 
						|
    if (colorFA != null) geometry.setAttribute('color', new three__WEBPACK_IMPORTED_MODULE_0__["BufferAttribute"](colorFA, 3, false));
 | 
						|
    if (indexUA !== null) geometry.setIndex(new three__WEBPACK_IMPORTED_MODULE_0__["BufferAttribute"](indexUA, 1, false));
 | 
						|
    let meshOutputGroup;
 | 
						|
    let vertexFAOffset = 0;
 | 
						|
    let indexUAOffset = 0;
 | 
						|
    let colorFAOffset = 0;
 | 
						|
    let normalFAOffset = 0;
 | 
						|
    let uvFAOffset = 0;
 | 
						|
    let materialGroupOffset = 0;
 | 
						|
    let materialGroupLength = 0;
 | 
						|
    const createMultiMaterial = meshOutputGroups.length > 1;
 | 
						|
    const multiMaterial = [];
 | 
						|
    const haveVertexColors = colorFA !== null;
 | 
						|
    let flatShading;
 | 
						|
    let materialIndex = 0;
 | 
						|
    let materialOrg, material, materialName, materialNameOrg;
 | 
						|
    const materialMetaInfo = {
 | 
						|
      cloneInstructions: [],
 | 
						|
      multiMaterialNames: {},
 | 
						|
      modelName: this.modelName,
 | 
						|
      progress: this.globalCounts.currentByte / this.globalCounts.totalBytes,
 | 
						|
      geometryType: this.rawMesh.faceType < 4 ? 0 : this.rawMesh.faceType === 6 ? 2 : 1,
 | 
						|
      objectId: this.objectId
 | 
						|
    };
 | 
						|
 | 
						|
    for (const oodIndex in meshOutputGroups) {
 | 
						|
      if (!meshOutputGroups.hasOwnProperty(oodIndex)) continue;
 | 
						|
      meshOutputGroup = meshOutputGroups[oodIndex];
 | 
						|
      materialNameOrg = meshOutputGroup.materialName;
 | 
						|
      flatShading = meshOutputGroup.smoothingGroup === 0;
 | 
						|
 | 
						|
      if (this.rawMesh.faceType < 4) {
 | 
						|
        materialName = materialNameOrg;
 | 
						|
 | 
						|
        if (haveVertexColors) {
 | 
						|
          materialName += '_vertexColor';
 | 
						|
        }
 | 
						|
 | 
						|
        if (flatShading) {
 | 
						|
          materialName += '_flat';
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        materialName = this.rawMesh.faceType === 6 ? 'defaultPointMaterial' : 'defaultLineMaterial';
 | 
						|
      }
 | 
						|
 | 
						|
      materialOrg = this.materials[materialNameOrg];
 | 
						|
      material = this.materials[materialName]; // both original and derived names do not lead to an existing material => need to use a default material
 | 
						|
 | 
						|
      if ((materialOrg === undefined || materialOrg === null) && (material === undefined || material === null)) {
 | 
						|
        materialName = haveVertexColors ? 'defaultVertexColorMaterial' : 'defaultMaterial';
 | 
						|
        material = this.materials[materialName];
 | 
						|
 | 
						|
        if (this.logging.enabled) {
 | 
						|
          console.info('object_group "' + meshOutputGroup.objectName + '_' + meshOutputGroup.groupName + '" was defined with unresolvable material "' + materialNameOrg + '"! Assigning "' + materialName + '".');
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (material === undefined || material === null) {
 | 
						|
        const materialCloneInstruction = {
 | 
						|
          materialNameOrg: materialNameOrg,
 | 
						|
          materialProperties: {
 | 
						|
            name: materialName,
 | 
						|
            vertexColors: haveVertexColors ? 2 : 0,
 | 
						|
            flatShading: flatShading
 | 
						|
          }
 | 
						|
        };
 | 
						|
        material = three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialUtils"].cloneMaterial(this.materials, materialCloneInstruction, this.logging.enabled && this.logging.debug);
 | 
						|
        materialMetaInfo.cloneInstructions.push(materialCloneInstruction);
 | 
						|
      }
 | 
						|
 | 
						|
      if (createMultiMaterial) {
 | 
						|
        materialGroupLength = this.useIndices ? meshOutputGroup.indices.length : meshOutputGroup.vertices.length / 3;
 | 
						|
        geometry.addGroup(materialGroupOffset, materialGroupLength, materialIndex);
 | 
						|
        material = this.materials[materialName];
 | 
						|
        multiMaterial[materialIndex] = material;
 | 
						|
        materialMetaInfo.multiMaterialNames[materialIndex] = material.name;
 | 
						|
        materialGroupOffset += materialGroupLength;
 | 
						|
        materialIndex++;
 | 
						|
      }
 | 
						|
 | 
						|
      vertexFA.set(meshOutputGroup.vertices, vertexFAOffset);
 | 
						|
      vertexFAOffset += meshOutputGroup.vertices.length;
 | 
						|
 | 
						|
      if (indexUA !== null) {
 | 
						|
        indexUA.set(meshOutputGroup.indices, indexUAOffset);
 | 
						|
        indexUAOffset += meshOutputGroup.indices.length;
 | 
						|
      }
 | 
						|
 | 
						|
      if (colorFA !== null) {
 | 
						|
        colorFA.set(meshOutputGroup.colors, colorFAOffset);
 | 
						|
        colorFAOffset += meshOutputGroup.colors.length;
 | 
						|
      }
 | 
						|
 | 
						|
      if (normalFA !== null) {
 | 
						|
        normalFA.set(meshOutputGroup.normals, normalFAOffset);
 | 
						|
        normalFAOffset += meshOutputGroup.normals.length;
 | 
						|
      }
 | 
						|
 | 
						|
      if (uvFA !== null) {
 | 
						|
        uvFA.set(meshOutputGroup.uvs, uvFAOffset);
 | 
						|
        uvFAOffset += meshOutputGroup.uvs.length;
 | 
						|
      }
 | 
						|
 | 
						|
      if (this.logging.enabled && this.logging.debug) {
 | 
						|
        let materialIndexLine = '';
 | 
						|
 | 
						|
        if (materialIndex > 0) {
 | 
						|
          materialIndexLine = '\n\t\tmaterialIndex: ' + materialIndex;
 | 
						|
        }
 | 
						|
 | 
						|
        const createdReport = '\tOutput Object no.: ' + this.outputObjectCount + '\n\t\tgroupName: ' + meshOutputGroup.groupName + '\n\t\tIndex: ' + meshOutputGroup.index + '\n\t\tfaceType: ' + this.rawMesh.faceType + '\n\t\tmaterialName: ' + meshOutputGroup.materialName + '\n\t\tsmoothingGroup: ' + meshOutputGroup.smoothingGroup + materialIndexLine + '\n\t\tobjectName: ' + meshOutputGroup.objectName + '\n\t\t#vertices: ' + meshOutputGroup.vertices.length / 3 + '\n\t\t#indices: ' + meshOutputGroup.indices.length + '\n\t\t#colors: ' + meshOutputGroup.colors.length / 3 + '\n\t\t#uvs: ' + meshOutputGroup.uvs.length / 2 + '\n\t\t#normals: ' + meshOutputGroup.normals.length / 3;
 | 
						|
        console.debug(createdReport);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    this.outputObjectCount++;
 | 
						|
    let normalBA = geometry.getAttribute('normal');
 | 
						|
    if (normalBA === undefined || normalBA === null) geometry.computeVertexNormals();
 | 
						|
    let mesh;
 | 
						|
    const appliedMaterial = createMultiMaterial ? multiMaterial : material;
 | 
						|
 | 
						|
    if (materialMetaInfo.geometryType === 0) {
 | 
						|
      mesh = new three__WEBPACK_IMPORTED_MODULE_0__["Mesh"](geometry, appliedMaterial);
 | 
						|
    } else if (materialMetaInfo.geometryType === 1) {
 | 
						|
      mesh = new three__WEBPACK_IMPORTED_MODULE_0__["LineSegments"](geometry, appliedMaterial);
 | 
						|
    } else {
 | 
						|
      mesh = new three__WEBPACK_IMPORTED_MODULE_0__["Points"](geometry, appliedMaterial);
 | 
						|
    }
 | 
						|
 | 
						|
    mesh.name = result.name;
 | 
						|
 | 
						|
    this._onAssetAvailable(mesh, materialMetaInfo);
 | 
						|
  }
 | 
						|
 | 
						|
  _finalizeParsing() {
 | 
						|
    if (this.logging.enabled) console.info('Global output object count: ' + this.outputObjectCount);
 | 
						|
 | 
						|
    if (this._processCompletedMesh() && this.logging.enabled) {
 | 
						|
      const parserFinalReport = 'Overall counts: ' + '\n\tVertices: ' + this.globalCounts.vertices + '\n\tFaces: ' + this.globalCounts.faces + '\n\tMultiple definitions: ' + this.globalCounts.doubleIndicesCount;
 | 
						|
      console.info(parserFinalReport);
 | 
						|
    }
 | 
						|
 | 
						|
    this._onLoad();
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Announce parse progress feedback which is logged to the console.
 | 
						|
   * @private
 | 
						|
   *
 | 
						|
   * @param {string} text Textual description of the event
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _onProgress(text) {
 | 
						|
    if (this.callbacks.onProgress !== null) {
 | 
						|
      this.callbacks.onProgress(text);
 | 
						|
    } else {
 | 
						|
      const message = text ? text : '';
 | 
						|
      if (this.logging.enabled && this.logging.debug) console.log(message);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Announce error feedback which is logged as error message.
 | 
						|
   * @private
 | 
						|
   *
 | 
						|
   * @param {String} errorMessage The event containing the error
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _onError(errorMessage) {
 | 
						|
    if (this.callbacks.onError !== null) {
 | 
						|
      this.callbacks.onError(errorMessage);
 | 
						|
    } else {
 | 
						|
      if (this.logging.enabled && this.logging.debug) console.error(errorMessage);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   *
 | 
						|
   * @param {Mesh} mesh
 | 
						|
   * @param {object} materialMetaInfo
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _onAssetAvailable(mesh, materialMetaInfo) {
 | 
						|
    // hook for alteration or transfer to main when parser is run in worker
 | 
						|
    this._onMeshAlter(mesh, materialMetaInfo);
 | 
						|
 | 
						|
    this.baseObject3d.add(mesh);
 | 
						|
  }
 | 
						|
 | 
						|
  _onMeshAlter(mesh) {
 | 
						|
    if (this.callbacks.onMeshAlter !== null) this.callbacks.onMeshAlter(mesh, this.baseObject3d);
 | 
						|
  }
 | 
						|
 | 
						|
  _onLoad() {
 | 
						|
    if (this.callbacks.onLoad !== null) this.callbacks.onLoad(this.baseObject3d, this.objectId);
 | 
						|
  }
 | 
						|
 | 
						|
  static buildUglifiedMapping() {
 | 
						|
    function _OBJLoader2Parser() {
 | 
						|
      return OBJLoader2Parser;
 | 
						|
    }
 | 
						|
 | 
						|
    return three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildUglifiedNameAssignment(_OBJLoader2Parser, 'OBJLoader2Parser', /_OBJLoader2Parser/, true);
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
class OBJ2LoaderWorker {
 | 
						|
  static buildStandardWorkerDependencies(threeJsLocation) {
 | 
						|
    return [{
 | 
						|
      url: threeJsLocation
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildThreeConst()
 | 
						|
    }, {
 | 
						|
      code: OBJ2LoaderWorker.buildThreeExtraConst()
 | 
						|
    }, {
 | 
						|
      code: '\n\n'
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildUglifiedThreeMapping()
 | 
						|
    }, {
 | 
						|
      code: OBJ2LoaderWorker.buildUglifiedThreeExtraMapping()
 | 
						|
    }, {
 | 
						|
      code: '\n\n'
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectUtils"].serializeClass(three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"])
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectUtils"].serializeClass(three_wtm__WEBPACK_IMPORTED_MODULE_1__["GeometryTransport"])
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectUtils"].serializeClass(three_wtm__WEBPACK_IMPORTED_MODULE_1__["MeshTransport"])
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectUtils"].serializeClass(three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialsTransport"])
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectUtils"].serializeClass(three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialUtils"])
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectUtils"].serializeClass(OBJLoader2Parser)
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectUtils"].serializeClass(three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectManipulator"])
 | 
						|
    }, {
 | 
						|
      code: three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildUglifiedThreeWtmMapping()
 | 
						|
    }, {
 | 
						|
      code: '\n\n'
 | 
						|
    }, {
 | 
						|
      code: OBJLoader2Parser.buildUglifiedMapping()
 | 
						|
    }, {
 | 
						|
      code: '\n\n'
 | 
						|
    }];
 | 
						|
  }
 | 
						|
 | 
						|
  static buildThreeExtraConst() {
 | 
						|
    return 'const MathUtils = THREE.MathUtils;\n' + 'const Material = THREE.Material;\n' + 'const Object3D = THREE.Object3D;\n' + 'const Mesh = THREE.Mesh;\n';
 | 
						|
  }
 | 
						|
 | 
						|
  static buildUglifiedThreeExtraMapping() {
 | 
						|
    function _MathUtils() {
 | 
						|
      return three__WEBPACK_IMPORTED_MODULE_0__["MathUtils"];
 | 
						|
    }
 | 
						|
 | 
						|
    function _Material() {
 | 
						|
      return three__WEBPACK_IMPORTED_MODULE_0__["Material"];
 | 
						|
    }
 | 
						|
 | 
						|
    function _Object3D() {
 | 
						|
      return three__WEBPACK_IMPORTED_MODULE_0__["Object3D"];
 | 
						|
    }
 | 
						|
 | 
						|
    function _Mesh() {
 | 
						|
      return three__WEBPACK_IMPORTED_MODULE_0__["Mesh"];
 | 
						|
    }
 | 
						|
 | 
						|
    return three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildUglifiedNameAssignment(_MathUtils, 'MathUtils', /_MathUtils/, false) + three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildUglifiedNameAssignment(_Material, 'Material', /_Material/, false) + three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildUglifiedNameAssignment(_Object3D, 'Object3D', /_Object3D/, false) + three_wtm__WEBPACK_IMPORTED_MODULE_1__["DeUglify"].buildUglifiedNameAssignment(_Mesh, 'Mesh', /_Mesh/, false);
 | 
						|
  }
 | 
						|
 | 
						|
  static init(context, id, config) {
 | 
						|
    const materialsTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialsTransport"]().loadData(config);
 | 
						|
    context.obj2 = {
 | 
						|
      parser: new OBJLoader2Parser(),
 | 
						|
      buffer: null,
 | 
						|
      materials: materialsTransport.getMaterials()
 | 
						|
    };
 | 
						|
 | 
						|
    context.obj2.parser._onMeshAlter = (mesh, materialMetaInfo) => {
 | 
						|
      const materialsTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialsTransport"]();
 | 
						|
      materialsTransport.main.multiMaterialNames = materialMetaInfo.multiMaterialNames; // only makes sense if materials are newly created, what they currently are not
 | 
						|
 | 
						|
      if (Object.keys(materialsTransport.main.multiMaterialNames).length === 0) {
 | 
						|
        const material = mesh.material;
 | 
						|
        three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialUtils"].addMaterial(materialsTransport.main.materials, material, material.name, false, false);
 | 
						|
      }
 | 
						|
 | 
						|
      materialsTransport.main.cloneInstructions = materialMetaInfo.cloneInstructions;
 | 
						|
      materialsTransport.cleanMaterials();
 | 
						|
      const meshTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["MeshTransport"]('assetAvailable', materialMetaInfo.objectId).setProgress(materialMetaInfo.progress).setParams({
 | 
						|
        modelName: materialMetaInfo.modelName
 | 
						|
      }).setMesh(mesh, materialMetaInfo.geometryType).setMaterialsTransport(materialsTransport);
 | 
						|
      meshTransport.postMessage(context);
 | 
						|
    };
 | 
						|
 | 
						|
    context.obj2.parser.callbacks.onLoad = () => {
 | 
						|
      const dataTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"]('execComplete', context.obj2.parser.objectId);
 | 
						|
      dataTransport.postMessage(context);
 | 
						|
    };
 | 
						|
 | 
						|
    context.obj2.parser.callbacks.onProgress = text => {
 | 
						|
      if (context.obj2.parser.logging.debug) console.debug('WorkerRunner: progress: ' + text);
 | 
						|
    };
 | 
						|
 | 
						|
    three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectManipulator"].applyProperties(context.obj2.parser, materialsTransport.getParams(), false);
 | 
						|
    const buffer = materialsTransport.getBuffer('modelData');
 | 
						|
    if (buffer !== undefined && buffer !== null) context.obj2.buffer = buffer;
 | 
						|
    new three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"]('init', id).postMessage(context);
 | 
						|
  }
 | 
						|
 | 
						|
  static execute(context, id, config) {
 | 
						|
    if (context.obj2.parser.usedBefore) {
 | 
						|
      context.obj2.parser._init();
 | 
						|
    }
 | 
						|
 | 
						|
    context.obj2.parser.materials = context.obj2.materials;
 | 
						|
    const dataTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"]().loadData(config);
 | 
						|
    three_wtm__WEBPACK_IMPORTED_MODULE_1__["ObjectManipulator"].applyProperties(context.obj2.parser, dataTransport.getParams(), false);
 | 
						|
    const buffer = dataTransport.getBuffer('modelData');
 | 
						|
    if (buffer !== undefined && buffer !== null) context.obj2.buffer = buffer;
 | 
						|
 | 
						|
    if (context.obj2.buffer) {
 | 
						|
      context.obj2.parser.objectId = dataTransport.getId();
 | 
						|
 | 
						|
      context.obj2.parser._execute(context.obj2.buffer);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
/**
 | 
						|
 * Creates a new OBJLoader2Parallel. Use it to load OBJ data from files or to parse OBJ data from arraybuffer.
 | 
						|
 * It extends {@link OBJLoader2} with the capability to run the parser in a web worker.
 | 
						|
 *
 | 
						|
 * @param [LoadingManager] manager The loadingManager for the loader to use. Default is {@link LoadingManager}
 | 
						|
 * @constructor
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
class OBJLoader2Parallel extends OBJLoader2 {
 | 
						|
  /**
 | 
						|
   *
 | 
						|
   * @param {LoadingManager} [manager]
 | 
						|
   */
 | 
						|
  constructor(manager) {
 | 
						|
    super(manager);
 | 
						|
    this.preferJsmWorker = false;
 | 
						|
    this.urls = {
 | 
						|
      /** @type {URL} */
 | 
						|
      jsmWorker: new URL(OBJLoader2Parallel.DEFAULT_JSM_WORKER_PATH, window.location.href),
 | 
						|
 | 
						|
      /** @type {URL} */
 | 
						|
      threejs: new URL(OBJLoader2Parallel.DEFAULT_JSM_THREEJS_PATH, window.location.href)
 | 
						|
    };
 | 
						|
    this.workerTaskManager = null;
 | 
						|
    this.taskName = 'tmOBJLoader2';
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * @param {WorkerTaskManager} workerTaskManager The {@link WorkerTaskManager}
 | 
						|
   * @param {string} [taskName] A specific taskName to allow distinction between legacy and module workers
 | 
						|
   *
 | 
						|
   * @return {OBJLoader2Parallel}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setWorkerTaskManager(workerTaskManager, taskName) {
 | 
						|
    this.workerTaskManager = workerTaskManager;
 | 
						|
    if (taskName) this.taskName = taskName;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Set whether jsm modules in workers should be used. This requires browser support which is currently only experimental.
 | 
						|
   *
 | 
						|
   * @param {boolean} preferJsmWorker True or False
 | 
						|
   * @param {URL} jsmWorkerUrl Provide complete jsm worker URL otherwise relative path to this module may not be correct
 | 
						|
   * @return {OBJLoader2Parallel}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setJsmWorker(preferJsmWorker, jsmWorkerUrl) {
 | 
						|
    this.preferJsmWorker = preferJsmWorker === true;
 | 
						|
 | 
						|
    if (jsmWorkerUrl === undefined || jsmWorkerUrl === null || !(jsmWorkerUrl instanceof URL)) {
 | 
						|
      throw 'The url to the jsm worker is not valid. Aborting...';
 | 
						|
    } else {
 | 
						|
      this.urls.jsmWorker = jsmWorkerUrl;
 | 
						|
    }
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Override the default URL for three.js. This is only required when standard workers are build (preferJsmWorker=false).
 | 
						|
   *
 | 
						|
   * @param {URL} threejsUrl Provide complete three module URL otherwise relative path to this module may not be correct
 | 
						|
   * @return {OBJLoader2Parallel}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setThreejsLocation(threejsUrl) {
 | 
						|
    if (threejsUrl === undefined || threejsUrl === null || !(threejsUrl instanceof URL)) {
 | 
						|
      throw 'The url to the jsm worker is not valid. Aborting...';
 | 
						|
    } else {
 | 
						|
      this.urls.threejs = threejsUrl;
 | 
						|
    }
 | 
						|
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Request termination of worker once parser is finished.
 | 
						|
   *
 | 
						|
   * @param {boolean} terminateWorkerOnLoad True or false.
 | 
						|
   * @return {OBJLoader2Parallel}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  setTerminateWorkerOnLoad(terminateWorkerOnLoad) {
 | 
						|
    this.terminateWorkerOnLoad = terminateWorkerOnLoad === true;
 | 
						|
    return this;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Provide instructions on what is to be contained in the worker.
 | 
						|
   *
 | 
						|
   * @param {DataTransport} dataTransport Configuration object
 | 
						|
   * @return {Promise<void>}
 | 
						|
   * @private
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  async _buildWorkerCode(dataTransport) {
 | 
						|
    if (this.workerTaskManager === null || !(this.workerTaskManager instanceof three_wtm__WEBPACK_IMPORTED_MODULE_1__["WorkerTaskManager"])) {
 | 
						|
      if (this.parser.logging.debug) console.log('Needed to create new WorkerTaskManager');
 | 
						|
      this.workerTaskManager = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["WorkerTaskManager"](1);
 | 
						|
      this.workerTaskManager.setVerbose(this.parser.logging.enabled && this.parser.logging.debug);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!this.workerTaskManager.supportsTaskType(this.taskName)) {
 | 
						|
      if (this.preferJsmWorker) {
 | 
						|
        this.workerTaskManager.registerTaskTypeModule(this.taskName, this.urls.jsmWorker);
 | 
						|
      } else {
 | 
						|
        // build the standard worker from code imported here and don't reference three.js build with fixed path
 | 
						|
        this.workerTaskManager.registerTaskType(this.taskName, OBJ2LoaderWorker.init, OBJ2LoaderWorker.execute, null, false, OBJ2LoaderWorker.buildStandardWorkerDependencies(this.urls.threejs));
 | 
						|
      }
 | 
						|
 | 
						|
      await this.workerTaskManager.initTaskType(this.taskName, dataTransport.getMain());
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * See {@link OBJLoader2.load}
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  load(content, onLoad, onFileLoadProgress, onError, onMeshAlter) {
 | 
						|
    const scope = this;
 | 
						|
 | 
						|
    function interceptOnLoad(object3d, objectId) {
 | 
						|
      if (object3d.name === 'OBJLoader2ParallelDummy') {
 | 
						|
        if (scope.parser.logging.enabled && scope.parser.logging.debug) {
 | 
						|
          console.debug('Received dummy answer from OBJLoader2Parallel#parse');
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        onLoad(object3d, objectId);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    OBJLoader2.prototype.load.call(this, content, interceptOnLoad, onFileLoadProgress, onError, onMeshAlter);
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * See {@link OBJLoader2.parse}
 | 
						|
   * The callback onLoad needs to be set to be able to receive the content if used in parallel mode.
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  parse(content) {
 | 
						|
    if (this.parser.logging.enabled) {
 | 
						|
      console.info('Using OBJLoader2Parallel version: ' + OBJLoader2Parallel.OBJLOADER2_PARALLEL_VERSION);
 | 
						|
    }
 | 
						|
 | 
						|
    const dataTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"]().setParams({
 | 
						|
      logging: {
 | 
						|
        enabled: this.parser.logging.enabled,
 | 
						|
        debug: this.parser.logging.debug
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
    this._buildWorkerCode(dataTransport).then(() => {
 | 
						|
      if (this.parser.logging.debug) console.log('OBJLoader2Parallel init was performed');
 | 
						|
 | 
						|
      this._executeWorkerParse(content);
 | 
						|
    }).catch(e => console.error(e));
 | 
						|
 | 
						|
    let dummy = new three__WEBPACK_IMPORTED_MODULE_0__["Object3D"]();
 | 
						|
    dummy.name = 'OBJLoader2ParallelDummy';
 | 
						|
    return dummy;
 | 
						|
  }
 | 
						|
 | 
						|
  _executeWorkerParse(content) {
 | 
						|
    const dataTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"]('execute', Math.floor(Math.random() * Math.floor(65536)));
 | 
						|
    dataTransport.setParams({
 | 
						|
      modelName: this.parser.modelName,
 | 
						|
      useIndices: this.parser.useIndices,
 | 
						|
      disregardNormals: this.parser.disregardNormals,
 | 
						|
      materialPerSmoothingGroup: this.parser.materialPerSmoothingGroup,
 | 
						|
      useOAsMesh: this.parser.useOAsMesh,
 | 
						|
      materials: three_wtm__WEBPACK_IMPORTED_MODULE_1__["MaterialUtils"].getMaterialsJSON(this.materialStore.getMaterials())
 | 
						|
    }).addBuffer('modelData', content).package(false);
 | 
						|
    this.workerTaskManager.enqueueForExecution(this.taskName, dataTransport.getMain(), dataTransport => this._onLoad(dataTransport), dataTransport.getTransferables()).then(dataTransport => {
 | 
						|
      this._onLoad(dataTransport);
 | 
						|
 | 
						|
      if (this.terminateWorkerOnLoad) this.workerTaskManager.dispose();
 | 
						|
    }).catch(e => console.error(e));
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   *
 | 
						|
   * @param {Mesh} mesh
 | 
						|
   * @param {object} materialMetaInfo
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  _onLoad(asset) {
 | 
						|
    let cmd = asset.cmd;
 | 
						|
 | 
						|
    if (cmd === 'assetAvailable') {
 | 
						|
      let meshTransport;
 | 
						|
 | 
						|
      if (asset.type === 'MeshTransport') {
 | 
						|
        meshTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["MeshTransport"]().loadData(asset).reconstruct(false);
 | 
						|
      } else {
 | 
						|
        console.error('Received unknown asset.type: ' + asset.type);
 | 
						|
      }
 | 
						|
 | 
						|
      if (meshTransport) {
 | 
						|
        const materialsTransport = meshTransport.getMaterialsTransport();
 | 
						|
        let material = materialsTransport.processMaterialTransport(this.materialStore.getMaterials(), this.parser.logging.enabled);
 | 
						|
        if (material === null) material = new three__WEBPACK_IMPORTED_MODULE_0__["MeshStandardMaterial"]({
 | 
						|
          color: 0xFF0000
 | 
						|
        });
 | 
						|
        let mesh;
 | 
						|
 | 
						|
        if (meshTransport.getGeometryType() === 0) {
 | 
						|
          mesh = new three__WEBPACK_IMPORTED_MODULE_0__["Mesh"](meshTransport.getBufferGeometry(), material);
 | 
						|
        } else if (meshTransport.getGeometryType() === 1) {
 | 
						|
          mesh = new three__WEBPACK_IMPORTED_MODULE_0__["LineSegments"](meshTransport.getBufferGeometry(), material);
 | 
						|
        } else {
 | 
						|
          mesh = new three__WEBPACK_IMPORTED_MODULE_0__["Points"](meshTransport.getBufferGeometry(), material);
 | 
						|
        }
 | 
						|
 | 
						|
        this.parser._onMeshAlter(mesh);
 | 
						|
 | 
						|
        this.parser.baseObject3d.add(mesh);
 | 
						|
      }
 | 
						|
    } else if (cmd === 'execComplete') {
 | 
						|
      let dataTransport;
 | 
						|
 | 
						|
      if (asset.type === 'DataTransport') {
 | 
						|
        dataTransport = new three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"]().loadData(asset);
 | 
						|
 | 
						|
        if (dataTransport instanceof three_wtm__WEBPACK_IMPORTED_MODULE_1__["DataTransport"] && this.parser.callbacks.onLoad !== null) {
 | 
						|
          this.parser.callbacks.onLoad(this.parser.baseObject3d, dataTransport.getId());
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        console.error('Received unknown asset.type: ' + asset.type);
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      console.error('Received unknown command: ' + cmd);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
_defineProperty(OBJLoader2Parallel, "OBJLOADER2_PARALLEL_VERSION", OBJLoader2.OBJLOADER2_VERSION);
 | 
						|
 | 
						|
_defineProperty(OBJLoader2Parallel, "DEFAULT_JSM_WORKER_PATH", '/src/loaders/tmOBJLoader2.js');
 | 
						|
 | 
						|
_defineProperty(OBJLoader2Parallel, "DEFAULT_JSM_THREEJS_PATH", '/node_modules/three/build/three.min.js');
 | 
						|
 | 
						|
class MtlObjBridge {
 | 
						|
  /**
 | 
						|
   *
 | 
						|
   * @param processResult
 | 
						|
   * @param assetLoader
 | 
						|
   */
 | 
						|
  static link(processResult, assetLoader) {
 | 
						|
    if (typeof assetLoader.setMaterials === 'function') {
 | 
						|
      assetLoader.setMaterials(MtlObjBridge.addMaterialsFromMtlLoader(processResult), true);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Returns the array instance of {@link Material}.
 | 
						|
   *
 | 
						|
   * @param materialCreator instance of MTLLoader
 | 
						|
   */
 | 
						|
 | 
						|
 | 
						|
  static addMaterialsFromMtlLoader(materialCreator) {
 | 
						|
    let newMaterials = {};
 | 
						|
 | 
						|
    if (materialCreator['preload'] !== undefined && materialCreator['preload'] instanceof Function) {
 | 
						|
      materialCreator['preload']();
 | 
						|
      newMaterials = materialCreator.materials;
 | 
						|
    }
 | 
						|
 | 
						|
    return newMaterials;
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/***/ })
 | 
						|
/******/ ]);
 | 
						|
}); |