(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports", "three", "../libs/fflate.module.js"], factory); } else if (typeof exports !== "undefined") { factory(exports, require("three"), require("../libs/fflate.module.js")); } else { var mod = { exports: {} }; factory(mod.exports, global.three, global.fflateModule); global.AMFLoader = mod.exports; } })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three, fflate) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.AMFLoader = void 0; fflate = _interopRequireWildcard(fflate); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } Object.defineProperty(subClass, "prototype", { value: Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }), writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } /** * Description: Early release of an AMF Loader following the pattern of the * example loaders in the three.js project. * * More information about the AMF format: http://amf.wikispaces.com * * Usage: * const loader = new AMFLoader(); * loader.load('/path/to/project.amf', function(objecttree) { * scene.add(objecttree); * }); * * Materials now supported, material colors supported * Zip support, requires fflate * No constellation support (yet)! * */ var AMFLoader = /*#__PURE__*/function (_Loader) { _inherits(AMFLoader, _Loader); var _super = _createSuper(AMFLoader); function AMFLoader(manager) { _classCallCheck(this, AMFLoader); return _super.call(this, manager); } _createClass(AMFLoader, [{ key: "load", value: function load(url, onLoad, onProgress, onError) { var scope = this; var loader = new _three.FileLoader(scope.manager); loader.setPath(scope.path); loader.setResponseType('arraybuffer'); loader.setRequestHeader(scope.requestHeader); loader.setWithCredentials(scope.withCredentials); loader.load(url, function (text) { try { onLoad(scope.parse(text)); } catch (e) { if (onError) { onError(e); } else { console.error(e); } scope.manager.itemError(url); } }, onProgress, onError); } }, { key: "parse", value: function parse(data) { function loadDocument(data) { var view = new DataView(data); var magic = String.fromCharCode(view.getUint8(0), view.getUint8(1)); if (magic === 'PK') { var zip = null; var file = null; console.log('THREE.AMFLoader: Loading Zip'); try { zip = fflate.unzipSync(new Uint8Array(data)); // eslint-disable-line no-undef } catch (e) { if (e instanceof ReferenceError) { console.log('THREE.AMFLoader: fflate missing and file is compressed.'); return null; } } for (file in zip) { if (file.toLowerCase().substr(-4) === '.amf') { break; } } console.log('THREE.AMFLoader: Trying to load file asset: ' + file); view = new DataView(zip[file].buffer); } var fileText = _three.LoaderUtils.decodeText(view); var xmlData = new DOMParser().parseFromString(fileText, 'application/xml'); if (xmlData.documentElement.nodeName.toLowerCase() !== 'amf') { console.log('THREE.AMFLoader: Error loading AMF - no AMF document found.'); return null; } return xmlData; } function loadDocumentScale(node) { var scale = 1.0; var unit = 'millimeter'; if (node.documentElement.attributes.unit !== undefined) { unit = node.documentElement.attributes.unit.value.toLowerCase(); } var scaleUnits = { millimeter: 1.0, inch: 25.4, feet: 304.8, meter: 1000.0, micron: 0.001 }; if (scaleUnits[unit] !== undefined) { scale = scaleUnits[unit]; } console.log('THREE.AMFLoader: Unit scale: ' + scale); return scale; } function loadMaterials(node) { var matName = 'AMF Material'; var matId = node.attributes.id.textContent; var color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 }; var loadedMaterial = null; for (var _i = 0; _i < node.childNodes.length; _i++) { var matChildEl = node.childNodes[_i]; if (matChildEl.nodeName === 'metadata' && matChildEl.attributes.type !== undefined) { if (matChildEl.attributes.type.value === 'name') { matName = matChildEl.textContent; } } else if (matChildEl.nodeName === 'color') { color = loadColor(matChildEl); } } loadedMaterial = new _three.MeshPhongMaterial({ flatShading: true, color: new _three.Color(color.r, color.g, color.b), name: matName }); if (color.a !== 1.0) { loadedMaterial.transparent = true; loadedMaterial.opacity = color.a; } return { id: matId, material: loadedMaterial }; } function loadColor(node) { var color = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 }; for (var _i2 = 0; _i2 < node.childNodes.length; _i2++) { var matColor = node.childNodes[_i2]; if (matColor.nodeName === 'r') { color.r = matColor.textContent; } else if (matColor.nodeName === 'g') { color.g = matColor.textContent; } else if (matColor.nodeName === 'b') { color.b = matColor.textContent; } else if (matColor.nodeName === 'a') { color.a = matColor.textContent; } } return color; } function loadMeshVolume(node) { var volume = { name: '', triangles: [], materialid: null }; var currVolumeNode = node.firstElementChild; if (node.attributes.materialid !== undefined) { volume.materialId = node.attributes.materialid.nodeValue; } while (currVolumeNode) { if (currVolumeNode.nodeName === 'metadata') { if (currVolumeNode.attributes.type !== undefined) { if (currVolumeNode.attributes.type.value === 'name') { volume.name = currVolumeNode.textContent; } } } else if (currVolumeNode.nodeName === 'triangle') { var v1 = currVolumeNode.getElementsByTagName('v1')[0].textContent; var v2 = currVolumeNode.getElementsByTagName('v2')[0].textContent; var v3 = currVolumeNode.getElementsByTagName('v3')[0].textContent; volume.triangles.push(v1, v2, v3); } currVolumeNode = currVolumeNode.nextElementSibling; } return volume; } function loadMeshVertices(node) { var vertArray = []; var normalArray = []; var currVerticesNode = node.firstElementChild; while (currVerticesNode) { if (currVerticesNode.nodeName === 'vertex') { var vNode = currVerticesNode.firstElementChild; while (vNode) { if (vNode.nodeName === 'coordinates') { var x = vNode.getElementsByTagName('x')[0].textContent; var y = vNode.getElementsByTagName('y')[0].textContent; var z = vNode.getElementsByTagName('z')[0].textContent; vertArray.push(x, y, z); } else if (vNode.nodeName === 'normal') { var nx = vNode.getElementsByTagName('nx')[0].textContent; var ny = vNode.getElementsByTagName('ny')[0].textContent; var nz = vNode.getElementsByTagName('nz')[0].textContent; normalArray.push(nx, ny, nz); } vNode = vNode.nextElementSibling; } } currVerticesNode = currVerticesNode.nextElementSibling; } return { 'vertices': vertArray, 'normals': normalArray }; } function loadObject(node) { var objId = node.attributes.id.textContent; var loadedObject = { name: 'amfobject', meshes: [] }; var currColor = null; var currObjNode = node.firstElementChild; while (currObjNode) { if (currObjNode.nodeName === 'metadata') { if (currObjNode.attributes.type !== undefined) { if (currObjNode.attributes.type.value === 'name') { loadedObject.name = currObjNode.textContent; } } } else if (currObjNode.nodeName === 'color') { currColor = loadColor(currObjNode); } else if (currObjNode.nodeName === 'mesh') { var currMeshNode = currObjNode.firstElementChild; var mesh = { vertices: [], normals: [], volumes: [], color: currColor }; while (currMeshNode) { if (currMeshNode.nodeName === 'vertices') { var loadedVertices = loadMeshVertices(currMeshNode); mesh.normals = mesh.normals.concat(loadedVertices.normals); mesh.vertices = mesh.vertices.concat(loadedVertices.vertices); } else if (currMeshNode.nodeName === 'volume') { mesh.volumes.push(loadMeshVolume(currMeshNode)); } currMeshNode = currMeshNode.nextElementSibling; } loadedObject.meshes.push(mesh); } currObjNode = currObjNode.nextElementSibling; } return { 'id': objId, 'obj': loadedObject }; } var xmlData = loadDocument(data); var amfName = ''; var amfAuthor = ''; var amfScale = loadDocumentScale(xmlData); var amfMaterials = {}; var amfObjects = {}; var childNodes = xmlData.documentElement.childNodes; var i, j; for (i = 0; i < childNodes.length; i++) { var child = childNodes[i]; if (child.nodeName === 'metadata') { if (child.attributes.type !== undefined) { if (child.attributes.type.value === 'name') { amfName = child.textContent; } else if (child.attributes.type.value === 'author') { amfAuthor = child.textContent; } } } else if (child.nodeName === 'material') { var loadedMaterial = loadMaterials(child); amfMaterials[loadedMaterial.id] = loadedMaterial.material; } else if (child.nodeName === 'object') { var loadedObject = loadObject(child); amfObjects[loadedObject.id] = loadedObject.obj; } } var sceneObject = new _three.Group(); var defaultMaterial = new _three.MeshPhongMaterial({ color: 0xaaaaff, flatShading: true }); sceneObject.name = amfName; sceneObject.userData.author = amfAuthor; sceneObject.userData.loader = 'AMF'; for (var id in amfObjects) { var part = amfObjects[id]; var meshes = part.meshes; var newObject = new _three.Group(); newObject.name = part.name || ''; for (i = 0; i < meshes.length; i++) { var objDefaultMaterial = defaultMaterial; var mesh = meshes[i]; var vertices = new _three.Float32BufferAttribute(mesh.vertices, 3); var normals = null; if (mesh.normals.length) { normals = new _three.Float32BufferAttribute(mesh.normals, 3); } if (mesh.color) { var color = mesh.color; objDefaultMaterial = defaultMaterial.clone(); objDefaultMaterial.color = new _three.Color(color.r, color.g, color.b); if (color.a !== 1.0) { objDefaultMaterial.transparent = true; objDefaultMaterial.opacity = color.a; } } var volumes = mesh.volumes; for (j = 0; j < volumes.length; j++) { var volume = volumes[j]; var newGeometry = new _three.BufferGeometry(); var material = objDefaultMaterial; newGeometry.setIndex(volume.triangles); newGeometry.setAttribute('position', vertices.clone()); if (normals) { newGeometry.setAttribute('normal', normals.clone()); } if (amfMaterials[volume.materialId] !== undefined) { material = amfMaterials[volume.materialId]; } newGeometry.scale(amfScale, amfScale, amfScale); newObject.add(new _three.Mesh(newGeometry, material.clone())); } } sceneObject.add(newObject); } return sceneObject; } }]); return AMFLoader; }(_three.Loader); _exports.AMFLoader = AMFLoader; });