/** * Name: kankan-sdk.js * Date: 2024/7/19 * Author: https://www.4dkankan.com * Copyright © 2024 4DAGE Co., Ltd. All rights reserved. * Licensed under the GLP license */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('three')) : typeof define === 'function' && define.amd ? define(['three'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.KanKan = factory(global.THREE)); }(this, (function (THREE$1) { 'use strict'; function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n['default'] = e; return Object.freeze(n); } var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE$1); 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); return Constructor; } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 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 _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function createCommonjsModule(fn) { var module = { exports: {} }; return fn(module, module.exports), module.exports; } /** * Copyright (c) 2014-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var runtime_1 = createCommonjsModule(function (module) { var runtime = function (exports) { var Op = Object.prototype; var hasOwn = Op.hasOwnProperty; var undefined$1; // More compressible than void 0. var $Symbol = typeof Symbol === "function" ? Symbol : {}; var iteratorSymbol = $Symbol.iterator || "@@iterator"; var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); return obj[key]; } try { // IE 8 has a broken Object.defineProperty that only works on DOM objects. define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; var generator = Object.create(protoGenerator.prototype); var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next, // .throw, and .return methods. generator._invoke = makeInvokeMethod(innerFn, self, context); return generator; } exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion // record like context.tryEntries[i].completion. This interface could // have been (and was previously) designed to take a closure to be // invoked without arguments, but in all the cases we care about we // already have an existing method we want to call, so there's no need // to create a new function object. We can even get away with assuming // the method takes exactly one argument, since that happens to be true // in every case, so we don't have to touch the arguments object. The // only additional allocation required is the completion record, which // has a stable shape and so hopefully should be cheap to allocate. function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } var GenStateSuspendedStart = "suspendedStart"; var GenStateSuspendedYield = "suspendedYield"; var GenStateExecuting = "executing"; var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as // breaking out of the dispatch switch statement. var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and // .constructor.prototype properties for functions that return Generator // objects. For full spec compliance, you may wish to configure your // minifier not to mangle the names of these two functions. function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that // don't natively support it. var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf; var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { // This environment has a native %IteratorPrototype%; use it instead // of the polyfill. IteratorPrototype = NativeIteratorPrototype; } var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); GeneratorFunction.prototype = GeneratorFunctionPrototype; define(Gp, "constructor", GeneratorFunctionPrototype); define(GeneratorFunctionPrototype, "constructor", GeneratorFunction); GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the // Iterator interface in terms of a single ._invoke method. function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } exports.isGeneratorFunction = function (genFun) { var ctor = typeof genFun === "function" && genFun.constructor; return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can // do is to check its .name property. (ctor.displayName || ctor.name) === "GeneratorFunction" : false; }; exports.mark = function (genFun) { if (Object.setPrototypeOf) { Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { genFun.__proto__ = GeneratorFunctionPrototype; define(genFun, toStringTagSymbol, "GeneratorFunction"); } genFun.prototype = Object.create(Gp); return genFun; }; // Within the body of any async function, `await x` is transformed to // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test // `hasOwn.call(value, "__await")` to determine if the yielded value is // meant to be awaited. exports.awrap = function (arg) { return { __await: arg }; }; function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if (record.type === "throw") { reject(record.arg); } else { var result = record.arg; var value = result.value; if (value && typeof value === "object" && hasOwn.call(value, "__await")) { return PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }); } return PromiseImpl.resolve(value).then(function (unwrapped) { // When a yielded Promise is resolved, its final value becomes // the .value of the Promise<{value,done}> result for the // current iteration. result.value = unwrapped; resolve(result); }, function (error) { // If a rejected Promise was yielded, throw the rejection back // into the async generator function so it can be handled there. return invoke("throw", error, resolve, reject); }); } } var previousPromise; function enqueue(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = // If enqueue has been called before, then we want to wait until // all previous Promises have been resolved before calling invoke, // so that results are always delivered in the correct order. If // enqueue has not been called before, then it is important to // call invoke immediately, without waiting on a callback to fire, // so that the async generator function has the opportunity to do // any necessary setup in a predictable way. This predictability // is why the Promise constructor synchronously invokes its // executor callback, and why async functions synchronously // execute code before the first await. Since we implement simple // async functions in terms of async generators, it is especially // important to get this right, even though it requires care. previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later // invocations of the iterator. callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } // Define the unified helper method that is used to implement .next, // .throw, and .return (see defineIteratorMethods). this._invoke = enqueue; } defineIteratorMethods(AsyncIterator.prototype); define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }); exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of // AsyncIterator objects; they just return a Promise for the value of // the final result produced by the iterator. exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { if (PromiseImpl === void 0) PromiseImpl = Promise; var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }; function makeInvokeMethod(innerFn, self, context) { var state = GenStateSuspendedStart; return function invoke(method, arg) { if (state === GenStateExecuting) { throw new Error("Generator is already running"); } if (state === GenStateCompleted) { if (method === "throw") { throw arg; } // Be forgiving, per 25.3.3.3.3 of the spec: // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume return doneResult(); } context.method = method; context.arg = arg; while (true) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if (context.method === "next") { // Setting context._sent for legacy support of Babel's // function.sent implementation. context.sent = context._sent = context.arg; } else if (context.method === "throw") { if (state === GenStateSuspendedStart) { state = GenStateCompleted; throw context.arg; } context.dispatchException(context.arg); } else if (context.method === "return") { context.abrupt("return", context.arg); } state = GenStateExecuting; var record = tryCatch(innerFn, self, context); if (record.type === "normal") { // If an exception is thrown from innerFn, we leave state === // GenStateExecuting and loop back for another invocation. state = context.done ? GenStateCompleted : GenStateSuspendedYield; if (record.arg === ContinueSentinel) { continue; } return { value: record.arg, done: context.done }; } else if (record.type === "throw") { state = GenStateCompleted; // Dispatch the exception by looping back around to the // context.dispatchException(context.arg) call above. context.method = "throw"; context.arg = record.arg; } } }; } // Call delegate.iterator[context.method](context.arg) and handle the // result, either by returning a { value, done } result from the // delegate iterator, or by modifying context.method and context.arg, // setting context.delegate to null, and returning the ContinueSentinel. function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (method === undefined$1) { // A .throw or .return when the delegate iterator has no .throw // method always terminates the yield* loop. context.delegate = null; if (context.method === "throw") { // Note: ["return"] must be used for ES3 parsing compatibility. if (delegate.iterator["return"]) { // If the delegate iterator has a return method, give it a // chance to clean up. context.method = "return"; context.arg = undefined$1; maybeInvokeDelegate(delegate, context); if (context.method === "throw") { // If maybeInvokeDelegate(context) changed context.method from // "return" to "throw", let that override the TypeError below. return ContinueSentinel; } } context.method = "throw"; context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if (record.type === "throw") { context.method = "throw"; context.arg = record.arg; context.delegate = null; return ContinueSentinel; } var info = record.arg; if (!info) { context.method = "throw"; context.arg = new TypeError("iterator result is not an object"); context.delegate = null; return ContinueSentinel; } if (info.done) { // Assign the result of the finished delegate to the temporary // variable specified by delegate.resultName (see delegateYield). context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield). context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the // exception, let the outer generator proceed normally. If // context.method was "next", forget context.arg since it has been // "consumed" by the delegate iterator. If context.method was // "return", allow the original .return call to continue in the // outer generator. if (context.method !== "return") { context.method = "next"; context.arg = undefined$1; } } else { // Re-yield the result returned by the delegate method. return info; } // The delegate iterator is finished, so forget it and continue with // the outer generator. context.delegate = null; return ContinueSentinel; } // Define Generator.prototype.{next,throw,return} in terms of the // unified ._invoke helper method. defineIteratorMethods(Gp); define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the // @@iterator function is called on it. Some browsers' implementations of the // iterator prototype chain incorrectly implement this, causing the Generator // object to not be returned from this call. This ensures that doesn't happen. // See https://github.com/facebook/regenerator/issues/274 for more details. define(Gp, iteratorSymbol, function () { return this; }); define(Gp, "toString", function () { return "[object Generator]"; }); function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; if (1 in locs) { entry.catchLoc = locs[1]; } if (2 in locs) { entry.finallyLoc = locs[2]; entry.afterLoc = locs[3]; } this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal"; delete record.arg; entry.completion = record; } function Context(tryLocsList) { // The root entry object (effectively a try statement without a catch // or a finally block) gives us a place to store values thrown from // locations where there is no enclosing try statement. this.tryEntries = [{ tryLoc: "root" }]; tryLocsList.forEach(pushTryEntry, this); this.reset(true); } exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } keys.reverse(); // Rather than returning an object with a next method, we keep // things simple and return the next function itself. return function next() { while (keys.length) { var key = keys.pop(); if (key in object) { next.value = key; next.done = false; return next; } } // To avoid creating an additional object, we just hang the .value // and .done properties off the next function object itself. This // also ensures that the minifier will not anonymize the function. next.done = true; return next; }; }; function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) { return iteratorMethod.call(iterable); } if (typeof iterable.next === "function") { return iterable; } if (!isNaN(iterable.length)) { var i = -1, next = function next() { while (++i < iterable.length) { if (hasOwn.call(iterable, i)) { next.value = iterable[i]; next.done = false; return next; } } next.value = undefined$1; next.done = true; return next; }; return next.next = next; } } // Return an iterator with no values. return { next: doneResult }; } exports.values = values; function doneResult() { return { value: undefined$1, done: true }; } Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { this.prev = 0; this.next = 0; // Resetting context._sent for legacy support of Babel's // function.sent implementation. this.sent = this._sent = undefined$1; this.done = false; this.delegate = null; this.method = "next"; this.arg = undefined$1; this.tryEntries.forEach(resetTryEntry); if (!skipTempReset) { for (var name in this) { // Not sure about the optimal order of these conditions: if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { this[name] = undefined$1; } } } }, stop: function stop() { this.done = true; var rootEntry = this.tryEntries[0]; var rootRecord = rootEntry.completion; if (rootRecord.type === "throw") { throw rootRecord.arg; } return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) { throw exception; } var context = this; function handle(loc, caught) { record.type = "throw"; record.arg = exception; context.next = loc; if (caught) { // If the dispatched exception was caught by a catch block, // then let that catch block handle the exception normally. context.method = "next"; context.arg = undefined$1; } return !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; var record = entry.completion; if (entry.tryLoc === "root") { // Exception thrown outside of any try block that could handle // it, so set the completion value of the entire function to // throw the exception. return handle("end"); } if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"); var hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } else if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else if (hasCatch) { if (this.prev < entry.catchLoc) { return handle(entry.catchLoc, true); } } else if (hasFinally) { if (this.prev < entry.finallyLoc) { return handle(entry.finallyLoc); } } else { throw new Error("try statement without catch or finally"); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { // Ignore the finally entry if control is not jumping to a // location outside the try/catch block. finallyEntry = null; } var record = finallyEntry ? finallyEntry.completion : {}; record.type = type; record.arg = arg; if (finallyEntry) { this.method = "next"; this.next = finallyEntry.finallyLoc; return ContinueSentinel; } return this.complete(record); }, complete: function complete(record, afterLoc) { if (record.type === "throw") { throw record.arg; } if (record.type === "break" || record.type === "continue") { this.next = record.arg; } else if (record.type === "return") { this.rval = this.arg = record.arg; this.method = "return"; this.next = "end"; } else if (record.type === "normal" && afterLoc) { this.next = afterLoc; } return ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) { this.complete(entry.completion, entry.afterLoc); resetTryEntry(entry); return ContinueSentinel; } } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if (record.type === "throw") { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } // The context.catch method must only be called with a location // argument that corresponds to a known catch block. throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }; if (this.method === "next") { // Deliberately forget the last sent value so that we don't // accidentally pass it on to the delegate. this.arg = undefined$1; } return ContinueSentinel; } }; // Regardless of whether this script is executing as a CommonJS module // or not, return the runtime object so that we can declare the variable // regeneratorRuntime in the outer scope, which allows this module to be // injected easily by `bin/regenerator --include-runtime script.js`. return exports; }( // If this script is executing as a CommonJS module, use module.exports // as the regeneratorRuntime namespace. Otherwise create a new empty // object. Either way, the resulting object will be used to initialize // the regeneratorRuntime variable at the top of this file. module.exports ); try { regeneratorRuntime = runtime; } catch (accidentalStrictMode) { // This module should not be running in strict mode, so the above // assignment should always work unless something is misconfigured. Just // in case runtime.js accidentally runs in strict mode, in modern engines // we can explicitly access globalThis. In older engines we can escape // strict mode using a global Function call. This could conceivably fail // if a Content Security Policy forbids using Function, but in that case // the proper solution is to fix the accidental strict mode problem. If // you've misconfigured your bundler to force strict mode and applied a // CSP to forbid Function, and you're not willing to fix either of those // problems, please detail your unique predicament in a GitHub issue. if (typeof globalThis === "object") { globalThis.regeneratorRuntime = runtime; } else { Function("r", "regeneratorRuntime = r")(runtime); } } }); var regenerator = runtime_1; function _arrayLikeToArray$9(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray$9(arr); } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } function _unsupportedIterableToArray$9(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$9(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$9(o, minLen); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray$9(arr) || _nonIterableSpread(); } function _isNativeReflectConstruct$1A() { 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 _construct(Parent, args, Class) { if (_isNativeReflectConstruct$1A()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } var e = [], t$1 = []; function n$4(n, r) { if (n && "undefined" != typeof document) { var a, s = !0 === r.prepend ? "prepend" : "append", d = !0 === r.singleTag, i = "string" == typeof r.container ? document.querySelector(r.container) : document.getElementsByTagName("head")[0]; if (d) { var u = e.indexOf(i); -1 === u && (u = e.push(i) - 1, t$1[u] = {}), a = t$1[u] && t$1[u][s] ? t$1[u][s] : t$1[u][s] = c(); } else a = c(); 65279 === n.charCodeAt(0) && (n = n.substring(1)), a.styleSheet ? a.styleSheet.cssText += n : a.appendChild(document.createTextNode(n)); } function c() { var e = document.createElement("style"); if (e.setAttribute("type", "text/css"), r.attributes) for (var t = Object.keys(r.attributes), n = 0; n < t.length; n++) { e.setAttribute(t[n], r.attributes[t[n]]); } var a = "prepend" === s ? "afterbegin" : "beforeend"; return i.insertAdjacentElement(a, e), e; } } var css$3 = ":root {\n --main-color: #00c8af;\n --font-color: #999;\n}\n\n[x-cloak] {\n display: none !important;\n}\n\n*,\n::before,\n::after {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n -webkit-tap-highlight-color: rgba(255, 255, 255, 0);\n text-rendering: optimizeLegibility !important;\n -webkit-font-smoothing: antialiased !important;\n}\n\n.kankan-app {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n background-color: #292929;\n}\n\n.kankan-app .player {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 1;\n overflow: hidden;\n outline: none;\n border: none;\n}\n\n.kankan-app .player[name='copy'] {\n display: none;\n}\n\n.kankan-app .player-mark {\n display: none;\n cursor: grab;\n position: absolute;\n left: calc(50% - 56px);\n top: calc(50% - 56px);\n z-index: 999;\n width: 102px;\n height: 102px;\n}\n\n.kankan-app__split .player {\n cursor: crosshair;\n}\n\n.kankan-app__split .player[name='main'] {\n width: calc(50% - 1px);\n}\n\n.kankan-app__split .player[name='copy'] {\n width: calc(50% - 1px);\n display: block;\n left: auto;\n right: 0;\n}\n\n.kankan-app__split .player-mark {\n display: block;\n}\n\n.kankan-app__split [xui_tags] div {\n display: none !important;\n}\n\n.ui-view-layout[is-mobile='true'] .kankan-app__split .player[name='main'] {\n width: 100%;\n height: calc(50% - 1px);\n}\n\n.ui-view-layout[is-mobile='true'] .kankan-app__split .player[name='copy'] {\n width: 100%;\n height: calc(50% - 1px);\n display: block;\n top: 50%;\n left: auto;\n right: 0;\n}\n\n.kankan-app__slide-right {\n will-change: transform;\n transition: all 0.2s ease-in-out;\n}\n\n.kankan-app__slide-right-enter {\n opacity: 1;\n transform: translate3d(0, 0, 0);\n}\n\n.kankan-app__slide-right-leave {\n opacity: 0;\n transform: translate3d(100%, 0, 0);\n}\n\n/* plugins */\n.kankan-plugins input {\n padding: 0 5px;\n width: 100%;\n height: 34px;\n background: rgba(255, 255, 255, 0.1);\n border-radius: 4px;\n border: 1px solid rgba(255, 255, 255, 0.2);\n outline: none;\n color: #fff;\n}\n\n.kankan-plugins input:focus {\n border: 1px solid var(--main-color);\n}\n\n.kankan-plugins button {\n cursor: pointer;\n width: 100%;\n height: 34px;\n outline: none;\n border-radius: 4px;\n font-size: 14px;\n background: none !important;\n transition: all 0.3s ease;\n color: var(--main-color);\n border: 1px solid var(--main-color);\n}\n\n/* xui */\n.kankan-app_combox {\n cursor: pointer;\n position: relative;\n background: #323233;\n border-radius: 4px;\n border: 1px solid rgba(255, 255, 255, 0.2);\n outline: none;\n color: #fff;\n height: 34px;\n width: 100%;\n}\n\n.kankan-app_combox .inner-icon {\n cursor: pointer;\n font-size: 12px;\n position: absolute;\n right: 5px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--font-color);\n}\n\n.kankan-app_combox .inner-text {\n display: flex;\n align-items: center;\n padding: 0 5px;\n height: 100%;\n}\n\n.kankan-app_combox .inner-list {\n position: absolute;\n left: 0px;\n right: 0px;\n top: 100%;\n border: 1px solid rgba(255, 255, 255, 0.2);\n background: #323233;\n z-index: 1000;\n}\n\n.kankan-app_combox .inner-list>div {\n height: 34px;\n display: flex;\n align-items: center;\n padding: 0 5px;\n}\n\n.kankan-app_combox .inner-list>div:hover {\n color: var(--main-color);\n}"; n$4(css$3,{}); /* * @Author: Rindy * @Date: 2021-04-25 16:49:05 * @LastEditors: Rindy * @LastEditTime: 2021-09-15 11:31:00 * @Description: 注释 */ /** * 配置对象 */ var lang_zh = { 'common.about': '约', 'common.meter': '米', 'cad.input': '请输入名称', 'model.enter': '入户门' }; var config$4 = { num: null, dom: null, /** * 运行环境 */ env: "development", /** * SDK版本号 */ version: "4.12.0-alpha.26", /** * 源码版本号 */ edition: null, lang: 'zh', langs: {}, /** * SDK展示模式 */ view: true, /** * 移动端模式 */ mobile: false, /** * 部署方式,本地版为local */ deploy: '', /** * 区域 */ region: '', /** * 服务器地址 */ server: '', //'https://www.4dkankan.com/', /** * 场景资源地址 */ resource: 'https://4dkk.4dage.com/', /** * 显示SDK信息 */ showSDKInfo: true, /** * 是否使用场景控制快捷键 */ useShortcutKeys: false, /** * statistics */ useStatistics: true, /** * 是否需要用户鉴权 */ useAuth: false, /** * 抗锯齿 */ antialias: true, /** * 全景关联设置 */ link: { onAction: null, target: 'self' }, /** * 模型设置 */ model: { /** * 模型名称 */ name: '' // 铁塔 //name: 'tieta.dam', }, /** * 场景设置 */ scene: { /** * 图片质量 */ quality: null, /** * 自定义marker图片地址 */ markerURL: null, /** * 自定义marker透明的 */ markerOpacity: null, /** * 自定义当前点位颜色 */ pathEndColor: null, /** * 自定义地面logoId */ floorlogoId: null // 铁塔 //floorlogoId: 2, }, camera: { lookLimitUp: null, lookLimitDown: null // // 铁塔 // lookLimitUp: 89.9, // lookLimitDown: -89.9, }, vr: { markerHeight: null }, tag: { showIn: null }, /** * 获取服务器资源 */ getServerURL(path) { return this.server + path; }, /** * 获取场景资源地址 * @param {String} path 资源路径 */ getResourceURL(path) { return this.resource + path; }, /** * 获取场景图片地址 * @param {*} path 图片路径 */ getResourceImageURL(path) { return this.getResourceURL("scene_view_data/".concat(this.num, "/images/").concat(path)); }, /** * 获取场景数据地址 * @param {*} path 数据路径 */ getResourceDataURL(path) { return this.getResourceURL("scene_view_data/".concat(this.num, "/data/").concat(path)); }, i18n(key) { if (this.langs[this.lang] && this.langs[this.lang][key]) { return this.langs[this.lang][key]; } if (!this.langs['zh']) { this.langs['zh'] = lang_zh; } return this.langs['zh'][key] || ''; }, /** * 是否加载热点 */ isLoadTags: true }; if (config$4.showSDKInfo) { if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { var log$1 = ['\n %c %c 4DKanKan SDK ' + config$4.version + ' - https://www.4dkankan.com/ \n', 'background: #1fe4dc; padding:5px 0;', 'color: #000; background: #1fe4dc; padding:5px 0;']; console.log.apply(console, log$1); } else console && console.log('4DKanKan SDK ' + config$4.version + ' - https://www.4dkankan.com/'); } /* * @Author: Rindy * @Date: 2021-09-14 20:02:23 * @LastEditors: Rindy * @LastEditTime: 2021-09-14 20:03:48 * @Description: */ /** * Merges two arrays and returns the new one. * @param a * @param b * @param fn */ function mergeArrays(a, b, fn) { var result = []; for (var i = 0; i < a.length; i += 1) { if (typeof a !== 'undefined') { if (a[i] !== null && typeof a[i] === 'object') { result[i] = fn({}, a[i]); } else { result[i] = a[i]; } } } for (var _i = 0; _i < b.length; _i += 1) { if (typeof b[_i] !== 'undefined') { if (b[_i] !== null && typeof b[_i] === 'object') { result[_i] = fn(a[_i], b[_i]); } else { result[_i] = b[_i]; } } } return result; } /** * Merge deep objects * @param args */ function deepExtend() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var a = args.shift(); for (var i = 0; i < args.length; i += 1) { var b = args[i]; if (a !== null && b !== null && typeof a !== 'undefined' && typeof b !== 'undefined') { // Merge objects if (typeof a === 'object' && typeof b === 'object') { // Merge arrays if (a instanceof Array && b instanceof Array) { a = mergeArrays(a, b, deepExtend); } else { var keys = Object.keys(b); for (var j = 0; j < keys.length; j += 1) { var key = keys[j]; // Avoid prototype pollution. if (key !== '__proto__') { if (typeof b[key] === 'object' && b[key] !== null) { a[key] = deepExtend(a[key], b[key]); } else if (typeof b[key] !== 'undefined') { a[key] = b[key]; } } } } } } else if (b !== null && typeof b !== 'undefined') { if (b instanceof Array) { a = mergeArrays([], b, deepExtend); } else { a = b; } } } return a; } function _classPrivateFieldBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } var id = 0; function _classPrivateFieldKey(name) { return "__private_" + id++ + "_" + name; } function isArray$4(arr) { return Object.prototype.toString.call(arr) === '[object Array]'; } function foreach(arr, handler) { if (isArray$4(arr)) { for (var i = 0; i < arr.length; i++) { handler(arr[i]); } } else handler(arr); } function D(fn) { var status = 'pending', doneFuncs = [], failFuncs = [], progressFuncs = [], resultArgs = null, _promise = { done: function done() { for (var i = 0; i < arguments.length; i++) { // skip any undefined or null arguments if (!arguments[i]) { continue; } if (isArray$4(arguments[i])) { var arr = arguments[i]; for (var j = 0; j < arr.length; j++) { // immediately call the function if the deferred has been resolved if (status === 'resolved') { arr[j].apply(this, resultArgs); } doneFuncs.push(arr[j]); } } else { // immediately call the function if the deferred has been resolved if (status === 'resolved') { arguments[i].apply(this, resultArgs); } doneFuncs.push(arguments[i]); } } return this; }, fail: function fail() { for (var i = 0; i < arguments.length; i++) { // skip any undefined or null arguments if (!arguments[i]) { continue; } if (isArray$4(arguments[i])) { var arr = arguments[i]; for (var j = 0; j < arr.length; j++) { // immediately call the function if the deferred has been resolved if (status === 'rejected') { arr[j].apply(this, resultArgs); } failFuncs.push(arr[j]); } } else { // immediately call the function if the deferred has been resolved if (status === 'rejected') { arguments[i].apply(this, resultArgs); } failFuncs.push(arguments[i]); } } return this; }, always: function always() { return this.done.apply(this, arguments).fail.apply(this, arguments); }, progress: function progress() { for (var i = 0; i < arguments.length; i++) { // skip any undefined or null arguments if (!arguments[i]) { continue; } if (isArray$4(arguments[i])) { var arr = arguments[i]; for (var j = 0; j < arr.length; j++) { // immediately call the function if the deferred has been resolved if (status === 'pending') { progressFuncs.push(arr[j]); } } } else { // immediately call the function if the deferred has been resolved if (status === 'pending') { progressFuncs.push(arguments[i]); } } } return this; }, then: function then(done, fail, progress) { /* // fail callbacks if (arguments.length > 1 && arguments[1]) { this.fail(arguments[1]) } // done callbacks if (arguments.length > 0 && arguments[0]) { this.done(arguments[0]) } // notify callbacks if (arguments.length > 2 && arguments[2]) { this.progress(arguments[2]) } return this */ return D(function (def) { foreach(done, function (func) { // filter function if (typeof func === 'function') { deferred.done(function () { var returnval = func.apply(this, arguments); // if a new deferred/promise is returned, its state is passed to the current deferred/promise if (returnval && typeof returnval === 'function') { returnval.promise().then(def.resolve, def.reject, def.notify); } else { // if new return val is passed, it is passed to the piped done def.resolve(returnval); } }); } else { deferred.done(def.resolve); } }); foreach(fail, function (func) { if (typeof func === 'function') { deferred.fail(function () { var returnval = func.apply(this, arguments); if (returnval && typeof returnval === 'function') { returnval.promise().then(def.resolve, def.reject, def.notify); } else { def.reject(returnval); } }); } else { deferred.fail(def.reject); } }); }).promise(); }, catch: function _catch() { for (var i = 0; i < arguments.length; i++) { // skip any undefined or null arguments if (!arguments[i]) { continue; } if (isArray$4(arguments[i])) { var arr = arguments[i]; for (var j = 0; j < arr.length; j++) { // immediately call the function if the deferred has been resolved if (status === 'rejected') { arr[j].apply(this, resultArgs); } failFuncs.push(arr[j]); } } else { // immediately call the function if the deferred has been resolved if (status === 'rejected') { arguments[i].apply(this, resultArgs); } failFuncs.push(arguments[i]); } } return this; }, promise: function promise(obj) { if (obj == null) { return _promise; } else { for (var i in _promise) { obj[i] = _promise[i]; } return obj; } }, state: function state() { return status; }, debug: function debug() { console.log('[debug]', doneFuncs, failFuncs, status); }, isRejected: function isRejected() { return status === 'rejected'; }, isResolved: function isResolved() { return status === 'resolved'; }, pipe: function pipe(done, fail, progress) { return D(function (def) { foreach(done, function (func) { // filter function if (typeof func === 'function') { deferred.done(function () { var returnval = func.apply(this, arguments); // if a new deferred/promise is returned, its state is passed to the current deferred/promise if (returnval && typeof returnval === 'function') { returnval.promise().then(def.resolve, def.reject, def.notify); } else { // if new return val is passed, it is passed to the piped done def.resolve(returnval); } }); } else { deferred.done(def.resolve); } }); foreach(fail, function (func) { if (typeof func === 'function') { deferred.fail(function () { var returnval = func.apply(this, arguments); if (returnval && typeof returnval === 'function') { returnval.promise().then(def.resolve, def.reject, def.notify); } else { def.reject(returnval); } }); } else { deferred.fail(def.reject); } }); }).promise(); } }, deferred = { resolveWith: function resolveWith(context) { if (status === 'pending') { status = 'resolved'; var args = resultArgs = arguments.length > 1 ? arguments[1] : []; for (var i = 0; i < doneFuncs.length; i++) { doneFuncs[i].apply(context, args); } } return this; }, rejectWith: function rejectWith(context) { if (status === 'pending') { status = 'rejected'; var args = resultArgs = arguments.length > 1 ? arguments[1] : []; for (var i = 0; i < failFuncs.length; i++) { failFuncs[i].apply(context, args); } } return this; }, notifyWith: function notifyWith(context) { if (status === 'pending') { var args = resultArgs = arguments.length > 1 ? arguments[1] : []; for (var i = 0; i < progressFuncs.length; i++) { progressFuncs[i].apply(context, args); } } return this; }, resolve: function resolve() { return this.resolveWith(this, arguments); }, reject: function reject() { return this.rejectWith(this, arguments); }, notify: function notify() { return this.notifyWith(this, arguments); } }; var obj = _promise.promise(deferred); if (fn) { fn.apply(obj, [obj]); } return obj; } D.when = function () { if (arguments.length < 2) { var obj = arguments.length ? arguments[0] : undefined; if (obj && typeof obj.isResolved === 'function' && typeof obj.isRejected === 'function') { return obj.promise(); } else { return D().resolve(obj).promise(); } } else { return function (args) { var df = D(), size = args.length, done = 0, rp = new Array(size); // resolve params: params of each resolve, we need to track down them to be able to pass them in the correct order if the master needs to be resolved for (var i = 0; i < args.length; i++) { (function (j) { var obj = null; if (args[j].done) { args[j].done(function () { rp[j] = arguments.length < 2 ? arguments[0] : arguments; if (++done == size) { df.resolve.apply(df, rp); } }).fail(function () { df.reject(arguments); }); } else { obj = args[j]; args[j] = new Deferred(); args[j].done(function () { rp[j] = arguments.length < 2 ? arguments[0] : arguments; if (++done == size) { df.resolve.apply(df, rp); } }).fail(function () { df.reject(arguments); }).resolve(obj); } })(i); } return df.promise(); }(arguments); } }; var Defer = D; function Deferred$1 () { return new D(); } var _deferrals = /*#__PURE__*/_classPrivateFieldKey("deferrals"); var Plugins = /*#__PURE__*/function () { function Plugins(app) { _classCallCheck(this, Plugins); Object.defineProperty(this, _deferrals, { writable: true, value: {} }); this.app = app; } _createClass(Plugins, [{ key: "add", value: function () { var _add = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(Plugin, config) { var _this = this; var plugin; return regenerator.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: plugin = Plugin(this.app, config); return _context.abrupt("return", new Promise(function (resolve, reject) { if (plugin.then) { plugin.then(function (instance) { if (!instance.$name) { return reject('require a plugin name'); } if (_this[instance.$name]) { return resolve(_this[instance.$name]); } if (instance.$html) { if (instance.$scope) { instance.$scope.insertAdjacentHTML('beforeend', instance.$html); } else { _this.app.$plugins.insertAdjacentHTML('beforeend', instance.$html); } delete instance.$html; } _this[instance.$name] = instance; if (instance.$load) { instance.$load(); delete instance.$load; } if (_classPrivateFieldBase(_this, _deferrals)[_deferrals][instance.$name]) { _classPrivateFieldBase(_this, _deferrals)[_deferrals][instance.$name].resolve(instance); } resolve(instance); }); } })); case 2: case "end": return _context.stop(); } } }, _callee, this); })); function add(_x, _x2) { return _add.apply(this, arguments); } return add; }() }, { key: "get", value: function get(name) { if (_classPrivateFieldBase(this, _deferrals)[_deferrals][name] == void 0) { _classPrivateFieldBase(this, _deferrals)[_deferrals][name] = Deferred$1(); } return _classPrivateFieldBase(this, _deferrals)[_deferrals][name]; } }]); return Plugins; }(); var _components = /*#__PURE__*/_classPrivateFieldKey("components"); /* * @Author: Rindy * @Date: 2021-09-15 09:31:50 * @LastEditors: Rindy * @LastEditTime: 2021-11-01 10:40:09 * @Description: Core Component */ var Component = /*#__PURE__*/function () { function Component(app) { _classCallCheck(this, Component); Object.defineProperty(this, _components, { writable: true, value: void 0 }); this.app = app; _classPrivateFieldBase(this, _components)[_components] = {}; } _createClass(Component, [{ key: "add", value: function add(name, component) { if (['store', 'resource'].indexOf(name) == -1) { _classPrivateFieldBase(this, _components)[_components][name] = component; } else { this.app[name] = component; } } }, { key: "get", value: function get(name) { return _classPrivateFieldBase(this, _components)[_components][name]; } }]); return Component; }(); /* * @Author: Rindy * @Date: 2021-04-26 14:18:55 * @LastEditors: Rindy * @LastEditTime: 2021-09-13 12:28:00 * @Description: 注释 */ var baseOrigin = location.origin; var currentScript = (document.currentScript || {}).src; /** * 获取当前脚本路径 */ var getScriptURL = function () { if (!currentScript) { var a = {}; try { a.b(); } catch (e) { var stack = e.stack || e.sourceURL || e.stacktrace; var match = /(?:http|https|file):\/\/.*?\/.+?.js/.exec(stack); if (match) { currentScript = match[0]; } } } var filepathPart = currentScript.split('/'); filepathPart.pop(); currentScript = filepathPart.join('/') + '/'; return function () { return currentScript; }; }(); window.addEventListener('error', function (evt) { }); function createScript(url) { var script = document.createElement('script'); script.async = true; // Only add cross origin for actual cross origin // this is because Safari triggers for all // - https://bugs.webkit.org/show_bug.cgi?id=171566 if (url.indexOf(baseOrigin + '/')) { script.crossOrigin = 'anonymous'; } script.src = url; return script; } function loadScript(url, name, version) { return new Promise(function (resolve, reject) { var script = createScript(url + (version ? "?v=".concat(version) : '')); script.addEventListener('error', function () { console.error('load:' + url + ' error'); reject(); }); script.addEventListener('load', function () { document.head.removeChild(script); resolve(name); }); document.head.appendChild(script); }); } function usePlugin(name, version) { return loadScript(getScriptURL() + 'plugins/' + name + '.js', name, version); } var GUI = /*#__PURE__*/function () { function GUI(app) { _classCallCheck(this, GUI); this.app = app; } // data可直接传String,默认为content /** * @param data * { type: String, delay: Number, content: String, showClose: Boolean } */ _createClass(GUI, [{ key: "toast", value: function toast(data) { // alert(data.content) this.app.emit('gui.toast', data); } /** * @param data * { title: { type: String, default: '提示' }, okText: { type: String, default: '确定' }, func: Function, content: String } */ }, { key: "alert", value: function alert(data) { // alert(data) this.app.emit('gui.alert', data); } /** * @param data * { title: { type: String, default: '提示' }, okText: { type: String, default: '确定' }, noText: { type: String, default: '取消' }, single: { type: Boolean, default: true }, func: Function, content: String } */ }, { key: "confirm", value: function confirm(data) { // alert(data) this.app.emit('gui.confirm', data); } }]); return GUI; }(); function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray$9(arr, i) || _nonIterableRest(); } var math$1 = { getBaseLog(x, y) { //返回以 x 为底 y 的对数(即 logx y) . Math.log 返回一个数的自然对数 return Math.log(y) / Math.log(x); }, convertVisionVector: function convertVisionVector(e) { return new THREE.Vector3(e.x, e.z, -e.y); }, invertVisionVector: function invertVisionVector(e) { //反转给算法部 return new THREE.Vector3(e.x, -e.z, e.y); }, convertVisionQuaternion: function convertVisionQuaternion(e) { return new THREE.Quaternion(e.x, e.z, -e.y, e.w).multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(90))); }, invertVisionQuaternion: function invertVisionQuaternion(e) { //反转给算法部 var a = e.clone().multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(-90))); return new THREE.Quaternion(a.x, -a.z, a.y, a.w); }, convertWorkshopVector: function convertWorkshopVector(e) { return new THREE.Vector3(-e.x, e.y, e.z); }, convertWorkshopQuaternion: function convertWorkshopQuaternion(e) { return new THREE.Quaternion(-e.x, e.y, e.z, -e.w).multiply(new THREE.Quaternion(Math.sqrt(2) / 2, Math.sqrt(2) / 2, 0, 0)); }, convertWorkshopPanoramaQuaternion: function convertWorkshopPanoramaQuaternion(e) { return new THREE.Quaternion(e.x, -e.y, -e.z, e.w).normalize().multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(270))); }, convertWorkshopOrthoZoom: function convertWorkshopOrthoZoom(e, dom) { //xzw return e === -1 ? -1 : e * (dom.clientHeight / dom.clientHeight); }, getVec2Angle: function getVec2Angle(dir1, dir2) { return Math.acos(THREE.MathUtils.clamp(this.getVec2Cos(dir1, dir2), -1, 1)); }, getVec2Cos: function getVec2Cos(dir1, dir2) { return dir1.dot(dir2) / dir1.length() / dir2.length(); }, closeTo: function closeTo(a, b, num) { if (num != void 0) return Math.abs(a - b) < num; return Math.abs(a - b) < 1e-6; }, toPrecision: function toPrecision(e, t) { //xzw change 保留小数 var f = function f(e, t) { var i = Math.pow(10, t); return Math.round(e * i) / i; }; if (e instanceof Array) { for (var s = 0; s < e.length; s++) { e[s] = f(e[s], t); } return e; } else if (e instanceof Object) { for (var s in e) { e[s] = f(e[s], t); } return e; } else return f(e, t); }, isEmptyQuaternion: function isEmptyQuaternion(e) { return 0 === Math.abs(e.x) && 0 === Math.abs(e.y) && 0 === Math.abs(e.z) && 0 === Math.abs(e.w); }, projectPositionToCanvas: function projectPositionToCanvas(e, t, i, domE) { i = i || new THREE.Vector3(), i.copy(e); var r = 0.5 * domE.clientWidth, o = 0.5 * domE.clientHeight; return i.project(t), i.x = i.x * r + r, i.y = -(i.y * o) + o, i; }, convertScreenPositionToNDC: function convertScreenPositionToNDC(e, t, i, domE) { /* return i = i || new THREE.Vector2, i.x = e / window.innerWidth * 2 - 1, i.y = 2 * -(t / window.innerHeight) + 1, i */ return i = i || new n.Vector2(), i.x = e / domE.clientWidth * 2 - 1, i.y = 2 * -(t / domE.clientHeight) + 1, i; }, handelPadding: function () { //去除player左边和上面的宽高,因为pc的player左上有其他element 许钟文 var pads = new Map(); //记录下来避免反复计算 return function (x, y, domE) { var pad; var padInfo = pads.get(domE); if (padInfo) { if (domE.clientWidth == padInfo.width && domE.clientHeight == padInfo.height) { //resize pad = padInfo.pad; } } if (!pad) { pad = domE.getBoundingClientRect(); pads.set(domE, { width: domE.clientWidth, height: domE.clientHeight, pad }); } return { x: x - pad.x, y: y - pad.y }; }; }(), /* getOffset: function (type, element, parent) { //弃用,因body上的offset得不到 //获取元素的边距 许钟文 var offset = type == 'left' ? element.offsetLeft : element.offsetTop if (!parent) parent = document.body while ((element = element.offsetParent)) { if (element == parent) break offset += type == 'left' ? element.offsetLeft : element.offsetTop } return offset }, */ constrainedTurn: function constrainedTurn(e) { var t = e % (2 * Math.PI); return t = t > Math.PI ? t -= 2 * Math.PI : t < -Math.PI ? t += 2 * Math.PI : t; }, getFOVDotThreshold: function getFOVDotThreshold(e) { return Math.cos(THREE.MathUtils.degToRad(e / 2)); }, transform2DForwardVectorByCubeFace: function transform2DForwardVectorByCubeFace(e, t, i, n) { switch (e) { case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_X: i.set(1, t.y, t.x); break; case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_X: i.set(-1, t.y, -t.x); break; case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Y: i.set(-t.x, 1, -t.y); break; case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: i.set(-t.x, -1, t.y); break; case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Z: i.set(-t.x, t.y, 1); break; case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: i.set(t.x, t.y, -1); } n && i.normalize(); }, getFootPoint: function getFootPoint(oldPos, p1, p2, restricInline) { //找oldPos在线段p1, p2上的垂足 /* if(isWorld){//输出全局坐标 需要考虑meshGroup.position p1 = p1.clone(); p2 = p2.clone(); p1.y += mainDesign.meshGroup.position.y; p2.y += mainDesign.meshGroup.position.y; } */ var op1 = oldPos.clone().sub(p1); var p1p2 = p1.clone().sub(p2); var p1p2Len = p1p2.length(); var leftLen = op1.dot(p1p2) / p1p2Len; var pos = p1.clone().add(p1p2.multiplyScalar(leftLen / p1p2Len)); if (restricInline && pos.clone().sub(p1).dot(pos.clone().sub(p2)) > 0) { //foot不在线段上 if (pos.distanceTo(p1) < pos.distanceTo(p2)) pos = p1.clone();else pos = p2.clone(); } return pos; }, /** * 计算多边形的重心 * @param {*} points */ getCenterOfGravityPoint: function getCenterOfGravityPoint(mPoints) { var area = 0.0; //多边形面积 var Gx = 0.0, Gy = 0.0; // 重心的x、y for (var i = 1; i <= mPoints.length; i++) { var ix = mPoints[i % mPoints.length].x; var iy = mPoints[i % mPoints.length].y; var nx = mPoints[i - 1].x; var ny = mPoints[i - 1].y; var temp = (ix * ny - iy * nx) / 2.0; area += temp; Gx += temp * (ix + nx) / 3.0; Gy += temp * (iy + ny) / 3.0; } Gx = Gx / area; Gy = Gy / area; return { x: Gx, y: Gy }; }, getBound: function getBound(ring) { var bound = new THREE.Box2(); for (var j = 0, len = ring.length; j < len; j++) { bound.expandByPoint(ring[j]); } return bound; }, isPointInArea: function isPointInArea(ring, point, ifAtLine) { //判断点是否在某个环内 var bound = this.getBound(ring); if (point.x < bound.min.x || point.x > bound.max.x || point.y < bound.min.y || point.y > bound.max.y) return false; var inside = false; var x = point.x, y = point.y; for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) { var xi = ring[i].x, yi = ring[i].y; var xj = ring[j].x, yj = ring[j].y; if ((xi - x) * (yj - y) == (xi - x) * (yi - y) && x >= Math.min(xi, xj) && x <= Math.max(xi, xj) && //xzw add y >= Math.min(yi, yj) && y <= Math.max(yi, yj)) { return !!ifAtLine; //在线段上,则判断为…… (默认在外) } if (yi > y != yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi) { inside = !inside; } } return inside; }, getArea: function getArea(ring) { //求面积 顺时针为正 来自three shape for (var t = ring.length, i = 0, n = t - 1, r = 0; r < t; n = r++) { i += ring[n].x * ring[r].y - ring[r].x * ring[n].y; } return -0.5 * i; }, isInBetween: function isInBetween(a, b, c, precision) { // 如果b几乎等于a或c,返回false.为了避免浮点运行时两值几乎相等,但存在相差0.00000...0001的这种情况出现使用下面方式进行避免 /* if (Math.abs(a - b) < 0.000001 || Math.abs(b - c) < 0.000001) { return false; } return (a <= b && b <= c) || (c <= b && b <= a);*/ //更改:如果b和a或c中一个接近 就算在a和c之间 return a <= b && b <= c || c <= b && b <= a || this.closeTo(a, b, precision) || this.closeTo(b, c, precision); }, ifPointAtLineBound: function ifPointAtLineBound(point, linePoints, precision) { //待验证 横线和竖线比较特殊 return math$1.isInBetween(linePoints[0].x, point.x, linePoints[1].x, precision) && math$1.isInBetween(linePoints[0].y, point.y, linePoints[1].y, precision); }, isLineIntersect: function isLineIntersect(line1, line2, notSegment) { //线段和线段是否有交点. notSegment代表是直线而不是线段 var a1 = line1[1].y - line1[0].y; var b1 = line1[0].x - line1[1].x; var c1 = a1 * line1[0].x + b1 * line1[0].y; //转换成一般式: Ax+By = C var a2 = line2[1].y - line2[0].y; var b2 = line2[0].x - line2[1].x; var c2 = a2 * line2[0].x + b2 * line2[0].y; // 计算交点 var d = a1 * b2 - a2 * b1; // 当d==0时,两线平行 if (d == 0) { return false; } else { var x = (b2 * c1 - b1 * c2) / d; var y = (a1 * c2 - a2 * c1) / d; // 检测交点是否在两条线段上 /* if (notSegment || (isInBetween(line1[0].x, x, line1[1].x) || isInBetween(line1[0].y, y, line1[1].y)) && (isInBetween(line2[0].x, x, line2[1].x) || isInBetween(line2[0].y, y, line2[1].y))) { return {x,y}; } */ if (notSegment || math$1.ifPointAtLineBound({ x, y }, line1) && math$1.ifPointAtLineBound({ x, y }, line2)) { return { x, y }; } } }, getNormal: function getNormal(line2d) { //获取二维法向量 方向向内 var x, y; //要求的向量 //line2d的向量 var x1 = line2d.points[1].x - line2d.points[0].x; var y1 = line2d.points[1].y - line2d.points[0].y; //假设法向量的x或y固定为1或-1 if (y1 != 0) { x = 1; y = -(x1 * x) / y1; } else if (x1 != 0) { //y如果为0,正常情况x不会是0 y = 1; x = -(y1 * y) / x1; } else { console.log('两个点一样'); return null; } //判断方向里或者外: var vNormal = new THREE.Vector3(x, 0, y); var vLine = new THREE.Vector3(x1, 0, y1); var vDir = vNormal.cross(vLine); if (vDir.y > 0) { x *= -1; y *= -1; } return new THREE.Vector2(x, y).normalize(); }, getQuaBetween2Vector: function getQuaBetween2Vector(oriVec, newVec, upVec) { //获取从oriVec旋转到newVec可以应用的quaternion var angle = oriVec.angleTo(newVec); var axis = oriVec.clone().cross(newVec).normalize(); //两个up之间 if (axis.length() == 0) { //当夹角为180 或 0 度时,得到的axis为(0,0,0),故使用备用的指定upVec return new THREE.Quaternion().setFromAxisAngle(upVec, angle); } return new THREE.Quaternion().setFromAxisAngle(axis, angle); }, getScaleForConstantSize: function () { //获得规定二维大小的mesh的scale值。可以避免因camera的projection造成的mesh视觉大小改变。 来源:tag.updateDisc var w; var i = new THREE.Vector3(), o = new THREE.Vector3(), l = new THREE.Vector3(), c = new THREE.Vector3(), h = new THREE.Vector3(); return function () { var op = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (op.width2d) w = op.width2d; //如果恒定二维宽度 else { var currentDis; if (op.camera.type == 'OrthographicCamera') { //floorplan要直接使用activeControl.camera,主要用到projectionMatrix currentDis = (op.camera.right - op.camera.left) / op.camera.zoom / 3; } else { currentDis = op.position.distanceTo(op.camera.position); //dollhouse要直接使用player.camera, 因为activeControl.camera没有更新matrixWorld } if (op.nearBound == void 0 && op.farBound != void 0 || op.nearBound != void 0 && op.farBound == void 0) { //仅限制最大或最小的话,不判断像素大小,直接限制mesh的scale //这个判断也可以写到getScaleForConstantSize里,可以更严谨控制像素宽度,这里只简单计算大小 var scale; if (op.farBound == void 0 && currentDis < op.nearBound) { scale = op.scale * currentDis / op.nearBound; } else if (op.nearBound == void 0 && currentDis > op.farBound) { scale = op.scale * currentDis / op.farBound; } else { scale = op.scale; } return scale; } w = op.maxSize - (op.maxSize - op.minSize) * THREE.MathUtils.smoothstep(currentDis, op.nearBound, op.farBound); //maxSize : mesh要表现的最大像素宽度; nearBound: 最近距离,若比nearBound近,则使用maxSize } i.copy(op.position).project(op.camera), //tag中心在屏幕上的二维坐标 o.set(op.dom.clientWidth / 2, op.dom.clientHeight / 2, 1).multiply(i), //转化成px -w/2 到 w/2的范围 l.set(w / 2, 0, 0).add(o), //加上tag宽度的一半 c.set(2 / op.dom.clientWidth, 2 / op.dom.clientHeight, 1).multiply(l), //再转回 -1 到 1的范围 h.copy(c).unproject(op.camera); //再转成三维坐标,求得tag边缘的位置 var g = h.distanceTo(op.position); //就能得到tag的三维半径 return g; }; }(), //W , H, left, top分别是rect的宽、高、左、上 getCrossPointAtRect: function getCrossPointAtRect(p1, aim, W, H, left, top) { //求射线p1-aim在rect边界上的交点,其中aim在rect范围内,p1则不一定(交点在aim这边的延长线上) var x, y, borderX; var r = (aim.x - p1.x) / (aim.y - p1.y); //根据相似三角形原理先求出这个比值 var getX = function getX(y) { return r * (y - p1.y) + p1.x; }; var getY = function getY(x) { return 1 / r * (x - p1.x) + p1.y; }; if (aim.x >= p1.x) { borderX = W + left; } else { borderX = left; } x = borderX; y = getY(x); if (y < top || y > top + H) { if (y < top) { y = top; } else { y = top + H; } x = getX(y); } return new THREE.Vector2(x, y); }, getDirFromUV: function getDirFromUV(uv) { //获取dir 反向计算 - - 二维转三维比较麻烦 var dirB; //所求 单位向量 uv.x %= 1; if (uv.x < 0) uv.x += 1; //调整为0-1 var y = Math.cos(uv.y * Math.PI); //uv中纵向可以直接确定y, 根据上面getUVfromDir的反向计算 var angle = 2 * Math.PI * uv.x - Math.PI; //x/z代表的是角度 var axisZ; //axis为1代表是正,-1是负数 if (-Math.PI / 2 <= angle && angle < Math.PI / 2) { axisZ = 1; //右半圆 } else { axisZ = -1; //左半圆 } var XDivideZ = Math.tan(angle); var z = Math.sqrt((1 - y * y) / (1 + XDivideZ * XDivideZ)); var x = XDivideZ * z; if (z * axisZ < 0) { //异号 z *= -1; x *= -1; } x *= -1; //计算完成后这里不能漏掉 *= -1 dirB = new THREE.Vector3(x, y, z); //理想状态下x和z和anotherDir相同 return dirB; }, getUVfromDir: function getUVfromDir(dir) { //获取UV 同shader里的计算 var dir = dir.clone(); dir.x *= -1; //计算前这里不能漏掉 *= -1 见shader var tx = Math.atan2(dir.x, dir.z) / (Math.PI * 2.0) + 0.5; //atan2(y,x) 返回从 X 轴正向逆时针旋转到点 (x,y) 时经过的角度。区间是-PI 到 PI 之间的值 var ty = Math.acos(dir.y) / Math.PI; return { x: tx, y: ty }; //理想状态下tx相同 }, crossRight: function crossRight(vec3, matrix) { //向量右乘矩阵,不能用向量的applyMatrix4(左乘) var e = matrix.elements; var v = new THREE.Vector3(); v.x = e[0] * vec3.x + e[1] * vec3.y + e[2] * vec3.z + e[3]; v.y = e[4] * vec3.x + e[5] * vec3.y + e[6] * vec3.z + e[7]; v.z = e[8] * vec3.x + e[9] * vec3.y + e[10] * vec3.z + e[11]; //v.w不要 return v; }, getNormalDir: function getNormalDir(point, supportsTiles, currentPano) { //获取A单位法线 /* console.log("lookVector:") console.log(objects.player.cameraControls.activeControl.lookVector) */ var dir = point.clone().sub(currentPano.position); //OA /* console.log("A的dir(无matrix转化):") console.log(dir.clone().normalize()); */ if (supportsTiles) { var matrixWorld = currentPano.rot90Matrix.clone(); //因为热点求点时所右乘的matrix必须是单张全景照片时用的转90度的matrix才行 } else { var matrixWorld = currentPano.matrixWorld.clone(); } dir = this.crossRight(dir, matrixWorld); //右乘matrixWorld 得matrix转化的向量 dir.normalize(); /* var b = player.currentPano.skyboxMesh.matrixWorld.clone().getInverse(player.currentPano.skyboxMesh.matrixWorld) console.log(crossRight(dir,b).normalize()) */ return dir; }, getDirByLonLat: function getDirByLonLat(lon, lat) { var dir = new THREE.Vector3(); var phi = THREE.MathUtils.degToRad(90 - lat); var theta = THREE.MathUtils.degToRad(lon); dir.x = Math.sin(phi) * Math.cos(theta); dir.y = Math.cos(phi); dir.z = Math.sin(phi) * Math.sin(theta); return dir; }, //0,0 => (1,0,0) 270=>(0,0,-1) getLineIntersect2() { var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; //得两条直线在其向量构成的面的法线方向的交点,投影在线上点的中点。 if (o.A != void 0) { // Ap1为一条线,Bp2为一条线 var A = o.A; var B = o.B; var p1 = o.p1 || new THREE.Vector3().addVctors(A, o.dir0); var p2 = o.p2 || new THREE.Vector3().addVctors(B, o.dir1); var dir0 = o.dir0 || new THREE.Vector3().subVectors(p1, A); var dir1 = o.dir1 || new THREE.Vector3().subVectors(p2, B); } if (A.equals(B)) return { pos3d: p1.clone() }; //寻找两个向量所在的面 var normal = dir0.clone().cross(dir1); //面的法线 //先把整体旋转到使在xz平面上,求完交点再转回来 var qua = math$1.getQuaBetween2Vector(normal, new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 1, 0)); var newPoints = [A, B, p1, p2].map(function (e) { return e.clone().applyQuaternion(qua); }); var pos2d = math$1.isLineIntersect([{ x: newPoints[0].x, y: newPoints[0].z }, { x: newPoints[2].x, y: newPoints[2].z }], [{ x: newPoints[1].x, y: newPoints[1].z }, { x: newPoints[3].x, y: newPoints[3].z }], true); var quaInverse = qua.clone().invert(); var pos3d = new THREE.Vector3(pos2d.x, 0, pos2d.y); var pos3d1 = pos3d.clone().setY(newPoints[0].y); var pos3d2 = pos3d.clone().setY(newPoints[1].y); pos3d1.applyQuaternion(quaInverse); pos3d2.applyQuaternion(quaInverse); pos3d = new THREE.Vector3().addVectors(pos3d1, pos3d2).multiplyScalar(0.5); return { pos3d, mid1: pos3d1, mid2: pos3d2 }; }, getLineIntersect(o) { //两条三维直线相交 //取两线最短线段中心点 并且不能超出起点 o = o || {}; if (o.A != void 0) { // Ap1为一条线,Bp2为一条线 var A = o.A; var B = o.B; var p1 = o.p1; var p2 = o.p2; } if (A.equals(B)) return { pos3d: p1.clone() }; /* console.log("v1:") console.log(A.clone().sub(p1).normalize()) console.log("v2:") console.log(B.clone().sub(p2).normalize()) */ //调试热点夹角 var line1 = p1.clone().sub(A).normalize(); var line2 = p2.clone().sub(B).normalize(); line1.angleTo(line2); //var pano = player.model.panos.index[player.posGets.list[1]] //console.log('真实两线夹角: ', THREE.MathUtils.radToDeg(angle)) /*+ "旧夹角min: "+getAngle(pano.recentAngleScore)+"("+pano.recentAngleScore+")" */ //---------- var compute = function compute() { var pos3d; var ux = p1.x - A.x; var uy = p1.y - A.y; var uz = p1.z - A.z; var vx = p2.x - B.x; var vy = p2.y - B.y; var vz = p2.z - B.z; var wx = A.x - B.x; var wy = A.y - B.y; var wz = A.z - B.z; var a = ux * ux + uy * uy + uz * uz; //u*u var b = ux * vx + uy * vy + uz * vz; //u*v var c = vx * vx + vy * vy + vz * vz; //v*v var d = ux * wx + uy * wy + uz * wz; //u*w var e = vx * wx + vy * wy + vz * wz; //v*w var dt = a * c - b * b; var sd = dt; var td = dt; var sn = 0.0; //sn = be-cd var tn = 0.0; //tn = ae-bd var behind = function (index) { //在后方交点的话,直接其中一个点 不用两posget点中心点是因为可能从不同方位 距离很大 pos3d = (index == 1 ? p1 : p2).clone(); //console.log(pos3d , ' 在后方交点,使用点' + index) }.bind(this); if (math$1.closeTo(dt, 0.0)) { //两直线平行 sn = 0.0; //在s上指定取s0 sd = 1.0; //防止计算时除0错误 tn = e; //按(公式3)求tc td = c; } else { sn = b * e - c * d; tn = a * e - b * d; if (sn < 0.0) { //最近点在s起点以外,同平行条件 behind(1); return { pos3d, behind: true }; } } if (tn < 0.0) { //最近点在t起点以外 behind(2); return { pos3d, behind: true }; } /* else if (tn > td){ //超出终点不限制 tn = td; if ((-d + b) < 0.0) sn = 0.0; else if ((-d + b) > a) sn = sd; else { sn = (-d + b); sd = a; } } */ var sc = 0.0; var tc = 0.0; if (math$1.closeTo(sn, 0.0)) sc = 0.0;else sc = sn / sd; if (math$1.closeTo(tn, 0.0)) tc = 0.0;else tc = tn / td; //两个最近点 var mid1 = new THREE.Vector3(A.x + sc * ux, A.y + sc * uy, A.z + sc * uz); var mid2 = new THREE.Vector3(B.x + tc * vx, B.y + tc * vy, B.z + tc * vz); /* console.log("v11:") console.log(A.clone().sub(mid1).normalize()) console.log("v22:") console.log(B.clone().sub(mid2).normalize()) */ //console.log('另一个结果', math.getLineIntersect2(o)) //结果一样的,只是没有限制后方交点 var r = { pos3d: mid1.clone().add(mid2).multiplyScalar(0.5), mid1, mid2 }; return r; }; return compute(); //https://blog.csdn.net/u011511587/article/details/52063663 三维空间两直线/线段最短距离、线段计算算法 }, getShapeGeo: function getShapeGeo(points, holes) { //获取任意形状(多边形或弧形)的形状面 //quadraticCurveTo() 这是弧形的含函数 var shape = new THREE.Shape(); shape.moveTo(points[0].x, points[0].y); for (var i = 1, len = points.length; i < len; i++) { shape.lineTo(points[i].x, points[i].y); } /* var holePath = new THREE.Path() .moveTo( 20, 10 ) .absarc( 10, 10, 10, 0, Math.PI * 2, true ) arcShape.holes.push( holePath ); */ if (holes) { //挖空 holes.forEach(function (points) { var holePath = new THREE.Path(); holePath.moveTo(points[0].x, points[0].y); for (var i = 1, len = points.length; i < len; i++) { holePath.lineTo(points[i].x, points[i].y); } shape.holes.push(holePath); }); } var geometry = new THREE.ShapeBufferGeometry(shape); //ShapeGeometry return geometry; }, getUnPosPlaneGeo: function () { //获取还没有赋值位置的plane geometry var e = new Uint16Array([0, 1, 2, 0, 2, 3]), // , t = new Float32Array([-.5, -.5, 0, .5, -.5, 0, .5, .5, 0, -.5, .5, 0]) i = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]), g = new THREE.BufferGeometry(); g.setIndex(new THREE.BufferAttribute(e, 1)), //g.setAttribute("position", new n.BufferAttribute(t, 3)), g.setAttribute('uv', new THREE.BufferAttribute(i, 2)); return function () { return g; }; }(), getPlaneGeo: function getPlaneGeo(A, B, C, D) { var geo = this.getUnPosPlaneGeo().clone(); var pos = new Float32Array([A.x, A.y, A.z, B.x, B.y, B.z, C.x, C.y, C.z, D.x, D.y, D.z]); geo.setAttribute('position', new THREE.BufferAttribute(pos, 3)); geo.computeVertexNormals(); geo.computeBoundingSphere(); //for raycaster return geo; }, drawPlane: function drawPlane(A, B, C, D, material) { var wall = new THREE.Mesh(this.getPlaneGeo(A, B, C, D), material); return wall; }, movePlane: function movePlane(mesh, A, B, C, D) { var pos = new Float32Array([A.x, A.y, A.z, B.x, B.y, B.z, C.x, C.y, C.z, D.x, D.y, D.z]); mesh.geometry.setAttribute('position', new THREE.BufferAttribute(pos, 3)); mesh.geometry.computeBoundingSphere(); //for checkIntersect }, getAngle(vec1, vec2, axis) { var angle = vec1.angleTo(vec2); var axis_ = vec1.clone().cross(vec2); if (axis_[axis] < 0) { angle *= -1; } return angle; }, linearClamp(value, xArr, yArr) { if (arguments.length == 5) { xArr = [arguments[1], arguments[2]]; yArr = [arguments[3], arguments[4]]; } var len = xArr.length; if (value <= xArr[0]) return yArr[0]; if (value >= xArr[len - 1]) return yArr[len - 1]; var i = 0; while (++i < len) { if (value < xArr[i]) { var x1 = xArr[i - 1], x2 = xArr[i], y1 = yArr[i - 1], y2 = yArr[i]; value = y1 + (y2 - y1) * (value - x1) / (x2 - x1); break; } } return value; }, isInsideFrustum(bounding, camera) { // bounding是否在视野范围内有可见部分(视野就是一个锥状box) var frustumMatrix = new THREE.Matrix4(); frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); var frustum = new THREE.Frustum(); frustum.setFromProjectionMatrix(frustumMatrix); if (bounding instanceof THREE.Sphere) { return frustum.intersectsSphere(bounding); } else { return frustum.intersectsBox(bounding); } }, getStandardYaw(yaw1, yaw2) { //使yaw1过渡到yaw2时朝角度差小的那边走。如果差距大于半个圆,就要反个方向转(把大的那个数字减去360度) if (Math.abs(yaw1 - yaw2) > Math.PI) { yaw1 > yaw2 ? yaw1 -= Math.PI * 2 : yaw2 -= Math.PI * 2; } return [yaw1, yaw2]; } }; var easing = {}; //渐变曲线函数,反应加速度的变化 //currentTime:x轴当前时间(从0-到duration), startY:起始点, duration:总时长, wholeY:路程 (即endY-startY) //参数基本是 x, 0, 1, 1 /* easeOut 基本是y= m * (x-dur)^k + n, 若k为偶数,m<0, 若k为奇数,m>0; (因为偶数的话必须开口向下才能获得斜率递减的递增的那段,而奇数是对称的,单调递增. ) 根据x=0时y=0, x=dur时y=S , 得 n = S,m = -S/(-dur)^k */ easing.getEaseOut = function (k) { // k 是>=2的整数. 越大变化率越大, 相同初始速度所需要时间越久 var easeFun; k = Math.round(k); if (k < 2) { k = Math.PI / 2; easeFun = easing.easeOutSine; } else { easeFun = function easeFun(currentTime, startY, wholeY, duration) { if (k > 2) { console.log(k); } return -wholeY / Math.pow(-duration, k) * Math.pow(currentTime - duration, k) + wholeY; }; } return { k, easeFun }; }; easing.linearTween = function (currentTime, startY, wholeY, duration) { return wholeY * currentTime / duration + startY; }, easing.easeInQuad = function (currentTime, startY, wholeY, duration) { return currentTime /= duration, wholeY * currentTime * currentTime + startY; }, easing.easeOutQuad = function (currentTime, startY, wholeY, duration) { // 如套上实际的距离S和时长dur, y = - S / dur *(x^2-2x) 当s为1,dur为1时,是 y = -(x-1)^2 + 1 , 在0-1中是斜率递减的递增函数. 导数- S / dur *(2x-2 ) 可求出实时速度 故在0这一时刻,速度为 2S/dur return currentTime /= duration, -wholeY * currentTime * (currentTime - 2) + startY; }, easing.easeInOutQuad = function (currentTime, startY, wholeY, duration) { return currentTime /= duration / 2, currentTime < 1 ? wholeY / 2 * currentTime * currentTime + startY : (currentTime--, -wholeY / 2 * (currentTime * (currentTime - 2) - 1) + startY); }, easing.easeInCubic = function (currentTime, startY, wholeY, duration) { return currentTime /= duration, wholeY * currentTime * currentTime * currentTime + startY; }, easing.easeOutCubic = function (currentTime, startY, wholeY, duration) { // y = S / dur^3 *(x-dur)^3 + S,对称中心是(dur,S),从0-dur是 斜率递减的递增函数,导数为3S/dur^3 * (x-dur)^2, 0时速度为3S/dur return currentTime /= duration, currentTime--, wholeY * (currentTime * currentTime * currentTime + 1) + startY; }, easing.easeInOutCubic = function (currentTime, startY, wholeY, duration) { return currentTime /= duration / 2, currentTime < 1 ? wholeY / 2 * currentTime * currentTime * currentTime + startY : (currentTime -= 2, wholeY / 2 * (currentTime * currentTime * currentTime + 2) + startY); }, easing.easeInQuart = function (currentTime, startY, wholeY, duration) { return currentTime /= duration, wholeY * currentTime * currentTime * currentTime * currentTime + startY; }, easing.easeOutQuart = function (currentTime, startY, wholeY, duration) { //根据上面的计算,估计0时速度应该是4S/dur吧…… return currentTime /= duration, currentTime--, -wholeY * (currentTime * currentTime * currentTime * currentTime - 1) + startY; }, easing.easeInOutQuart = function (currentTime, startY, wholeY, duration) { return currentTime /= duration / 2, currentTime < 1 ? wholeY / 2 * currentTime * currentTime * currentTime * currentTime + startY : (currentTime -= 2, -wholeY / 2 * (currentTime * currentTime * currentTime * currentTime - 2) + startY); }, easing.easeInQuint = function (currentTime, startY, wholeY, duration) { return currentTime /= duration, wholeY * currentTime * currentTime * currentTime * currentTime * currentTime + startY; }, easing.easeOutQuint = function (currentTime, startY, wholeY, duration) { return currentTime /= duration, currentTime--, wholeY * (currentTime * currentTime * currentTime * currentTime * currentTime + 1) + startY; }, easing.easeInOutQuint = function (currentTime, startY, wholeY, duration) { return currentTime /= duration / 2, currentTime < 1 ? wholeY / 2 * currentTime * currentTime * currentTime * currentTime * currentTime + startY : (currentTime -= 2, wholeY / 2 * (currentTime * currentTime * currentTime * currentTime * currentTime + 2) + startY); }, easing.easeInSine = function (currentTime, startY, wholeY, duration) { return -wholeY * Math.cos(currentTime / duration * (Math.PI / 2)) + wholeY + startY; }, easing.easeOutSine = function (currentTime, startY, wholeY, duration) { // y' = S * PI / 2 / dur * cos(PI/2/dur * x) return wholeY * Math.sin(currentTime / duration * (Math.PI / 2)) + startY; }, easing.easeInOutSine = function (currentTime, startY, wholeY, duration) { return -wholeY / 2 * (Math.cos(Math.PI * currentTime / duration) - 1) + startY; }, easing.easeInExpo = function (currentTime, startY, wholeY, duration) { return wholeY * Math.pow(2, 10 * (currentTime / duration - 1)) + startY; }, easing.easeOutExpo = function (currentTime, startY, wholeY, duration) { return wholeY * (-Math.pow(2, -10 * currentTime / duration) + 1) + startY; }, easing.easeInOutExpo = function (currentTime, startY, wholeY, duration) { return currentTime /= duration / 2, currentTime < 1 ? wholeY / 2 * Math.pow(2, 10 * (currentTime - 1)) + startY : (currentTime--, wholeY / 2 * (-Math.pow(2, -10 * currentTime) + 2) + startY); }, easing.easeInCirc = function (currentTime, startY, wholeY, duration) { return currentTime /= duration, -wholeY * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY; }, easing.easeOutCirc = function (currentTime, startY, wholeY, duration) { return currentTime /= duration, currentTime--, wholeY * Math.sqrt(1 - currentTime * currentTime) + startY; }, easing.easeInOutCirc = function (currentTime, startY, wholeY, duration) { return currentTime /= duration / 2, currentTime < 1 ? -wholeY / 2 * (Math.sqrt(1 - currentTime * currentTime) - 1) + startY : (currentTime -= 2, wholeY / 2 * (Math.sqrt(1 - currentTime * currentTime) + 1) + startY); }, easing.easeInElastic = function (currentTime, startY, wholeY, duration) { var r = 1.70158, o = 0, a = wholeY; return 0 === currentTime ? startY : 1 === (currentTime /= duration) ? startY + wholeY : (o || (o = 0.3 * duration), a < Math.abs(wholeY) ? (a = wholeY, r = o / 4) : r = o / (2 * Math.PI) * Math.asin(wholeY / a), -(a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o)) + startY); }, easing.easeOutElastic = function (currentTime, startY, wholeY, duration) { var r = 1.70158, o = 0, a = wholeY; return 0 === currentTime ? startY : 1 === (currentTime /= duration) ? startY + wholeY : (o || (o = 0.3 * duration), a < Math.abs(wholeY) ? (a = wholeY, r = o / 4) : r = o / (2 * Math.PI) * Math.asin(wholeY / a), a * Math.pow(2, -10 * currentTime) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o) + wholeY + startY); }, easing.easeInOutElastic = function (currentTime, startY, wholeY, duration) { var r = 1.70158, o = 0, a = wholeY; return 0 === currentTime ? startY : 2 === (currentTime /= duration / 2) ? startY + wholeY : (o || (o = duration * (0.3 * 1.5)), a < Math.abs(wholeY) ? (a = wholeY, r = o / 4) : r = o / (2 * Math.PI) * Math.asin(wholeY / a), currentTime < 1 ? -0.5 * (a * Math.pow(2, 10 * (currentTime -= 1)) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o)) + startY : a * Math.pow(2, -10 * (currentTime -= 1)) * Math.sin((currentTime * duration - r) * (2 * Math.PI) / o) * 0.5 + wholeY + startY); }, easing.easeInBack = function (currentTime, startY, wholeY, duration, r) { return void 0 === r && (r = 1.70158), wholeY * (currentTime /= duration) * currentTime * ((r + 1) * currentTime - r) + startY; }, easing.easeOutBack = function (currentTime, startY, wholeY, duration, r) { return void 0 === r && (r = 1.70158), wholeY * ((currentTime = currentTime / duration - 1) * currentTime * ((r + 1) * currentTime + r) + 1) + startY; }, easing.easeInOutBack = function (currentTime, startY, wholeY, duration, r) { return void 0 === r && (r = 1.70158), (currentTime /= duration / 2) < 1 ? wholeY / 2 * (currentTime * currentTime * (((r *= 1.525) + 1) * currentTime - r)) + startY : wholeY / 2 * ((currentTime -= 2) * currentTime * (((r *= 1.525) + 1) * currentTime + r) + 2) + startY; }, easing.easeOutBounce = function (currentTime, startY, wholeY, duration) { return (currentTime /= duration) < 1 / 2.75 ? wholeY * (7.5625 * currentTime * currentTime) + startY : currentTime < 2 / 2.75 ? wholeY * (7.5625 * (currentTime -= 1.5 / 2.75) * currentTime + 0.75) + startY : currentTime < 2.5 / 2.75 ? wholeY * (7.5625 * (currentTime -= 2.25 / 2.75) * currentTime + 0.9375) + startY : wholeY * (7.5625 * (currentTime -= 2.625 / 2.75) * currentTime + 0.984375) + startY; }, easing.easeInBounce = function (currentTime, startY, wholeY, r) { return wholeY - easing.easeOutBounce(r - currentTime, 0, wholeY, r) + startY; }, easing.easeInOutBounce = function (currentTime, startY, wholeY, r) { return currentTime < r / 2 ? 0.5 * easing.easeInBounce(2 * currentTime, 0, wholeY, r) + startY : 0.5 * easing.easeOutBounce(x, 2 * currentTime - r, 0, wholeY, r) + 0.5 * wholeY + startY; }; var transitions$1 = { globalDone: null, funcs: [], counter: 0, uniqueID: 0, start(e, t, i) { var r = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; var o = arguments.length > 4 ? arguments[4] : undefined; var a = arguments.length > 5 ? arguments[5] : undefined; var s = arguments.length > 6 ? arguments[6] : undefined; var cancelFun = arguments.length > 7 ? arguments[7] : undefined; var ignoreFirstFrame = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : true; var object = { func: e, current: -r * Math.abs(t), duration: (1 - Math.max(r, 0)) * Math.abs(t), done: i, easing: o || easing.linearTween, cycling: t < 0, running: !0, debug: r < 0, name: a || 'T' + this.counter, id: void 0 === s ? this.counter : s, paused: !1, cancelFun: cancelFun, //取消时执行的函数 updateCount: 0, //add ignoreFirstFrame //add }; this.funcs.push(object); e(0, 16); this.counter += 1; return e; }, trigger(e) { var t = void 0 === e.delayRatio ? 0 : e.delayRatio, i = e.func || function () {}, r = void 0 === e.duration ? 0 : e.duration; void 0 !== e.cycling && e.cycling && (r = -Math.abs(r)); var o = e.done || null, a = e.easing || easing.linearTween, s = e.name || 'R' + this.counter, l = void 0 === e.id ? this.counter : e.id; return this.start(i, r, o, t, a, s, l); }, setTimeout(e, t, i) { var n = void 0 === i ? this.counter : i; return this.trigger({ done: e, duration: void 0 === t ? 0 : t, name: 'O' + this.counter, id: n }); }, pause() { this.paused = !0; }, resume() { this.paused = !1; }, update(e) { this.funcs.forEach(function (t) { if (t.updateCount++ == 0 && t.ignoreFirstFrame) return; //add start可能发生在一帧中任意时刻,而每次update的是在一帧中的固定时刻,所以从start到第一次update的时间并不是所传入的delta,该delta 是上一帧的update到这一帧的update的耗时。 故去掉了第一次的update,相当于延迟一帧再update. if (!(t.paused || (t.current += 1e3 * e, t.current < 0))) if (t.current >= t.duration && !t.cycling) { var i = t.easing(1, 0, 1, 1); t.func(i, 1e3 * e), t.done && t.done(), t.running = !1; } else { var n = t.easing(t.current % t.duration / t.duration, 0, 1, 1), r = t.func(n, 1e3 * e) || !1; r && (t.done && t.done(), t.running = !1); } }); var t = this.funcs.length; this.funcs = this.funcs.filter(function (e) { return e.running; }); var i = this.funcs.length; if (t > 0 && 0 === i && this.globalDone) { var n = this.globalDone; this.globalDone = null, n(); } }, adjustSpeed(e, t) { for (var i = this.getById(e), n = 0; n < i.length; n++) { var r = i[n]; r.duration /= t, r.current /= t; } }, getById(e) { return this.funcs.filter(function (t) { return e === t.id; }); }, get(e) { for (var t = 0; t < this.funcs.length; t += 1) { if (this.funcs[t].func === e) return this.funcs[t]; } return null; }, isRunning(e) { var t = this.get(e); return null !== t && t.running; }, countActive() { for (var e = 0, t = 0; t < this.funcs.length; t += 1) { e += this.funcs[t].running; } return e; }, listActive() { for (var e = [], t = 0; t < this.funcs.length; t += 1) { this.funcs[t].running && e.push(this.funcs[t].name); } return e; }, done(e) { this.globalDone = e; }, cancelById: function cancelById(e, dealCancelFun) { //xzw add dealDone var t = void 0 === e ? 0 : e; this.funcs = this.funcs.filter(function (e) { var is = e.id == t; if (is && dealCancelFun) { e.cancelFun && e.cancelFun(); } return !is; }); }, cancel(e) { this.funcs = this.funcs.filter(function (t) { return t.func !== e; }); }, getUniqueId() { return this.uniqueID -= 1, this.uniqueID; } }; function _createForOfIteratorHelper$8(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$8(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$8(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$8(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$8(o, minLen); } function _arrayLikeToArray$8(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } var lastCallTime = 0; var common = { delayOneFrame(e) { window.setTimeout(e, 1); }, normalizeUrl(e) { return e.replace('https://', 'http://'); }, domainFromUrl(e) { var t = /^([^:]*:\/\/)?(www\.)?([^\/]+)/.exec(e); return t ? t[3] : e; }, average(e, t) { if (0 === e.length) return null; for (var i = 0, n = 0, r = 0; r < e.length; r++) { var o = t ? e[r][t] : e[r]; i += o, n++; } return i / n; }, countUnique(e) { for (var t = {}, i = 0; i < e.length; i++) { t[e[i]] = 1 + (t[e[i]] || 0); } return Object.keys(t).length; }, averageVectors(e, t) { var i = new THREE.Vector3(); if (0 === e.length) return i; for (var r = 0, o = 0; o < e.length; o++) { var a = t ? e[o][t] : e[o]; i.add(a), r++; } return i.divideScalar(r); }, equalLists(e, t) { if (e.length !== t.length) return !1; for (var i = 0; i < e.length; i++) { if (e[i] !== t[i]) return !1; } return !0; }, lowerMedian(e, t) { if (0 === e.length) return null; t = t || 2, e.sort(function (e, t) { return e - t; }); var i = Math.floor(e.length / t); return e[i]; }, stableSort(e, t) { return e.map(function (e, t) { return { value: e, index: t }; }).sort(function (e, i) { var n = t(e.value, i.value); return 0 !== n ? n : e.index - i.index; }).map(function (e) { return e.value; }); }, sortByScore: function sortByScore(list, request, rank) { var i = request ? common.filterAll(list, request) : list; return 0 === i.length ? [] : i = i.map(function (e) { var scores = rank.map(function (f) { return f(e); }); //add return { item: e, scores, score: scores.reduce(function (t, i) { return t + i; }, 0) }; }).sort(function (e, t) { return t.score - e.score; }); }, filterAll(e, t) { return e.filter(function (e) { return t.every(function (t) { return t(e); }); }); }, formatDate(e) { return [e.getFullYear(), e.getMonth() + 1, e.getDate()].join('-'); }, formatDatetime(e) { return [e.getFullYear(), e.getMonth() + 1, e.getDate(), e.getHours(), e.getMinutes()].join('-'); }, randomString(e) { for (var t = '', i = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', n = 0; n < e; n++) { t += i.charAt(Math.floor(Math.random() * i.length)); } return t; }, uint8ToBase64(e, t) { t && 'number' == typeof t || (t = 8192); for (var i = [], n = 0; n < e.length; n += t) { i.push(String.fromCharCode.apply(null, e.subarray(n, n + t))); } return btoa(i.join('')); }, uuid4: function e(t) { return t ? (t ^ 16 * Math.random() >> t / 4).toString(16) : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, e); }, nth(e) { return e %= 10, 1 === e ? e + 'st' : 2 === e ? e + 'nd' : 3 === e ? e + 'rd' : e + 'th'; }, extendObject(e, t) { return Object.keys(t).forEach(function (i) { e[i] = t[i]; }), e; }, deepExtend: function e(t) { t = t || {}; for (var i = 1; i < arguments.length; i++) { var n = arguments[i]; if (n) for (var r in n) { n.hasOwnProperty(r) && ('object' == typeof n[r] ? t[r] = e(t[r], n[r]) : t[r] = n[r]); } } return t; }, inherit(e, t) { e.prototype = Object.create(t.prototype), e.prototype.constructor = e; }, extend(e, t) { for (var i in t.prototype) { e.prototype[i] = t.prototype[i]; } }, //额外添加的 extendObject(e, t) { if (!(t instanceof Object)) return; //许钟文 加 ie有遇到非object的数据 return Object.keys(t).forEach(function (i) { e[i] = t[i]; }), e; }, _textureCache: {}, loadTextureFromCache(c) { return this._textureCache[c] || (this._textureCache[c] = getTexture(c)), this._textureCache[c]; }, extend(c, d) { for (var f in d.prototype) { c.prototype[f] = d.prototype[f]; } }, valueFromHash(e, t) { var i = new RegExp('[#&?]' + e + '=([^#&?]*)'), n = i.exec(window.location.href); if (!n) return t; var r = n[1]; return 'boolean' == typeof t ? 'true' === r || '1' === r : 'number' == typeof t ? parseFloat(r) : window.decodeURIComponent(r); }, deepFreeze(o) { var _this = this; Object.freeze(o); Object.getOwnPropertyNames(o).forEach(function (prop) { if (o.hasOwnProperty(prop) && o[prop] !== null && (typeof o[prop] === 'object' || typeof o[prop] === 'function') && !Object.isFrozen(o[prop])) { _this.deepFreeze(o[prop]); } }); return o; }, defaultValue(value) { if (value != void 0 && typeof value === 'object') { return Array.isArray(value) ? [] : {}; } }, randomUnique() { return crypto.getRandomValues(new Uint32Array(1))[0]; }, debounce(fn, delay) { var isImmediateCall = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var timer = null; // 上次调用的时刻 if (isImmediateCall) { return function () { var context = this; var currentTime = Date.now(); if (currentTime - lastCallTime >= delay) { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } fn.apply(context, args); lastCallTime = currentTime; } }; } else { return function () { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } if (timer) { clearTimeout(timer); } var context = this; timer = setTimeout(function () { fn.apply(context, args); }, delay); }; } }, getMixedSet: function getMixedSet(arr1, arr2) { //交集 return arr1.filter(function (item) { return arr2.includes(item); }); }, getUnionSet: function getUnionSet(arr1, arr2) { //并集 return arr1.concat(arr2.filter(function (item) { return !arr1.includes(item); })); }, getDifferenceSet: function getDifferenceSet(arr1, arr2) { //差集 不能识别重复的,如getDifferenceSet([1,2,2],[1,1,2]) 为空 var arr11 = arr1.filter(function (item) { return !arr2.includes(item); }); var arr22 = arr2.filter(function (item) { return !arr1.includes(item); }); return arr11.concat(arr22); }, getDifferenceSetMuti: function getDifferenceSetMuti(arr) { //收集绝对没有重复的元素,也就是判断出现次数=1的 var set = []; arr.forEach(function (arr1) { arr1.forEach(function (item) { var index = set.indexOf(item); if (index > -1) { set.splice(index, 1); } else { set.push(item); } }); }); return set; }, pushToGroupAuto: function pushToGroupAuto(items, groups, recognizeFunction, judgeRelationFun) { //自动分组。 items是将分到一起的组合。items.length = 1 or 2. var isSame = function isSame(a, b) { return a == b || recognizeFunction && recognizeFunction(a, b); }; var atGroups = groups.filter(function (group) { return group.find(function (item) { return (isSame(item, items[0]) || isSame(item, items[1])) && (!judgeRelationFun || judgeRelationFun(group)); } //根据关系进一步判断是否应该一组 ); }); if (atGroups.length) { //在不同组 //因为items是一组的,所以先都放入组1 items.forEach(function (item) { if (!atGroups[0].includes(item)) atGroups[0].push(item); }); if (atGroups.length > 1) { //如果在不同组,说明这两个组需要合并 var combineGroup = []; combineGroup.relationships = [items.slice()]; atGroups.forEach(function (group) { var relationships = common.getUnionSet(combineGroup.relationships, group.relationships); combineGroup = common.getUnionSet(combineGroup, group); combineGroup.relationships = relationships; groups.splice(groups.indexOf(group), 1); }); groups.push(combineGroup); } else { atGroups[0].relationships.push(items.slice()); } } else { //直接加入为一组 items.relationships = [items.slice()]; groups.push(items); } }, disconnectGroup: function disconnectGroup(pairs, groups, recognizeFunction) { //将atGroup中的pairs关系解除,然后重新分组 var isSame = function isSame(a, b) { return a == b || recognizeFunction && recognizeFunction(a, b); }; var oldGroups = groups.slice(); pairs.forEach(function (items) { var relationship; var atGroup = groups.find(function (group) { var r = group.relationships.find(function (arr) { return items.every(function (e) { return arr.some(function (a) { return isSame(a, e); }); }); }); if (r) { relationship = r; return true; } }); //能找到relationships 有包含items的, 代表它们有绑定关系 if (!atGroup) return; //断开连接时,因为组内没有其他成员的连接信息,所以需要清除整组,并将剩余的一个个重新连接 groups.splice(groups.indexOf(atGroup), 1); //删除 atGroup.relationships.splice(atGroup.relationships.indexOf(relationship), 1); var newGroups_ = []; //为了防止裂解的该组(因之前有judgeRelationFun但现在没传)混入其他组,先放一个空组合里 atGroup.relationships.forEach(function (pair) { //然后再重新生成这两个和组的关系,各自分组 common.pushToGroupAuto(pair, newGroups_, recognizeFunction); }); groups.push.apply(groups, newGroups_); }); var newGroups = groups.filter(function (e) { return !oldGroups.includes(e); }); return { newGroups }; }, removeFromGroup: function removeFromGroup(items, atGroup, groups, recognizeFunction) { //将该组移除items中的所有元素,以及包含它的关系 var isSame = function isSame(a, b) { return a == b || recognizeFunction && recognizeFunction(a, b); }; var newRelations = atGroup.relationships.filter(function (arr) { return !arr.some(function (e) { return items.some(function (item) { return isSame(e, item); }); }); }); if (newRelations.length == atGroup.relationships) return; //断开连接时,因为组内没有其他成员的连接信息,所以需要清除整组,并将剩余的一个个重新连接 groups.splice(groups.indexOf(atGroup), 1); //删除 var newGroups = []; //为了防止裂解的该组(因之前有judgeRelationFun但现在没传)混入其他组,先放一个空组合里 atGroup.relationships.forEach(function (pair) { //然后再重新生成这两个和组的关系,各自分组 common.pushToGroupAuto(pair, newGroups, recognizeFunction); }); groups.push.apply(groups, newGroups); return { newGroups }; } }; common.getMAXCUBETEXTURESIZE = function () { try { var e = document.createElement('canvas'), t = e.getContext('webgl'); t || (t = e.getContext('experimental-webgl')); var i = t.getParameter(t.MAX_CUBE_MAP_TEXTURE_SIZE); return i; } catch (e) { return 0; } }; var getTexture = function () { var textureLoader = new THREE.TextureLoader(); textureLoader.setCrossOrigin('Anonymous'); textureLoader.crossOrigin = true; return function (url, onLoad, onProgress, onError) { var map = textureLoader.load(url, onLoad, onProgress, onError); map.magFilter = map.minFilter = THREE.LinearFilter; map.needsUpadte = true; return map; }; }(); common.dataURLtoBlob = function (dataurl) { //将base64转换blob var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }; common.dataURLtoFile = function (dataurl, filename) { //将base64转换为文件 var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, { type: mime }); }; common.saveFile = function (data, filename, cb) { var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a'); save_link.href = data; save_link.download = filename; var event = document.createEvent('MouseEvents'); event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); save_link.dispatchEvent(event); cb && cb(); }; common.PrefixPng = 'data:image/png;base64,'; common.getBlobSrc = function (base64, addPre) { //base64 --> blobsrc var blob = common.dataURLtoBlob((addPre ? common.PrefixPng : '') + base64); return window.URL.createObjectURL(blob); }; common.replaceAll = function (str, f, e) { //f全部替换成e var reg = new RegExp(f, 'g'); //创建正则RegExp对象 return str.replace(reg, e); }; common.randomWord = function (randomFlag, min, max) { //随机字符串 var str = '', range = min, arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; if (randomFlag) { // 随机长度 range = Math.round(Math.random() * (max - min)) + min; } for (var i = 0; i < range; i++) { var pos = Math.round(Math.random() * (arr.length - 1)); str += arr[pos]; } return str; }; common.getRandomSid = function () { //5-7位随机字符串 + 6位时间 为热点准备 var pre = common.randomWord(true, 5, 7); var post = new Date().getTime() + ''; var len = post.length; post = post.substring(len - 8, len - 5) + post.substring(len - 3, len); //其实还是有可能重复的.... return pre + post; }; common.getTime = function (second) { //秒 var str = ''; //不支持大于60分钟的时间哟 var minute = Math.round(second / 60); if (minute < 10) str += '0'; str += minute; second = Math.round(second % 60) + ''; if (second.length == 1) second = '0' + second; str = str + ':' + second; return str; }; common.CloneJson = function (data) { var str = JSON.stringify(data); return JSON.parse(str); }, common.CloneObject = function (copyObj, isSimpleCopy) { var _this2 = this; var simpleCopyList = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; var judgeSimpleCopyFun = arguments.length > 3 ? arguments[3] : undefined; //isSimpleCopy 只复制最外层 //复制json result的可能:普通数字或字符串、普通数组、复杂对象 simpleCopyList.includes(THREE.Object3D) || simpleCopyList.push(THREE.Object3D); //遇到simpleCopyList中的类直接使用不拷贝 judgeSimpleCopyFun || (judgeSimpleCopyFun = function judgeSimpleCopyFun() {}); if (!copyObj || typeof copyObj == 'number' || typeof copyObj == 'string' || copyObj instanceof Function || simpleCopyList.some(function (className) { return copyObj instanceof className; }) || judgeSimpleCopyFun(copyObj)) { return copyObj; } if (copyObj instanceof Array) { return copyObj.map(function (e) { return _this2.CloneObject(e, isSimpleCopy, simpleCopyList, judgeSimpleCopyFun); }); } else { if (copyObj.clone instanceof Function) { //解决一部分 return copyObj.clone(); } } var result = {}; for (var key in copyObj) { if (copyObj[key] instanceof Object && !isSimpleCopy) result[key] = this.CloneObject(copyObj[key], isSimpleCopy, simpleCopyList, judgeSimpleCopyFun);else result[key] = copyObj[key]; //如果是函数类同基本数据,即复制引用 } return result; }, common.CloneClassObject = function (copyObj) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$ignoreList = _ref.ignoreList, ignoreList = _ref$ignoreList === void 0 ? [] : _ref$ignoreList, _ref$simpleCopyList = _ref.simpleCopyList, simpleCopyList = _ref$simpleCopyList === void 0 ? [] : _ref$simpleCopyList; //复杂类对象 var newobj = new copyObj.constructor(); this.CopyClassObject(newobj, copyObj, { ignoreList, simpleCopyList }); return newobj; }, common.CopyClassObject = function (targetObj, copyObj) { var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, _ref2$ignoreList = _ref2.ignoreList, ignoreList = _ref2$ignoreList === void 0 ? [] : _ref2$ignoreList, _ref2$simpleCopyList = _ref2.simpleCopyList, simpleCopyList = _ref2$simpleCopyList === void 0 ? [] : _ref2$simpleCopyList; //复杂类对象 for (var i in copyObj) { if (i in copyObj.__proto__) break; //到函数了跳出 if (ignoreList.includes(i)) { continue; } else if (simpleCopyList.includes(i)) { targetObj[i] = copyObj[i]; } else { targetObj[i] = this.CloneObject(copyObj[i], false, simpleCopyList); } } }, common.ifSame = function (object1, object2) { if (object1 == object2) return true; // 0 != undefined , 0 == '' else if (!object1 || !object2) return false;else if (object1.constructor != object2.constructor) { return false; } else if (object1 instanceof Array) { if (object1.length != object2.length) return false; var _object2 = object2.slice(0); var _loop = function _loop(i) { u = _object2.find(function (e) { return ifSame(object1[i], e); }); if (u == void 0 && !_object2.includes(u) && !object1.includes(u)) return { v: false };else { var index = _object2.indexOf(u); _object2.splice(index, 1); } }; for (var i = 0; i < object1.length; i++) { var u; var _ret = _loop(i); if (typeof _ret === "object") return _ret.v; } return true; } else if (object1.equals instanceof Function) { //复杂数据仅支持这种,其他的可能卡住? return object1.equals(object2); } else if (typeof object1 == 'number' || typeof object1 == 'string') { if (isNaN(object1) && isNaN(object2)) return true;else return object1 == object2; } else if (typeof object1 == 'object') { var keys1 = Object.keys(object1); var keys2 = Object.keys(object2); if (!ifSame(keys1, keys2)) return false; for (var _i in object1) { var same = ifSame(object1[_i], object2[_i]); if (!same) return false; } return true; } else { console.log('isSame出现例外'); } }; common.canvasToImg = function (canvas) { var compressRatio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; var download = arguments.length > 2 ? arguments[2] : undefined; var type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'image/jpeg'; var filename = arguments.length > 4 ? arguments[4] : undefined; // 图片导出为 png 格式 var imgData = canvas.toDataURL(type, compressRatio); // 加工image data,替换mime type if (download) { this.saveTex(imgData, type, filename); } return imgData; }; var _fixType = function _fixType(type) { type = type.toLowerCase().replace(/jpg/i, 'jpeg'); var r = type.match(/png|jpeg|bmp|gif/)[0]; return 'image/' + r; }; common.saveTex = function (imgData) { var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'image/jpeg'; var filename = arguments.length > 2 ? arguments[2] : undefined; return function (filename) { imgData = imgData.replace(_fixType(type), 'image/octet-stream'); // 下载后的图片名 var filename = filename || '4dage_' + new Date().getTime() + (type == 'png' ? '.png' : '.jpg'); // download common.saveFile(imgData, filename); }(filename); }; common.imgAddLabel = function (img, labelImg) { var labelInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; //图上加另一张小图,用于添加水印 var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.canvas.width = img.width; context.canvas.height = img.height; context.drawImage(img, 0, 0, img.width, img.height); var labelWidth = img.width * labelInfo.widthRatioToImg; //widthRatioToImg:label的width占img的width的比例 var labelHeight = labelWidth * labelImg.height / labelImg.width; if (!labelInfo.leftRatioToImg && labelInfo.rightRatioToImg) { labelInfo.leftRatioToImg = 1 - labelInfo.rightRatioToImg - labelInfo.widthRatioToImg; } if (!labelInfo.topRatioToImg && labelInfo.bottomRatioToImg) { labelInfo.topRatioToImg = 1 - labelInfo.bottomRatioToImg - labelHeight / img.height; } var labelLeft = img.width * labelInfo.leftRatioToImg; //leftRatioToImg:label的left占img的width的比例 var labelTop = img.height * labelInfo.topRatioToImg; //topRatioToImg:label的top占img的height的比例 context.globalAlpha = labelInfo.opacity != void 0 ? labelInfo.opacity : 1; context.drawImage(labelImg, labelLeft, labelTop, labelWidth, labelHeight); return common.canvasToImg(canvas); }; common.pixelsArrayToDataUrl = function (pixels, width, height) { var compressRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0.7; var dontFlipY = arguments.length > 4 ? arguments[4] : undefined; var canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; var context = canvas.getContext('2d'); pixels = new pixels.constructor(pixels); if (!dontFlipY) { var bytesPerLine = width * 4; for (var i = 0; i < parseInt(height / 2); i++) { var j = height - i - 1; var lineI = pixels.slice(i * bytesPerLine, i * bytesPerLine + bytesPerLine); var lineJ = pixels.slice(j * bytesPerLine, j * bytesPerLine + bytesPerLine); pixels.set(lineJ, i * bytesPerLine); pixels.set(lineI, j * bytesPerLine); } } var imageData = context.createImageData(width, height); imageData.data.set(pixels); context.putImageData(imageData, 0, 0); var dataURL = canvas.toDataURL(compressRatio); return dataURL; }; common.renderTargetToDataUrl = function (renderTarget, width, height, renderer) { var compressRatio = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0.7; var dontFlipY = arguments.length > 5 ? arguments[5] : undefined; var pixelCount = width * height; var buffer = new Uint8Array(4 * pixelCount); renderer.readRenderTargetPixels(renderTarget, 0, 0, width, height, buffer); //耗时 var dataUrl = this.pixelsArrayToDataUrl(buffer, width, height, compressRatio, dontFlipY); return dataUrl; }; common.screenPass = new function () { this.screenScene = new THREE.Scene(); this.screenQuad = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2, 1)); this.screenQuad.material.depthTest = true; this.screenQuad.material.depthWrite = true; this.screenQuad.material.transparent = true; this.screenScene.add(this.screenQuad); this.camera = new THREE.Camera(); this.render = function (renderer, material, target) { this.screenQuad.material = material; //material.premultipliedAlpha = true //每次都要吗 var alpha = renderer.getClearAlpha(); renderer.setClearAlpha(0); if (typeof target === 'undefined') { renderer.render(this.screenScene, this.camera); } else { var oldTarget = renderer.getRenderTarget(); renderer.setRenderTarget(target); renderer.clear(); renderer.render(this.screenScene, this.camera); renderer.setRenderTarget(oldTarget); /* let data = common.renderTargetToDataUrl(target, target.width, target.height, renderer) common.saveTex(data) */ } renderer.setClearAlpha(alpha); }; }(); common.renderTex = function (material, renderer, size) { var rt = new THREE.WebGLRenderTarget(size.x, size.y, { minFilter: THREE.LinearMipmapLinearFilter, generateMipmaps: true, format: THREE.RGBAFormat }); this.screenPass.render(renderer, material, rt); return rt.texture; }; //根据原因更新显示,便于将每种显示操作打上标签,管理优先级 common.updateVisible = function (object, reason, ifShow) { var level = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; var type = arguments.length > 4 ? arguments[4] : undefined; //当所有加入的条件都不为false时才显示. reason='force'一般是强制、临时的 if (!object.unvisibleReasons) object.unvisibleReasons = []; //如果length>0代表不可见 if (!object.visibleReasons) object.visibleReasons = []; //在同级时,优先可见 var update = function update() { //先按从高到低的level排列 object.unvisibleReasons = object.unvisibleReasons.sort(function (a, b) { return b.level - a.level; }); object.visibleReasons = object.visibleReasons.sort(function (a, b) { return b.level - a.level; }); var maxVisiLevel = object.visibleReasons[0] ? object.visibleReasons[0].level : -1; var maxunVisiLevel = object.unvisibleReasons[0] ? object.unvisibleReasons[0].level : -1; var shouldVisi = maxVisiLevel >= maxunVisiLevel; var visiBefore = object.visible; if (visiBefore != shouldVisi) { object.visible = shouldVisi; object.dispatchEvent({ type: 'isVisible', visible: shouldVisi, reason }); } }; if (ifShow) { var index = object.unvisibleReasons.findIndex(function (e) { return e.reason == reason; }); if (index > -1) { type = 'cancel'; object.unvisibleReasons.splice(index, 1); } if (type == 'add') { if (!object.visibleReasons.some(function (e) { return e.reason == reason; })) { object.visibleReasons.push({ reason, level }); } } } else { var index = object.visibleReasons.findIndex(function (e) { return e.reason == reason; }); if (index > -1) { type = 'cancel'; object.visibleReasons.splice(index, 1); } if (type != 'cancel') { if (!object.unvisibleReasons.some(function (e) { return e.reason == reason; })) { object.unvisibleReasons.push({ reason, level }); } } } update(); }; common.getObjVisiByReason = function (object, reason) { //获取在某条件下是否可见. 注: 用户在数据集选择可不可见为"datasetSelection" if (object.visible) return true;else { return !object.unvisibleReasons || !object.unvisibleReasons.some(function (e) { return e.reason == reason; }); } }; common.setCameraLayers = function (camera, enableLayers) { var extraEnableLayers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; //设置相机或raycaster的layers camera.layers.disableAll(); enableLayers.concat(extraEnableLayers).forEach(function (e) { var layer = Potree.config.renderLayers[e]; if (layer == void 0) { console.error('setCameraLayer没找到layer!'); return; } camera.layers.enable(layer); }); }; common.setObjectLayers = function (object, layerName) { //设置物体的layers var layer = Potree.config.renderLayers[layerName]; if (layer == void 0) { console.error('setCameraLayer没找到layer!'); return; } object.traverse(function (e) { e.layers.set(layer); }); }; common.intervalTool = { //延时update,防止卡顿 list: [], isWaiting: function isWaiting(name, func, delayTime) { var _this3 = this; var item = this.list.find(function (e) { return e.name == name; }); if (!item) { //如果没有该项, 则加入循环 var ifContinue = func(); item = { name }; this.list.push(item); setTimeout(function () { var a = _this3.list.indexOf(item); _this3.list.splice(a, 1); if (item.requestUpdate || ifContinue) _this3.isWaiting(name, func, delayTime); //循环 }, delayTime); } else { //如果有该项,说明现在请求下一次继续更新 /* if(delayTime == 0){//想立刻更新一次 func() }else{ */ item.requestUpdate = true; //} } } }; common.batchHandling = { //分批处理 lists: [], getSlice: function getSlice(name, items, _ref3) { var stopWhenAllUsed = _ref3.stopWhenAllUsed, _ref3$minCount = _ref3.minCount, minCount = _ref3$minCount === void 0 ? 5 : _ref3$minCount, _ref3$maxCount = _ref3.maxCount, maxCount = _ref3$maxCount === void 0 ? 100 : _ref3$maxCount, durBound1 = _ref3.durBound1, durBound2 = _ref3.durBound2, maxUseCount = _ref3.maxUseCount; if (items.length == 0 || (maxUseCount = maxUseCount == void 0 ? common.getBestCount({ name, minCount, maxCount, durBound1, durBound2, ifLog: false }) : maxUseCount, !maxUseCount) //本次最多可以使用的个数 ) { return { list: [] }; } if (!this.lists[name]) this.lists[name] = { list: [] }; //更新列表项目,但不变原来的顺序 var list = this.lists[name].list.filter(function (a) { return items.some(function (item) { return a.item == item; }); }); //去掉已经不在items里的项目 this.lists[name].list = list; items.forEach(function (item) { //增加新的项目。 if (!list.some(function (a) { return a.item == item; })) { list.push({ item, count: 0 }); } }); //至此,在后排的都是未使用的 var unUsed = list.filter(function (e) { return e.count == 0; }); //未使用的项目(count为0)优先 var result = []; unUsed.slice(0, maxUseCount).forEach(function (e) { result.push(e.item); e.count++; }); if (unUsed.length > maxUseCount) ; else { //所有项目都能使用一次 if (!stopWhenAllUsed) { //若不是全部使用就停止 var wholeCount = Math.min(items.length, maxUseCount); var restCount = wholeCount - result.length; //补齐 list.slice(0, restCount).forEach(function (e) { result.push(e.item); e.count++; }); } list.forEach(function (e) { return e.count--; }); //复原,等待新的循环 } return { list: result }; }, addSliceListen(_ref4) { var getList = _ref4.getList, callback = _ref4.callback, minCount = _ref4.minCount, maxCount = _ref4.maxCount; _ref4.durBound1; _ref4.durBound2; _ref4.maxHistory; var player = _ref4.player; var unUpdate, lastUpdate; player.on('update', function (e) { if (player.flying) return; var waitForUpdate = getList(); var stopWhenAllUsed = !player.lastFrameChanged; var standardUpdate = player.lastFrameChanged || !lastUpdate; //相机变化或第一次 var list; if (standardUpdate) { list = waitForUpdate; unUpdate = null; } else { if (!unUpdate) { unUpdate = common.getDifferenceSet(waitForUpdate, lastUpdate); //unUpdate = unUpdate.filter(e => e.visible) //如飞出后最后一次更新之后,都隐藏了,隐藏的就不用更新了 } list = unUpdate; } var result = common.batchHandling.getSlice('ifVideoInsight', list, { stopWhenAllUsed, minCount, maxCount, durBound1: 3, durBound2: 13, maxHistory: 3 }); //iphonex稳定后大概在7-10。 var updateList = result.list; //updateList.length && console.log(updateList.map(e=>e.sid)) updateList.forEach(callback); if (!standardUpdate) { //相机停止变化后只更新还未更新的 unUpdate = common.getDifferenceSet(unUpdate, updateList); } lastUpdate = updateList; }); } }; common.getBestCount = function () { var lastCount = {}; return function (_ref5) { var name = _ref5.name, _ref5$minCount = _ref5.minCount, minCount = _ref5$minCount === void 0 ? 1 : _ref5$minCount, _ref5$maxCount = _ref5.maxCount, maxCount = _ref5$maxCount === void 0 ? 6 : _ref5$maxCount, _ref5$durBound = _ref5.durBound1, durBound1 = _ref5$durBound === void 0 ? 1 : _ref5$durBound, _ref5$durBound2 = _ref5.durBound2, durBound2 = _ref5$durBound2 === void 0 ? 4 : _ref5$durBound2, ifLog = _ref5.ifLog, maxHistory = _ref5.maxHistory; var timeStamp = performance.getEntriesByName('loop-start'); var count; if (timeStamp.length) { var dur = performance.now() - timeStamp[timeStamp.length - 1].startTime; /*let k = -(maxCount - minCount) / (durBound2 - durBound1) let m = maxCount - durBound1 * k count = THREE.MathUtils.clamp(Math.round(k * dur + m), minCount, maxCount) //dur在iphoneX中静止有7,pc是2 */ count = Math.round(math$1.linearClamp(dur, durBound1, durBound2, maxCount, minCount)); if (maxHistory) { if (!lastCount[name]) lastCount[name] = []; if (count == 0 && lastCount[name].length > maxHistory - 1 && !lastCount[name].some(function (e) { return e > 0; })) { count = 1; } lastCount[name].push(count); if (lastCount[name].length > maxHistory) lastCount[name].splice(0, 1); } ifLog && console.log(name, count, ' ,dur:', dur.toFixed(3)); } else { count = maxCount; // ? } //主要在手机端有效果。 return count; }; }(); common.timeMeasuring = { reportTimings: false, collection: {}, registerCollect(name, o) { this.collection[name] = o; o.measures = []; o.sum = 0; }, addTimeMark: function addTimeMark(name, type, ifLog) { var record = this.collection[name]; var now = performance.now(); var needRecord = record && (record.measures.length < record.minCount || now - record.lastAddTime > record.refreshTime); //间隔时间超过refreshTime重新收集 if (needRecord || this.reportTimings) { if (type == 'end' && performance.getEntriesByName(name + '-start').length == 0) return; performance.mark(name + '-' + type); if (type == 'end') { var measure = performance.measure(name, name + '-start', name + '-end'); if (!measure) { //console.error('没找到measure',name) //可能是其他地方报错了没进行下去所以找不到 return; } if (ifLog) console.log(name, '耗时', measure.duration.toFixed(3)); if (needRecord) { if (record.measures.length >= record.minCount) { //先清空上一轮的 record.measures = []; record.sum = 0; } record.measures.push(measure.duration); record.sum += measure.duration; record.mean = record.sum / record.measures.length; record.measures.sort(function (a, b) { return a - b; }); record.median = record.measures[parseInt(record.measures.length / 2)]; record.lastAddTime = now; if (record.measures.length == record.minCount) ; } } } }, report: function report(timestamp) { //原resolveTimings //打印用时。 注:performance手机的精度只到整数位 if (!this.toggle) { this.toggle = timestamp; } var duration = timestamp - this.toggle; if (duration > 1000.0) { if (this.reportTimings) { var measures = performance.getEntriesByType('measure'); var names = new Set(); var _iterator = _createForOfIteratorHelper$8(measures), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var measure = _step.value; names.add(measure.name); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } var groups = new Map(); var _iterator2 = _createForOfIteratorHelper$8(names), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var name = _step2.value; groups.set(name, { measures: [], sum: 0, n: 0, min: Infinity, max: -Infinity }); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } var _iterator3 = _createForOfIteratorHelper$8(measures), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var _measure = _step3.value; var group = groups.get(_measure.name); group.measures.push(_measure); group.sum += _measure.duration; group.n++; group.min = Math.min(group.min, _measure.duration); group.max = Math.max(group.max, _measure.duration); } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } var _iterator4 = _createForOfIteratorHelper$8(groups), _step4; try { for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { var _step4$value = _slicedToArray(_step4.value, 2), _name = _step4$value[0], _group = _step4$value[1]; _group.mean = _group.sum / _group.n; _group.measures.sort(function (a, b) { return a.duration - b.duration; }); if (_group.n === 1) { _group.median = _group.measures[0].duration; } else if (_group.n > 1) { _group.median = _group.measures[parseInt(_group.n / 2)].duration; } } } catch (err) { _iterator4.e(err); } finally { _iterator4.f(); } var cn = Array.from(names).reduce(function (a, i) { return Math.max(a, i.length); }, 0) + 5; var cmin = 5; var cmed = 5; var cmax = 5; var csam = 4; var message = " ".concat('NAME'.padEnd(cn), " |") + " ".concat('MIN'.padStart(cmin), " |") + " ".concat('MEDIAN'.padStart(cmed), " |") + " ".concat('MAX'.padStart(cmax), " |") + " ".concat('AVE'.padStart(cmax), " |") + " ".concat('SAMPLES'.padStart(csam), " \n"); message += " ".concat('-'.repeat(message.length), "\n"); names = Array.from(names).sort(); var _iterator5 = _createForOfIteratorHelper$8(names), _step5; try { for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { var _name2 = _step5.value; var _group2 = groups.get(_name2); var min = _group2.min.toFixed(2); var median = _group2.median.toFixed(2); var max = _group2.max.toFixed(2); var n = _group2.n; var ave = _group2.mean.toFixed(2); //add message += " ".concat(_name2.padEnd(cn), " |") + " ".concat(min.padStart(cmin), " |") + " ".concat(median.padStart(cmed), " |") + " ".concat(max.padStart(cmax), " |") + " ".concat(ave.padStart(cmax), " |") + " ".concat(n.toString().padStart(csam), "\n"); } } catch (err) { _iterator5.e(err); } finally { _iterator5.f(); } message += "\n"; console.log(message); } performance.clearMarks(); performance.clearMeasures(); this.toggle = timestamp; } } }; common.isVideoPlayed = function (video) { return !video.paused && !isNaN(video.duration); //注意,有的手机首次play时会立即paused为false,但其实没加载好, duration为NAN }; common.GifTexDeal = { animateObjects: [], animateTexs: [], addAnimation: function addAnimation(texture, owner) { var info = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { delay: 0 }; var id = arguments.length > 3 ? arguments[3] : undefined; /* if(this.animateObjects.find(e=> e.texture == texture && !ifSame(info, e.info) )) */ var animation; var tex = this.animateTexs.find(function (e) { return e.texture == texture; }); if (tex) { animation = tex; } else { animation = { texture, info }; this.animateTexs.push(animation); this.setRepeart(animation); } var object = { animation, //默认相同的texture对应的info是一样的, 对应一个animation owner, id }; this.animateObjects.push(object); return object; }, remove: function remove(object) { var index = this.animateObjects.indexOf(object); if (index > -1) { this.animateObjects.splice(index, 1); if (!this.animateObjects.find(function (e) { return e.animation == object.animation; })) { var i = this.animateTexs.indexOf(object.animation); this.animateTexs.splice(i, 1); object.animation.texture.repeat.set(1, 1); } this.stop(object); } }, setRepeart: function setRepeart(animation) { animation.texture.repeat.set(1 / animation.info.cellXcount, 1 / animation.info.cellYcount); }, start: function start(object) { var _this4 = this; if (!object || object.started) return; object.started = true; if (object.animation.started) return; object.animation.started = true; var info = object.animation.info; var count = info.cellXcount * info.cellYcount - (info.voidCount || 0); if (count <= 1) return; if (object.startCallback) object.startCallback(); var duration = info.duration + info.delay; var delay = info.delay / duration; transitions$1.start(function (progress) { var index = Math.floor((count - 1) * progress); var indexX = index % info.cellXcount; var indexY = info.cellYcount - Math.floor(index / info.cellXcount) - 1; //uv.offset.y是从下到上的 object.animation.texture.offset.x = indexX / info.cellXcount; object.animation.texture.offset.y = indexY / info.cellYcount; //console.log(object.id + " : "+ index, indexX, indexY /* object.texture.offset.toArray() */) }, duration /* * -1 */ , function () { //done (-1):循环 //先停在最后一帧 object.started = false; object.animation.started = false; info.waitNextLoop = setTimeout(function () { //从头开始 /* object.animation.texture.offset.x = 0; object.animation.texture.offset.y = 0; */ _this4.start(object); }, info.waitNextTime || 0); }, delay, null, object.id, 'gif_' + object.animation.texture.id); }, stop: function stop(object) { if (!object || !object.started) return; object.started = false; //只有该object对应的texture对应的所有object都停止了,才能真的停止动画: if (this.animateObjects.find(function (e) { return e.animation == object.animation && e.started; })) return; transitions$1.cancelById('gif_' + object.animation.texture.id); object.animation.texture.offset.set(0, 0); object.animation.started = false; clearTimeout(object.animation.info.waitNextLoop); } }; common.getNestedValue = function (obj, path) { // Split the path string into an array of keys. var keys = path.split('.'); // Iterate over the keys and access the nested values. var current = obj; var _iterator6 = _createForOfIteratorHelper$8(keys), _step6; try { for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { var key = _step6.value; // If the current value is an array and the key is an index, access the array element. if (Array.isArray(current) && !isNaN(parseInt(key))) { current = current[parseInt(key)]; } else { // If the current value is an object, access the property. current = current[key]; } // If the current value is undefined, return undefined. if (current === undefined) { return undefined; } } } catch (err) { _iterator6.e(err); } finally { _iterator6.f(); } return current; }; common.watch = function (object, propName, initialValue) { //监听某个属性的变化 var v = initialValue; Object.defineProperty(object, propName, { get: function get() { return v; }, set: function set(e) { console.warn('watch:', propName, e); v = e; } }); }; common.realVisible = function (object) { var v = true; var parent = object; var lastParent; while (parent) { if (parent.visible === false) { v = false; break; } lastParent = parent; parent = parent.parent; } if (v && !(lastParent instanceof THREE.Scene)) { //已被删除 v = false; } return v; }; common.isChildOf = function (child, parent) { var curParent; while (curParent && curParent != parent) { curParent = curParent.curParent; } if (curParent) { return true; } }; /* * @Author: Rindy * @Date: 2021-05-12 12:05:29 * @LastEditors: Rindy * @LastEditTime: 2021-10-20 11:09:29 * @Description: decorators */ /** * 集成EventEmitter * @param {*} target */ var Emitter = function Emitter(target) { common.extend(target, EventEmitter); }; var browser$1 = { mobileVersion(e, t) { var i = window.navigator.userAgent, n = i.match(e); return n = n ? n[1].split(t) : [], { major: parseInt(n[0]) || 0, minor: parseInt(n[1]) || 0, patch: parseInt(n[2]) || 0 }; }, isFullscreen() { return document.fullscreenElement || document.mozFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement; }, supportsFullscreen() { return document.fullscreenEnabled || document.mozFullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled; }, isPointerLocked() { return document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement; }, requestFullscreen(dom, t) { dom.requestFullscreen ? dom.requestFullscreen() : dom.mozRequestFullScreen ? dom.mozRequestFullScreen() : dom.webkitRequestFullscreen ? dom.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT) : dom.msRequestFullscreen && dom.msRequestFullscreen(), t && $(document).on('fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange', browser$1.requestPointerLock); }, requestPointerLock() { var e; if (document.fullscreenElement) e = document.fullscreenElement();else if (document.mozFullscreenElement) e = document.mozFullscreenElement();else if (document.mozFullScreenElement) e = document.mozFullScreenElement();else { if (!document.webkitFullscreenElement) return; e = document.webkitFullscreenElement(); } e.requestPointerLock = e.requestPointerLock || e.mozRequestPointerLock || e.webkitRequestPointerLock, e.requestPointerLock(), $(document).off('fullscreenchange webkitfullscreenchange mozfullscreenchange MSFullscreenChange', this); }, exitPointerLock() { document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock, document.exitPointerLock(); }, exitFullscreen() { document.exitFullscreen ? document.exitFullscreen() : document.msExitFullscreen ? document.msExitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitExitFullscreen && document.webkitExitFullscreen(); }, details() { var e = navigator.userAgent.match('(Firefox|Chrome|Safari)/([\\d]+)'); return e ? { name: e[1], version: parseInt(e[2]), platform: navigator.platform } : {}; }, is(e) { return this.details() && this.details().name === e; }, inIframe() { return window.parent !== window; }, aspectRatio() { var e = window.innerWidth / window.innerHeight; return isFinite(e) ? e : 0; }, userAgent() { return window.navigator.userAgent; }, isMobile() { var e = navigator.userAgent || navigator.vendor || window.opera; return /(android|bb\d+|meego).+mobile|android|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(e) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(e.substr(0, 4)); }, isLandscape() { return this.isMobile && this.aspectRatio() > 1; }, isSmallScreen() { var e = screen.width / window.devicePixelRatio; return e < 240; }, detectWeixin: function detectWeixin() { //微信 包括PC的微信 return window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'; }, detectWeixinMiniProgram: function detectWeixinMiniProgram() { return window.navigator.userAgent.match('miniProgram'); }, detectIE() { var e = window.navigator.userAgent, t = e.indexOf('MSIE '); return t !== -1 || !!navigator.userAgent.match(/Trident.*rv\:11\./); }, detectSafari() { var e = window.navigator.userAgent, t = e.indexOf('Safari'); return t !== -1 && !this.detectChrome(); }, detectFirefox() { var e = window.navigator.userAgent; return e.indexOf('Firefox') !== -1; }, detectChrome() { var e = window.navigator.userAgent; return e.indexOf('Chrome') !== -1 && !this.detectOpera(); }, detectOpera() { var e = window.navigator.userAgent; return e.indexOf('OPR') !== -1; }, detectIOS() { return this.detectIPhone() || this.detectIPad() || this.detectIPod(); }, detectIPad() { var e = window.navigator.userAgent, t = /iPad/; return t.test(e); }, detectIPod() { var e = window.navigator.userAgent, t = /iPod/; return t.test(e); }, detectIPhone() { var e = window.navigator.userAgent, t = /iPhone/; return t.test(e); }, detectAndroid() { var e = window.navigator.userAgent; return e.indexOf('Android') !== -1; }, detectAndroidMobile() { var e = window.navigator.userAgent; return this.detectAndroid() && e.indexOf('Mobile') !== -1; }, detectSamsungNative() { var e = window.navigator.userAgent; return e.indexOf('SM-G900H') !== -1 || e.indexOf('GT-I9500') !== -1 || e.indexOf('SM-N900') !== -1; }, detectSamsungS6() { var e = window.navigator.userAgent; return e.indexOf('SM-G92') !== -1; }, /************************************************************徐世廷*************************************************************/ detectHUAWEI5X() { return -1 !== window.navigator.userAgent.indexOf('KIW-TL00H'); }, /*******************************************************************************************************************************/ detectWebVR() { return !(!window.navigator.getVRDisplays || !window.VRDisplay); }, getVRDisplay() { var _this = this; // var e = $.Deferred() // return this.detectWebVR() // ? (navigator.getVRDisplays().then(function (t) { // t.length >= 1 && e.resolve(t[0]), e.reject(null) // }), // e) // : e.reject(null) return new Promise(function (resolve, reject) { if (_this.detectWebVR()) { navigator.getVRDisplays().then(function (t) { if (t.length >= 1) { resolve(t[0]); } else { reject(null); } }).catch(function () { return reject(null); }); } else { reject(null); } }); }, iosVersion() { if (!this.detectIOS()) throw new DeviceMismatchException('Did not detect an iDevice'); var e = /((?:\d+\_?){1,3}) like Mac OS/, t = '_'; return this.mobileVersion(e, t); }, androidVersion() { if (!this.detectAndroid()) throw new DeviceMismatchException('Did not detect an Android based device'); var e = /Android ((?:\d+\.?){1,3})/, t = '.'; return this.mobileVersion(e, t); }, valueFromCookie(e, t) { var i = new RegExp(e + '=([0-9a-f]+)(; ?|$)').exec(document.cookie); if (!i) return t; var n = i[1]; return 'boolean' == typeof t ? 'true' === n || '1' === n : 'number' == typeof t ? parseFloat(n) : n; }, valueFromHash(e, t) { var i = new RegExp('[#&?]' + e + '=([^#&?]*)'), n = i.exec(window.location.href); if (!n) return t; var r = n[1]; return 'boolean' == typeof t ? 'true' === r || '1' === r : 'number' == typeof t ? parseFloat(r) : window.decodeURIComponent(r); }, valueFromUrl(key) { return this.urlHasValue(key, true); }, urlHasValue: function urlHasValue(key, isGetValue) { var querys = window.location.search.substr(1).split('&'); if (isGetValue) { for (var i = 0; i < querys.length; i++) { var keypair = querys[i].split('='); if (keypair.length === 2 && keypair[0] === key) { return keypair[1]; } } return ''; } else { //return window.location.search.match("&" + key + "|\\?" + key) != null 有bug for (var _i = 0; _i < querys.length; _i++) { var _keypair = querys[_i].split('='); if (_keypair[0] == key) { return true; } } return false; } } }; var Colors = { //加个4dkk经典原谅绿----许钟文 //green: new THREE.Color('#00c8aF'), green: new THREE.Color('#15FFE2'), yellow: new THREE.Color('#F6FE14'), lightGreen: new THREE.Color('#09e1c0'), newBlue: new THREE.Color('#00c8ae'), //new THREE.Color(4967932), altBlue: new THREE.Color(47355), tagDefault: new THREE.Color(223357), classicBlue: new THREE.Color(53759), mpYellow: new THREE.Color(16502016), mpOrange: new THREE.Color(16428055), mpBlue: new THREE.Color(12096), mpLtGrey: new THREE.Color(13751252), mpDkGrey: new THREE.Color(10000019), mpRed: new THREE.Color(12525854), mpOrangeDesat: new THREE.Color(16764529), mpBlueDesat: new THREE.Color(4034734), mpRedDesat: new THREE.Color(14705505), white: new THREE.Color(16777215), black: new THREE.Color(0), _desat(e, t) { var i = t || 0.3, r = new THREE.Color().copy(e).getHSL(e); return new THREE.Color().setHSL(r.h, r.s * (1 - i), r.l); }, _darken(e, t) { var i = t || 0.2, r = e.getHSL(e); return new THREE.Color().setHSL(r.h, r.s, r.l * (1 - i)); } }; var WarpStyle = { BLACK: 'black', STD: 'std', WALK: 'walk' }; Math.sign = function (e) { return e < 0 ? -1 : 1; }; var constants$4 = { signedUrlDefaultExpireTime: 24e4, signedUrlCheckInterval: 1e4, signedUrlRefreshBuffer: 15e3, dollhouseFOV: browser$1.isMobile() ? 90 : 70, dollhouseNear: 1, dollhouseFar: 5e3, insideFOV: browser$1.isMobile() ? 90 : 70, insideFOVMax: 120, insideNear: 0.1, insideFar: 5e3, insideLookSpeed: 0.12, insideLookLimitUp: browser$1.valueFromUrl('ai') == 'sds' ? 50 : browser$1.isMobile() ? 15 : 25, insideLookLimitDown: browser$1.valueFromUrl('ai') == 'sds' ? -50 : browser$1.isMobile() ? -15 : -25, orthoNear: 1, orthoFar: 5e3, orthoBase: 10, planeHeightShift: 0.1, narrowLandscapeHeight: 290, reallyNarrowLandscapeHeight: 250, visionTilingStartDate: new Date('8/26/2016'), visionTilingStartVersion: '1.1.407.13667', windowHeightHighQualityThreshold: 900, tourStepDelayDefault: 3500, tourStepDelaySlideShow: 5e3, workshopApsect: 9 / 16, highQualityMaxZoom: 2, ultraHighQualityMaxZoom: 3 }; var RenderOrder = { boundingSkybox: 1, visibleFloor: 1, highTileCube: 2, panoMarker: 2, //不能遮挡住overlay等物体 overlay: 5, //panoLabel: 6, footIcon: 6, reticule: 7, tagStem: 8, tagDisc: 9, ribbon: 9, ghostFloor: 10, //透明的不能在不透明(visibleFloor、videoTag)之前渲染否则会遮住 cad: 11, //floorplan view: 13, measure: 14, entryArrow: 14, monitorPlane: 20 }; /* renderOrder并非大的就一定能盖住小的, 透明的反而需要后渲染,否则会盖住先渲染的。 */ var settings$2 = { visions: 2, //2有下相机 debug: false, version: '2.23.8-0-g24ec69e', skyboxRadius: 2500, job: 'dacf7dfa24ae47fab8fcebfe4dc41ab9', preTexture: '_50k_texture_jpg_high1', format: '_50k.dam', skyboxRadius: 2500, modelBoundsPadding: 5, showNeighbors: !1, useWheel: browser$1.valueFromHash('wh', !0), crossOrigin: 'anonymous', fancierTransition: !1, wireframe: !1, skyboxWireframe: !1, modelAlpha: 1, highlightPanoSelection: !1, showSweeps: !0, showSkyboxes: !1, showMesh: !0, showFloors: !1, showFloorDuration: 300, showFloorDelay: 300, hideFloorDuration: 300, hideFloorDelay: 0, reticuleOpacityTransitionTime: 250, reticuleColor: Colors.newBlue, markerOpacityTransitionTime: 500, guiAnimationSpeed: 250, highlightAnimationDuration: 500, modelComponentLoadSpinnerDelay: 150, captureErrors: !1, maxMobileTextures: 6, minimalMemoryMode: browser$1.valueFromHash('m3', browser$1.isMobile()), startupFlyinDelay: 3e3, vrEnabled: false, overlay: { width: 1, height: 0.5, depth: 0.04 }, dollhouseDefault: { minDistance: 15, maxDistance: 50, minPolarAngle: THREE.MathUtils.degToRad(10), maxPolarAngle: THREE.MathUtils.degToRad(90) }, hideReticuleTimeout: 1e3, analytics: { inactivityThreshold: 30, sessionTrackingRate: 0.15, maxTrackedErrors: 20, sessionDurationPingFrequency: 10, sessionDurationTimeout: 15 }, flydown: { movementEasing: 'easeInOutQuad', movementDelay: 0.001, rotationEasing: 'easeInOutQuad', rotationDelay: 0.5, modelTextureDelay: 0.75, skyboxDelay: 0.75 }, transition: { /* flySpeed: 0.0037, //匀速行走的速度,稍微比正常过渡快一些 //0.01, flyTime: 300, //750, 最小时间 flytimeMaxDistanceThreshold: 7, //5, flytimeDistanceMultiplier: 300, //120,//150, */ flySpeed: 0.0043, //匀速行走的速度,稍微比正常过渡快一些 //0.01, flyTime: 650, //750, 最小时间 flytimeMaxDistanceThreshold: 10, //5, flytimeDistanceMultiplier: 120, //120,//150, maxRotSpeed: 1.2, //add aimTime: 1500, aimSlowFactor: 1.5, blur: 0.8, movementEasing: 'easeOutSine', //'easeOutSine',//'easeInOutQuad', blendEasing: 'easeInOutQuad', fastForwardFactor: browser$1.valueFromHash('mfis', 3) }, show360Views: { enabled: !0, transitionTime: 1e3 }, quickstart: { enabled: 1, //1 === browser.valueFromHash('qust', 0) || 1 === browser.valueFromHash('qs', 0), animation: 1400, showTextDelay: 500, fadeOutDelay: 3e3, fovChange: 10 }, appConfig: { webvr_version: null, segment_key: null, embedly_key: null, branch_key: null, keen_write_key: null, keen_project_id: null }, input: { longTapThreshold: 200, moveToleranceNDC: 0.08, touchMoveThreshold: 25 }, labels: { enabled: !1, hideUntilStart: !0, fadeInDuration: 250, fadeInDelay: 250, fadeOutDuration: 250, fadeOutDelay: 0, zoomHideThreshhold: { mobile: browser$1.isSmallScreen() ? 0.45 : 0.6, desktop: 2 }, zoomTruncateThreshhold: { mobile: browser$1.isSmallScreen() ? 0.35 : 0.45, desktop: 0.85 }, minLengthForTruncate: 16, truncateLength: 12, truncateSuffix: '...' }, tags: { enabled: browser$1.valueFromHash('mt', 1), startup: { hideUntilStart: !0, fadeInDuration: 500, fadeInDelay: 100 }, visibility: { anyDistance: !0, visibleDistance: 8, cameraClearance: 0.1, alphaTestLevel: 0.05, hideViaFloor: !0, hideOffScreenDisc: !1, hideOffScreenObject: !1 }, disc: { opacity: 1, disabledOpacity: 0.5, scale: { nearBound: 1.5, farBound: 4.8, linkFarBound: !1, linkPercent: 40, maxSize: 80, minSize: 40, baseViewportSize: 800, responsiveness: 100 } }, pole: { enabled: !0, height: 0.5, width: 2, opacity: 0.5, color: 'white' }, navigate: { nearestPano: !0, lineOfSight: !0, reactivate: !0, aimAt: 'disc', tiltTolerance: 25, rotateSpeedFactor: 0.6 } }, view360: { //xzw add circleDisToCenter: 2.4, visibleDisAtView: 15 }, boundExpandLength: 1.5, path: { color: Colors.newBlue, colorUp: Colors._desat(Colors.newBlue, 0.5), colorDown: Colors._darken(Colors.newBlue, 0.35), opacity: 0.5, style: 'ribbon', height: 0.025, ribbonWidth: 0.24, outsideHeight: 0.5, waypointRadius: 0.5, waypointIndoorRadius: 0.24, waypointPulse: 1e3, typ: WarpStyle.BLACK, meshFree: browser$1.valueFromHash('mf', 1), mapGuides: browser$1.valueFromHash('guides', !0), fadeInTime: 400, fadeOutTime: 300 }, warp: { nearPanoDist: 0.1, matchCam: !1, blur: 0.33, fastTime: 1500, teleportTime: 1500, outsideTime: 2e3, lookAheadMax: 0.3, lookAheadDist: 2.5, softPushDist: 0.37, softPushEnd: 0.3, softBendAngle: 8, softBendTilt: 4, softBendEnd: 0.3, doBurns: browser$1.valueFromHash('kb', !0), burnsAngle: 35, minBurnsAngle: 35, minDownAngle: -35, maxTurnPerSec: 280, maxAimPerSec: 35, minRotation: 12, maxAimRotation: 33.2, turnFriction: 0.2, flySpeed: 0.01, minWarpTime: 1200, warpInterruptionRedirectTime: 500, tourStepDelay: browser$1.valueFromHash('st', 0), walkDelay: 0, walkMaxDist: 50, walkMinDist: 0.8, walkSlideShowThreshhold: 3e3, walkExtraPanosDistance: 0.4, timePerMeter: 800, motionLeadTime: 500, movementEasing: 'easeInOutQuad', blendEasing: 'easeInOutQuad', showBunny: !1, loop: browser$1.valueFromHash('lp', !1), auto: browser$1.valueFromHash('ts', -1), eOrder: 'YXZ', stepFactor: 0.25, brakeStrength: 2, minBrakeAngle: 0.1, maxBrakeAngle: 1.8, climbEffort: 4 }, rotationFriction: browser$1.isMobile() ? 0.08 : 0.05, rotationAccelerationInside: 4.5, rotationAccelerationOutside: 0.15, rotationAfterMoveMultiplierX: browser$1.isMobile() ? 120 : 40, rotationAfterMoveMultiplierY: 40, rotationAfterMoveHistoryCount: 5, panFriction: 0.09, panAccelerationOutside: 60, //onload: browser.valueFromHash('onload', Viewmode.PANORAMA), zoomNearLimit: 0.1, zoomFarLimit: 10, navigation: { panoScores: !1, mouseDirection: !0, filterStrictness: 0.75, angleFactor: -30, directionFactor: 10, distanceFactor: -1, optionalityFactor: 3 }, sdkInit: !1, secretPanelWord: [38, 38, 40, 40, 37, 39, 37, 39, 66, 65], console: browser$1.valueFromHash('console', !1), noMeshFloorPositionOffset: new THREE.Vector3(0, -1.2, 0), panoramaNeighbourMaxDistance: 5, panoFloorClickRadius: 0.35, showScreenshotLocations: !1, showAxis: !1, showNeighbourRaycasts: !1, colorMarkerOnLoad: !1, colorMarkerByFloor: !1, tiling: { panoPreRenderRepeatDelay: 2500, panoPreRenderDelay: 500, preRenderTourPanos: browser$1.valueFromHash('tileprerender', 0), tilingFlagNames: ['usetiles', 'tiles'], maxNavPanoQuality: browser$1.valueFromHash('maxtileq', null), maxZoomPanoQuality: browser$1.valueFromHash('maxztileq', null), overlayStyle: browser$1.valueFromHash('tileoverlay', 0), uploadIntervalDelay: browser$1.valueFromHash('tileupdelay', 10), initialIntervalDelay: browser$1.valueFromHash('itiledelay', 0), maxNonBaseUploadsPerFrame: browser$1.valueFromHash('maxnbtpf', 2), maxBaseUploadsPerFrame: browser$1.valueFromHash('maxbtpf', 6), customCompression: browser$1.valueFromHash('tilecustcomp', 0), mobileHighQualityOverride: !1, allowUltraHighResolution: !0 }, zoom: { enabled: !0, forceOff: browser$1.valueFromHash('nozoom', 0), overridemax: browser$1.valueFromHash('maxzoom', null), overridemin: browser$1.valueFromHash('minzoom', null), max: constants$4.highQualityMaxZoom, min: 1, transitionStyle: browser$1.valueFromHash('zoomtrans', 1), activationThreshold: 1.1, restoreTime: 500, zoomToDefaultWhenToPano: true //add }, profiling: { enabled: browser$1.valueFromHash('mem', !1) } /* insideFOV: browser.valueFromHash("fov", constants.insideFOV), insideFOVMax: browser.valueFromHash("fovmax", constants.insideFOVMax), panorama: { transitionTime: 1e3, modelAlpha: 0, modelAlphaDelay: .75, modelAlphaLength: 1, skyboxOpacity: 1, skyboxOpacityDelay: .75, skyboxOpacityLength: .9, fovLength: 1, fovDelay: 0, cameraMatrixDuration: .8, cameraMatrixDelay: 0, cameraMatrixEase: easing.easeInCubic, reticuleOpacity: 1, markerOpacity: .3, markerOpacityOnHover: 1 }, dollhouse: { transitionTime: 1e3, modelAlpha: 1, modelAlphaDelay: 0, modelAlphaLength: 1 - .75, skyboxOpacity: 0, skyboxOpacityDelay: 0, skyboxOpacityLength: 1 - .75, fovLength: 1, fovDelay: 0, cameraMatrixDuration: .8, cameraMatrixDelay: .3, cameraMatrixEase: easing.easeInCubic, reticuleOpacity: 1, markerOpacity: 0, markerOpacityOnHover: 0 }, floorplan: { transitionTime: 1e3, modelAlpha: 1, modelAlphaDelay: 0, modelAlphaLength: 1 - .75, skyboxOpacity: 0, skyboxOpacityDelay: 0, skyboxOpacityLength: 1 - .75, fovLength: 1, fovDelay: 0, cameraMatrixDuration: .5, cameraMatrixDelay: 0, cameraMatrixEase: easing.easeOutCubic, reticuleOpacity: 1, markerOpacity: 0, markerOpacityOnHover: 0, cameraHeight: 50 }, transitioning: { reticuleOpacity: 0, markerOpacity: .3, markerOpacityOnHover: 1 }, "floorplan-dollhouse": { rotationDelay: 0, rotationDuration: 1 }, "floorplan-panorama": { rotationDelay: .5, rotationDuration: 1 }, "dollhouse-panorama": { rotationDelay: .5, rotationDuration: 1 }, "dollhouse-floorplan": { rotationDelay: 0, rotationDuration: 1, cameraMatrixDuration: 1.05, cameraMatrixDelay: .5 }, "panorama-dollhouse": { rotationDelay: 0, rotationDuration: .5 }, "panorama-floorplan": { transitionTime: 1500, rotationDelay: 0, rotationDuration: .5 } */ }; settings$2 = common.deepExtend(settings$2, constants$4, { insideFOV: browser$1.valueFromHash('fov', constants$4.insideFOV), insideFOVMax: browser$1.valueFromHash('fovmax', constants$4.insideFOVMax), panorama: { transitionTime: 1e3, modelAlpha: 0, modelAlphaDelay: settings$2.flydown.modelTextureDelay, modelAlphaLength: 1, skyboxOpacity: 1, skyboxOpacityDelay: settings$2.flydown.skyboxDelay, skyboxOpacityLength: 0.9, fovLength: 1, fovDelay: 0, cameraMatrixDuration: 0.8, cameraMatrixDelay: 0, cameraMatrixEase: easing.easeInCubic, reticuleOpacity: 1, markerOpacity: 0.3, markerOpacityOnHover: 1 }, dollhouse: { transitionTime: 1e3, modelAlpha: 1, modelAlphaDelay: 0, modelAlphaLength: 1 - settings$2.flydown.modelTextureDelay, skyboxOpacity: 0, skyboxOpacityDelay: 0, skyboxOpacityLength: 1 - settings$2.flydown.skyboxDelay, fovLength: 1, fovDelay: 0, cameraMatrixDuration: 0.8, cameraMatrixDelay: 0.3, cameraMatrixEase: easing.easeInQuint, //原先的ease模型较大时效果不好 reticuleOpacity: 1, markerOpacity: 0, markerOpacityOnHover: 0 }, floorplan: { transitionTime: 1e3, modelAlpha: 1, modelAlphaDelay: 0, modelAlphaLength: 1 - settings$2.flydown.modelTextureDelay, skyboxOpacity: 0, skyboxOpacityDelay: 0, skyboxOpacityLength: 1 - settings$2.flydown.skyboxDelay, fovLength: 1, fovDelay: 0, cameraMatrixDuration: 0.5, cameraMatrixDelay: 0, cameraMatrixEase: easing.easeOutQuint, //easing.easeOutCubic, reticuleOpacity: 1, markerOpacity: 0, markerOpacityOnHover: 0, cameraHeight: 50 }, transitioning: { reticuleOpacity: 0, markerOpacity: 0.3, markerOpacityOnHover: 1 }, 'floorplan-dollhouse': { rotationDelay: 0, rotationDuration: 1, cameraMatrixEase: easing.easeInQuint //原先的ease模型较大时效果不好 }, 'floorplan-panorama': { rotationDelay: 0.5, rotationDuration: 1 }, 'dollhouse-panorama': { rotationDelay: 0.5, rotationDuration: 1 }, 'dollhouse-floorplan': { rotationDelay: 0, rotationDuration: 1, cameraMatrixDuration: 1.05, cameraMatrixDelay: 0.5 }, 'panorama-dollhouse': { rotationDelay: 0, rotationDuration: 0.5, cameraMatrixEase: easing.easeInOutQuad //fov渐变 }, 'panorama-floorplan': { transitionTime: 1500, rotationDelay: 0, rotationDuration: 0.5 }, //底图版 /* floorMat: { //楼层材质 'stardard-hide': { //没有plane时的隐藏楼层 opacity: 0.2, brightness: 0.12, mixRatio: 0.7, depthTest: true, //depthWrite: false, renderOrder: RenderOrder.ghostFloor, //透明在上层 //transparent:true }, 'stardard-show': { //没有plane时的所有显示楼层 opacity: 1, brightness: 0, mixRatio: 0, depthTest: true, //depthWrite: false, renderOrder: RenderOrder.visibleFloor, //transparent:true }, 'hasPlane-normal': { //有plane时的其他楼层 opacity: 0.024, brightness: 0.6, mixRatio: 1, depthTest: true, //depthWrite: false, renderOrder: RenderOrder.visibleFloor, //transparent:true }, 'hasPlane-curFloor': { //有plane时的当前楼层 opacity: 1, brightness: 0.3, //0.11, mixRatio: 0.78, //0.94, depthTest: false, //depthWrite: false, renderOrder: RenderOrder.ghostFloor, //当前楼在上层,所以和之前反一下 //transparent:true }, }, */ //修改depthTest超黑版,但会引起其他物体遮挡混乱 /* 'stardard-hide': { //没有plane时的隐藏楼层 opacity: 0.2, brightness: 0.12, mixRatio: 0.7, depthTest: true, //depthWrite: false, renderOrder: RenderOrder.ghostFloor, //透明在上层 //transparent:true }, 'stardard-show': { //没有plane时的所有显示楼层 opacity: 1, brightness: 0, mixRatio: 0, depthTest: true, //depthWrite: false, renderOrder: RenderOrder.visibleFloor, //transparent:true }, 'hasPlane-normal': { //有plane时的其他楼层 opacity: 0.024, brightness: 0.6, mixRatio: 1, depthTest: true, //depthWrite: false, renderOrder: RenderOrder.ghostFloor , //transparent:true }, 'hasPlane-curFloor': { //有plane时的当前楼层 opacity: 1, brightness: 0.1, //0.11, mixRatio: 0.98, //0.94, depthTest: false, //depthWrite: false, renderOrder: RenderOrder.ghostFloor+1, //当前楼在上层,所以和之前反一下 //transparent:true }, */ floorMat: { //楼层材质 'stardard-hide': { //没有plane时的隐藏楼层 opacity: 0.2, brightness: 0.12, mixRatio: 0.7, depthTest: true, renderOrder: RenderOrder.ghostFloor //透明在上层 }, 'stardard-show': { //没有plane时的所有显示楼层 opacity: 1, brightness: 0, mixRatio: 0, depthTest: true, renderOrder: RenderOrder.visibleFloor }, 'hasPlane-normal': { //有plane时的其他楼层 opacity: 0.024, brightness: 0.6, mixRatio: 1, depthTest: true, //depthWrite: false, renderOrder: RenderOrder.ghostFloor }, 'hasPlane-curFloor': { //有plane时的当前楼层 opacity: 1, brightness: 0.1, //0.11, mixRatio: 0.98, //0.94, depthTest: true, renderOrder: RenderOrder.visibleFloor } } }); settings$2.path.meshFree && (settings$2.path.typ = WarpStyle.WALK); settings$2.zoom.max = settings$2.zoom.overridemax || settings$2.zoom.max; settings$2.zoom.min = settings$2.zoom.overridemin || settings$2.zoom.min; settings$2.HorizontalBlurShader = new THREE.ShaderPass(THREE.HorizontalBlurShader); settings$2.VerticalBlurShader = new THREE.ShaderPass(THREE.VerticalBlurShader); settings$2.VerticalBlurShader.renderToScreen; settings$2.aspect = window.innerWidth / window.innerHeight; isNaN(constants$4.aspect) && (constants$4.aspect = 1); //settings.sphereBufferGeometry = new THREE.SphereBufferGeometry(0.1) settings$2.planeBufferGeometry = new THREE.PlaneBufferGeometry(0.4, 0.4, 1, 1); settings$2.freeze = Object.freeze({ FlyToPano: transitions$1.getUniqueId(), FlyToNewMode: transitions$1.getUniqueId(), FlyToSameMode: transitions$1.getUniqueId(), FlyToViewFloor: transitions$1.getUniqueId(), LookTransition: transitions$1.getUniqueId(), ZoomTransition: transitions$1.getUniqueId(), LookRotationForPlay: transitions$1.getUniqueId(), wallLineShine: transitions$1.getUniqueId(), spotShine: transitions$1.getUniqueId(), rulerShine: transitions$1.getUniqueId(), outsideFocus: transitions$1.getUniqueId(), shopCircle: transitions$1.getUniqueId() }); var settings$3 = settings$2; var _class$1, _class2, _temp; var _root = getScriptURL(); var components = {}; function defineComponent(name, component) { if (typeof components[name] !== 'undefined') { console.warn("Identifier component.".concat(name, " has already been declared")); } if (typeof component !== 'function') { throw TypeError("argument component not a function"); } components[name] = component; } var KanKan = Emitter(_class$1 = (_temp = _class2 = /*#__PURE__*/function () { function KanKan(options) { _classCallCheck(this, KanKan); this.uid = KanKan.uid++; this.env = KanKan.env; this.version = KanKan.version; this.dom = null; this.$plugins = null; this.core = new Component(this); this.config = KanKan.config(options, {}); this.Plugins = new Plugins(this); this.gui = new GUI(this); if (this.config.vr.markerHeight != null) { settings$3.vrMarkerHeight = this.config.vr.markerHeight; } if (this.config.scene.markerOpacity != null) { settings$3.panorama.markerOpacity = this.config.scene.markerOpacity; } if (this.config.scene.pathEndColor != null) { settings$3.path.color = this.config.scene.pathEndColor; } } _createClass(KanKan, [{ key: "withConfig", value: function withConfig(options) { this.config = deepExtend(this.config, options || {}); //deepMergeObject(this.config, options || {}) } }, { key: "withDom", value: function withDom() { if (this.dom) { // 已经初始化好,不再创建dom return; } var container = typeof this.config.dom === 'string' ? document.querySelector(this.config.dom) : this.config.dom; if (!container) { throw new Error('options.dom must be require'); } var dom = document.createElement('div'); dom.className = 'kankan-app'; var plugins = document.createElement('div'); plugins.id = "kankan-plugins__".concat(this.uid); plugins.className = 'kankan-plugins'; plugins.style.position = 'absolute'; plugins.style.top = 0; plugins.style.left = 0; plugins.style.width = '100%'; plugins.style.height = '100%'; plugins.style.pointerEvents = 'none'; plugins.style.zIndex = 10; var player_a = document.createElement('div'); player_a.className = 'player'; player_a.setAttribute('name', 'main'); var player_b = document.createElement('div'); player_b.className = 'player'; player_b.setAttribute('name', 'copy'); var player_mark = document.createElement('div'); player_mark.className = 'player-mark'; player_mark.style.backgroundImage = "url(".concat(this.resource.base('images/tag_pointer.png'), ")"); player_a.appendChild(player_mark); player_b.appendChild(player_mark.cloneNode()); dom.appendChild(plugins); dom.appendChild(player_a); dom.appendChild(player_b); container.appendChild(dom); this.dom = dom; this.$plugins = plugins; } }, { key: "withComponent", value: function withComponent(name) { var factory = components[name]; if (typeof factory === 'undefined') { console.warn("component[".concat(name, "] not a function")); return; } var Instance = factory(); Instance.prototype.$app = this; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } this.core.add(name, _construct(Instance, args)); } }, { key: "withNewComponent", value: function withNewComponent(name) { var factory = components[name]; if (typeof factory === 'undefined') { console.warn("component[".concat(name, "] not a function")); return; } var Instance = factory(); Instance.prototype.$app = this; for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } return _construct(Instance, args); } }], [{ key: "root", value: function root(path) { return _root + path; } }, { key: "config", value: function config(options, target) { if (typeof options !== 'object') { return config$4; } if (target) { target = Object.assign(target, config$4); } for (var key in options) { if (['env', 'version'].indexOf(key) != -1) { continue; } if (typeof config$4[key] === 'undefined') { continue; } if (target) { target[key] = options[key]; } config$4[key] = options[key]; } return target || config$4; } }]); return KanKan; }(), _class2.uid = 1, _class2.env = config$4.env, _class2.version = config$4.version, _class2.Config = config$4, _temp)) || _class$1; var MathLight = {}; MathLight.RADIANS_PER_DEGREE = Math.PI / 180; MathLight.DEGREES_PER_RADIAN = 180 / Math.PI; MathLight.Vector3 = function (e, t, i) { this.x = e || 0, this.y = t || 0, this.z = i || 0; }; MathLight.Matrix4 = function () { this.elements = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]), arguments.length > 0 && console.error('MathLight.Matrix4: the constructor no longer reads arguments. use .set() instead.'); }; MathLight.Matrix4.prototype = { identity: function identity() { return this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), this; }, copy: function copy(e) { return this.elements.set(e.elements), this; }, applyToVector3: function applyToVector3(e) { var t = e.x, i = e.y, n = e.z, r = this.elements; return e.x = r[0] * t + r[4] * i + r[8] * n + r[12], e.y = r[1] * t + r[5] * i + r[9] * n + r[13], e.z = r[2] * t + r[6] * i + r[10] * n + r[14], this; }, getInverse: function getInverse(e, t) { var i = this.elements, n = e.elements, r = n[0], o = n[1], a = n[2], s = n[3], l = n[4], c = n[5], h = n[6], u = n[7], d = n[8], p = n[9], f = n[10], g = n[11], m = n[12], v = n[13], A = n[14], y = n[15], C = p * A * u - v * f * u + v * h * g - c * A * g - p * h * y + c * f * y, I = m * f * u - d * A * u - m * h * g + l * A * g + d * h * y - l * f * y, E = d * v * u - m * p * u + m * c * g - l * v * g - d * c * y + l * p * y, b = m * p * h - d * v * h - m * c * f + l * v * f + d * c * A - l * p * A, w = r * C + o * I + a * E + s * b; if (0 === w) { var _ = "MathLight.Matrix4.getInverse(): can't invert matrix, determinant is 0"; if (t) throw new Error(_); return console.warn(_), this.identity(); } var T = 1 / w; return i[0] = C * T, i[1] = (v * f * s - p * A * s - v * a * g + o * A * g + p * a * y - o * f * y) * T, i[2] = (c * A * s - v * h * s + v * a * u - o * A * u - c * a * y + o * h * y) * T, i[3] = (p * h * s - c * f * s - p * a * u + o * f * u + c * a * g - o * h * g) * T, i[4] = I * T, i[5] = (d * A * s - m * f * s + m * a * g - r * A * g - d * a * y + r * f * y) * T, i[6] = (m * h * s - l * A * s - m * a * u + r * A * u + l * a * y - r * h * y) * T, i[7] = (l * f * s - d * h * s + d * a * u - r * f * u - l * a * g + r * h * g) * T, i[8] = E * T, i[9] = (m * p * s - d * v * s - m * o * g + r * v * g + d * o * y - r * p * y) * T, i[10] = (l * v * s - m * c * s + m * o * u - r * v * u - l * o * y + r * c * y) * T, i[11] = (d * c * s - l * p * s - d * o * u + r * p * u + l * o * g - r * c * g) * T, i[12] = b * T, i[13] = (d * v * a - m * p * a + m * o * f - r * v * f - d * o * A + r * p * A) * T, i[14] = (m * c * a - l * v * a - m * o * h + r * v * h + l * o * A - r * c * A) * T, i[15] = (l * p * a - d * c * a + d * o * h - r * p * h - l * o * f + r * c * f) * T, this; }, makeRotationFromQuaternion: function makeRotationFromQuaternion(e) { var t = this.elements, i = e.x, n = e.y, r = e.z, o = e.w, a = i + i, s = n + n, l = r + r, c = i * a, h = i * s, u = i * l, d = n * s, p = n * l, f = r * l, g = o * a, m = o * s, v = o * l; return t[0] = 1 - (d + f), t[4] = h - v, t[8] = u + m, t[1] = h + v, t[5] = 1 - (c + f), t[9] = p - g, t[2] = u - m, t[6] = p + g, t[10] = 1 - (c + d), t[3] = 0, t[7] = 0, t[11] = 0, t[12] = 0, t[13] = 0, t[14] = 0, t[15] = 1, this; } }; MathLight.Quaternion = function (e, t, i, n) { this._x = e || 0, this._y = t || 0, this._z = i || 0, this._w = void 0 !== n ? n : 1; }; MathLight.Quaternion.prototype = { get x() { return this._x; }, set x(e) { this._x = e; }, get y() { return this._y; }, set y(e) { this._y = e; }, get z() { return this._z; }, set z(e) { this._z = e; }, get w() { return this._w; }, set w(e) { this._w = e; }, copy: function copy(e) { this._x = e.x, this._y = e.y, this._z = e.z, this._w = e.w; }, inverse: function inverse() { return this.conjugate().normalize(); }, conjugate: function conjugate() { return this._x *= -1, this._y *= -1, this._z *= -1, this; }, length: function length() { return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w); }, normalize: function normalize() { var e = this.length(); return 0 === e ? (this._x = 0, this._y = 0, this._z = 0, this._w = 1) : (e = 1 / e, this._x = this._x * e, this._y = this._y * e, this._z = this._z * e, this._w = this._w * e), this; }, setFromAxisAngle: function setFromAxisAngle(e, t) { var i = t / 2, n = Math.sin(i); return this._x = e.x * n, this._y = e.y * n, this._z = e.z * n, this._w = Math.cos(i), this; }, setFromUnitVectors: function () { var e, t, i = 1e-6; return function (n, o) { return void 0 === e && (e = new MathLight.Vector3()), t = MathLight.dot(n, o) + 1, t < i ? (t = 0, Math.abs(n.x) > Math.abs(n.z) ? MathLight.setVector(e, -n.y, n.x, 0) : MathLight.setVector(e, 0, -n.z, n.y)) : MathLight.cross(n, o, e), this._x = e.x, this._y = e.y, this._z = e.z, this._w = t, this.normalize(); }; }(), multiply: function multiply(e) { return this.multiplyQuaternions(this, e); }, premultiply: function premultiply(e) { return this.multiplyQuaternions(e, this); }, multiplyQuaternions: function multiplyQuaternions(e, t) { var i = e._x, n = e._y, r = e._z, o = e._w, a = t._x, s = t._y, l = t._z, c = t._w; return this._x = i * c + o * a + n * l - r * s, this._y = n * c + o * s + r * a - i * l, this._z = r * c + o * l + i * s - n * a, this._w = o * c - i * a - n * s - r * l, this; } }; MathLight.convertWorkshopVector = function (e) { return new MathLight.Vector3(-e.x, e.y, e.z); }; MathLight.convertWorkshopQuaternion = function (e) { return new MathLight.Quaternion(-e.x, e.y, e.z, -e.w).multiply(new MathLight.Quaternion(Math.sqrt(2) / 2, Math.sqrt(2) / 2, 0, 0)); }; MathLight.convertWorkshopOrthoZoom = function (e) { return e === -1 ? -1 : e / 16 * (window.innerWidth / window.innerHeight) / constants$4.workshopApsect; }; MathLight.convertWorkshopPanoramaQuaternion = function (e) { return new MathLight.Quaternion(e.x, -e.y, -e.z, e.w).normalize().multiply(new MathLight.Quaternion().setFromAxisAngle(new MathLight.Vector3(0, 1, 0), 270 * MathLight.RADIANS_PER_DEGREE)); }; MathLight.normalize = function (e) { var t = e.x * e.x + e.y * e.y + e.z * e.z, i = Math.sqrt(t); e.x /= i, e.y /= i, e.z /= i; }; MathLight.dot = function (e, t) { return e.x * t.x + e.y * t.y + e.z * t.z; }; MathLight.cross = function (e, t, i) { var n = e.x, r = e.y, o = e.z; i.x = r * t.z - o * t.y, i.y = o * t.x - n * t.z, i.z = n * t.y - r * t.x; }; MathLight.setVector = function (e, t, i, n) { e.x = t, e.y = i, e.z = n; }; MathLight.copyVector = function (e, t) { t.x = e.x, t.y = e.y, t.z = e.z; }; MathLight.addVector = function (e, t) { e.x += t.x, e.y += t.y, e.z += t.z; }; MathLight.subVector = function (e, t) { e.x -= t.x, e.y -= t.y, e.z -= t.z; }; MathLight.applyQuaternionToVector = function (e, t) { var i = t.x, n = t.y, r = t.z, o = e.x, a = e.y, s = e.z, l = e.w, c = l * i + a * r - s * n, h = l * n + s * i - o * r, u = l * r + o * n - a * i, d = -o * i - a * n - s * r; t.x = c * l + d * -o + h * -s - u * -a, t.y = h * l + d * -a + u * -o - c * -s, t.z = u * l + d * -s + c * -a - h * -o; }; MathLight.angleBetweenVectors = function (e, t) { return Math.acos(MathLight.dot(e, t)); }; MathLight.closeTo = function (e1, e2, precision) { //xzw add 判断e1,e2是否接近 var prec = Math.pow(10, -(precision || 4)); var s1 = Math.abs(e1.x - e2.x) < prec && Math.abs(e1.y - e2.y) < prec && Math.abs(e1.z - e2.z) < prec; if (e1.w) { return s1 && Math.abs(e1.w - e2.w) < prec; } else return s1; }; var ray$2 = new THREE.Raycaster(); var convertTool = { getPos2d: function getPos2d(point, player, camera, dom) { //获取一个三维坐标对应屏幕中的二维坐标 var camera = camera || player.camera; var dom = dom || player.domElement; var pos = point.clone().project(camera); //比之前hotspot的计算方式写得简单 project用于3转2(求法同shader); unproject用于2转3 :new r.Vector3(e.x, e.y, -1).unproject(this.camera); var x, y; x = (pos.x + 1) / 2 * dom.clientWidth; y = (1 - (pos.y + 1) / 2) * dom.clientHeight; var inSight = x <= dom.clientWidth && x >= 0 && //是否在屏幕中 y <= dom.clientHeight && y >= 0; return { pos: new THREE.Vector2(x, y), // 屏幕像素坐标 vector: pos, //(范围 -1 ~ 1) trueSide: pos.z < 1, //trueSide为false时,即使在屏幕范围内可见,也是反方向的另一个不可以被渲染的点 参见Tag.update inSight: inSight //在屏幕范围内可见 }; }, ifShelter: function ifShelter(pos3d, player, pos2d, camera, floorIndex) { //检测某点在视线中是否被mesh遮挡 if (!pos2d) pos2d = this.getPos2d(pos3d, player); camera = camera || player.camera; var ori = new THREE.Vector3(pos2d.x, pos2d.y, -1).unproject(camera); //找到视线原点 var dir = pos3d.clone().sub(ori).normalize(); ray$2.set(ori, dir); //由外向里 因为模型从内侧是可见的所以从外侧 /* if(config.isEdit && publicObjectSet.editor.mainDesign.editing){ var o = ray.intersectObjects(publicObjectSet.editor.mainDesign.wallMeshes); }else{ */ var colliders = floorIndex == void 0 ? player.model.colliders : player.model.floors.index[floorIndex].collider.children; var o = ray$2.intersectObjects(colliders); //} var len = pos3d.distanceTo(ori); if (o && o.length) { for (var i = 0; i < o.length; i++) { if (o[i].distance < len) { return true; } //有遮挡 } } }, /* 拖拽时,获取鼠标在拖拽面上的位置(需要借助另一个intersectPlane面来计算,即和相机方向一样的面,可保证铺满屏幕) 但是不一定能获取到,比如鼠标射线不朝向拖拽面时,即使获取也会是一个意外的反方向的交点。 */ getPosAtPlane: function getPosAtPlane(pos, player, info /* , mouse, camera */ ) { //pos:与intersectPlane的交点 见笔记 var A = pos; var mouse = player.mouse; var O = new THREE.Vector3(mouse.x, mouse.y, -1).unproject(player.camera); if (info.y != void 0) { //地面线的 var y = info.y; if (player.mode == 'floorplan' /* || Math.abs(O.x-pos.x)<0.0001 && Math.abs(O.z-pos.z)<0.0001) */ ) { //intersectPlane和地面平行,无交点 var x = pos.x, z = pos.z; } else { if (y < player.camera.position.y && O.y <= A.y /* || y>player.camera.position.y && O.y >= A.y */ ) return null; //鼠标射线向上。因为相机一定位于地面以上(地面不会抬高到相机上吧?),所以无交点。 if (O.y == A.y) { console.log('一样??'); return; } if (A.y == y) { console.log('一样2??'); return; } var r = (O.y - y) / (A.y - y); var x = (r * A.x - O.x) / (r - 1); var z = (r * A.z - O.z) / (r - 1); } } else { //垂直的也有越过消失点以后反向变化的情况,但使用时影响不大 var N = info.normalVec; var P = info.pullPos; if (N.y != 0) { console.log('N.y != 0'); return; } //仅仅支持垂直于地面的的墙壁,目前都是 if (O.z == A.z) { console.log('O.z==A.z?'); return; } if (N.z != 0 && N.x != 0) { //直接用这个通用的也可以,支持斜线的墙 //console.log('N.z==0 && N.x == 0?'); var c = N.x * (A.x - O.x) + N.y * (A.y - O.y) + N.z * (A.z - O.z); if (c == 0) { console.log('分母为0?? return;'); return; } var t = -(N.x * O.x + N.y * O.y + N.z * O.z - (P.x * N.x + P.y * N.y + P.z * N.z)) / c; var x = t * (A.x - O.x) + O.x; var y = t * (A.y - O.y) + O.y; var z = t * (A.z - O.z) + O.z; /*原理: 已知空间直线L:(x-a)/m=(x-b)/n=(z-c)/p和空间平面π:Ax+By+Cz+D=0; 求直线L与平面π的交点的坐标。 把直线方程改写成参数形式:设(x-a)/m=(x-b)/n=(z-c)/p=t; 则x=mt+a;y=nt+b;z=pt+c;代入平面π的方程得: A(mt+a)+B(nt+b)+C(pt+c)+D=0 由此解得t=-(Aa+Bb+Cc+D)/(Am+Bn+Cp) 再代入参数方程即得交点的坐标(x,y,z). */ } else if (N.x == 0) { //z与pullPos相等 var z = P.z; if (O.y == A.y) { console.log('一样??'); return; } if (A.y == y) { console.log('一样2??'); return; } if (A.z == z) { console.log('一样3??'); return; } var r = (O.z - z) / (A.z - z); var x = (r * A.x - O.x) / (r - 1); var y = (r * A.y - O.y) / (r - 1); } else if (N.z == 0) { //x与pullPos相等 var x = P.x; if (O.y == A.y) { console.log('一样??'); return; } if (A.y == y) { console.log('一样2??'); return; } if (A.x == x) { console.log('一样3??'); return; } var r = (O.x - x) / (A.x - x); var y = (r * A.y - O.y) / (r - 1); var z = (r * A.z - O.z) / (r - 1); } } return new THREE.Vector3(x, y, z); }, getMouseIntersect: function getMouseIntersect(camera, meshes, mouse) { //获取鼠标和meshes交点 var raycaster = new THREE.Raycaster(); camera.updateMatrixWorld(); var origin = new THREE.Vector3(mouse.x, mouse.y, -1).unproject(camera), end = new THREE.Vector3(mouse.x, mouse.y, 1).unproject(camera); var dir = end.sub(origin).normalize(); raycaster.set(origin, dir); meshes.forEach(function (e) { raycaster.layers.enable(math$1.getBaseLog(2, e.layers.mask)); }); var n = raycaster.intersectObjects(meshes); if (0 === n.length) return null; var i = n.find(function (e) { return e.object.visible === true; }); if (i) return i; return null; }, ifIntersectChunks: function ifIntersectChunks(A, B, model) { var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; //获取某个线段/射线和meshes的交点 var dir = B.clone().sub(A).normalize(); var len = options.InfinityLen ? Infinity : A.distanceTo(B) + (options.extLen || 0); if (len == 0) return; var ray = new THREE.Raycaster(A.clone(), dir, 0, len); var meshes = options.meshes || []; if (meshes.length == 0) { meshes = model.floors.reduce(function (e, t) { return t.hidden ? e : e.concat(t.collider.children); }, meshes); } var o = ray.intersectObjects(meshes); //var o = ray.intersectObjects(options.meshes || model.colliders) if (o && o.length) return o; if (options.throughWidth) { //允许最小宽度,防止穿过极小的缝隙导致撞墙感 var normal = math$1.getNormal({ points: [{ x: A.x, y: A.z }, { x: B.x, y: B.z }] }); //线段法线 normal.multiplyScalar(options.throughWidth); var normalVec3 = new THREE.Vector3(normal.x, 0, normal.y); var A2 = A.clone().add(normalVec3); ray.set(A2, dir); var o2 = ray.intersectObjects(options.meshes || model.colliders); ray.set(A.clone().add(normalVec3.negate()), dir); if (o2 && o2.length) return o2; var o3 = ray.intersectObjects(options.meshes || model.colliders); if (o3 && o3.length) return o3; } return null; }, /* getPosAtSphere : function(pos3d, toPanoPos){ var dir = pos3d.clone().sub(toPanoPos); dir.normalize();//然后计算在球中 dir.multiplyScalar(Constants.skyRadius); dir.add(toPanoPos); return dir; }, */ getVisiblePano: function getVisiblePano(position, model) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; //获取某个坐标的可见pano。即没有遮挡的位置。 var visiblePanos = []; //var wallDepth = 0.075, discScale = 0.06; var B = position.clone(); var panos = options.panos || model.panos.list; panos.forEach(function (pano) { if (!pano.isAligned()) return; var A = pano.position.clone(); var distance = A.distanceTo(B); if (options.maxDis != void 0 && distance > options.maxDis) { //超出这个距离不可见 //console.log('超出',pano.id, distance-options.maxDis) return; } var ray = new THREE.Raycaster(A.clone(), B.clone().sub(A).normalize(), 0, distance - (options.tolerance || 0)); /* discScale / 2 - wallDepth */ var o = ray.intersectObjects(options.model || model.colliders, true); /* if(o && o.length){ console.log('ex', pano.id, distance - o[0].distance) }else console.log('visi',pano.id) */ if (!o || !o.length) visiblePanos.push(pano); }); return visiblePanos; }, raycastToFindFloor: function () { //八个方向上寻找floor,返回碰撞到最多的floor var e = [new THREE.Vector3(0, -1, 0), new THREE.Vector3(1, -1, 0), new THREE.Vector3(0, -1, 1), new THREE.Vector3(-1, -1, 0), new THREE.Vector3(0, -1, -1), new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 0, 1), new THREE.Vector3(-1, 0, 0), new THREE.Vector3(0, 0, -1)]; return function (player, position) { /* var floors = []; //有时候在建筑外侧,容易识别到其他层 var max = {floor:null,count:0}; for (var t = 0; t < e.length; t++) { var i = new THREE.Raycaster(position.clone(), e[t].clone()) , n = i.intersectObjects(objects.model.colliders); if (n.length){ var floor = n[0].object.parent.parent var item = floors.find(item=>item.floor == floor) if(item)item.len++ else floors.push({floor:floor , len:1}) } } floors.sort((a,b)=>{b.len-a.len}) if(floors[0]) return floors[0].floor */ var floors = [], colliders = [], floorScores = []; for (var u in player.model.floors.list) { //寻找高度区间 var floor = player.model.floors.list[u]; if (position.y >= floor.boundingBox.min.y && position.y <= floor.boundingBox.max.y) { floors.push(floor); colliders.push.apply(colliders, _toConsumableArray(floor.collider.children)); //在floor区间的话就添加 } } if (floors.length == 1) return floors[0];else if (floors.length > 1) { //寻找 raycaster最多的floor for (var t = 0; t < e.length; t++) { var i = new THREE.Raycaster(position.clone(), e[t].clone()), n = i.intersectObjects(colliders); if (n.length) { (function () { var floor = n[0].object.parent.floor; var item = floorScores.find(function (item) { return item.floor == floor; }); if (item) item.len++;else floorScores.push({ floor: floor, len: 1 }); })(); } } floorScores.sort(function (a, b) { b.len - a.len; }); //可能数量一致 if (floorScores[0]) return floorScores[0].floor;else { //如果找不到mesh,直接用boundingbox floorScores = []; floors.forEach(function (floor) { var box = floor.boundingBox; var points = [new THREE.Vector3(box.min.x, box.min.y, box.min.z), new THREE.Vector3(box.max.x, box.max.y, box.max.z), new THREE.Vector3(box.min.x, box.min.y, box.max.z), new THREE.Vector3(box.min.x, box.max.y, box.min.z), new THREE.Vector3(box.max.x, box.min.y, box.min.z), new THREE.Vector3(box.max.x, box.max.y, box.min.z), new THREE.Vector3(box.min.x, box.max.y, box.max.z), new THREE.Vector3(box.max.x, box.min.y, box.max.z)]; var dis = 0; points.forEach(function (p) { return dis += p.distanceTo(position); }); floorScores.push({ floor, dis }); }); floorScores.sort(function (a, b) { a.dis - b.dis; }); //选择boundingbox八个点到position最短的 return floorScores[0].floor; } } else { //超出floor区间后要么是第一层,要么是最后一层(因为寻找最接近的) if (position.y < player.model.floors.list[0].center.y) { //比随意一层低 即 低于最低层 var floors = player.model.floors.list.sort(function (f1, f2) { return f1.boundingBox.min.y - f2.boundingBox.min.y; }); return floors[0]; } else { var floors = player.model.floors.list.sort(function (f1, f2) { return f2.boundingBox.max.y - f1.boundingBox.max.y; }); return floors[0]; } } /* 思路笔记:1 即使1个面片都能成为floor,可能是底面,可能是墙 2 且这个floor还不一定有panos 3 根据上述特征 最好是根据在不同panos的visible来判断楼层 4 但是存在一个bug : 漫游点和mesh之间可能不对应,也就是看上去在某个楼层,飞出后发现它对应的mesh是另一个。。(这个是明显错误。可以推给算法部) 5 在漫游时和楼层无关,一直显示overlay的。所以重点是要让飞出来的mesh看上去和overlay对应。所以直接考虑mesh即可。这样可以避开4 */ }; }(), getQuaByAim: function getQuaByAim(aim) { var center = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new THREE.Vector3(); var forward = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new THREE.Vector3(0, 0, -1); //z朝上的坐标系是 forward = new THREE.Vector3(0, 1, 0) var qua1 = new THREE.Quaternion().setFromUnitVectors(forward, aim.clone().sub(center).normalize()); //或var _ = (new THREE.Matrix4).lookAt(pano.position, aim, new THREE.Vector3(0,1,0)); aimQua = (new THREE.Quaternion).setFromRotationMatrix(_); return qua1; }, getAimByQua: function getAimByQua(quaternion, center) { return new THREE.Vector3(0, 0, -1).applyQuaternion(quaternion).add(center); } }; /** * 日志输出 */ var logger$1 = { info() { var _console; (_console = console).log.apply(_console, arguments); }, debug() { var _console2; (_console2 = console).debug.apply(_console2, arguments); }, error() { var _console3; (_console3 = console).error.apply(_console3, arguments); }, warn() { var _console4; (_console4 = console).warn.apply(_console4, arguments); }, time(s) { console.time(s); }, timeEnd(s) { console.timeEnd(s); }, message(s) { alert(s); } }; var BlackoutStyle$1 = { NONE: 0, MIDDLE: 1, END: 2, BEGINNING: 3, FADEIN: 4 }; var ZoomStats = function ZoomStats() { this.actionSequence = [], this.actionSequenceInProgress = !1; }; // function r(e, t, i, n) { ZoomStats.prototype.reset = function (e) { this.actionSequenceInProgress = !1, this.actionSequence.length = 0; }; ZoomStats.prototype.addZoomAction = function () { var e = null, t = null, i = !1, n = function n() { if (e = null, this.actionSequence.length > 0) { this.actionSequence[0].start; this.actionSequence[this.actionSequence.length - 1].end; } this.reset(); }; return function (r, o, a) { if (r !== o) { i || (n = n.bind(this), i = !0), e && (window.clearTimeout(e), e = null), a === t && this.actionSequenceInProgress || (this.reset(), t = a), this.actionSequenceInProgress = !0; var s = { start: r, end: o }; this.actionSequence.push(s), e = window.setTimeout(n, 150); } }; }(); var Joystick = { UP: 1, DOWN: -1, LEFT: 'L', RIGHT: 'R', FORWARD: 'F', BACK: 'B', reverse: {}, opposite: function opposite(e) { return this.reverse[e.toString()]; } }; !function () { Joystick.reverse[Joystick.UP] = Joystick.DOWN, Joystick.reverse[Joystick.DOWN] = Joystick.UP, Joystick.reverse[Joystick.LEFT] = Joystick.RIGHT, Joystick.reverse[Joystick.RIGHT] = Joystick.LEFT, Joystick.reverse[Joystick.FORWARD] = Joystick.BACK, Joystick.reverse[Joystick.BACK] = Joystick.FORWARD; }(); var History = /*#__PURE__*/function () { function History() { _classCallCheck(this, History); this.events = []; this.valid = !1; } _createClass(History, [{ key: "push", value: function push(e, t) { this.events.push({ direction: e, pano: t }); this.valid = !0; } }, { key: "pop", value: function pop(e) { var t = this.events.pop(); return this.events.length < 1 && (this.valid = !1), t; } }, { key: "peek", value: function peek() { return this.events.length ? this.events[this.events.length - 1] : { direction: null, pano: null }; } }, { key: "invalidate", value: function invalidate() { this.events = []; this.valid = !1; } }, { key: "reversePano", value: function reversePano(e) { if (!this.valid) return null; var t = this.peek(); return Joystick.opposite(e) === t.direction ? (this.pop(), t.pano) : null; } }]); return History; }(); var Viewmode$1 = { PANORAMA: 'panorama', DOLLHOUSE: 'dollhouse', FLOORPLAN: 'floorplan', TRANSITIONING: 'transitioning' }; Viewmode$1.toInt = function (mode) { switch (mode) { case this.PANORAMA: return 1; case this.DOLLHOUSE: return 2; case this.FLOORPLAN: return 3; case this.TRANSITIONING: return -1; } throw new Error('未知模式: ' + c); }; Viewmode$1.fromInt = function (mode) { switch (mode) { case '1': case 1: return this.PANORAMA; case '2': case 2: return this.DOLLHOUSE; case '3': case 3: return this.FLOORPLAN; } throw new Error('未知模式: ' + c); }; var ModelUrls = /*#__PURE__*/function () { function ModelUrls(projectNum, app) { _classCallCheck(this, ModelUrls); this.version = 1; this.cache = null; this.expires = 0; this.projectNum = projectNum; this.app = app; } _createClass(ModelUrls, [{ key: "validate", value: function validate(e) { return 'catalog.json' in e && Object.keys(e).length > 0; } }, { key: "update", value: function update(e) { this.cache = e; this.expires = Date.now() + constants.signedUrlDefaultExpireTime; return Deferred$1.when(); } }, { key: "get", value: function get(e) { return this.app.resource.getViewImagesURL(e); } }]); return ModelUrls; }(); function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } var IndexedCollection = /*#__PURE__*/function () { function IndexedCollection() { _classCallCheck(this, IndexedCollection); this.list = []; this.index = {}; Object.defineProperty(this, 'length', { get: function get() { return this.list.length; } }); if (typeof this.getIndex != 'function') { throw new Error('IndexedCollection.getIndex not implemented in subclass.'); } } _createClass(IndexedCollection, [{ key: "forEach", value: function forEach(e) { this.list.forEach(e); } }, { key: "add", value: function add(pano) { this.list.push(pano); this.index[this.getIndex(pano)] = pano; } }, { key: "extend", value: function extend(e) { for (var t = 0; t < e.length; t++) { this.add(e[t]); } } }, { key: "get", value: function get(panoId) { return this.index[panoId]; } }, { key: "first", value: function first() { return this.list[0]; } }, { key: "last", value: function last() { return this.list[this.list.length - 1]; } }, { key: "reIndex", value: function reIndex() { this.index = {}; var e = this; this.forEach(function (t) { e.index[e.getIndex(t)] = t; }); } }, { key: "filter", value: function filter(e) { var t = this.list.filter(e); return this.reIndex(), t; } }, { key: "reduce", value: function reduce(e, t) { return this.list.reduce(e, t); } }, { key: "sort", value: function sort(e) { return this.list.sort(e); } }, { key: "indexOf", value: function indexOf(e) { for (var t = 0; t < this.list.length; ++t) { if (this.list[t] === e) return t; } return -1; } }, { key: "clone", value: function clone() { //xzw add var newobj = new this.constructor(); newobj.extend(this.list); return newobj; } }]); return IndexedCollection; }(); var ChunkedCollider = /*#__PURE__*/function () { function ChunkedCollider(chunksize) { _classCallCheck(this, ChunkedCollider); this.chunksize = chunksize || 10; this.chunks = {}; this.boundingBoxes = {}; this.children = []; this.offset = new THREE.Vector3(0, 0.5, 0); this.material = new THREE.MeshBasicMaterial({ color: 16777215 * Math.random(), side: THREE.DoubleSide }); } _createClass(ChunkedCollider, [{ key: "add", value: function add(geometry) { var vertices, index, o, a, s, l, c, h, u, d, p, f, g, attributes = geometry.attributes; if (attributes) { vertices = attributes.position.array; index = void 0 !== geometry.index ? geometry.index.array : void 0; } else { vertices = geometry.vertices; } var v = new THREE.Vector3(); if (index) { for (o = 0, a = index.length; o < a; o += 3) { var triangleIndex1 = 3 * index[o], triangleIndex2 = 3 * index[o + 1], triangleIndex3 = 3 * index[o + 2]; s = (vertices[triangleIndex1] + vertices[triangleIndex2] + vertices[triangleIndex3]) / 3; l = (vertices[triangleIndex1 + 1] + vertices[triangleIndex2 + 1] + vertices[triangleIndex3 + 1]) / 3; c = (vertices[triangleIndex1 + 2] + vertices[triangleIndex2 + 2] + vertices[triangleIndex3 + 2]) / 3; h = Math.floor(s / this.chunksize); u = Math.floor(l / this.chunksize); d = Math.floor(c / this.chunksize); p = h + '.' + u + '.' + d; if (p in this.chunks) { g = this.chunks[p]; f = this.boundingBoxes[p]; } else { g = this.chunks[p] = []; f = this.boundingBoxes[p] = new THREE.Box3(); } g.push(vertices[triangleIndex1], vertices[triangleIndex1 + 1], vertices[triangleIndex1 + 2], vertices[triangleIndex2], vertices[triangleIndex2 + 1], vertices[triangleIndex2 + 2], vertices[triangleIndex3], vertices[triangleIndex3 + 1], vertices[triangleIndex3 + 2]); f.expandByPoint(v.set(vertices[triangleIndex1], vertices[triangleIndex1 + 1], vertices[triangleIndex1 + 2])); f.expandByPoint(v.set(vertices[triangleIndex2], vertices[triangleIndex2 + 1], vertices[triangleIndex2 + 2])); f.expandByPoint(v.set(vertices[triangleIndex3], vertices[triangleIndex3 + 1], vertices[triangleIndex3 + 2])); } } else { for (o = 0, a = vertices.length; o < a; o += 9) { s = (vertices[o] + vertices[o + 3] + vertices[o + 6]) / 3, l = (vertices[o + 1] + vertices[o + 4] + vertices[o + 7]) / 3, c = (vertices[o + 2] + vertices[o + 5] + vertices[o + 8]) / 3, h = Math.floor(s / this.chunksize), u = Math.floor(l / this.chunksize), d = Math.floor(c / this.chunksize), p = h + '.' + u + '.' + d; if (p in this.chunks) { g = this.chunks[p]; f = this.boundingBoxes[p]; } else { g = this.chunks[p] = []; f = this.boundingBoxes[p] = new THREE.Box3(); } g.push(vertices[o], vertices[o + 1], vertices[o + 2], vertices[o + 3], vertices[o + 4], vertices[o + 5], vertices[o + 6], vertices[o + 7], vertices[o + 8]); f.expandByPoint(v.set(vertices[o], vertices[o + 1], vertices[o + 2])); f.expandByPoint(v.set(vertices[o + 3], vertices[o + 4], vertices[o + 5])); f.expandByPoint(v.set(vertices[o + 6], vertices[o + 7], vertices[o + 8])); } } } }, { key: "build", value: function build() { var object3D = new THREE.Object3D(); object3D.material = this.material; object3D.name = 'colliderGroup'; for (var t in this.chunks) { var chunk = this.chunks[t], bufferGeometry = new THREE.BufferGeometry(); bufferGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(chunk), 3)); bufferGeometry.boundingBox = this.boundingBoxes[t]; var mesh = new THREE.Mesh(bufferGeometry, this.material); mesh.material.visible = !1; mesh.name = 'collider'; object3D.add(mesh); this.chunks[t] = []; } return object3D; } }]); return ChunkedCollider; }(); function _createSuper$1z(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1z(); 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 _isNativeReflectConstruct$1z() { 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; } } var Floor$1 = /*#__PURE__*/function (_THREE$Object3D) { _inherits(Floor, _THREE$Object3D); var _super = _createSuper$1z(Floor); function Floor(model, floorIndex, name) { var _this; _classCallCheck(this, Floor); _this = _super.call(this); _this.model = model; _this.floorIndex = floorIndex; _this.name = name || '楼层' + (floorIndex + 1); _this.panos = []; _this.chunksDam = []; _this.tiles = []; _this.colliderBuilder = new ChunkedCollider(3); _this.collider = null; _this.center = null; _this.boundingBox = new THREE.Box3(); _this.size = null; _this.hidden = !1; _this.display = true; _this.conservativeBoundingBox = new THREE.Box3(); _this.debugColor = 16777215 * Math.random(); _this.transition = null; _this.entryArrow = []; _this.views = []; return _this; } _createClass(Floor, [{ key: "chunks", get: function get() { if (this.chunksDam.length) { // Dam return this.chunksDam; } else { // 3dTiles var chunks = []; this.tiles.forEach(function (tile) { tile.traverse(function (obj) { if (obj.isChunk) { chunks.push(obj); } }); }); return chunks; } } /** * 设置为当前楼层 */ }, { key: "enter", value: function enter(mode) { // setFloor会设置楼层显隐 this.model.setFloor(this, mode); } /** * 显示该楼层 */ }, { key: "show", value: function show() { var _this2 = this; var player = this.model.$app.core.get('Player'); this.hidden = !1; //transparent恒为true才能设置遮挡 /* this.chunks.forEach(chunk => { chunk.material.transparent = !1 }) */ // 显示该楼层的球幕marker(locked时、飞入时、编辑cad时不显示), var canShowVideoMarker = this.model.$app.core.get('PanoVideoRenderer').canShowMarker(); player.modeTran.split('-')[1] == 'panorama' || player.locked || canShowVideoMarker && this.panos.forEach(function (pano) { return pano.hasVideo && pano.hasNeighbor() && (pano.marker.material.opacity = 1); }); // 显示楼层label和overlay等 setTimeout(function () { // setTimeout用于防止flyToNewModel前执行show player.mode == 'floorplan' && _this2.model.floorplanCadImg.showCadPlane(); // 显示cad _this2.setMaterial(); player.labelManager && player.labelManager.show(_this2.floorIndex); player.OverlayManager && player.OverlayManager.show(_this2.floorIndex, true); player.GLTFEditor && player.GLTFEditor.show(_this2.floorIndex, true); _this2.model.$app.Camera.monitor.control.showAll(_this2.floorIndex); }, 1); // console.error('显示楼层:' + this.floorIndex) } /** * 隐藏该楼层 */ }, { key: "hide", value: function hide() { var _this3 = this; this.hidden = !0; /* this.chunks.forEach(chunk => { chunk.material.transparent = !0 }) */ this.setMaterial(); // 隐藏该楼层的球幕marker this.panos.forEach(function (pano) { return pano.hasVideo && (pano.marker.material.opacity = 0); }); // 隐藏楼层label和overlay等 var player = this.model.$app.core.get('Player'); setTimeout(function () { player.labelManager && player.labelManager.hide(_this3.floorIndex); player.OverlayManager && player.OverlayManager.hide(_this3.floorIndex); player.GLTFEditor && player.GLTFEditor.hide(_this3.floorIndex); _this3.model.$app.Camera.monitor.control.hideAll(_this3.floorIndex); }, 1); // console.error('隐藏楼层:' + this.floorIndex) } /** * 切换该楼层显隐 */ }, { key: "toggle", value: function toggle(ifShow) { //switch状态 if (ifShow === void 0) ifShow = this.hidden; ifShow ? this.show() : this.hide(); } /** * chunks(Dam) */ }, { key: "addChunk", value: function addChunk(chunk) { //chunk.renderOrder = RenderOrder.ghostFloor this.add(chunk); this.chunksDam.push(chunk); this.boundingBox.union(chunk.geometry.boundingBox); var size = new THREE.Vector3(); this.boundingBox.getSize(size); this.size = size; this.colliderBuilder.add(chunk.geometry); chunk.floor = this; } /** * tiles */ }, { key: "addTile", value: function addTile(tileContent) { var _this4 = this; tileContent.floorIndex = this.floorIndex; this.tiles.push(tileContent); this.add(tileContent); tileContent.modified = ''; tileContent.traverse(function (obj) { if (obj.isChunk) { obj.setMode(_this4.model.mode, _this4.model.$app.core.get('Player').modeTran); //obj.renderOrder = RenderOrder.ghostFloor _this4.setMaterial(obj); // floor显隐判断 // floor显隐判断 /* if(this.hidden){ obj.material.uniforms.opacity.value = settings.floorMat['stardard-hide'].opacity obj.material.uniforms.mixRatio && (obj.material.uniforms.mixRatio.value = settings.floorMat['stardard-hide'].mixRatio ) obj.material.uniforms.brightness && (obj.material.uniforms.brightness.value = settings.floorMat['stardard-hide'].brightness ) }else{ obj.material.uniforms.opacity.value = settings.floorMat['stardard-show'].opacity obj.material.uniforms.mixRatio && (obj.material.uniforms.mixRatio.value = settings.floorMat['stardard-show'].mixRatio ) obj.material.uniforms.brightness && (obj.material.uniforms.brightness.value = settings.floorMat['stardard-show'].brightness ) } */ //obj.material.transparent = this.hidden // todo 关于3dtiles的boundingBox和collider _this4.boundingBox.union(obj.geometry.boundingBox); var size = new THREE.Vector3(); _this4.boundingBox.getSize(size); _this4.size = size; _this4.colliderBuilder && _this4.colliderBuilder.add(obj.geometry); } }); } }, { key: "removeTile", value: function removeTile(tileContent) { this.tiles = this.tiles.filter(function (tile) { return tile !== tileContent; }); tileContent.traverse(function (obj) { if (obj.isChunk) { obj.geometry.dispose(); obj.material.dispose(); obj.material.uniforms.map.value && obj.material.uniforms.map.value.dispose(); } }); this.remove(tileContent); tileContent.modified = 'remove'; } /** * panos */ }, { key: "addPano", value: function addPano(pano) { this.panos.push(pano); //this.add(pano.skyboxMesh) pano.marker && this.add(pano.marker); var t = new THREE.Vector3(1, 1, 1), i = new THREE.Box3().setFromCenterAndSize(pano.position, t); this.boundingBox.union(i); } }, { key: "removePano", value: function removePano(pano) { var index = this.panos.indexOf(pano); index > -1 && this.panos.splice(index, 1); } /** * 场景关联 */ }, { key: "addView", value: function addView(view) { this.views.push(view); } }, { key: "removeView", value: function removeView(view) { var index = this.views.indexOf(view); index > -1 && this.views.splice(index, 1); } /** * 初始化 */ }, { key: "build", value: function build() { this.collider = this.colliderBuilder.build(!0); this.collider.floor = this; //this.add(this.collider) var center = new THREE.Vector3(); this.boundingBox.getCenter(center); this.center = center; this.conservativeBoundingBox.copy(this.boundingBox); this.conservativeBoundingBox.min.y = common.lowerMedian(this.collider.children.map(function (mesh) { return mesh.geometry.boundingBox.min.y; }), 5); this.conservativeBoundingBox.max.y = common.lowerMedian(this.collider.children.map(function (mesh) { return mesh.geometry.boundingBox.max.y; }), 5); this.colliderBuilder = null; } }, { key: "toShortString", value: function toShortString() { return common.nth(this.floorIndex + 1); } }, { key: "toString", value: function toString() { return this.name; } }, { key: "setMaterial", value: function setMaterial(mesh) { var matPropName, meshes; if (mesh) { matPropName = this.matPropName, meshes = [mesh]; } else { var modeTran = this.model.$app.core.get('Player').modeTran; var hasCadPlane = modeTran.split('-')[1] == 'floorplan' && this.model.currentFloor.shouldShowPlane && !this.model.currentFloor.imgLoadFailed && this.model.$app.store.getValue('metadata').floorPlanUser; //需要展示cad(默认floorplan没有all的可能) matPropName = this.matPropName = hasCadPlane ? this.hidden ? 'hasPlane-normal' : 'hasPlane-curFloor' : this.hidden ? 'stardard-hide' : 'stardard-show'; meshes = this.chunks; //console.log(matPropName, hasCadPlane) } var matProps = settings$3.floorMat[matPropName]; meshes.forEach(function (chunk) { for (var name in matProps) { if (name == 'renderOrder') { chunk.renderOrder = matProps[name]; } else if (name == 'depthTest' || name == 'depthWrite' || name == 'transparent') { //不知道为什么当前楼层不能完全遮住其他楼层,即使更改了depthTest等 chunk.materialOutside[name] = matProps[name]; } else { chunk.materialOutside.extraValues[name] = chunk.materialOutside.uniforms[name].value = matProps[name]; } } }); } }]); return Floor; }(THREE.Object3D); function _createSuper$1y(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1y(); 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 _isNativeReflectConstruct$1y() { 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; } } var FloorCollection = /*#__PURE__*/function (_IndexedCollection) { _inherits(FloorCollection, _IndexedCollection); var _super = _createSuper$1y(FloorCollection); function FloorCollection(model) { var _this; _classCallCheck(this, FloorCollection); _this = _super.call(this); _this.model = model; _this.exploded = !1; return _this; } _createClass(FloorCollection, [{ key: "add", value: function add(floor) { _get(_getPrototypeOf(FloorCollection.prototype), "add", this).call(this, floor); this.model.add(floor); } }, { key: "getIndex", value: function getIndex(floor) { return floor.floorIndex; } }, { key: "build", value: function build() { this.list.forEach(function (floor) { floor.build(); }); } }, { key: "nextFloor", value: function nextFloor(e, t) { return this.index[e.floorIndex + t] || null; } }, { key: "getOrMakeFloor", value: function getOrMakeFloor(floorIndex) { var floor = this.index[floorIndex]; if (!floor) { floor = new Floor$1(this.model, floorIndex); this.add(floor); } return floor; } }, { key: "hide", value: function hide() { this.list.forEach(function (floor) { floor.hide(); }); } }, { key: "show", value: function show() { this.list.forEach(function (floor) { floor.show(); }); } }, { key: "getFloorAtPoint", value: function getFloorAtPoint(e) { for (var t = null, i = 1 / 0, n = 0; n < this.list.length; n++) { var r = this.list[n], o = r.distanceToPoint(e); (!t || i > o) && (i = o, t = r); } return t; } }]); return FloorCollection; }(IndexedCollection); var lerp = { vector: function vector(e, t, f) { //xzw change, add f var i = e.clone(); return t = t.clone(), function (n) { e.set(i.x * (1 - n) + t.x * n, i.y * (1 - n) + t.y * n, i.z * (1 - n) + t.z * n); f && f(e, n); }; }, quaternion: function quaternion(e, t, f) { //xzw change, add f var i = e.clone(); return function (n) { e.copy(i).slerp(t, n); f && f(e, n); }; }, color: function color(e, t, f) { var i = e.clone(); return function (n) { e.copy(i).lerp(t, n); f && f(e, n); }; }, property(e, t, i, n) { var r = e[t]; return function (o) { e[t] = r * (1 - o) + i * o, n && n(e[t]); }; }, uniform(e, t, i) { var n = e.material.uniforms[t].value; return function (r) { e.material.uniforms[t] && (e.material.uniforms[t].value = n * (1 - r) + i * r); }; }, matrix4(e, t) { var i = e.clone(); return function (n) { for (var r = e.elements, o = i.elements, a = t.elements, s = 0; s < 16; s++) { r[s] = o[s] * (1 - n) + a[s] * n; } }; }, allUniforms(e, t, i) { var n = e.map(function (e) { return this.uniform(e, t, i); }.bind(this)); return function (e) { n.forEach(function (t) { t(e); }); }; } }; var PanoRendererEvents = { PanoRenderComplete: 'panorama.render.complete', TileRenderFailure: 'panorama.tile.render.failed', TileRenderSuccess: 'panorama.tile.render.success', TileUploadAttempted: 'panorama.tile.upload.attempted', UploadAttemptedForAllTiles: 'panorama.upload.attempted.all.tiles', ZoomLevelRenderStarted: 'panorama.zoom.render.started' }; var RenderLayers = { DEFAULT: 0, //mesh默认都会显示在DEFAULT层。若不要需要手动toggle(DEFAULT) PANOMARKERS: 1, //这三个是在截图时用到的,其实也可以不用分这么多 RETICULE: 2, // add by xzw: BothAtMainAndSubScreen: 3, //在主屏幕和分屏幕上都有的 SubScreen: 4, //仅在分屏幕上有的 Monitor: 5 }; var PanoramaEvents = { LoadComplete: 'panorama.load.complete', LoadFailed: 'panorama.load.failed', TileLoaded: 'panorama.tile.loaded' }; var PanoSizeClass = { BASE: 1, STANDARD: 2, HIGH: 3, ULTRAHIGH: 4 }; /* * @Author: Rindy * @Date: 2021-05-07 15:48:57 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 15:49:49 * @Description: 注释 */ var basicTextured = { uniforms: { tDiffuse: { type: 't', value: null }, alpha: { type: 'f', value: 1 } }, vertexShader: 'varying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}', fragmentShader: 'varying vec2 vUv;\nuniform float alpha;\nuniform sampler2D tDiffuse;\nvoid main() {\n vec4 texColor = texture2D(tDiffuse, vUv);\n gl_FragColor = vec4(texColor.rgb, texColor.a * alpha);\n}' }; /* * @Author: Rindy * @Date: 2021-05-07 15:50:38 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 15:51:20 * @Description: 注释 */ var copyCubeMap = { uniforms: { tDiffuse: { type: 't', value: null }, alpha: { type: 'f', value: 1 } }, vertexShader: 'varying vec3 vWorldPos;\nvoid main() {\n vWorldPos = vec3(-position.x, -position.y, position.z);\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}', fragmentShader: 'varying vec3 vWorldPos;\nuniform float alpha;\nuniform samplerCube tDiffuse;\nvoid main() {\n vec4 texColor = textureCube(tDiffuse, vWorldPos);\n gl_FragColor = vec4(texColor.rgb, texColor.a * alpha);\n}' }; /* * @Author: Rindy * @Date: 2021-05-07 15:52:29 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 15:53:00 * @Description: 注释 */ var cube = { uniforms: { map: { type: 't', value: null }, opacity: { type: 'f', value: 1 } }, vertexShader: 'varying vec3 vWorldPosition;\n\nvoid main() {\n vWorldPosition = position;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n', fragmentShader: 'uniform samplerCube map;\nuniform float opacity;\n\nvarying vec3 vWorldPosition;\n\nvoid main() {\n vec4 color = textureCube( map, vec3( -vWorldPosition.x, vWorldPosition.yz ) );\n gl_FragColor = vec4(color.rgb, opacity);\n}\n' }; /* * @Author: Rindy * @Date: 2021-05-07 16:02:08 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 16:02:27 * @Description: 注释 */ var customDepth = { uniforms: { panoPosition: { type: 'v3', value: new THREE.Vector3() } }, vertexShader: 'varying vec4 worldPosition;\n\nvoid main() {\n\n worldPosition = modelMatrix * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n}\n', fragmentShader: 'uniform vec3 panoPosition;\nvarying vec4 worldPosition;\n\nvoid main() {\n\n float depth = distance(worldPosition.xyz, panoPosition);\n float color = 1.0 - depth / 10.0;\n gl_FragColor = vec4(color, color, color, 1.0);\n\n}\n' }; /* * @Author: Rindy * @Date: 2021-05-07 15:52:29 * @LastEditors: Rindy * @LastEditTime: 2021-05-12 15:35:23 * @Description: 注释 */ var modelPaint = { fragmentShader: { Common: "\n \n uniform vec4 iMouse;\n uniform vec2 iResolution;\n uniform sampler2D iChannel0; // bufferArray\n uniform sampler2D iChannel1; // \u5168\u666F\u56FE\n uniform int iBrushType; // \u7B14\u5237\u7C7B\u578B\uFF08\u9A6C\u8D5B\u514B\u3001\u9AD8\u65AF\u6A21\u7CCA\u3001\u6A61\u76AE\uFF09\n uniform float iBrushSize;\n uniform float iAngle;\n uniform float iPitch;\n \n \n const float MAX_TRACE_DISTANCE = 3.0; // max trace distance\n const float INTERSECTION_PRECISION = 0.001; // precision of the intersection\n const int NUM_OF_TRACE_STEPS = 100;\n \n const float PI = 3.145;\n \n vec3 spCenter = vec3( 0.0 , 0.0 , -0.8 ); // \u753B\u7B14\u4E2D\u5FC3\u504F\u79FB\n float spRad = 1.; // \u503C\u8D8A\u5927\uFF0C \u534A\u5F84\u8D8A\u5C0F\n \n // camera\u89C6\u89D2\u53D8\u6362\u77E9\u9635\uFF0Cpitch\u7ED5x\u8F74\uFF0Croll\u7ED5z\u8F74\uFF0Cangle\u7ED5y\u8F74\n mat3 calcLookAtMatrix( in float angle, in float roll, in float pitch )\n {\n vec3 angleVec = vec3( cos(angle), sqrt(cos(angle)*cos(angle) + sin(angle)*sin(angle)) * tan(pitch), sin(angle) );\n vec3 rollVec = vec3( sin(roll), cos(roll), 0.0 );\n \n vec3 ww = normalize( angleVec );\n vec3 uu = normalize( cross(ww, rollVec) );\n vec3 vv = normalize( cross(ww, uu));\n return mat3( uu, vv, ww );\n }\n \n float posMap( vec3 pos ){\n return length(pos - spCenter) - spRad;\n }\n \n float calcIntersection( in vec3 spCenter, in vec3 rayDirec ){\n float h = INTERSECTION_PRECISION*2.0;\n float trace = 0.0;\n \n for( int i=0; i< NUM_OF_TRACE_STEPS ; i++ ){\n if( h < INTERSECTION_PRECISION || trace > MAX_TRACE_DISTANCE ) break;\n h = posMap( spCenter + rayDirec * trace );\n trace += h;\n }\n \n if( trace < MAX_TRACE_DISTANCE ) \n return trace;\n else \n return -1.0;\n }\n \n vec3 calcPoint(vec2 screenPoint, float angle, float pitch) {\n \n mat3 camMat = calcLookAtMatrix(angle, 0.0, pitch);\n vec3 rayDirec = normalize( camMat * vec3(screenPoint.xy, 1.4) ); // create view ray. 2.0 is the lens length\n \n float trace = calcIntersection(spCenter, rayDirec);\n vec3 point = spCenter + rayDirec * trace;\n return point;\n }\n \n // \u6297\u952F\u9F7F \u539F\u7406\uFF1A\u7ED9\u8FB9\u7F18\u4E00\u4E2A\u900F\u660E\u6E10\u53D8\n // edge0 \u5411\u5185\u6E10\u53D8\u8303\u56F4\uFF0Cedge1 \u5411\u5916\u6E10\u53D8\u8303\u56F4\uFF0Cx \u548C\u4E2D\u5FC3\u7684\u8DDD\u79BB\n float smootherstep(float edge0, float edge1, float x) {\n float t = (x - edge0)/(edge1 - edge0);\n float t1 = t*t*t*(t*(t*6. - 15.) + 10.);\n return clamp(t1, 0.0, 1.0);\n }\n //\u65B0\u7248\u9AD8\u65AF\u6A21\u7CCA\u7B97\u6CD5\n float weight(float t, float log2radius, float gamma)\n {\n return exp(-gamma * pow(log2radius - t, 2.0));\n }\n vec4 sample_blured(vec2 uv, float radius, float gamma) {\n vec4 pix = vec4(0.0);\n float norm = 0.0;\n for(float i = 0.0; i < 10.0; i += 0.5)\n {\n float k = weight(i, log2(radius), gamma);\n pix += k*texture2D(iChannel1, uv, i); \n norm += k;\n }\n return pix * pow(norm, -0.95);\n }\n\n \n // modelPaint\u6709\u4E24\u4E2A\u4F5C\u7528\uFF1A\u6839\u636E\u9F20\u6807\u4F4D\u7F6E\u663E\u793A\u7B14\u5237\u3001\u6839\u636E\u9F20\u6807\u4F4D\u7F6E\u6D82\u62B9 \uFF08\u901A\u8FC7iIsBrush\u533A\u5206\uFF09\n vec4 modelPaint(vec2 uv, int iIsBrush)\n {\n vec2 mouse = (-iResolution.xy + 2.0*iMouse.xy)/iResolution.y;\n \n float hAngle = (uv.x * 2.0 + 0.5) * -PI * 0.9989; // uv\u5728\u5168\u666F\u56FE\u8FB9\u754C\u5904\u4F1A\u6709\u4E9B\u8BB8\u7684\u9519\u4F4D\uFF0C\u4E58\u4E0A0.9989\u5219\u6B63\u5E38\n float vAngle = uv.y * PI;\n vec3 n = normalize( vec3(\n sin(vAngle) * sin(hAngle),\n -cos(vAngle),\n sin(vAngle) * cos(hAngle)\n ));\n vec3 wPos = spCenter + n * spRad; // \u5C06uv\u5750\u6807\u6620\u5C04\u5230\u4E09\u7EF4\u4E0A \n vec3 point = calcPoint(mouse, iAngle, iPitch); // \u5C06\u9F20\u6807\u4F4D\u7F6E\u6620\u5C04\u5230\u4E09\u7EF4\u4E0A \n\n float brushSize = iBrushSize / 100.; // \u7B14\u5237\u5927\u5C0F\n if(iIsBrush == 0) brushSize += 0.005; // \u8865\u507F\u9ED1\u8FB9\n vec4 col;\n // \u9650\u5236\u5728brushSize\u8303\u56F4\u5185 && (\u6309\u4E0B\u9F20\u6807 || \u663E\u793A\u7B14\u5237)\n if( length( point - wPos ) < brushSize && (iMouse.z > 0.0 || iIsBrush == 1))\n {\n // \u6D82\u62B9\n if(iMouse.z > 0.0) {\n if(iBrushType == 2) {\n // \u9A6C\u8D5B\u514B\n float mosaicAccuracy = 2. * iResolution.x / 1024.; // \u9A6C\u8D5B\u514B\u7CBE\u5EA6\n vec2 pixelSize = mosaicAccuracy / iResolution.xy;\n vec2 fixedUV = uv + pixelSize;\n vec2 pxUV = floor(fixedUV/pixelSize)*pixelSize;\n col = texture2D(iChannel1, pxUV);\n } \n else if(iBrushType == 1) {\n // \u65E7\u7248\u9AD8\u65AF\u6A21\u7CCA \u5728apple\u7AEF\u4F1A\u51FA\u73B0\u5947\u602A\u7684\u8FB9\u7F18bug\uFF0C\u539F\u56E0\u4E0D\u660E\uFF0C\u9700\u8981\u5C06\u51FA\u73B0bug\u7684\u8FB9\u7F18\u8FDB\u884C\u88C1\u526A\u3002\u4E14\u5728ios\u7AEF\u6A21\u7CCA\u540Ergb\u503C\u504F\u9AD8\n // const float Directions = 16.0;\n // const float Quality =5.0;\n // float Size = 20.0; // \u6A21\u7CCA\u5EA6\n // vec2 Radius = Size/iResolution.xy;\n // col = texture2D(iChannel1, uv);\n \n // for( float d=0.0; d < PI*2.; d += PI*2./Directions) {\n // for(float i = 1.0/Quality; i <= 1.0; i += 1.0/Quality) {\n //\u7591\u4F3Ctexture2D\u65B9\u6CD5\u4E2D\u7684uv\u53C2\u6570\u4E0D\u4E3A\u539F\u59CBuv\u5C31\u4F1A\u51FA\u73B0\u8FB9\u7F18bug\n // col += texture2D(iChannel1, uv + vec2(cos(d), sin(d)) * Radius * i);\n // }\n // }\n // col /= (Quality * Directions - 16.0);\n\n //\u65B0\u7248\u9AD8\u65AF\u6A21\u7CCA\u7B97\u6CD5\n float strong = 0.45;\n float blur_radius = 50.0 * strong;\n col = sample_blured(uv, blur_radius, 0.5);\n // \u5BF9\u5168\u666F\u8D34\u56FE\u8FDB\u884C\u6A21\u7CCA\u5904\u7406\u540E\u5168\u666F\u8D34\u56FE\u4E4B\u95F4\u7684\u63A5\u7F1D\u4F1A\u8F83\u4E3A\u660E\u663E\uFF0C\u9700\u8981\u5BF9\u5168\u666F\u8D34\u56FE\u63A5\u7F1D\u8FDB\u884C\u5904\u7406\n float handlepixel = 10.0; //\u5904\u7406\u5BBD\u5EA6\n if (uv.x > 0.0 && uv.x < handlepixel / iResolution.x) {\n float newuvx = 1.0 - uv.x;\n vec3 mixColor = sample_blured(vec2(newuvx, uv.y), blur_radius, 0.5).rgb;\n col.rgb = col.rgb * (uv.x * iResolution.x / handlepixel) + mixColor * (1.0-uv.x * iResolution.x / handlepixel);\n }\n //\u6A21\u7CCA\u5904\u7406\u540E\u56E0\u4E3A\u91C7\u6837\u539F\u56E0\u8F83\u539F\u56FE\u6709\u6240\u63D0\u4EAE\uFF0C\u9700\u5C06rgb\u603B\u4F53\u8C03\u4F4E\n col.rgb *=0.95;\n } \n else {\n // \u6A61\u76AE\n col = vec4(texture2D(iChannel0, uv).rgb, 0.);\n }\n\n // \u8FB9\u7F18\u6E10\u53D8\n // \u8FD9\u4E2Ashader\u5728\u6D82\u62B9\u8D34\u56FE\u548C\u5168\u666F\u56FE\u7684\u8854\u63A5\u5904\u4F1A\u5B58\u5728\u9ED1\u8FB9\uFF0C\u539F\u56E0\u4E0D\u660E\u3002\u76EE\u524D\u901A\u8FC7\u7ED9\u9ED1\u8FB9\u4E00\u4E2A\u5F88\u5C0F\u7684\u900F\u660E\u5EA6\u6765\u89C4\u907F\u8FD9\u4E2A\u95EE\u9898\u3002\n // \u5982\u679C\u60F3\u663E\u793A\u9ED1\u8FB9\u7684\u8BDD\uFF0C\u6CE8\u91CA\u6389\u53BB\u9ED1\u8FB9\u7684\u90A3\u884C\u4EE3\u7801\uFF0C\u7136\u540E\u628AnewAlpha\u6539\u62101.\u3002\n if(iBrushType != 0) {\n // \u6A61\u76AE\u4EE5\u5916\n // float newAlpha = 1.;\n float newAlpha = min(max(1.-length(point-wPos)/brushSize, 0.) * 2., 1.); // \u4ECE\u5185\u5230\u5916\u6E10\u53D8\u6D88\u5931\n if(length(point-wPos) - brushSize < 0. && length(point-wPos) - brushSize > -0.005){// 0.005\u53BB\u9ED1\u8FB9\n if (texture2D(iChannel0, uv).a != 0.0) { //\u4FEE\u590D\u8FB9\u7F18bug\n col = texture2D(iChannel0, uv);\n col.a = 0.01;\n }\n newAlpha = 0.01;\n }\n col.a = newAlpha > texture2D(iChannel0, uv).a ? newAlpha : texture2D(iChannel0, uv).a; // \u9AD8alpha\u8986\u76D6\u4F4Ealpha\n } else {\n // \u6A61\u76AE\u67D4\u8F6F\u5EA6\n float newAlpha = min(max(length(point-wPos)/brushSize-0.5, 0.) * (1./0.5), 1.); // \u4ECE\u5916\u5230\u5185\u6E10\u53D8\u6D88\u5931\n if(length(point-wPos) - brushSize*.5 < 0.005 && length(point-wPos) - brushSize*.5 > 0.) newAlpha = 0.01; // 0.005\u53BB\u9ED1\u8FB9\n col.a = newAlpha < texture2D(iChannel0, uv).a ? newAlpha : texture2D(iChannel0, uv).a; // \u4F4Ealpha\u8986\u76D6\u9AD8alpha\n }\n }\n \n // \u663E\u793A\u7B14\u5237\n if(iIsBrush == 1) {\n if(iBrushType != 0) {\n col = vec4(1., 1., 1., 0.4); // \u5176\u4ED6\u7B14\u5237\u767D\u8272\u534A\u900F\u660E\n } else {\n col = vec4(1., 1., 1., 0.); // \u6A61\u76AE\u7B14\u5237\u5B8C\u5168\u900F\u660E\n }\n\n // \u7B14\u5237\u8FB9\u7F18\n float ratio = 0.93; // \u975E\u8FB9\u7F18\u5360brushSize\u7684\u6BD4\u7387\n if(length(point-wPos)/brushSize > ratio) col = vec4(.9, .9, .9, 1.);\n // \u5916\u8FB9\u7F18\u6297\u952F\u9F7F\n float m0 = smootherstep(brushSize-0.002, brushSize+0.002, length(point - wPos));\n col = mix(col, vec4(0.), m0);\n if(length(point - wPos) <= brushSize*ratio+0.002) {\n // \u5185\u8FB9\u7F18\u6297\u952F\u9F7F\n float m1 = smootherstep(brushSize*ratio-0.002, brushSize*ratio+0.002, length(point - wPos));\n col = mix(col, vec4(.9, .9, .9, 1.), m1);\n }\n }\n \n } else if(iIsBrush == 0) {\n // brushSize\u8303\u56F4\u5916\u663E\u793A\u5DF2\u6709\u7684\u6D82\u62B9 bufferTexture\n col = texture2D(iChannel0, uv);\n }\n \n return col;\n }\n \n ", Buffer: "\n \n varying vec2 vUv;\n \n void main()\n {\n vec2 uv = vUv;\n gl_FragColor = modelPaint(uv, 0);\n }\n " } }; /* * @Author: Rindy * @Date: 2021-05-07 15:52:29 * @LastEditors: Rindy * @LastEditTime: 2021-05-12 15:35:23 * @Description: 注释 */ var model$1 = { //非fish uniforms: { //许钟文加 和编辑墙有关 minOpa: { //最小透明度系数 type: 'f', value: 0.14 }, minDistance: { //最小距离控制 type: 'f', value: 2.5 }, maxDistance: { //最大距离控制 type: 'f', value: 4 }, //--------------- map: { // 模型贴图(即dollhouse贴图);当定义了BasePanoMap后,它就是全景贴图,但用的是普通映射 type: 't', value: null }, repeatInfoMap: { //重复比率图 sxz type: 't', value: null }, modelAlpha: { type: 'f', value: settings$3.modelAlpha }, baseColor: { //用来调试的颜色 type: 'v3', value: new THREE.Color(1, 1, 1) }, opacity: { type: 'f', value: 1 }, progress: { type: 'f', value: 0 }, blackout: { type: 'i', value: 0 }, // pano0Map和pano1Map的区分是为了过渡,pano0Map是上一个点位全景图,pano1Map是下一个。一般取pano1Map为当前点位。 pano0Map: { type: 't', value: null }, pano0Position: { type: 'v3', value: new THREE.Vector3() }, pano0Matrix: { type: 'm4', value: new THREE.Matrix4() }, pano1Map: { type: 't', value: null }, pano1Position: { type: 'v3', value: new THREE.Vector3() }, pano1Matrix: { type: 'm4', value: new THREE.Matrix4() }, /**球幕视频 */ videoReady: { type: '', value: 0 }, videoTexture: { type: 't', value: null }, exposure: { type: 'f', value: 1 }, parameters: { type: 'm4', value: new THREE.Matrix4().set(4608, 3456, 8192, 4096, 1.95985, 1.34, 1739, 2285, -0.00173905, 0.0000274835, -0.0340487, 0, 1235, 954, 2112, 1584) }, clipRect: { type: 'v4', value: new THREE.Vector4(0.1, 0.1, 0.5, 0.5) }, blendFov: { type: 'f', value: 5 }, // 用于判断球幕视频是否横竖旋转 bFlag: { type: 'i', value: 1 }, /**马赛克 */ paint1Map: { type: 't', value: null }, paint0Map: { type: 't', value: null }, iShowBrush: { type: 'i', value: 0 }, iMouse: { type: 'v4', value: new THREE.Vector4() }, iResolution: { type: 'v2', value: new THREE.Vector2() }, iChannel0: { type: 't', value: null }, iChannel1: { type: 't', value: null }, iBrushType: { type: 'i', value: 1 }, iBrushSize: { type: 'f', value: null }, // 相机的上下转角和左右转角 iAngle: { type: 'f', value: null }, iPitch: { type: 'f', value: null }, /**滤镜 */ // [-1.0, 1.0] 亮度 对比度 饱和度 filterBase0: { type: 'v3', value: new THREE.Vector3(0, 0, 0) // brightness contrast saturation }, // [-1.0, 1.0] 色温调节范围,[ 冷 -- 暖 ] filterTemperature0: { type: 'f', value: 0 }, filterBase1: { type: 'v3', value: new THREE.Vector3(0, 0, 0) }, filterTemperature1: { type: 'f', value: 0 }, //裁剪 clipBoxType: { type: 'a', value: null }, clipBoxPoints: { type: 'a', value: null } }, //全景贴图的shader不同-许钟文----------------- /* fragmentShader: prefixFragment + (config.scene_version == 1 ? "\n#define Not_Cube\n":"") + "uniform sampler2D map;uniform float modelAlpha;uniform float opacity;uniform float progress;uniform int blackout;uniform vec3 pano0Position;uniform vec3 pano1Position;varying vec2 vUv;varying vec3 vWorldPosition0;varying vec3 vWorldPosition1;\n\n#define PI 3.141592653 \n#if defined(Not_Cube)\nuniform sampler2D pano0Map;uniform sampler2D pano1Map;vec4 texCubemapWith2D(sampler2D t,vec3 dir){dir=normalize(dir);float tx=atan(dir.x,dir.z)/(PI*2.0)+0.5;float ty=acos(dir.y)/PI;vec4 color=texture2D(t,vec2(tx,ty));return color;}\n#else\nuniform samplerCube pano0Map;uniform samplerCube pano1Map;\n#endif\nconst vec4 BLACK=vec4(0.0,0.0,0.0,1.0);const vec4 GREY=vec4(0.5,0.5,0.5,1.0);void main(){vec4 colorFromPanos;\n#if defined(Not_Cube)\nvec4 colorFromPano0=texCubemapWith2D(pano0Map,vWorldPosition0);vec4 colorFromPano1=texCubemapWith2D(pano1Map,vWorldPosition1);\n#else\nvec4 colorFromPano0=textureCube(pano0Map,vWorldPosition0.xyz);vec4 colorFromPano1=textureCube(pano1Map,vWorldPosition1.xyz);\n#endif\nif(blackout==0){colorFromPanos=mix(colorFromPano0,colorFromPano1,progress);}else if(blackout==1){colorFromPanos=mix(colorFromPano0,BLACK,min(1.0,progress*2.0));colorFromPanos=mix(colorFromPanos,colorFromPano1,max(0.0,progress*2.0-1.0));}else if(blackout==2){colorFromPanos=mix(colorFromPano0,BLACK,progress);}else if(blackout==3){colorFromPanos=mix(BLACK,colorFromPano1,max(0.0,progress*2.0-1.0));}vec4 colorFromTexture=texture2D(map,vUv);colorFromPanos=mix(colorFromPanos,colorFromTexture,modelAlpha);float whiteness=1.0-smoothstep(0.1,0.2,opacity);colorFromPanos=mix(colorFromPanos,GREY,whiteness);gl_FragColor=vec4(colorFromPanos.rgb,opacity);}" */ vertexShader: "\n\n uniform vec3 pano0Position;\n uniform mat4 pano0Matrix;\n \n uniform vec3 pano1Position;\n uniform mat4 pano1Matrix;\n\n #if defined(checkDistance)\n varying vec3 world_Position; \n #endif\n\n varying vec2 vUv;\n varying vec3 vWorldPosition0;\n varying vec3 vWorldPosition1;\n #ifdef HasClip\n //\u88C1\u526A\u6A21\u5757\n varying vec3 vPos;\n #endif\n \n void main() {\n \n vUv = uv;\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n \n #if defined(checkDistance)\n world_Position = worldPosition.xyz; \n #endif\n \n vec3 positionLocalToPanoCenter0 = worldPosition.xyz - pano0Position;\n vWorldPosition0 = (vec4(positionLocalToPanoCenter0, 1.0) * pano0Matrix).xyz;\n vWorldPosition0.x *= -1.0;\n \n vec3 positionLocalToPanoCenter1 = worldPosition.xyz - pano1Position;\n vWorldPosition1 = (vec4(positionLocalToPanoCenter1, 1.0) * pano1Matrix).xyz;\n vWorldPosition1.x *= -1.0;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n #ifdef HasClip\n vPos = position;\n #endif\n }\n\n ", fragmentShader: "\n #ifdef HasPaint" + modelPaint.fragmentShader.Common + "\n #endif\n\n #define PI 3.141592653 \n\n // #define Not_Cube_0 1\n // #define Not_Cube_1 1\n \n const vec4 BLACK=vec4(0.0,0.0,0.0,1.0);\n const vec4 GREY2=vec4(0.5,0.5,0.5,1.0); \n const vec4 GREY=vec4(0.23,0.23,0.23,1.0); //cadImg greyArea to cover model\n \n uniform sampler2D map;\n uniform float modelAlpha;\n uniform float opacity;\n uniform float progress;\n uniform int blackout;\n uniform vec3 pano0Position;\n uniform vec3 pano1Position;\n uniform float maxDistance;\n uniform float minDistance;\n uniform float minOpa;\n uniform int bFlag;\n uniform vec3 baseColor;\n \n uniform sampler2D paint1Map;\n uniform sampler2D paint0Map;\n uniform int iShowBrush;\n\n uniform vec3 filterBase0;\n uniform float filterTemperature0;\n uniform vec3 filterBase1;\n uniform float filterTemperature1;\n \n #if defined(HasVideo)\n uniform int videoReady;\n uniform sampler2D videoTexture;\n uniform float exposure;\n uniform mat4 parameters;\n uniform float blendFov;\n #endif\n #ifdef HasClip\n //\u88C1\u526A\u6A21\u5757\n varying vec3 vPos;\n uniform vec3 clipBoxPoints[40]; \n //4\u4E2Avec3\u4E3A\u4E00\u7EC4(\u4E00\u4E2A\u7ACB\u65B9\u4F53)\n uniform int clipBoxType[10];\n //\u5224\u65AD\u88C1\u526A\u7C7B\u578B\u5E76\u8BB0\u5F55\u6709\u6548\u6570\u636E 0\u4E3AclipInside 1\u4E3AclipOutSide -1\u4E3A\u65E0\u6548\u6570\u636E\n #endif\n \n //split Not_Cube defines\n #if defined(Not_Cube_0) \n uniform sampler2D pano0Map;\n #else\n uniform samplerCube pano0Map;\n #endif\n \n #if defined(Not_Cube_1) \n uniform sampler2D pano1Map;\n #else\n uniform samplerCube pano1Map;\n #endif\n \n \n \n \n \n #if defined(RepeatUV) \n uniform sampler2D repeatInfoMap;\n #endif\n \n \n varying vec2 vUv;\n varying vec3 vWorldPosition0;\n varying vec3 vWorldPosition1;\n\n #if defined(checkDistance)\n varying vec3 world_Position; \n #endif\n\n \n uniform vec4 clipRect;\n \n\n float linearStep( float start, float end, float value ) {\n\n return clamp( (value - start) / (end - start), 0.0, 1.0 );\n }\n\n vec2 getSamplerCoord( vec3 direction ) \n {\n direction = normalize(direction);\n float tx=atan(direction.x,direction.z)/(PI*2.0)+0.5; //\u7ECF\u5EA6\u89D2\u5EA6\n float ty=acos(direction.y)/PI; //\u7EAC\u5EA6\u89D2\u5EA6\n\n return vec2(tx,ty);\n }\n\n // \u4ECELinearEncoding\u8F6C\u5230sRGBEncoding\n // \u53C2\u8003\uFF1Ahttps://www.zhangxinxu.com/wordpress/2017/12/linear-rgb-srgb-js-convert/\n vec3 linearToSrgb(vec3 col){\n return mix(col*12.92, 1.055 * pow(col, vec3(0.41667)) - 0.055, step(0.0031308, col));\n }\n #ifdef HasClip\n float inBox(vec3 P, vec3 C, vec3 G, vec3 O, vec3 A){\n return step(0.0,(sign(dot(O-A, P-A)) \n +sign(dot(A-O, P-O)) \n +sign(dot(P-O, C-O)) \n +sign(dot(O-C, P-C)) \n +sign(dot(G-O, P-O)) \n +sign(dot(P-G, O-G))\n - 5.0));\n }\n #endif\n \n #if defined(HasVideo)\n\n #if (HasVideo == 8)\n \n float f42( float phi_undistorted )\n {\n return - 0.0497*phi_undistorted*phi_undistorted*phi_undistorted*phi_undistorted*phi_undistorted\n + 0.2548*phi_undistorted*phi_undistorted*phi_undistorted*phi_undistorted\n - 0.4303*phi_undistorted*phi_undistorted*phi_undistorted\n - 0.016 *phi_undistorted*phi_undistorted \n + 1.0068*phi_undistorted - 0.0004;\t\t \n }\n\n vec2 uv2CameraCoord( vec2 uv) \n {\n vec2 coor;\n coor.x = (uv.x* parameters[0][0] - parameters[0][3]) / parameters[2][3];\n coor.y = (uv.y* parameters[1][0] - parameters[1][3]) / parameters[3][3];\n return coor;\n }\n \n vec4 f44(sampler2D texture, vec2 dc)\n {\n \n float vm = parameters[0][0];\n float vb = parameters[1][0];\n float vy = parameters[2][0];\n float oh = parameters[3][0];\n\n float wa = parameters[0][1];\n float qa = parameters[1][1];\n float cx = parameters[2][1];\n float cy = parameters[3][1];\n \n float tx = parameters[0][2];\n float ty = parameters[1][2];\n float tz = parameters[2][2];\n \n\n \n float focal_final = wa * 1000.0 / qa;\n \n float ptIn_x = dc.x * vy;\n float ptIn_y = (1.0 - dc.y) * oh;\n \n float ptOut_x, ptOut_y;\n \n float size = vy > oh ? vy : oh;\n \n float camx, camy;\n \n camx = (ptIn_x - vy / 2.0) / size;\n camy = (ptIn_y - oh / 2.0) / size;\n \n float lon, lat;\n \n lon = camx * 2.0 * 3.1415926;\n lat = camy * 2.0 * 3.1415926;\n \n float zq, zw, zr;\n \n zq = 0.33 * tx + cos(lat) * sin(lon);\n zw = 0.33 * ty - sin(lat);\n zr = 0.33 * tz + cos(lat) * cos(lon); \n \n \n float theta = atan(-zw, zq);\n \n float al = atan( sqrt(zq * zq + zw * zw), zr);\n \n float x12, x13;\n \n float wea = f42(al);\n float r = focal_final * tan(wea);\n \n x12 = cx + r * cos(theta);\n x13 = cy - r * sin(theta);\n \n ptOut_x = x13 / vm;\n ptOut_y = x12 / vb;\n \n \n vec2 samplerCoord = vec2(ptOut_x, ptOut_y);\n\n #if VideoMapping == 1\n samplerCoord = uv2CameraCoord(samplerCoord);\n #endif\n\n vec2 samplerCoord_final;\n\n if(bFlag==0)\n {\n samplerCoord_final.x = samplerCoord.y;\n samplerCoord_final.y = 1.0 - samplerCoord.x;\n }\n else\n {\n samplerCoord_final.x = samplerCoord.x;\n samplerCoord_final.y = samplerCoord.y; \n }\n \n // \u7403\u5E55\u89C6\u9891\u7FFB\u8F6C\n return texture2D(texture, samplerCoord_final);\n // return texture2D(texture, samplerCoord);\n \n }\n\n float smoothRect( vec4 clipRect, vec2 mixWidth, vec2 uv )\n {\n float x = clipRect.x < clipRect.z ? \n \n step( clipRect.x, uv.x ) * linearStep( clipRect.x, clipRect.x + mixWidth.x, uv.x ) *\n step( uv.x, clipRect.z ) * linearStep( clipRect.z, clipRect.z - mixWidth.x, uv.x ):\n \n step( clipRect.x, uv.x ) * step( uv.x, 1.0 ) * linearStep( clipRect.x, clipRect.x + mixWidth.x, uv.x ) + \n step( 0.0, uv.x ) * step( uv.x, clipRect.z ) * linearStep( clipRect.z, clipRect.z - mixWidth.x, uv.x );\n \n \n float y = step( clipRect.y, uv.y ) * linearStep( clipRect.y, clipRect.y + mixWidth.y, uv.y ) // from\n * step( uv.y, clipRect.w ) * linearStep( clipRect.w, clipRect.w - mixWidth.y, uv.y ); // to \n \n \n return x * y;\n }\n \n vec3 satEnhance( vec3 inputColor, float sat )\n {\n float R = inputColor.r * 255.0;\n float G = inputColor.g * 255.0;\n float B = inputColor.b * 255.0;\n \n float Y = 0.257 * R + 0.564 * G + 0.098 * B + 16.0;\n float Cb = -0.148 * R - 0.291 * G + 0.439 * B + 128.0;\n float Cr = 0.439 * R - 0.368 * G - 0.071 * B + 128.0;\n\n Cr = sat * (Cr - 128.0) + 128.0;\n Cb = sat * (Cb - 128.0) + 128.0; \n \n float newB = 1.164*(Y-16.0)+2.017*(Cb-128.0);\n float newR = 1.164*(Y-16.0)+1.596*(Cr-128.0);\n float newG = 1.164*(Y-16.0)-0.392*(Cb-128.0)-0.813*(Cr-128.0);\n \n newB /= 255.0;\n newR /= 255.0;\n newG /= 255.0;\n \n return vec3(newR, newG, newB); \n }\n\n\n #elif (HasVideo == 2)\n\n float f42( float phi )\n {\n return (-2.08836240e-05) * pow(phi, 9.0)\n + (-2.20461427e-04) * pow(phi, 8.0) \n + (-8.04183603e-03) * pow(phi, 7.0) \n + (3.95783387e-02) * pow(phi, 6.0)\n + (-6.51361598e-02) * pow(phi, 5.0)\n + (3.16523167e-02) * pow(phi, 4.0)\n + (-1.35220728e-02) * pow(phi, 3.0) \n + (3.86472740e-03) * pow(phi, 2.0)\n + (9.99717594e-01) * pow(phi, 1.0) \n + (3.98472625e-06) * pow(phi, 0.0);\t\t \n }\n\n vec2 uv2CameraCoord( vec2 uv) \n {\n vec2 coor;\n coor.x = (uv.x* parameters[0][0] - parameters[0][3]) / parameters[2][3];\n coor.y = (uv.y* parameters[1][0] - parameters[1][3]) / parameters[3][3];\n return coor;\n }\n \n vec4 f44(sampler2D texture, vec2 dc)\n {\n \n float iw = parameters[0][0]; //inputWidth\n float ih = parameters[1][0]; //inputHeight\n float ow = parameters[2][0]; //outputWidth\n float oh = parameters[3][0]; //outputHeight\n\n float wa = parameters[0][1]; //focal\n float qa = parameters[1][1]; //pixel\n float cx = parameters[2][1]; //cx\n float cy = parameters[3][1]; //cy\n \n float tx = parameters[0][2];\n float ty = parameters[1][2];\n float tz = parameters[2][2];\n \n\n \n float focal_final = wa * 1000.0 / qa;\n \n float ptIn_x = dc.x * ow;\n float ptIn_y = dc.y * oh;\n\n float ptOut_x, ptOut_y;\n \n float size = ow > oh ? ow : oh;\n\n float camx, camy;\n\n camx = (ptIn_x - ow / 2.0) / size;\n camy = (ptIn_y - oh / 2.0) / size;\n\n float lon, lat;\n\n lon = camx * 2.0 * 3.1415926;\n lat = -1.0 * camy * 2.0 * 3.1415926;\n\n float sphx, sphy, sphz;\n\n sphx = cos(lat) * sin(lon);\n sphy = -sin(lat);\n sphz = cos(lat) * cos(lon);\n\n float theta = atan(-sphy, sphx);\n\n float phi_undistorted = atan( sqrt(sphx * sphx + sphy * sphy), sphz);\n\n float phi_distorted = f42(phi_undistorted);\n float r = focal_final * phi_distorted;\n\n float du = cx + r * cos(theta);\n float dv = cy - r * sin(theta);\n \n ptOut_x = (du - 508.0) / 1984.0;\n ptOut_y = 1.0 - (dv - 508.0) / 1984.0;\n \n vec2 samplerCoord = vec2(ptOut_x, ptOut_y);\n \n \n return texture2D(texture, samplerCoord);\n \n }\n\n #elif (HasVideo == 3)\n \n float f42( float phi )\n {\n return (-1.47485770e-02) * pow(phi, 9.0)\n + (9.72111981e-02) * pow(phi, 8.0) \n + (-2.48315153e-01) * pow(phi, 7.0) \n + (3.20998529e-01) * pow(phi, 6.0)\n + (-2.46321067e-01) * pow(phi, 5.0)\n + (9.53838280e-02) * pow(phi, 4.0)\n + (-4.29416319e-02) * pow(phi, 3.0) \n + (1.84551397e-03) * pow(phi, 2.0)\n + (9.99948738e-01) * pow(phi, 1.0) \n + (5.00118946e-07) * pow(phi, 0.0);;\t\t \n }\n\n vec2 uv2CameraCoord( vec2 uv) \n {\n vec2 coor;\n coor.x = (uv.x* parameters[0][0] - parameters[0][3]) / parameters[2][3];\n coor.y = (uv.y* parameters[1][0] - parameters[1][3]) / parameters[3][3];\n return coor;\n }\n \n vec4 f44(sampler2D texture, vec2 dc)\n {\n \n float vm = parameters[0][0];\n float vb = parameters[1][0];\n float vy = parameters[2][0];\n float oh = parameters[3][0];\n\n float wa = parameters[0][1];\n float qa = parameters[1][1];\n float cx = parameters[2][1];\n float cy = parameters[3][1];\n \n float tx = parameters[0][2];\n float ty = parameters[1][2];\n float tz = parameters[2][2];\n \n\n \n float focal_final = wa;\n \n float ptIn_x = dc.x * vy;\n float ptIn_y = (1.0 - dc.y) * oh;\n \n float ptOut_x, ptOut_y;\n \n float size = vy > oh ? vy : oh;\n \n float camx, camy;\n \n camx = (ptIn_x - vy / 2.0) / size;\n camy = (ptIn_y - oh / 2.0) / size;\n \n float lon, lat;\n \n lon = camx * 2.0 * 3.1415926;\n lat = camy * 2.0 * 3.1415926;\n \n float sphx, sphy, sphz;\n \n sphx = cos(lat) * sin(lon);\n sphy = - sin(lat);\n sphz = cos(lat) * cos(lon); \n\n\n //apply rz to video stitch\n\n float r00 = cos(tz);\n float r01 = -1.0 * sin(tz);\n float r02 = 0.0;\n\n float r10 = sin(tz);\n float r11 = cos(tz);\n float r12 = 0.0;\n\n float r20 = 0.0;\n float r21 = 0.0;\n float r22 = 1.0;\n\n float zq, zw, zr;\n\n zq = r00*sphx + r01*sphy + r02*sphz;\n zw = r10*sphx + r11*sphy + r12*sphz;\n zr = r20*sphx + r21*sphy + r22*sphz;\n\n\n float theta = atan(-zw, zq);\n \n float al = atan( sqrt(zq * zq + zw * zw), zr);\n \n float x12, x13;\n \n float wea = f42(al);\n float r = focal_final * (wea);\n \n x12 = cx + r * cos(theta);\n x13 = cy - r * sin(theta);\n \n ptOut_x = x13 / vm;\n ptOut_y = x12 / vb;\n \n \n vec2 samplerCoord = vec2(ptOut_x, ptOut_y);\n\n #if VideoMapping == 1\n samplerCoord = uv2CameraCoord(samplerCoord);\n #endif\n \n samplerCoord.x = 1.0 - samplerCoord.x;\n samplerCoord.y = 1.0 - samplerCoord.y;\n\n vec2 samplerCoord_final;\n\n if(bFlag==0)\n {\n samplerCoord_final.x = 1.0 - samplerCoord.y;\n samplerCoord_final.y = samplerCoord.x;\n }\n else\n {\n samplerCoord_final.x = samplerCoord.x;\n samplerCoord_final.y = samplerCoord.y; \n }\n\n return texture2D(texture, samplerCoord_final);\n // return texture2D(texture, samplerCoord);\n }\n\n float smoothRect( vec4 clipRect, vec2 mixWidth, vec2 uv )\n {\n float x = clipRect.x < clipRect.z ? \n \n step( clipRect.x, uv.x ) * linearStep( clipRect.x, clipRect.x + mixWidth.x, uv.x ) *\n step( uv.x, clipRect.z ) * linearStep( clipRect.z, clipRect.z - mixWidth.x, uv.x ):\n \n step( clipRect.x, uv.x ) * step( uv.x, 1.0 ) * linearStep( clipRect.x, clipRect.x + mixWidth.x, uv.x ) + \n step( 0.0, uv.x ) * step( uv.x, clipRect.z ) * linearStep( clipRect.z, clipRect.z - mixWidth.x, uv.x );\n \n \n float y = step( clipRect.y, uv.y ) * linearStep( clipRect.y, clipRect.y + mixWidth.y, uv.y ) // from\n * step( uv.y, clipRect.w ) * linearStep( clipRect.w, clipRect.w - mixWidth.y, uv.y ); // to \n \n \n return x * y;\n }\n\n vec3 satEnhance( vec3 inputColor, float sat )\n {\n float R = inputColor.r * 255.0;\n float G = inputColor.g * 255.0;\n float B = inputColor.b * 255.0;\n \n float Y = 0.257 * R + 0.564 * G + 0.098 * B + 16.0;\n float Cb = -0.148 * R - 0.291 * G + 0.439 * B + 128.0;\n float Cr = 0.439 * R - 0.368 * G - 0.071 * B + 128.0;\n\n Cr = sat * (Cr - 128.0) + 128.0;\n Cb = sat * (Cb - 128.0) + 128.0; \n \n float newB = 1.164*(Y-16.0)+2.017*(Cb-128.0);\n float newR = 1.164*(Y-16.0)+1.596*(Cr-128.0);\n float newG = 1.164*(Y-16.0)-0.392*(Cb-128.0)-0.813*(Cr-128.0);\n \n newB /= 255.0;\n newR /= 255.0;\n newG /= 255.0;\n \n return vec3(newR, newG, newB); \n }\n\n vec3 conAdjust( vec3 inputColor, float alpha )\n {\n float R = inputColor.r * 255.0;\n float G = inputColor.g * 255.0;\n float B = inputColor.b * 255.0;\n\n float newB = alpha * (B - 0.5) + 0.5;\n float newG = alpha * (G - 0.5) + 0.5;\n float newR = alpha * (R - 0.5) + 0.5;\n\n newB /= 255.0;\n newR /= 255.0;\n newG /= 255.0;\n\n return vec3(newR, newG, newB); \n }\n\n\n #endif\n\n \n\n #endif\n\n\n #if defined(RepeatUV) \n float getUV(float num, float cellSize, float mul){ \n float index = floor(num / cellSize); //\u7B2Cindex\u9694\u95F4\n float start = index * cellSize; //\u533A\u95F4\u8D77\u59CB\n float delta = num - start; //\u76F8\u6BD4\u8D77\u59CB\u7684\u589E\u91CF\n float delta_mul = delta * mul; //\u653E\u5927\u540E\u7684\u589E\u91CF \n delta_mul = delta_mul - cellSize * floor(delta_mul / cellSize); //\u6C42\u4F59\u3002 \u6700\u7EC8\u9700\u8981\u7684\u589E\u52A0\u91CF\uFF0C\u4F46\u662F\u4E0D\u80FD\u8D85\u8FC7\u8BE5\u533A\u95F4\uFF0C\u6240\u4EE5\u591A\u51FA\u6765\u7684\u8981\u7F29\u51CF\uFF0Crepeat\n \n return start + delta_mul;\n }\n float round(float num){\n float intPart = floor(num);\n if(num - intPart < 0.5)return intPart;\n else return intPart+1.0;\n } \n #endif\n\n ////////////////////////////////////////////////////////////////\n // \u4F7F\u7528HasPaint\u3001hasFilter\u7684\u539F\u56E0\uFF1A\u51CF\u5C11\u9700\u8981\u8FD0\u884C\u7684shader\u4EE3\u7801\uFF0C\u4F18\u5316gpu\n\n // \u6D82\u62B9\n #ifdef HasPaint\n // \u5C06\u6D82\u62B9\u8D34\u56FE\u8D34\u5230\u5168\u666F\u56FE\u4E0A colorFromPano\uFF1A\u5168\u666F\u56FE\uFF0CpaintMap\uFF1A\u6D82\u62B9\u8D34\u56FE\n vec4 paint(vec4 colorFromPano, sampler2D paintMap, vec3 vWorldPosition) {\n // uv\u4FEE\u6B63\n vec2 sphereUv = getSamplerCoord(vWorldPosition.xyz);\n sphereUv.y = 1. - sphereUv.y;\n sphereUv.x -= 0.25; //\u5168\u666F\u56FE\u548CCube\u7684\u6C34\u5E73\u91C7\u6837\u8D77\u59CB\u5750\u6807\u76F8\u5DEE90\u5EA6\uFF0C\u8FD9\u91CC\u77EB\u6B63 0.25 \u4E2A\u91C7\u6837\u504F\u79FB\n if(sphereUv.x < 0.) sphereUv.x += 1.;\n \n vec4 colBuffer = texture2D(paintMap, sphereUv);\n\n return vec4(colBuffer.rgb * colBuffer.a + colorFromPano.rgb * (1. - colBuffer.a), 1.);\n }\n #endif\n\n ////////////////////////////////////////////////////////////////\n // \u6EE4\u955C\uFF08\u7B97\u6CD5\u6765\u81EAshadertoy\uFF09\n #ifdef hasFilter\n // \u8C03\u6574\u4EAE\u5EA6[-1, 1]\n vec4 colorBrightness(vec4 color, float brightness) {\n brightness = clamp(brightness, -1., 1.);\n if(brightness < 0.) brightness = brightness/2.;\n return color * (brightness + 1.);\n }\n\n // \u8C03\u6574\u5BF9\u6BD4\u5EA6[-1, 1]\n vec4 colorContrast(vec4 color, float contrast) {\n contrast = clamp(contrast, -1., 1.);\n // return mix(color, vec4(1.0) / (vec4(1.0) + exp(-(color * 10.0 - 5.0))), -contrast);\n return mix(color, smoothstep(0.0, 1.0, color), contrast);\n }\n\n // \u8C03\u6574\u9971\u548C\u5EA6[-1, 1]\n vec4 colorSaturation(vec4 color, float saturation) {\n saturation = clamp(saturation, -1., 1.);\n vec3 weights = vec3(0.2125, 0.7154, 0.0721);\n float luminance = dot(color.rgb, weights);\n return mix(vec4(luminance), color, saturation + 1.);\n }\n\n vec3 colorTemperatureToRGB(const in float temperature){\n mat3 m = (temperature <= 6500.0) ? \n mat3(vec3(0.0, -2902.1955373783176, -8257.7997278925690),\n vec3(0.0, 1669.5803561666639, 2575.2827530017594),\n vec3(1.0, 1.3302673723350029, 1.8993753891711275)) : \n mat3(vec3(1745.0425298314172, 1216.6168361476490, -8257.7997278925690),\n vec3(-2666.3474220535695, -2173.1012343082230, 2575.2827530017594),\n vec3(0.55995389139931482, 0.70381203140554553, 1.8993753891711275)); \n return mix(clamp(vec3(m[0] / (vec3(clamp(temperature, 4000.0, 9000.0)) + m[1]) + m[2]), vec3(0.0), vec3(1.0)), vec3(1.0), smoothstep(4000.0, 0.0, temperature));\n }\n // \u8C03\u6574\u8272\u6E29[-1, 1]\n vec4 colorTemperature(vec4 color, float temperature) {\n temperature = clamp(temperature, -1., 1.);\n const float LuminancePreservationFactor = 1.0;\n float temperatureFactor;\n float temperatureStrength;\n if(temperature > 0.) {\n temperatureFactor = 4000.0;\n temperatureStrength = mix(0., 1.5, abs(temperature));\n } else {\n temperatureFactor = 9000.0;\n temperatureStrength = mix(0., 2.3, abs(temperature));\n }\n vec3 inColor = color.rgb;\n vec3 outColor = mix(inColor, inColor * colorTemperatureToRGB(temperatureFactor), temperatureStrength); \n // WithQuickAndDirtyLuminancePreservation\n outColor *= mix(1.0, dot(inColor, vec3(0.2126, 0.7152, 0.0722)) / max(dot(outColor, vec3(0.2126, 0.7152, 0.0722)), 1e-5), LuminancePreservationFactor); \n return vec4(outColor, color.a);\n }\n\n // \u628A\u6EE4\u955C\u6548\u679C\u878D\u5165\u5168\u666F\u56FE colorFromPano\uFF1A\u5168\u666F\u56FE\uFF0CfilterBase\uFF1A\u4EAE\u5EA6\uFF08x\uFF09\u3001\u5BF9\u6BD4\u5EA6\uFF08y\uFF09\u3001\u9971\u548C\u5EA6\uFF08z\uFF09\uFF0CfilterTemperature\uFF1A\u8272\u6E29\n vec4 filter(vec4 colorFromPano, vec3 filterBase, float filterTemperature) {\n colorFromPano = colorBrightness(colorFromPano, filterBase.x);\n colorFromPano = colorContrast(colorFromPano, filterBase.y);\n colorFromPano = colorSaturation(colorFromPano, filterBase.z);\n colorFromPano = colorTemperature(colorFromPano, filterTemperature);\n return colorFromPano;\n }\n #endif\n\n\n \n \n void main()\n {\n #ifdef HasClip\n float isClip = 0.0; \n //isClip\u7528\u4E8E\u6807\u8BB0\u662F\u5426\u9700\u8981\u88C1\u526A, >0 \u5C06\u4F1A\u88ABdiscard\n #pragma unroll_loop_start\n for(int i = 0; i < 10; i++) {\n if(clipBoxType[i] == -1) {\n } else if (clipBoxType[i] == 0) {\n if (inBox(vPos, clipBoxPoints[UNROLLED_LOOP_INDEX*4], clipBoxPoints[UNROLLED_LOOP_INDEX*4+1], clipBoxPoints[UNROLLED_LOOP_INDEX*4+2], clipBoxPoints[UNROLLED_LOOP_INDEX*4+3]) == 1.0) {\n isClip = 2.0;\n }\n } else if (clipBoxType[i] == 1) {\n if(isClip != 2.0) isClip != -1.0 && inBox(vPos, clipBoxPoints[UNROLLED_LOOP_INDEX*4], clipBoxPoints[UNROLLED_LOOP_INDEX*4+1], clipBoxPoints[UNROLLED_LOOP_INDEX*4+2], clipBoxPoints[UNROLLED_LOOP_INDEX*4+3]) == 0.0 ? isClip = 1.0 : isClip = -1.0;\n }\n }\n #pragma unroll_loop_end\n if(isClip > 0.0) discard;\n #endif\n \n vec4 colorFromPano0 = vec4(0.0,0.0,0.0,0.0);\n #if defined(usePanoMap0)\n //\u5373progress < 1.0 \u901A\u5E38\u662F1 \n #if (defined(Not_Cube_0) || defined(HasVideo)) \n vec2 samplerCoord0 = getSamplerCoord(vWorldPosition0.xyz); \n #endif \n \n \n #if defined(Not_Cube_0)\n colorFromPano0=texture2D(pano0Map,samplerCoord0); \n #else\n colorFromPano0=textureCube(pano0Map,vWorldPosition0.xyz); \n #endif\n #endif \n \n \n #if (defined(Not_Cube_1) || defined(HasVideo)) \n vec2 samplerCoord1 = getSamplerCoord(vWorldPosition1.xyz); \n #endif \n \n\n #ifdef BasePanoMap\n //\u666E\u901A\u8D34\u56FE\u5F53\u505A\u5168\u666F\u56FE\n vec4 colorFromPano1 = texture2D(map, vUv);\n #ifdef HasVideo\n samplerCoord1.x -= 0.25; \n #endif\n #else \n #if defined(Not_Cube_1)\n vec4 colorFromPano1=texture2D(pano1Map,samplerCoord1); \n #else\n vec4 colorFromPano1=textureCube(pano1Map,vWorldPosition1.xyz); \n #ifdef HasVideo\n samplerCoord1.x -= 0.25; //\u5168\u666F\u56FE\u548CCube\u7684\u6C34\u5E73\u91C7\u6837\u8D77\u59CB\u5750\u6807\u76F8\u5DEE90\u5EA6\uFF0C\u8FD9\u91CC\u77EB\u6B63 0.25 \u4E2A\u91C7\u6837\u504F\u79FB\n #endif\n #endif\n #endif\n\n\n #ifdef HasPaint\n // \u6D82\u62B9\u56FE\u5C42\uFF08\u76EE\u524D\u6D82\u62B9\u56FE\u5C42\u8981\u5148\u4E8E\u7403\u5E55\u89C6\u9891\u56FE\u5C42\u6267\u884C\uFF0C\u6240\u4EE5\u4F1A\u88AB\u7403\u5E55\u89C6\u9891\u6321\u4F4F\uFF09\n colorFromPano0 = paint(colorFromPano0, paint0Map, vWorldPosition0);\n colorFromPano1 = paint(colorFromPano1, paint1Map, vWorldPosition1);\n #endif\n\n \n // \u7403\u5E55\u89C6\u9891\n #if defined(HasVideo)\n\n vec4 colorFromVideo = vec4(0.0,0.0,0.0,0.0);\n \n #if HasVideo == 8\n\n colorFromVideo = f44(videoTexture, samplerCoord1);\n colorFromVideo.rgb *= exposure;\n\n vec2 transitionSize = 80.0 / vec2( 4096.0, 2048.0 );\n\n \n #if VideoMapping == 0\n float alpha = linearStep(0.3, 0.33, samplerCoord1.x) * 1.0 - linearStep(0.66, 0.7, samplerCoord1.x);\n colorFromPano1 = mix(colorFromPano1, colorFromVideo, alpha * float(videoReady));\n #elif VideoMapping == 1\n\n \n float rect = smoothRect( vec4(\n 0.4166, 0.2833,\n 0.5833, 0.7133\n ), vec2( blendFov / 360.0, blendFov / 180.0 ), samplerCoord1 );\n\n colorFromPano1 = mix(colorFromPano1, colorFromVideo, rect * float(videoReady) * max(0.0,progress*2.0-1.0));\n \n #elif VideoMapping == 2\n\n samplerCoord1 = fract(samplerCoord1);\n\n vec2 clipUV = vec2(\n clipRect.x < clipRect.z ? linearStep( clipRect.x, clipRect.z, samplerCoord1.x ) : linearStep( clipRect.x, clipRect.z + 1.0, samplerCoord1.x < clipRect.z ? samplerCoord1.x + 1.0 : samplerCoord1.x ),\n linearStep( clipRect.y, clipRect.w, samplerCoord1.y )\n );\n clipUV.y = 1.0- clipUV.y;\n\n colorFromVideo = texture2D( videoTexture, clipUV );\n float rect = smoothRect( clipRect, vec2(0.02,0.02), samplerCoord1 );\n\n \n colorFromPano1 = mix( colorFromPano1, colorFromVideo, rect * float(videoReady) * max(0.0,progress*2.0-1.0) );\n\n #endif\n\n #elif HasVideo == 2\n\n colorFromVideo = f44(videoTexture, samplerCoord1);\n float alphaX = linearStep( 0.31, 0.33, samplerCoord1.x) * 1.0 - linearStep(0.65, 0.67, samplerCoord1.x);\n float alphaY = linearStep( 0.15, 0.17, 1.0 - samplerCoord1.y) * 1.0 - linearStep(0.82, 0.84, 1.0 - samplerCoord1.y);\n colorFromPano1 = mix(colorFromPano1, colorFromVideo, alphaX * alphaY * float(videoReady) * max(0.0,progress*2.0-1.0));\t\n\n #elif HasVideo == 3\n\n float cx = parameters[2][1]; //cx\n float cy = parameters[3][1]; //cy\n\n float diffx = (cx - 1824.0) / 16416.0;\n float diffy = (cy - 2736.0) / 7576.0;\n\n colorFromVideo = f44(videoTexture, samplerCoord1);\n colorFromVideo.rgb *= exposure;\n \n\n vec2 transitionSize = 80.0 / vec2( 4096.0, 2048.0 );\n\n \n #if VideoMapping == 0\n float alpha = linearStep(0.3, 0.33, samplerCoord1.x) * 1.0 - linearStep(0.66, 0.7, samplerCoord1.x);\n colorFromPano1 = mix(colorFromPano1, colorFromVideo, alpha * float(videoReady));\n #elif VideoMapping == 1\n \n float rect = smoothRect( vec4(\n 0.4277-diffx, 0.28-diffy,\n 0.572-diffx, 0.72-diffy\n ), vec2( blendFov / 360.0, blendFov / 180.0 ), samplerCoord1 );\n\n colorFromPano1 = mix(colorFromPano1, colorFromVideo, rect * float(videoReady) * max(0.0,progress*2.0-1.0));\n \n #elif VideoMapping == 2\n\n samplerCoord1 = fract(samplerCoord1);\n\n vec2 clipUV = vec2(\n clipRect.x < clipRect.z ? linearStep( clipRect.x, clipRect.z, samplerCoord1.x ) : linearStep( clipRect.x, clipRect.z + 1.0, samplerCoord1.x < clipRect.z ? samplerCoord1.x + 1.0 : samplerCoord1.x ),\n linearStep( clipRect.y, clipRect.w, samplerCoord1.y )\n );\n clipUV.y = 1.0- clipUV.y;\n\n colorFromVideo = texture2D( videoTexture, clipUV );\n\n \n float rect = smoothRect( clipRect, vec2(0.02,0.02), samplerCoord1 );\n\n \n colorFromPano1 = mix( colorFromPano1, colorFromVideo, rect * float(videoReady) * max(0.0,progress*2.0-1.0) );\n\n #endif\n\n #endif\n\n #endif\n\n\n #ifdef hasFilter\n // \u6EE4\u955C\n colorFromPano0 = filter(colorFromPano0, filterBase0, filterTemperature0);\n colorFromPano1 = filter(colorFromPano1, filterBase1, filterTemperature1);\n #endif\n\n\n\n\n // \u5408\u5E76colorFromPano0\u548CcolorFromPano1\n vec4 color; \n \n if(blackout==0)\n { \n #if defined(usePanoMap0) \n color=mix(colorFromPano0,colorFromPano1,progress);\n #else\n color = colorFromPano1;\n #endif \n \n }\n else if(blackout==1)\n {\n color=mix(colorFromPano0,BLACK,min(1.0,progress*2.0));\n color=mix(color,colorFromPano1,max(0.0,progress*2.0-1.0));\n }\n else if(blackout==2)\n {\n color=mix(colorFromPano0,BLACK,progress);\n }\n else if(blackout==3)\n {\n color=mix(BLACK,colorFromPano1,max(0.0,progress*2.0-1.0));\n }\n \n \n \n vec2 uv = vUv;\n \n #if defined(RepeatUV) \n \n vec4 infoColor = texture2D(repeatInfoMap, vUv); \n float mul = round(infoColor.r * 255.0 / 5.0) + round(infoColor.g * 255.0 / 5.0) / 10.0; \n \n if(mul>0.0 && mul != 1.0){\n float cellCount = 8.0; \n \n float cellSize = 1.0 / cellCount;\n float dir = round(infoColor.b * 255.0 / 5.0);\n if (dir == 0.0) {\n uv.x = getUV(uv.x, cellSize, mul) ;\n }else if (dir == 1.0) {\n uv.y = getUV(uv.y, cellSize, mul) ; \n }else{\n uv.x = getUV(uv.x, cellSize, mul) ;\n uv.y = getUV(uv.y, cellSize, mul) ;\n } \n }\n \n #endif\n \n \n #if defined(useModelMap) \n // \u5408\u5E76color\u548CmodelColor\n vec4 colorFromTexture = texture2D(map,uv);\n #ifdef Is3dTiles\n // 3dtiles\u8D34\u56FE\u9700\u8981\u7528linearToSrgb\u8F6C\u5230Srgb\u8272\u5F69\u7A7A\u95F4\n colorFromTexture = vec4(linearToSrgb(colorFromTexture.rgb), colorFromTexture.a);\n #endif\n color = mix(color, colorFromTexture, modelAlpha); \n #endif\n\n\n\n float whiteness = 1.0-smoothstep(0.1, 1.0, opacity); \n color = mix(color, GREY, whiteness ); \n \n float opa = opacity;\n #if defined(checkDistance)\n vec3 cameraPos = mix(pano0Position, pano1Position, progress);\n float dis = distance(cameraPos, world_Position);\n float disOpa=minOpa;\n if(dis < minDistance)\n {\n disOpa=1.0;\n }\n else if(dis 0.) {\n color = vec4(brushBuffer.rgb * brushBuffer.a + color.rgb * (1. - brushBuffer.a), 1.);\n } \n }\n #endif\n \n\n\n\n gl_FragColor = vec4(color.rgb * baseColor, opa);\n \n \n \n }\n ", fragmentBufferShader: modelPaint.fragmentShader.Common + modelPaint.fragmentShader.Buffer }; /* * @Author: Rindy * @Date: 2021-05-07 16:01:31 * @LastEditors: Rindy * @LastEditTime: 2021-05-12 15:35:42 * @Description: 注释 */ var modelDebug = { uniforms: { map: { type: 't', value: null }, modelAlpha: { type: 'f', value: settings$3.modelAlpha }, depthmapRatio: { type: 'f', value: 0 }, opacity: { type: 'f', value: 1 }, progress: { type: 'f', value: 0 }, considerOcclusion: { type: 'i', value: settings$3.fancierTransition }, highlightPanoSelection: { type: 'i', value: 0 }, useThirdPano: { type: 'i', value: settings$3.useThirdPano }, pano0Map: { type: 't', value: null }, pano0Depth: { type: 't', value: null }, pano0Position: { type: 'v3', value: new THREE.Vector3() }, pano0Matrix: { type: 'm4', value: new THREE.Matrix4() }, pano0Weight: { type: 'f', value: settings$3.transition.pano0Weight }, pano1Map: { type: 't', value: null }, pano1Depth: { type: 't', value: null }, pano1Position: { type: 'v3', value: new THREE.Vector3() }, pano1Matrix: { type: 'm4', value: new THREE.Matrix4() }, pano1Weight: { type: 'f', value: settings$3.transition.pano1Weight }, pano2Map: { type: 't', value: null }, pano2Depth: { type: 't', value: null }, pano2Position: { type: 'v3', value: new THREE.Vector3() }, pano2Matrix: { type: 'm4', value: new THREE.Matrix4() }, pano2Weight: { type: 'f', value: settings$3.transition.pano2Weight } }, vertexShader: 'uniform vec3 pano0Position;\nuniform mat4 pano0Matrix;\n\nuniform vec3 pano1Position;\nuniform mat4 pano1Matrix;\n\nuniform vec3 pano2Position;\nuniform mat4 pano2Matrix;\n\nvarying vec2 vUv;\nvarying vec3 vWorldPosition0;\nvarying vec3 vWorldPosition1;\nvarying vec3 vWorldPosition2;\n\nvarying vec4 worldPosition;\n\nvoid main() {\n\n vUv = uv;\n worldPosition = modelMatrix * vec4(position, 1.0);\n\n vec3 positionLocalToPanoCenter0 = worldPosition.xyz - pano0Position;\n vWorldPosition0 = (vec4(positionLocalToPanoCenter0, 1.0) * pano0Matrix).xyz;\n vWorldPosition0.x *= -1.0;\n\n vec3 positionLocalToPanoCenter1 = worldPosition.xyz - pano1Position;\n vWorldPosition1 = (vec4(positionLocalToPanoCenter1, 1.0) * pano1Matrix).xyz;\n vWorldPosition1.x *= -1.0;\n\n vec3 positionLocalToPanoCenter2 = worldPosition.xyz - pano2Position;\n vWorldPosition2 = (vec4(positionLocalToPanoCenter2, 2.0) * pano2Matrix).xyz;\n vWorldPosition2.x *= -1.0;\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n}\n', fragmentShader: 'uniform sampler2D map;\nuniform float depthmapRatio;\nuniform float modelAlpha;\nuniform float opacity;\nuniform float progress;\nuniform int considerOcclusion;\nuniform int highlightPanoSelection;\nuniform int useThirdPano;\n\nuniform vec3 pano0Position;\nuniform samplerCube pano0Map;\nuniform samplerCube pano0Depth;\nuniform float pano0Weight;\n\nuniform vec3 pano1Position;\nuniform samplerCube pano1Map;\nuniform samplerCube pano1Depth;\nuniform float pano1Weight;\n\nuniform vec3 pano2Position;\nuniform samplerCube pano2Map;\nuniform samplerCube pano2Depth;\nuniform float pano2Weight;\n\nvarying vec2 vUv;\nvarying vec3 vWorldPosition0;\nvarying vec3 vWorldPosition1;\nvarying vec3 vWorldPosition2;\n\nvarying vec4 worldPosition;\n\nvoid main() {\n\n vec4 depthFromPano0 = textureCube( pano0Depth, vWorldPosition0.xyz );\n vec4 depthFromPano1 = textureCube( pano1Depth, vWorldPosition1.xyz );\n vec4 depthFromPano2 = textureCube( pano2Depth, vWorldPosition2.xyz );\n\n vec4 colorFromPano0 = textureCube( pano0Map, vWorldPosition0.xyz );\n vec4 colorFromPano1 = textureCube( pano1Map, vWorldPosition1.xyz );\n vec4 colorFromPano2 = textureCube( pano2Map, vWorldPosition2.xyz );\n\n float distanceToPano0 = distance(worldPosition.xyz, pano0Position);\n float distanceToPano1 = distance(worldPosition.xyz, pano1Position);\n float distanceToPano2 = distance(worldPosition.xyz, pano2Position);\n\n float cameraToPano0 = distance(cameraPosition.xyz, pano0Position);\n float cameraToPano1 = distance(cameraPosition.xyz, pano1Position);\n float cameraToPano2 = distance(cameraPosition.xyz, pano2Position);\n\n float contributionFromPano0 = cameraToPano0 == 0.0 ? 1000.0 : pano0Weight / cameraToPano0;\n float contributionFromPano1 = cameraToPano1 == 0.0 ? 1000.0 : pano1Weight / cameraToPano1;\n float contributionFromPano2 = cameraToPano2 == 0.0 ? 1000.0 : pano2Weight / cameraToPano2;\n\n contributionFromPano0 *= 1.0 / distanceToPano0;\n contributionFromPano1 *= 1.0 / distanceToPano1;\n contributionFromPano2 *= 1.0 / distanceToPano2;\n\n if(considerOcclusion == 1) {\n bool occludedFromPano0 = distanceToPano0 / 10.0 > 1.01 - depthFromPano0.x;\n bool occludedFromPano1 = distanceToPano1 / 10.0 > 1.01 - depthFromPano1.x;\n bool occludedFromPano2 = distanceToPano2 / 10.0 > 1.01 - depthFromPano2.x;\n\n if(occludedFromPano0){contributionFromPano0 *= 0.1;}\n if(occludedFromPano1){contributionFromPano1 *= 0.1;}\n if(occludedFromPano2){contributionFromPano2 *= 0.1;}\n //if(occludedFromPano0 && occludedFromPano1 && !occludedFromPano2) { contributionFromPano2 += 0.5; }\n }\n\n float contributionSum = contributionFromPano0 + contributionFromPano1 + contributionFromPano2;\n contributionFromPano0 /= contributionSum;\n contributionFromPano1 /= contributionSum;\n contributionFromPano2 /= contributionSum;\n\n vec4 colorFromPanos = colorFromPano0 * contributionFromPano0;\n colorFromPanos += colorFromPano1 * contributionFromPano1;\n colorFromPanos += colorFromPano2 * contributionFromPano2;\n\n vec4 depthFromPanos = depthFromPano0 * contributionFromPano0;\n depthFromPanos += depthFromPano1 * contributionFromPano1;\n depthFromPanos += depthFromPano2 * contributionFromPano2;\n\n vec4 colorFromTexture = texture2D( map, vUv );\n colorFromPanos = mix(colorFromPanos, colorFromTexture, modelAlpha);\n\n if(highlightPanoSelection == 1) {\n colorFromPanos.r = contributionFromPano0;\n colorFromPanos.g = contributionFromPano1;\n colorFromPanos.b = contributionFromPano2;\n }\n\n gl_FragColor = vec4(mix(colorFromPanos, depthFromPanos, depthmapRatio).rgb, opacity);\n\n}\n' }; /* * @Author: Rindy * @Date: 2021-05-07 15:52:29 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 15:59:37 * @Description: 注释 */ var modelOutside = { uniforms: { map: { type: 't', value: null }, opacity: { type: 'f', value: 1 }, brightness: { type: 'f', value: 0.23 }, mixRatio: { type: 'f', value: 0.3 }, //裁剪 clipBoxType: { type: 'a', value: null }, clipBoxPoints: { type: 'a', value: null } }, // vertexShader: 'varying vec2 vUv;\n\nvoid main() {\n\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n}\n', vertexShader: "\n varying vec2 vUv;\n #ifdef HasClip \n //\u88C1\u526A\u6A21\u5757\n varying vec3 vPos; \n #endif\n\n void main() {\n vUv = uv;\n #ifdef HasClip\n vPos = position;\n #endif\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }", fragmentShader: "\n uniform sampler2D map;\n uniform float opacity;\n varying vec2 vUv;\n uniform float brightness;\n uniform float mixRatio;\n\n #ifdef HasClip \n //\u88C1\u526A\u6A21\u5757\n varying vec3 vPos;\n uniform vec3 clipBoxPoints[40]; \n //4\u4E2Avec3\u4E3A\u4E00\u7EC4(\u4E00\u4E2A\u7ACB\u65B9\u4F53)\n uniform int clipBoxType[10];\n //\u5224\u65AD\u88C1\u526A\u7C7B\u578B\u5E76\u8BB0\u5F55\u6709\u6548\u6570\u636E 0\u4E3AclipInside 1\u4E3AclipOutSide -1\u4E3A\u65E0\u6548\u6570\u636E\n #endif\n \n \n //vec4 grey = vec4(0.23, 0.23, 0.23, 1.0); //cadImg greyArea to cover model, base color\n \n vec4 grey = vec4(brightness, brightness, brightness, 1.0); \n \n // \u4ECELinearEncoding\u8F6C\u5230sRGBEncoding\n vec3 linearToSrgb(vec3 col){\n return mix(col*12.92, 1.055 * pow(col, vec3(0.41667)) - 0.055, step(0.0031308, col));\n }\n #ifdef HasClip\n float inBox(vec3 P, vec3 C, vec3 G, vec3 O, vec3 A){\n return step(0.0,(sign(dot(O-A, P-A)) \n +sign(dot(A-O, P-O)) \n +sign(dot(P-O, C-O)) \n +sign(dot(O-C, P-C)) \n +sign(dot(G-O, P-O)) \n +sign(dot(P-G, O-G))\n - 5.0));\n }\n #endif\n \n void main() {\n vec2 uv = vUv; \n vec4 colorFromTexture = texture2D( map, uv ); \n #ifdef Is3dTiles\n // 3dtiles\u8D34\u56FE\u9700\u8981\u7528linearToSrgb\u8F6C\u5230Srgb\u8272\u5F69\u7A7A\u95F4\n colorFromTexture = vec4(linearToSrgb(colorFromTexture.rgb), colorFromTexture.a);\n #endif\n #ifdef HasClip\n float isClip = 0.0; \n //isClip\u7528\u4E8E\u6807\u8BB0\u662F\u5426\u9700\u8981\u88C1\u526A, >0 \u5C06\u4F1A\u88ABdiscard\n #pragma unroll_loop_start\n for(int i = 0; i < 10; i++) {\n if(clipBoxType[i] == -1) {\n } else if (clipBoxType[i] == 0) {\n if (inBox(vPos, clipBoxPoints[UNROLLED_LOOP_INDEX*4], clipBoxPoints[UNROLLED_LOOP_INDEX*4+1], clipBoxPoints[UNROLLED_LOOP_INDEX*4+2], clipBoxPoints[UNROLLED_LOOP_INDEX*4+3]) == 1.0) {\n isClip = 2.0;\n }\n } else if (clipBoxType[i] == 1) {\n if(isClip != 2.0) isClip != -1.0 && inBox(vPos, clipBoxPoints[UNROLLED_LOOP_INDEX*4], clipBoxPoints[UNROLLED_LOOP_INDEX*4+1], clipBoxPoints[UNROLLED_LOOP_INDEX*4+2], clipBoxPoints[UNROLLED_LOOP_INDEX*4+3]) == 0.0 ? isClip = 1.0 : isClip = -1.0;\n }\n }\n #pragma unroll_loop_end\n if(isClip > 0.0) discard;\n #endif\n colorFromTexture = mix(colorFromTexture, grey, mixRatio ); \n gl_FragColor = vec4(colorFromTexture.rgb, opacity);\n }\n " }; /* * @Author: Rindy * @Date: 2021-05-07 15:59:59 * @LastEditors: Rindy * @LastEditTime: 2021-05-12 15:36:01 * @Description: 注释 */ var ribbon = { uniforms: { map: { type: 't', value: null }, opacity: { type: 'f', value: 1 }, color: { type: 'c', value: new THREE.Color(settings$3.path.color) } }, vertexShader: 'varying vec2 vUv;\nvarying vec3 vN;\nvarying vec4 vP;\n\nvoid main() {\n\n vUv = uv;\n vN= normalMatrix * normal;\n vP = modelViewMatrix * vec4( position, 1.0 );\n gl_Position = projectionMatrix * vP;\n}\n', fragmentShader: 'uniform sampler2D map;\nuniform float opacity;\nvarying vec2 vUv;\nuniform vec3 color;\nvarying vec3 vN; // show-1182\nvarying vec4 vP; // show-1182\n\nvoid main() {\n\t// TODO add scroll-in and pulsing behaviors\n\tvec3 vNn = normalize(vN);\n\tvec3 vPn = normalize(vP.xyz);\n\tfloat f = pow(1.0-abs(dot(vNn,vPn)),0.2);\n vec4 colorFromTexture = texture2D( map, vUv );\n colorFromTexture.a *= f;\n gl_FragColor = vec4((color.rgb*colorFromTexture.rgb),\n \t\t\t\t\t\t(opacity*colorFromTexture.a));\n}\n' }; /* * @Author: Rindy * @Date: 2021-05-07 16:02:38 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 16:03:01 * @Description: 注释 */ var skysphere = { uniforms: { radius: { type: 'f', value: 0 } }, vertexShader: 'varying vec4 worldPosition;\n\nvoid main() {\n\n worldPosition = modelMatrix * vec4(position, 1.0);\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n}\n', fragmentShader: 'varying vec4 worldPosition;\nuniform float radius;\n\nvoid main() {\n\n vec4 topColor = vec4(0.094, 0.102, 0.11, 1.0);\n vec4 bottomColor = vec4(0.2, 0.216, 0.235, 1.0);\n float normalizedHeight = (worldPosition.y + radius) / (radius * 2.0);\n float ratio = smoothstep(0.0, 0.5, normalizedHeight);\n gl_FragColor = mix(bottomColor, topColor, ratio);\n\n}\n' }; /* * @Author: Rindy * @Date: 2021-05-07 16:03:13 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 16:03:51 * @Description: 注释 */ var tagDisc = { uniforms: { opacity: { type: 'f', value: 0 }, color: { type: 'c', value: new THREE.Color() }, bg: { type: 't', value: null }, mask: { type: 't', value: null } }, vertexShader: 'varying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}', fragmentShader: 'uniform float opacity;\nuniform vec3 color;\nuniform sampler2D bg;\nuniform sampler2D mask;\n\nvarying vec2 vUv;\n\nvoid main() {\n vec4 maskColor = texture2D(mask, vUv);\n vec4 bgColor = texture2D(bg, vUv);\n vec3 mappedColor = mix(bgColor.rgb, color, maskColor.a);\n gl_FragColor = vec4(mappedColor, bgColor.a * opacity);\n}\n' }; /* * @Author: Rindy * @Date: 2021-05-07 16:03:13 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 16:03:51 * @Description: 注释 */ var tagDiscDefault = { uniforms: { uTime: { value: 0 }, opacity: { value: 1 }, dark: { type: 'i', value: 0 }, openning: { type: 'f', value: 0 }, uColor: { value: new THREE.Color().setRGB(0.0, 0.7843137254901961, 0.6862745098039216) } }, vertexShader: "\n\n uniform float uTime;\n uniform float openning;\n\n varying vec2 vUv;\n \n\n vec3 scalePos( vec3 pos ) {\n\n float s = 1.0 + 0.3 * abs( sin(uTime) ) ;\n\n pos.x *= s;\n pos.y *= s;\n pos.z *= s;\n\n return pos;\n }\n\n void main() \n {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( scalePos( position ), 1.0);\n }\n\n ", fragmentShader: "\n \n uniform float uTime;\n uniform vec3 uColor;\n uniform float opacity;\n uniform int dark;\n \n varying vec2 vUv;\n \n vec4 circle( vec2 position, vec2 center, float radius )\n {\n vec4 backgroundColor = vec4( 0.0, 0.0, 0.0, 0.0 );\n\n vec4 color = mix( backgroundColor, vec4(uColor, 1.0 ), smoothstep( radius + 0.05, radius, length( position - center )) );\n \n return color;\n }\n\n\n vec4 ring( vec2 position, vec2 center, vec2 radius )\n {\n \n float len = length( position - center );\n\n float alpha = smoothstep( radius.x - 0.03, radius.x + 0.01, len) - smoothstep(radius.y - 0.03, radius.y + 0.03, len);\n\n return mix( vec4( 0.0 ), vec4( 1.0 ), alpha);\n }\n\n\n\n void main() {\n\n\n vec2 uv = vUv * 2.0 - 1.0;\n\n //uv *= (0.85 + abs( sin(uTime) * 0.5 ));\n\n \n vec4 mainColor = vec4( 0.0 );\n mainColor += circle( uv, vec2(0.0), 0.4 );\n mainColor += ring( uv, vec2(0.0), vec2(0.3, 0.35));\n\n \n float r = (uv.x * uv.x + uv.y * uv.y) * 4.0;\n \n float intensity = sin( r - uTime * 2.5 );\n float alpha = 1.0 - 0.25* r;\n\n intensity = intensity * step(r, 3.5 ) * step(1.0, r);\t\n intensity = smoothstep( 0.9, 1.0, intensity );\n\n mainColor += vec4( vec3(intensity), intensity * alpha);\n \n \n \n gl_FragColor = vec4(mainColor.rgb, mainColor.a * opacity);\n \n }\n " }; /* * @Author: Rindy * @Date: 2021-05-07 16:03:13 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 16:03:51 * @Description: 注释 */ var tagDiscCustom = { uniforms: { opacity: { type: 'f', value: 1 }, dark: { //hover时会颜色会变深 type: 'i', value: 0 }, map: { type: 't', value: null }, uTime: { value: 0 }, openning: { type: 'f', value: 0 } }, vertexShader: "\n\n uniform float openning;\n uniform float uTime;\n\n varying vec2 vUv;\n\n vec3 scalePos( vec3 pos ) {\n\n float s = cos(openning * 3.1415926*0.28) * (1.0 + 0.3 * abs( sin(uTime)) * step( openning, 0.5 ) );\n\n pos.x *= s;\n pos.y *= s;\n pos.z *= s;\n\n return pos;\n }\n\n \n \n void main() \n {\n vUv = uv;\n\n gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( scalePos(position), 1.0);\n }\n \n ", fragmentShader: "\n\n uniform float opacity;\n uniform int dark;\n uniform float uTime;\n uniform sampler2D map;\n uniform float openning;\n \n varying vec2 vUv;\n \n\n vec4 circle( vec2 position, vec2 center, float radius, vec4 color )\n {\n vec4 backgroundColor = vec4( 0.0 );\n \n float alpha = smoothstep( radius + 0.03, radius - 0.03, length( position - center ));\n\n return mix( backgroundColor, color, alpha );\n }\n\n vec4 ring( vec2 position, vec2 center, vec2 radius, vec4 color )\n {\n vec4 backgroundColor = vec4( 0.0, 0.0, 0.0, 0.0);\n \n float len = length( position - center );\n \n float alpha = smoothstep( radius.x - 0.03, radius.x + 0.03, len) - smoothstep(radius.y - 0.03, radius.y + 0.03, len);\n \n return mix( backgroundColor, color, alpha);\n }\n\n void main() {\n\n vec2 uv = vUv;\n\n vec4 color = texture2D(map, uv);\n \n if(dark == 1 && (color.r + color.g + color.b < 240.0*3.0/255.0))\n {\n color.rgb *= 0.9;\n }\n\n\n vec2 coord = uv * 2.0 - 1.0;\n vec4 opennedColor = vec4(0.0);\n\n opennedColor += circle( coord, vec2(0.0), 0.25, vec4(1.0, 1.0, 1.0, 0.5) );\n opennedColor += circle( coord, vec2(0.0), 0.5, vec4(1.0, 1.0, 1.0, 0.3) );\n\n color = mix( color, opennedColor, openning );\n \n gl_FragColor = vec4(color.rgb, color.a * opacity);\n }\n\n " }; /* * @Author: Rindy * @Date: 2021-05-07 16:03:13 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 16:03:51 * @Description: 注释 videoPano Tag的shader 视频播放按钮 */ var tagVideoMarker = { // uniforms: { // opacity: { // type: 'f', // value: 1, // }, // dark: { // //hover时会颜色会变深 // type: 'i', // value: 0, // }, // map: { // type: 't', // value: null, // }, // uTime: { // value: 0, // }, // openning: { // type: 'f', // value: 0, // }, // }, uniforms: { progress: { type: 'f', value: 0 }, bigCircleProgress: { type: 'f', value: 0 }, smallCircleProgress: { type: 'f', value: 0 }, map: { type: 't', value: null }, map0: { type: 't', value: null }, map1: { type: 't', value: null }, map2: { type: 't', value: null }, opacity: { type: 'f', value: 0 } }, vertexShader: "\n\n // uniform float openning;\n // uniform float uTime;\n\n varying vec2 vUv;\n\n void main() \n {\n vUv = uv;\n gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);\n }\n \n ", fragmentShader: "\n\n // uniform float opacity;\n // uniform int dark;\n // uniform float uTime;\n // uniform sampler2D map;\n // uniform float openning;\n \n // varying vec2 vUv;\n \n\n // vec4 circle( vec2 position, vec2 center, float radius, vec4 color )\n // {\n // vec4 backgroundColor = vec4( 0.0 );\n \n // float alpha = smoothstep( radius + 0.03, radius - 0.03, length( position - center ));\n\n // return mix( backgroundColor, color, alpha );\n // }\n\n // vec4 ring( vec2 position, vec2 center, vec2 radius, vec4 color )\n // {\n // vec4 backgroundColor = vec4( 0.0, 0.0, 0.0, 0.0);\n \n // float len = length( position - center );\n \n // float alpha = smoothstep( radius.x - 0.03, radius.x + 0.03, len) - smoothstep(radius.y - 0.03, radius.y + 0.03, len);\n \n // return mix( backgroundColor, color, alpha);\n // }\n\n // void main() {\n\n // vec2 uv = vUv;\n\n // vec4 color = texture2D(map, uv);\n \n // if(dark == 1 && (color.r + color.g + color.b < 240.0*3.0/255.0))\n // {\n // color.rgb *= 0.9;\n // }\n\n\n // vec2 coord = uv * 2.0 - 1.0;\n // vec4 opennedColor = vec4(0.0);\n\n // opennedColor += circle( coord, vec2(0.0), 0.25, vec4(1.0, 1.0, 1.0, 0.5) );\n // opennedColor += circle( coord, vec2(0.0), 0.5, vec4(1.0, 1.0, 1.0, 0.3) );\n\n // color = mix( color, opennedColor, openning );\n \n // gl_FragColor = vec4(color.rgb, color.a * opacity);\n // //gl_FragColor = vec4( 0.86, 0.078, 0.2353, 1.0);\n // }\n\n //xst add\n //\u4ECEmin1-max1\u7F29\u653E\u5230min2-max2\uFF0Cvalue\u672C\u6765\u662Fmin1-max1\u8303\u56F4\u5185\u7684\uFF0C\u76F8\u5E94\u7684\u8FD4\u56DE\u5BF9\u5E94\u7684\u503C\n float linearClamp(float value, float min1,float max1,float min2,float max2){\n return min2 + (value - min1) * (max2 - min2)/(max1 - min1);\n }\n\n /* vec4 ring( vec2 position, vec2 center, float minRadius, float maxRadius, vec4 color, vec4 backgroundColor)\n {\n float len = length( position - center );\n if(len>minRadius && len < maxRadius){\n return color;\n }\n else{\n return backgroundColor;\n }\n } */\n\n \n\n /* bool sameside(vec2 uv, vec3 A, vec3 B, vec3 C) //permet d'indiquer de quel cot\xE9 d'une ligne on se trouve (0 ou 1)\n {\n vec3 u = vec3(uv.x,uv.y,0.0);\n vec3 valuexy = cross(B-A,C-A);\n vec3 valuexz = cross(B-A,u-A);\n \n if(dot(valuexy,valuexz)>=0.){return true;}\n else{return false;} \n }\n \n bool inTriangle(vec2 uv,vec3 v[3]) // permet d'indiquer si on se trouve bien a l'int\xE9rieur d'un triangle (3 ligne)\n {\n if(sameside(uv,v[0],v[1],v[2]) && sameside(uv,v[1],v[2],v[0]) && sameside(uv,v[2],v[0],v[1])){return true;}\n else{return false;}\n \n } */\n\n \n\n //\u653E\u5927\uFF0C\u4ECEradius\u653E\u5927\u5230maxRadius\n /* vec2 zoomUV2(vec2 vuv,float radius,float maxRadius){\n vec2 dis = vuv - vec2(0.5);\n float len = length(dis);\n\n float step = maxRadius/radius;\n if(len < radius ){\n return vec2(0.5 + dis.x/step,0.5 + dis.y/step);\n }\n else{\n return vuv; \n }\n } */\n\n uniform float bigCircleProgress;\n uniform sampler2D map;\n varying vec2 vUv;\n \n \n vec4 noRepeat(sampler2D sampler, vec2 uv){\t\t\t\t\t \n vec4 color;\n if(uv.x<0.0) \t color = vec4(0.0, 0.0, 0.0, 0.0) ;\n else if(uv.x>1.0) color = vec4(0.0, 0.0, 0.0, 0.0) ;\n else if(uv.y<0.0) color = vec4(0.0, 0.0, 0.0, 0.0) ;\n else if(uv.y>1.0) color = vec4(0.0, 0.0, 0.0, 0.0) ;\t\n else color = texture2D(sampler, uv);\n return color ;\t\t\n }\n //\u7F29\u5C0F\uFF0C\u628AmaxRadius\u7F29\u5C0F\u5230radius\n vec2 zoomInUV(vec2 vuv,float radius,float maxRadius){\n vec2 dis = vuv - vec2(0.5);\n float len = length(dis);\n \n float step = radius/maxRadius;\n if(len < maxRadius ){\n return vec2(0.5 + dis.x/step,0.5 + dis.y/step);\n }\n else{\n return vuv; \n }\n }\n \n float circle(vec2 vuv, float radius){\n vec2 dis = vuv - vec2(0.5);\n float len = length(dis);\n float w = abs(len - radius);\n \n if(w < 0.015 ){//\u753B\u5708\u5708\uFF0C\u6709\u6548\u7684\n return 2.0; \n }else if(w < 0.03){\n return 1.0 - (w-0.015) / (0.03-0.015); //\u8FB9\u7F18\u6A21\u7CCA\u6297\u952F\u9F7F\n }else if(lenradius){\n return -2.0;\n }\n }\n \n \n void main() {\n\n vec2 uv = vUv;\n\n float sTime = 0.26;\n float mTime = 0.48;\n float eTime = 0.8;\n\n\n float mTime2 = 0.57; \n\n float lineWidth = 0.02;\n float outerRadius = 0.4;\n float extendRadius = 0.5;\n float outerRadius2;\n \n vec2 center = vec2(0.5);\n \n //float innerRadius = 0.3; //\u4E09\u89D2\u5F62\u6240\u5728\u534A\u5F84\n\n\n\n\n //\u8D34\u56FE\u7F29\u5C0F\n \n\n float flag;\n //\u5F00\u59CB\u7684\u65F6\u5019\u662F\u9759\u6B62\u7684\n if(bigCircleProgress=0.0){ //\u5708\u8FB9\u7F18\u6A21\u7CCA\u6297\u952F\u9F7F\n gl_FragColor = vec4(1.0, 1.0, 1.0, flag);\n }else if(flag == -1.0){//\u5708\u5185 \n vec2 zoomuv = zoomInUV(uv, outerRadius,extendRadius);\n gl_FragColor = noRepeat(map, zoomuv); \n } \n }\n\n " }; /* * @Author: Rindy * @Date: 2021-05-07 16:00:54 * @LastEditors: Rindy * @LastEditTime: 2021-05-12 15:36:15 * @Description: 注释 */ var waypoint = { uniforms: { map: { type: 't', value: null }, opacity: { type: 'f', value: 1 }, pulse: { type: 'f', value: 1 }, nearFade: { type: 'v2', value: new THREE.Vector2(2 * settings$3.insideNear, 2 * settings$3.path.waypointIndoorRadius) }, color: { type: 'c', value: new THREE.Color('#fff') } }, vertexShader: 'varying vec2 vUv;\nvarying vec4 vPointView;\n\nvoid main() {\n\n vUv = uv;\n vPointView = modelViewMatrix * vec4( position, 1.0 );\n gl_Position = projectionMatrix * vPointView;\n\n}\n', fragmentShader: 'uniform sampler2D map;\nuniform float opacity;\nuniform float pulse; // another opacity, with a different clock\nuniform vec2 nearFade;\nvarying vec2 vUv;\nvarying vec4 vPointView;\nuniform vec3 color;\n\nvoid main() {\n\t// TODO add scroll-in and pulsing behaviors\n\tfloat depthFade = min(1.0, (abs(vPointView.z)-nearFade.x)/(nearFade.y-nearFade.x));\n vec4 colorFromTexture = texture2D( map, vUv );\t\t// we only use the alpha!\n gl_FragColor = vec4(color.rgb,\n \t\t\t\t\t\t(pulse*opacity*colorFromTexture.a * depthFade));\n}\n' }; //球上的鱼眼(无过渡): var skybox = { uniforms: { opacity: { type: 'f', value: 1 }, pano1Map: { type: 't', value: null }, pano1Matrix: { type: 'm4', value: new THREE.Matrix4() } }, vertexShader: 'uniform mat4 pano1Matrix;varying vec3 vWorldPosition;void main(){vWorldPosition=(vec4(position,1.0)*pano1Matrix).xyz;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);}', fragmentShader: 'uniform float opacity;varying vec3 vWorldPosition;\n#define PI 3.141592653 \n\n#if defined(Not_Cube)\nuniform sampler2D pano1Map;vec4 texCubemapWith2D(sampler2D t,vec3 dir){dir=normalize(dir);float tx=atan(dir.x,dir.z)/(PI*2.0)+0.5;float ty=acos(dir.y)/PI;vec4 color=texture2D(t,vec2(tx,ty));return color;}\n#else\nuniform samplerCube pano1Map;\n#endif\nvoid main(){\n#if defined(Not_Cube)\nvec4 colorFromPanos=texCubemapWith2D(pano1Map,vec3(-1.0*vWorldPosition.x,vWorldPosition.yz));\n#else\nvec4 colorFromPanos=textureCube(pano1Map,vec3(-1.0*vWorldPosition.x,vWorldPosition.yz));\n#endif\ngl_FragColor=vec4(colorFromPanos.rgb,opacity);}' }; /* * @Author: Rindy * @Date: 2021-05-07 15:48:57 * @LastEditors: zhou enguang * @LastEditTime: 2022-01-12 16:49:49 * @Description: 注释 */ var videoLoading = { uniforms: { uColor: { type: 'vec4', value: null }, uTime: { type: 'f', value: 0 } }, vertexShader: "\n \n varying vec2 vUv;\n \n void main() \n {\n vUv = uv;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n\n ", fragmentShader: "\n \n #define PI2 6.2831852 \n\n uniform vec4 uColor;\n uniform float uTime;\n\n varying vec2 vUv;\n\n float lerp( float a, float b, float alpha ) \n {\n return a + (b -a ) * alpha;\n }\n\n vec4 ring( vec2 uv, vec2 radius )\n {\n float len = length( uv );\n float angle = atan( uv.y, uv.x );\n float opacity = 0.7;\n \n float progress = fract( uTime / 4000.0 );\n\n float step1 = step( 0.0, progress );\n float step2 = step( 0.25, progress );\n float step3 = step( 0.75, progress );\n\n float progressStep1 = smoothstep( 0.0, 0.25, progress );\n float progressStep2 = smoothstep( 0.25, 1.0, progress );\n \n radius *= progressStep1 * step1;\n opacity *= (1.0 - smoothstep( 0.7, 1.0, progress ));\n\n float alpha = smoothstep( radius.x - 0.01, radius.x, len ) - smoothstep( radius.y, radius.y + 0.01, len );\n \n float speed = step2 * ( progressStep2 * 20.0 );\n\n float period = floor(30.0 - 29.0 * progressStep2);\n \n float interval = lerp( 0.0, 0.012, 1.0- progressStep2 );\n \n float dashed = smoothstep( interval * period, interval * period, fract( period * angle / PI2 + speed ) )\n - smoothstep( 1.0 - interval * period, 1.0 - interval * period , fract( period * angle / PI2 + speed ) );\n \n alpha *= dashed;\n \n return mix( vec4(0.0), vec4(1.0, 1.0, 1.0, opacity), alpha );\n }\n\n\n void main()\n {\n\n vec2 uv = vUv * 2.0 - 1.0;\n\n vec4 mainColor = vec4(0);\n\n mainColor += ring(uv, vec2(0.2, 0.22));\t\t\n \n gl_FragColor = mainColor;\n }\n " }; /* * @Author: Rindy * @Date: 2021-05-07 15:48:57 * @LastEditors: zhou enguang * @LastEditTime: 2022-01-12 16:49:49 * @Description: 注释 */ var videoMakerWidget = { uniforms: { opacity: { type: 'f', value: 1 }, dark: { //hover时会颜色会变深 type: 'i', value: 0 }, map: { type: 't', value: null }, position: { value: new THREE.Vector3(0, 0, 0) } }, vertexShader: "\n\n varying vec2 vUv;\n\n\n void main() \n {\n vUv = uv;\n\n vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0);\n\n vec2 scale;\n scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n scale *= mvPosition.z * 0.5;\n\n vec2 alignedPosition = position.xy * scale;\n\n mvPosition.xy += alignedPosition;\n\n gl_Position = projectionMatrix * mvPosition;\n\n }\n ", fragmentShader: "\n \n uniform float opacity;\n uniform int dark;\n uniform sampler2D map;\n \n \n varying vec2 vUv;\n \n void main()\n {\n\n vec4 color = texture2D(map, vUv); \n\n if( dark == 1 && (color.r + color.g + color.b < 240.0*3.0/255.0))\n {\n color.rgb *= 0.9;\n } \n\n gl_FragColor = vec4(color.rgb, color.a * opacity);\n }\n \n " }; /* * @Author: Rindy * @Date: 2021-05-07 15:48:57 * @LastEditors: zhou enguang * @LastEditTime: 2022-01-12 16:49:49 * @Description: 注释 videoPano marker 的shader */ var videoPanoMarker = { uniforms: { progress: { type: 'f', value: 0 }, bigCircleProgress: { type: 'f', value: 0 }, smallCircleProgress: { type: 'f', value: 0 }, map: { type: 't', value: null }, /* map0: { type: 't', value: null, }, map1: { type: 't', value: null, }, map2: { type: 't', value: null, }, */ opacity: { type: 'f', value: 0 } }, vertexShader: " \n varying vec2 vUv; \n /* vec2 Scale(vec2 vuv, float scale){\n scale = 1.0/scale; \n vuv.x=(uv.x-0.5) * scale + 0.5; \n vuv.y=(uv.y-0.5) * scale + 0.5 ; \n return vuv ; \t\t\t\t\t \t\t\n } */\t\n\n void main(){ \n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n \n }\n\n ", fragmentShader: "\n \n uniform sampler2D map;\n uniform float opacity; \n uniform float bigCircleProgress;\n uniform float smallCircleProgress;\n vec4 noRepeat(sampler2D sampler, vec2 uv){\t\t\t\t\t \n vec4 color;\n if(uv.x<0.0) \t color = vec4(0.0, 0.0, 0.0, 0.0) ;\n else if(uv.x>1.0) color = vec4(0.0, 0.0, 0.0, 0.0) ;\n else if(uv.y<0.0) color = vec4(0.0, 0.0, 0.0, 0.0) ;\n else if(uv.y>1.0) color = vec4(0.0, 0.0, 0.0, 0.0) ;\t\n else color = texture2D(sampler, uv);\n return color ;\t\t\n }\n vec4 mixColor(vec4 downColor,vec4 upColor){\n return vec4(upColor.rgb * upColor.a + (1.0 - upColor.a) * downColor.rgb, upColor.a+downColor.a);//\u4E0B\u5C42\u7684\u5206\u91CF\u901A\u8FC7\u4E0A\u5C42\u7684a\u6765\u51B3\u5B9A\uFF0C\u6682\u65F6\u8FD9\u4E48\u8BBE\u7F6E\n /* vec4 sum = downColor + upColor; \n if(sum.a == 0.0){\n \treturn sum;\n }\n float upPct = upColor.a / sum.a;\n float downPct = downColor.a / sum.a; \n return vec4(upColor.rgb * upPct + downColor.rgb * downPct , sum.a ); */\n }\n\n float drawMinCircle(vec2 vuv, float minR){\n vec2 dis = vuv - vec2(0.5);\n float len = length(dis);\n float w = abs(len - minR);\n \n if(w < 0.01 ){//\u753B\u5708\u5708\uFF0C\u6709\u6548\u7684\n return 1.0; \n }else if(w < 0.03){\n return 1.0 - (w-0.01) / (0.03-0.01); //\u8FB9\u7F18\u6A21\u7CCA\u6297\u952F\u9F7F\n }else if(len < minR){\n return 2.0; //\u5708\u5708\u5185\u7684\u60C5\u51B5\n }else{\n return 0.0; //\u900F\u660E \uFF0C\u4E0D\u8003\u8651\n }\n }\n \n float drawCircle(vec2 vuv, float maxR,float minR){\n vec2 dis = vuv - vec2(0.5);\n float len = length(dis);\n if(abs(len - maxR) < 0.04 ){//\u753B\u5708\u5708\uFF0C\u6709\u6548\u7684\n return len; \n }\n else if(len < maxR && len > minR){\n return 1.0; //minR\u5230maxR\u4E4B\u95F4\u7684\u533A\u57DF\n }\n else{\n return 2.0; //\u900F\u660E \uFF0C\u4E0D\u8003\u8651\n }\n }\n \n vec2 Scale(vec2 vuv, float scale){\n scale = 1.0/scale; \n vec2 uv;\n uv.x=(vuv.x-0.5) * scale + 0.5; \n uv.y=(vuv.y-0.5) * scale + 0.5 ; \n return uv ; \t\t\t\t\t \t\t\n }\t\n \n varying vec2 vUv; varying vec2 vUv1; varying vec2 vUv2; \n void main(){ \n //xst\u6DFB\u52A0\n \n float vtime2 = 0.08; //\u6536\u7F29\u7ED3\u675F\u65F6\u95F4\n float vtime22 = 0.24; //\u5F00\u59CB\u6269\u6563\u65F6\u95F4\n float vtime32 = 0.51; //\u7ED3\u675F\u6269\u6563\u65F6\u95F4\n float vtime3 = 0.56; //\u5F00\u59CB\u6E10\u53D8\u51FA\u5916\u5708\u7684\u65F6\u95F4\n float vtime4 = 1.0; //\u7ED3\u675F\u65F6\u95F4\n \n float minRadius = 0.32 ; //\u5185\u5708\u5916\u56F4\u7684\u534A\u5F84\n float progress1 = bigCircleProgress - vtime22; //\u5916\u5708\u8FDB\u5EA6\uFF0CbigCircleProgress\uFF1A0-1\n float progress2 = smallCircleProgress - vtime22; //\u5185\u5708\u8FDB\u5EA6\uFF0CsmallCircleProgress\uFF1A-0.2-1.5\n \n vec2 dis = vUv - vec2(0.5);\n float len = length(dis);\n \n if(bigCircleProgress>vtime3 || len < minRadius){//\u9759\u6B62 \n gl_FragColor = noRepeat(map, vUv); \n if(bigCircleProgress > vtime3 && bigCircleProgress < vtime4 && len > minRadius){ //\u7ED3\u5C3E\u9010\u6E10\u663E\u793A\u5916\u5708\n gl_FragColor.a *= (bigCircleProgress - vtime3) / (vtime4 - vtime3);\n }\n }else if(bigCircleProgressvtime22 && bigCircleProgress < vtime32){//\u6269\u5927\u6CE2\u7EB9\n \n float maxRadius = minRadius + 0.58*progress1; //\u5927\u4E00\u4E9B\uFF0C\u5148\u6269\u5927\uFF0Cprogress1\u7684\u8303\u56F4\uFF1A0-0.5\n float midRadius = minRadius + 0.58*progress2; //\u5C0F\u4E00\u4E9B\uFF0C\u540E\u6269\u5927\uFF0Cprogress2\u7684\u8303\u56F4\uFF1A-0.2-1.5\uFF0C\u6BD4progress1\u591A\u4E86\u70B9\uFF0C\u8FD9\u4E00\u70B9\u8981\u5728\u540E\u9762\u5904\u7406\u6389\n \n float value = drawMinCircle(vUv, minRadius);\n if(value == 0.0){ //\u5708\u5708\u5916\n value = drawCircle(vUv, midRadius,minRadius); //1.0\u8868\u793AmidRadius\u5230minRadius\u4E4B\u95F4\u7684\u533A\u57DF\uFF0C2.0\u8868\u793A\u5176\u4ED6\u533A\u57DF\uFF0C\u5176\u4ED6\u503C\u8868\u793AmidRadius\u4E0A\u7684\n if(value == 1.0){ //\u5185\u5708\u548C\u6700\u91CC\u9762\u7684\u5708\u5708\u4E2D\u95F4\uFF0C\u900F\u660E\n //gl_FragColor = vec4( 1.0, 1.0, 1.0, 0.0); \n }\n else if(value != 2.0){ //\u5185\u5708\u9644\u8FD1\uFF0C\u9700\u8981\u6E10\u53D8\n gl_FragColor = vec4( 1.0, 1.0, 1.0, ((value - midRadius) * 20.0+0.2) * (bigCircleProgress - vtime32) / (vtime22 - vtime32)); \n \n }\n else { //\u5185\u5708\u7684\u5916\u90E8\n value = drawCircle(vUv, maxRadius,midRadius); \n if(value == 1.0){ //\u4E2D\u95F4\u900F\u660E\n //gl_FragColor = vec4( 1.0, 1.0, 1.0, 0.0); \n }\n else if(value != 2.0){ //\u5916\u5708\u9644\u8FD1\uFF0C\u9700\u8981\u6E10\u53D8\n gl_FragColor = vec4( 1.0, 1.0, 1.0, ((value - maxRadius) * 20.0+0.2) * (bigCircleProgress - vtime32) / (vtime22 - vtime32)); \n }\n else{ \n gl_FragColor = vec4( 1.0, 1.0, 1.0, 0.0); //\u900F\u660E\n }\n }\n \n }\n /* else if(value == 1.0){\n //gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0); //\u767D\u8272\n }\n else if(value == 2.0){\n gl_FragColor = vec4( 1.0, 1.0, 1.0, 0.0); //\u5708\u5708\u5185\u900F\u660E\n }\n else{//\u6E10\u53D8\u6A21\u7CCA\uFF0C\u6297\u952F\u9F7F\n gl_FragColor = vec4( 1.0, 1.0, 1.0, value); \n } */\n\n /* //\u5904\u7406\u591A\u4E8Eprogress1\u7684\u90E8\u5206\n if(progress2 > vtime2){\n vec4 color = noRepeat(map, vUv);\n gl_FragColor = color;\n gl_FragColor.a = gl_FragColor.a * (progress2-vtime2)*2.0;\n } */\n }\n gl_FragColor.a *= opacity;\n }\n \n " }; /* * @Author: xst * @Date: 2021-05-07 15:48:57 * @LastEditors: xst * @LastEditTime: 2022-01-12 16:49:49 * @Description: 注释 */ var videoStemLine = { uniforms: { progress: { type: 'f', value: 0 }, bigCircleProgress: { type: 'f', value: 0 }, smallCircleProgress: { type: 'f', value: 0 }, map: { type: 't', value: null }, map0: { type: 't', value: null }, map1: { type: 't', value: null }, map2: { type: 't', value: null }, opacity: { type: 'f', value: 0 } }, vertexShader: "\n\n varying vec2 vUv;\n void main() \n {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n\n ", fragmentShader: "\n \n uniform float bigCircleProgress;\n varying vec2 vUv;\n\n //\u4ECEmin1-max1\u7F29\u653E\u5230min2-max2\uFF0Cvalue\u672C\u6765\u662Fmin1-max1\u8303\u56F4\u5185\u7684\uFF0C\u76F8\u5E94\u7684\u8FD4\u56DE\u5BF9\u5E94\u7684\u503C\n float linearClamp(float value, float min1,float max1,float min2,float max2){\n return min2 + (value - min1) * (max2 - min2)/(max1 - min1);\n }\n\n void main()\n {\n // if(vUv.y > 0.3){\n // gl_FragColor = vec4( 0.86, 0.078, 0.2353, 1.0);\n // } \n // else{\n // gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0);\n // }\n //gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0);\n //gl_FragColor = vec4( vPoint.x, vPoint.y, vPoint.z, 1.0);\n \n float vtime = 0.2; //\u6301\u7EED\u65F6\u95F4 \u4F46\u4E0D\u4E00\u5B9A\u662F\u79D2\n float step = 1.0/vtime;\n float len = 0.5;\n\n if(bigCircleProgress len && vUv.y < bigCircleProgress*step - len){\n if(vUv.y < bigCircleProgress*step - len){\n gl_FragColor.a = 0.0;\n }\n }\n } \n else{\n gl_FragColor.a = 0.0;\n }\n }\n " }; /* * @Author: Rindy * @Date: 2021-05-07 15:48:57 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 15:49:49 * @Description: 注释 */ var linkSpot = { //balloon uniforms: { /* isActive: { type: 'i', value: 0, }, */ activeProgress: { type: 'f', value: 0 }, mapIn: { type: 't', value: null }, mapOut: { type: 't', value: null }, mapOut2: { type: 't', value: null }, opacity: { type: 'f', value: 0 }, changeMap: { type: 'i', value: 0 } }, vertexShader: " \n varying vec2 vUv; \n void main() \n { \n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n\t\t", fragmentShader: "\n varying vec2 vUv; \n uniform sampler2D mapOut; \n uniform sampler2D mapOut2;\n uniform sampler2D mapIn; \n uniform float opacity;\n //uniform int isActive; \n \n uniform float activeProgress;\n \n uniform int changeMap; //\u662F\u5426\u6709mapIn\u8D34\u56FE\uFF0C\u6709\u7684\u8BDD\u5C31\u662F\u4E2D\u95F4\u8981\u6362\u6210mapIn\n \n const float x1=0.2333, x2=0.76669, y1=0.388, y2=0.9333; \n const vec4 sumColor = vec4(1.24,1.24,1.24,2.0);//\u7528\u4E8E\u4E2D\u5FC3\u90E8\u5206\u53CD\u8F6C\u9ED1\u767D\u7684\u989C\u8272\n \n \n \n vec4 getColor_default(vec4 mapColor, vec4 mapColor2, int where,vec2 vUvInside ,vec4 white){\n vec4 color;\n if(where == 1){\n color = vec4(1.0,1.0,1.0,mapColor.a);\n }else{\n\n if(changeMap == 1){ \n if(where == 2){\n vec4 color0 = texture2D(mapIn,vUvInside);\n if(mapColor2.r==1.0){color = color0;}\n else color = mix(white, color0, mapColor2.r);//\u5E73\u6ED11\u7684\u5185\u8FB9\u7F18 \n } \n else color = mapColor;\n }else{ \n if(where == 2){ \n vec4 color0 = sumColor-mapColor; \n if(mapColor2.r==1.0){color = color0;}\n else{\n color = mix(white, color0, mapColor2.r);//\u5E73\u6ED11\u7684\u5185\u8FB9\u7F18 \n float c = (color.x + color.y + color.z) / 3.0;//\u53BB\u7EA2\u8FB9\uFF0C\u6539\u4E3A\u7070\u8272 \n color = vec4(c,c,c,1.0); \n }\n } \n else color = mapColor; \n }\n } \n return color;\n }\n \n vec4 getColor_hovered(vec4 mapColor, vec4 mapColor2, int where,vec2 vUvInside ,vec4 green){\n vec4 color;\n if(changeMap == 1){\n if(where == 2){\n vec4 color0 = texture2D(mapIn,vUvInside);\n if(mapColor2.r==1.0){color = color0;}\n else color = mix(green, color0, mapColor2.r);//\u5E73\u6ED1\u5185\u8FB9\u7F18 \n }\n else if(mapColor.a>0.0 && mapColor.a<1.0) color = green; //\u56E0\u4E3A\u5F00\u542F\u4E86\u6297\u952F\u9F7F\uFF0C\u5BFC\u81F4\u5916\u8FB9\u7F18\u6709\u70B9\u95EE\u9898\uFF0C\u6240\u4EE5\u81EA\u5DF1\u7ED8\u5236\n else color = mapColor;\n }else{ \n color = mapColor; \n }\n return color;\n }\n \n \n \n \n void main(){ \n \n vec4 mapColor = texture2D(mapOut,vUv);\n vec4 mapColor2 = texture2D(mapOut2,vUv);//\u7528\u4E8E\u5206\u533A\u7684\u8D34\u56FE \n vec2 vUvInside = vec2((vUv.x-x1)/(x2-x1), (vUv.y-y1)/(y2-y1)); \n \n \n //\u7EFF\u8272\u7684 r=0 \u767D\u8272r=1\n //where: 0\u662F\u900F\u660E\u5916\u5C42\uFF0C 1\u662F\u7EFF\u73AF\uFF0C 2\u662F\u4E2D\u95F4\u5706 \n //int where = mapColor2.a <= 0.0 ? 0 : (mapColor2.r <= 0.0 || mapColor2.a<1.0 ) ? 1 : 2; // \u8FD9\u4E2A\u5E9F\u5F03\u662F\u56E0\u4E3A\u7F29\u5C0F\u65F61\u5916\u8FB9\u7F18\u7684\u534A\u900F\u660E\u4F1A\u4FB5\u72AF2\u533A\u57DF\uFF0C\u672C\u8BE5\u5C5E\u4E8E2\u7684\u53D8\u4E3A1\uFF0C\u5185\u8FB9\u7F18\u7ED8\u5236\u6210\u4E0D\u900F\u660E\u767D\u8272\u952F\u9F7F\u3002\u6545\u800C\u6539\u4E3A\u5148\u9009\u51FA2\n int where = mapColor2.a <= 0.0 ? 0 : (mapColor2.r >0.0 && mapColor2.a>0.5 ) ? 2 : 1; //2\u4E2D\u5305\u542B1-2\u7684\u8FC7\u6E21\uFF0C\u56E0\u4E3A\u8981\u57282\u4E2D\u5E73\u6ED1. \u4E4B\u6240\u4EE52\u9700\u8981mapColor2.a>0.5\u662F\u56E0\u4E3A\u5728\u5DE6\u8FB9\u7F18\u591A\u4E86\u4E00\u6761\u5947\u602Ar>0\u7684\u7AD6\u7EBF\uFF0C\u4E3A\u4E86\u53BB\u6389\u5B83\u63D0\u9AD8\u4E86a\u9608\u503C\u3002\n \n \n \n vec4 green = vec4(0.0, 0.7843137, 0.6823529, mapColor.a);\n vec4 white = vec4(1.0, 1.0, 1.0, mapColor.a);\n \n \n if(activeProgress == 0.0){ //\u666E\u901A\n gl_FragColor = getColor_default( mapColor, mapColor2, where, vUvInside , white);\n \n }else if(activeProgress == 1.0){ \n gl_FragColor = getColor_hovered( mapColor, mapColor2, where, vUvInside , green); \n }else{\n vec4 color0 = getColor_default(mapColor, mapColor2, where, vUvInside , white);\n vec4 color1 = getColor_hovered(mapColor, mapColor2, where, vUvInside , green);\n \n gl_FragColor = mix(color0,color1,activeProgress);\n } \n \n gl_FragColor.a *= opacity; \n \n \n }\n " /* fragmentShader: ` varying vec2 vUv; uniform sampler2D mapOut; uniform sampler2D mapOut2; uniform sampler2D mapIn; uniform float opacity; uniform int isActive; uniform int changeMap; //是否有mapIn贴图,有的话就是中间要换成mapIn void main(){ vec4 mapColor = texture2D(mapOut,vUv); vec4 mapColor2 = texture2D(mapOut2,vUv);//用于分区的贴图 vec4 sumColor = vec4(1.24,1.24,1.24,2.0);//用于中心部分反转黑白的颜色 float x1=0.2333, x2=0.76669, y1=0.388, y2=0.9333; vec2 vUvInside = vec2((vUv.x-x1)/(x2-x1), (vUv.y-y1)/(y2-y1)); //绿色的 r=0 白色r=1 //where: 0是外层, 1是环, 2是中间层 int where = mapColor2.a <= 0.0 ? 0 : (mapColor2.r <= 0.0 || mapColor2.a<1.0) ? 1 : 2; //2中包含1-2的过渡,待平滑 vec4 green = vec4(0.0, 0.7843137, 0.6823529, mapColor.a); vec4 white = vec4(1.0, 1.0, 1.0, mapColor.a); if(isActive!=1){ //普通 if(where == 1){ gl_FragColor = vec4(1.0,1.0,1.0,mapColor.a); }else{ if(changeMap == 1){ if(where == 2){ vec4 color = texture2D(mapIn,vUvInside); if(mapColor2.r==1.0){gl_FragColor = color;} else gl_FragColor = mix(white, color, mapColor2.r);//平滑内边缘 } else gl_FragColor = mapColor; }else{ if(where == 2){ vec4 color = sumColor-mapColor; if(mapColor2.r==1.0){gl_FragColor = color;} else gl_FragColor = mix(white, color, mapColor2.r);//平滑内边缘 } else gl_FragColor = mapColor; } } }else{//hover时 if(changeMap == 1){ if(where == 2){ vec4 color = texture2D(mapIn,vUvInside); if(mapColor2.r==1.0){gl_FragColor = color;} else gl_FragColor = mix(green, color, mapColor2.r);//平滑内边缘 } else if(mapColor.a>0.0 && mapColor.a<1.0) gl_FragColor = green; //因为开启了抗锯齿,导致外边缘有点问题,所以自己绘制 else gl_FragColor = mapColor; }else{ if(mapColor.a>0.0 && mapColor.a<1.0) gl_FragColor = green; else gl_FragColor = mapColor; } } gl_FragColor.a *= opacity; } `, */ }; /* * @Author: Rindy * @Date: 2021-05-07 15:48:57 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 15:49:49 * @Description: 注释 */ var linkSpotInside = { //circle uniforms: { circleRadius: { //UV内半径的平方 type: 'f', value: 0.815 }, progress: { type: 'f', value: 0 }, mapOut: { type: 't', value: null }, mapIn: { type: 't', value: null }, changeMap: { type: 'i', value: 0 } }, vertexShader: /* prefixVertex + */ " \n varying vec2 vUv; \n \n void main() \n { \n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n\t\t", fragmentShader: /* prefixFragment + */ "\n varying vec2 vUv; \n uniform float circleRadius;\n uniform float progress;\n uniform sampler2D mapOut; \n uniform sampler2D mapIn; \n uniform int changeMap;\n void main(){ \n vec4 mapColor = texture2D(mapOut,vUv);\n vec2 vUv2 = vec2(vUv.x*2.0-1.0,vUv.y*2.0-1.0);\n float d = vUv2.x*vUv2.x+vUv2.y*vUv2.y; \n if(progress > 0.0){ \n vec4 ringColorNew = vec4(0.0, 0.7943137, 0.6823529, 0.68);\n \n if(d>circleRadius && d<=1.0){\n gl_FragColor = mix(mapColor, ringColorNew, progress);\n }else{\n if(changeMap == 1 && d<=circleRadius){ \n vec4 colorFromTexture2 = texture2D(mapIn,vUv); \n gl_FragColor = mix(mapColor, colorFromTexture2, progress);\n }\n else{\n if(d<=circleRadius)gl_FragColor = mapColor;\n //else gl_FragColor = vec4(mapColor.xyz, min(1.0-progress,mapColor.a)); //\u5982\u679C\u4E0D\u628A\u81EA\u5B9A\u4E49\u56FE\u663E\u793A\u6210\u5706\u7684\u8BDD\u7528\u8FD9\u53E5\n else gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n }\n }else{\n if(d>1.0)gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n else gl_FragColor = mapColor;\n } \n \n \n }\n " }; var sphereRenderToCube = { uniforms: { tDiffuse: { type: 't', value: null } /* , panoMatrix:{ type:'m4', value:new THREE.Matrix4 } */ }, vertexShader: /* prefixVertex + */ " \n //uniform mat4 panoMatrix; \n varying vec4 vWorldPosition;\n void main() \n { \n \n vWorldPosition = modelMatrix * vec4(position, 1.0);\n //vWorldPosition = (vec4(vWorldPosition, 1.0) * panoMatrix).xyz;\n vWorldPosition.x *= -1.0;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n\t\t", fragmentShader: /* prefixFragment + */ "\n varying vec4 vWorldPosition;\n uniform sampler2D tDiffuse; \n \n #define PI 3.141592653 \n \n vec2 getSamplerCoord( vec3 direction ) \n {\n direction = normalize(direction);\n float tx=atan(direction.x,direction.z)/(PI*2.0)+0.5;\n float ty=acos(direction.y)/PI;\n\n return vec2(tx,ty);\n }\n \n void main() \n {\n vec2 samplerCoord = getSamplerCoord(vWorldPosition.xyz);\n gl_FragColor = texture2D(tDiffuse, samplerCoord);\n } \n \n " }; /* * @Author: Rindy * @Date: 2021-05-07 15:44:55 * @LastEditors: Rindy * @LastEditTime: 2021-05-08 16:01:48 * @Description: 注释 */ function mergePrefixVertex(vertex) { return 'precision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n' + vertex; } function mergePrefixFragment(fragment) { return 'precision highp float;\nprecision highp int;\n\nuniform mat4 viewMatrix;\nuniform vec3 cameraPosition;\n' + fragment; } function margePrefix(shader) { if (shader.vertexShader) { shader.vertexShader = mergePrefixVertex(shader.vertexShader); } if (shader.fragmentShader) { shader.fragmentShader = mergePrefixFragment(shader.fragmentShader); shader == model$1 && (shader.fragmentBufferShader = mergePrefixFragment(shader.fragmentBufferShader)); } } margePrefix(cube); margePrefix(customDepth); margePrefix(model$1); margePrefix(modelDebug); margePrefix(modelOutside); margePrefix(ribbon); margePrefix(skysphere); margePrefix(tagDisc); margePrefix(tagDiscDefault); margePrefix(tagDiscCustom); margePrefix(tagVideoMarker); margePrefix(waypoint); margePrefix(skybox); margePrefix(videoLoading); margePrefix(videoMakerWidget); margePrefix(videoPanoMarker); margePrefix(videoStemLine); margePrefix(linkSpot); margePrefix(linkSpotInside); margePrefix(sphereRenderToCube); var shaders = { cube, customDepth, model: model$1, modelDebug, modelOutside, ribbon, skysphere, tagDisc, tagDiscDefault, tagDiscCustom, tagVideoMarker, waypoint, basicTextured, copyCubeMap, skybox, videoLoading, videoMakerWidget, videoPanoMarker, videoStemLine, linkSpot, linkSpotInside, sphereRenderToCube }; // var bind$1 = function bind(fn, thisArg) { return function wrap() { var args = new Array(arguments.length); for (var i = 0; i < args.length; i++) { args[i] = arguments[i]; } return fn.apply(thisArg, args); }; }; /*global toString:true*/ // utils is a library of generic helper functions non-specific to axios var toString = Object.prototype.toString; /** * Determine if a value is an Array * * @param {Object} val The value to test * @returns {boolean} True if value is an Array, otherwise false */ function isArray$3(val) { return toString.call(val) === '[object Array]'; } /** * Determine if a value is undefined * * @param {Object} val The value to test * @returns {boolean} True if the value is undefined, otherwise false */ function isUndefined(val) { return typeof val === 'undefined'; } /** * Determine if a value is a Buffer * * @param {Object} val The value to test * @returns {boolean} True if value is a Buffer, otherwise false */ function isBuffer$2(val) { return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val); } /** * Determine if a value is an ArrayBuffer * * @param {Object} val The value to test * @returns {boolean} True if value is an ArrayBuffer, otherwise false */ function isArrayBuffer(val) { return toString.call(val) === '[object ArrayBuffer]'; } /** * Determine if a value is a FormData * * @param {Object} val The value to test * @returns {boolean} True if value is an FormData, otherwise false */ function isFormData(val) { return typeof FormData !== 'undefined' && val instanceof FormData; } /** * Determine if a value is a view on an ArrayBuffer * * @param {Object} val The value to test * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false */ function isArrayBufferView(val) { var result; if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) { result = ArrayBuffer.isView(val); } else { result = val && val.buffer && val.buffer instanceof ArrayBuffer; } return result; } /** * Determine if a value is a String * * @param {Object} val The value to test * @returns {boolean} True if value is a String, otherwise false */ function isString$2(val) { return typeof val === 'string'; } /** * Determine if a value is a Number * * @param {Object} val The value to test * @returns {boolean} True if value is a Number, otherwise false */ function isNumber$1(val) { return typeof val === 'number'; } /** * Determine if a value is an Object * * @param {Object} val The value to test * @returns {boolean} True if value is an Object, otherwise false */ function isObject$3(val) { return val !== null && typeof val === 'object'; } /** * Determine if a value is a plain Object * * @param {Object} val The value to test * @return {boolean} True if value is a plain Object, otherwise false */ function isPlainObject(val) { if (toString.call(val) !== '[object Object]') { return false; } var prototype = Object.getPrototypeOf(val); return prototype === null || prototype === Object.prototype; } /** * Determine if a value is a Date * * @param {Object} val The value to test * @returns {boolean} True if value is a Date, otherwise false */ function isDate$1(val) { return toString.call(val) === '[object Date]'; } /** * Determine if a value is a File * * @param {Object} val The value to test * @returns {boolean} True if value is a File, otherwise false */ function isFile(val) { return toString.call(val) === '[object File]'; } /** * Determine if a value is a Blob * * @param {Object} val The value to test * @returns {boolean} True if value is a Blob, otherwise false */ function isBlob$1(val) { return toString.call(val) === '[object Blob]'; } /** * Determine if a value is a Function * * @param {Object} val The value to test * @returns {boolean} True if value is a Function, otherwise false */ function isFunction$1(val) { return toString.call(val) === '[object Function]'; } /** * Determine if a value is a Stream * * @param {Object} val The value to test * @returns {boolean} True if value is a Stream, otherwise false */ function isStream(val) { return isObject$3(val) && isFunction$1(val.pipe); } /** * Determine if a value is a URLSearchParams object * * @param {Object} val The value to test * @returns {boolean} True if value is a URLSearchParams object, otherwise false */ function isURLSearchParams(val) { return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; } /** * Trim excess whitespace off the beginning and end of a string * * @param {String} str The String to trim * @returns {String} The String freed of excess whitespace */ function trim(str) { return str.replace(/^\s*/, '').replace(/\s*$/, ''); } /** * Determine if we're running in a standard browser environment * * This allows axios to run in a web worker, and react-native. * Both environments support XMLHttpRequest, but not fully standard globals. * * web workers: * typeof window -> undefined * typeof document -> undefined * * react-native: * navigator.product -> 'ReactNative' * nativescript * navigator.product -> 'NativeScript' or 'NS' */ function isStandardBrowserEnv() { if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || navigator.product === 'NativeScript' || navigator.product === 'NS')) { return false; } return typeof window !== 'undefined' && typeof document !== 'undefined'; } /** * Iterate over an Array or an Object invoking a function for each item. * * If `obj` is an Array callback will be called passing * the value, index, and complete array for each item. * * If 'obj' is an Object callback will be called passing * the value, key, and complete object for each property. * * @param {Object|Array} obj The object to iterate * @param {Function} fn The callback to invoke for each item */ function forEach(obj, fn) { // Don't bother if no value provided if (obj === null || typeof obj === 'undefined') { return; } // Force an array if not already something iterable if (typeof obj !== 'object') { /*eslint no-param-reassign:0*/ obj = [obj]; } if (isArray$3(obj)) { // Iterate over array values for (var i = 0, l = obj.length; i < l; i++) { fn.call(null, obj[i], i, obj); } } else { // Iterate over object keys for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { fn.call(null, obj[key], key, obj); } } } } /** * Accepts varargs expecting each argument to be an object, then * immutably merges the properties of each object and returns result. * * When multiple objects contain the same key the later object in * the arguments list will take precedence. * * Example: * * ```js * var result = merge({foo: 123}, {foo: 456}); * console.log(result.foo); // outputs 456 * ``` * * @param {Object} obj1 Object to merge * @returns {Object} Result of all merge properties */ function merge() { var result = {}; function assignValue(val, key) { if (isPlainObject(result[key]) && isPlainObject(val)) { result[key] = merge(result[key], val); } else if (isPlainObject(val)) { result[key] = merge({}, val); } else if (isArray$3(val)) { result[key] = val.slice(); } else { result[key] = val; } } for (var i = 0, l = arguments.length; i < l; i++) { forEach(arguments[i], assignValue); } return result; } /** * Extends object a by mutably adding to it the properties of object b. * * @param {Object} a The object to be extended * @param {Object} b The object to copy properties from * @param {Object} thisArg The object to bind function to * @return {Object} The resulting value of object a */ function extend$1(a, b, thisArg) { forEach(b, function assignValue(val, key) { if (thisArg && typeof val === 'function') { a[key] = bind$1(val, thisArg); } else { a[key] = val; } }); return a; } /** * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) * * @param {string} content with BOM * @return {string} content value without BOM */ function stripBOM(content) { if (content.charCodeAt(0) === 0xFEFF) { content = content.slice(1); } return content; } var utils = { isArray: isArray$3, isArrayBuffer: isArrayBuffer, isBuffer: isBuffer$2, isFormData: isFormData, isArrayBufferView: isArrayBufferView, isString: isString$2, isNumber: isNumber$1, isObject: isObject$3, isPlainObject: isPlainObject, isUndefined: isUndefined, isDate: isDate$1, isFile: isFile, isBlob: isBlob$1, isFunction: isFunction$1, isStream: isStream, isURLSearchParams: isURLSearchParams, isStandardBrowserEnv: isStandardBrowserEnv, forEach: forEach, merge: merge, extend: extend$1, trim: trim, stripBOM: stripBOM }; function encode$5(val) { return encodeURIComponent(val).replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']'); } /** * Build a URL by appending params to the end * * @param {string} url The base of the url (e.g., http://www.google.com) * @param {object} [params] The params to be appended * @returns {string} The formatted url */ var buildURL = function buildURL(url, params, paramsSerializer) { /*eslint no-param-reassign:0*/ if (!params) { return url; } var serializedParams; if (paramsSerializer) { serializedParams = paramsSerializer(params); } else if (utils.isURLSearchParams(params)) { serializedParams = params.toString(); } else { var parts = []; utils.forEach(params, function serialize(val, key) { if (val === null || typeof val === 'undefined') { return; } if (utils.isArray(val)) { key = key + '[]'; } else { val = [val]; } utils.forEach(val, function parseValue(v) { if (utils.isDate(v)) { v = v.toISOString(); } else if (utils.isObject(v)) { v = JSON.stringify(v); } parts.push(encode$5(key) + '=' + encode$5(v)); }); }); serializedParams = parts.join('&'); } if (serializedParams) { var hashmarkIndex = url.indexOf('#'); if (hashmarkIndex !== -1) { url = url.slice(0, hashmarkIndex); } url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; } return url; }; function InterceptorManager() { this.handlers = []; } /** * Add a new interceptor to the stack * * @param {Function} fulfilled The function to handle `then` for a `Promise` * @param {Function} rejected The function to handle `reject` for a `Promise` * * @return {Number} An ID used to remove interceptor later */ InterceptorManager.prototype.use = function use(fulfilled, rejected) { this.handlers.push({ fulfilled: fulfilled, rejected: rejected }); return this.handlers.length - 1; }; /** * Remove an interceptor from the stack * * @param {Number} id The ID that was returned by `use` */ InterceptorManager.prototype.eject = function eject(id) { if (this.handlers[id]) { this.handlers[id] = null; } }; /** * Iterate over all the registered interceptors * * This method is particularly useful for skipping over any * interceptors that may have become `null` calling `eject`. * * @param {Function} fn The function to call for each interceptor */ InterceptorManager.prototype.forEach = function forEach(fn) { utils.forEach(this.handlers, function forEachHandler(h) { if (h !== null) { fn(h); } }); }; var InterceptorManager_1 = InterceptorManager; /** * Transform the data for a request or a response * * @param {Object|String} data The data to be transformed * @param {Array} headers The headers for the request or response * @param {Array|Function} fns A single function or Array of functions * @returns {*} The resulting transformed data */ var transformData = function transformData(data, headers, fns) { /*eslint no-param-reassign:0*/ utils.forEach(fns, function transform(fn) { data = fn(data, headers); }); return data; }; var isCancel = function isCancel(value) { return !!(value && value.__CANCEL__); }; var normalizeHeaderName = function normalizeHeaderName(headers, normalizedName) { utils.forEach(headers, function processHeader(value, name) { if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { headers[normalizedName] = value; delete headers[name]; } }); }; /** * Update an Error with the specified config, error code, and response. * * @param {Error} error The error to update. * @param {Object} config The config. * @param {string} [code] The error code (for example, 'ECONNABORTED'). * @param {Object} [request] The request. * @param {Object} [response] The response. * @returns {Error} The error. */ var enhanceError = function enhanceError(error, config, code, request, response) { error.config = config; if (code) { error.code = code; } error.request = request; error.response = response; error.isAxiosError = true; error.toJSON = function toJSON() { return { // Standard message: this.message, name: this.name, // Microsoft description: this.description, number: this.number, // Mozilla fileName: this.fileName, lineNumber: this.lineNumber, columnNumber: this.columnNumber, stack: this.stack, // Axios config: this.config, code: this.code }; }; return error; }; /** * Create an Error with the specified message, config, error code, request and response. * * @param {string} message The error message. * @param {Object} config The config. * @param {string} [code] The error code (for example, 'ECONNABORTED'). * @param {Object} [request] The request. * @param {Object} [response] The response. * @returns {Error} The created error. */ var createError = function createError(message, config, code, request, response) { var error = new Error(message); return enhanceError(error, config, code, request, response); }; /** * Resolve or reject a Promise based on response status. * * @param {Function} resolve A function that resolves the promise. * @param {Function} reject A function that rejects the promise. * @param {object} response The response. */ var settle = function settle(resolve, reject, response) { var validateStatus = response.config.validateStatus; if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response); } else { reject(createError('Request failed with status code ' + response.status, response.config, null, response.request, response)); } }; var cookies = utils.isStandardBrowserEnv() ? // Standard browser envs support document.cookie function standardBrowserEnv() { return { write: function write(name, value, expires, path, domain, secure) { var cookie = []; cookie.push(name + '=' + encodeURIComponent(value)); if (utils.isNumber(expires)) { cookie.push('expires=' + new Date(expires).toGMTString()); } if (utils.isString(path)) { cookie.push('path=' + path); } if (utils.isString(domain)) { cookie.push('domain=' + domain); } if (secure === true) { cookie.push('secure'); } document.cookie = cookie.join('; '); }, read: function read(name) { var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); return match ? decodeURIComponent(match[3]) : null; }, remove: function remove(name) { this.write(name, '', Date.now() - 86400000); } }; }() : // Non standard browser env (web workers, react-native) lack needed support. function nonStandardBrowserEnv() { return { write: function write() {}, read: function read() { return null; }, remove: function remove() {} }; }(); /** * Determines whether the specified URL is absolute * * @param {string} url The URL to test * @returns {boolean} True if the specified URL is absolute, otherwise false */ var isAbsoluteURL = function isAbsoluteURL(url) { // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed // by any combination of letters, digits, plus, period, or hyphen. return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); }; /** * Creates a new URL by combining the specified URLs * * @param {string} baseURL The base URL * @param {string} relativeURL The relative URL * @returns {string} The combined URL */ var combineURLs = function combineURLs(baseURL, relativeURL) { return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL; }; /** * Creates a new URL by combining the baseURL with the requestedURL, * only when the requestedURL is not already an absolute URL. * If the requestURL is absolute, this function returns the requestedURL untouched. * * @param {string} baseURL The base URL * @param {string} requestedURL Absolute or relative URL to combine * @returns {string} The combined full path */ var buildFullPath = function buildFullPath(baseURL, requestedURL) { if (baseURL && !isAbsoluteURL(requestedURL)) { return combineURLs(baseURL, requestedURL); } return requestedURL; }; // Headers whose duplicates are ignored by node // c.f. https://nodejs.org/api/http.html#http_message_headers var ignoreDuplicateOf = ['age', 'authorization', 'content-length', 'content-type', 'etag', 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', 'last-modified', 'location', 'max-forwards', 'proxy-authorization', 'referer', 'retry-after', 'user-agent']; /** * Parse headers into an object * * ``` * Date: Wed, 27 Aug 2014 08:58:49 GMT * Content-Type: application/json * Connection: keep-alive * Transfer-Encoding: chunked * ``` * * @param {String} headers Headers needing to be parsed * @returns {Object} Headers parsed into an object */ var parseHeaders = function parseHeaders(headers) { var parsed = {}; var key; var val; var i; if (!headers) { return parsed; } utils.forEach(headers.split('\n'), function parser(line) { i = line.indexOf(':'); key = utils.trim(line.substr(0, i)).toLowerCase(); val = utils.trim(line.substr(i + 1)); if (key) { if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { return; } if (key === 'set-cookie') { parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]); } else { parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; } } }); return parsed; }; var isURLSameOrigin = utils.isStandardBrowserEnv() ? // Standard browser envs have full support of the APIs needed to test // whether the request URL is of the same origin as current location. function standardBrowserEnv() { var msie = /(msie|trident)/i.test(navigator.userAgent); var urlParsingNode = document.createElement('a'); var originURL; /** * Parse a URL to discover it's components * * @param {String} url The URL to be parsed * @returns {Object} */ function resolveURL(url) { var href = url; if (msie) { // IE needs attribute set twice to normalize properties urlParsingNode.setAttribute('href', href); href = urlParsingNode.href; } urlParsingNode.setAttribute('href', href); // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils return { href: urlParsingNode.href, protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', host: urlParsingNode.host, search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', hostname: urlParsingNode.hostname, port: urlParsingNode.port, pathname: urlParsingNode.pathname.charAt(0) === '/' ? urlParsingNode.pathname : '/' + urlParsingNode.pathname }; } originURL = resolveURL(window.location.href); /** * Determine if a URL shares the same origin as the current location * * @param {String} requestURL The URL to test * @returns {boolean} True if URL shares the same origin, otherwise false */ return function isURLSameOrigin(requestURL) { var parsed = utils.isString(requestURL) ? resolveURL(requestURL) : requestURL; return parsed.protocol === originURL.protocol && parsed.host === originURL.host; }; }() : // Non standard browser envs (web workers, react-native) lack needed support. function nonStandardBrowserEnv() { return function isURLSameOrigin() { return true; }; }(); var xhr = function xhrAdapter(config) { return new Promise(function dispatchXhrRequest(resolve, reject) { var requestData = config.data; var requestHeaders = config.headers; if (utils.isFormData(requestData)) { delete requestHeaders['Content-Type']; // Let the browser set it } var request = new XMLHttpRequest(); // HTTP basic authentication if (config.auth) { var username = config.auth.username || ''; var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : ''; requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); } var fullPath = buildFullPath(config.baseURL, config.url); request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); // Set the request timeout in MS request.timeout = config.timeout; // Listen for ready state request.onreadystatechange = function handleLoad() { if (!request || request.readyState !== 4) { return; } // The request errored out and we didn't get a response, this will be // handled by onerror instead // With one exception: request that using file: protocol, most browsers // will return status as 0 even though it's a successful request if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { return; } // Prepare the response var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; var response = { data: responseData, status: request.status, statusText: request.statusText, headers: responseHeaders, config: config, request: request }; settle(resolve, reject, response); // Clean up request request = null; }; // Handle browser request cancellation (as opposed to a manual cancellation) request.onabort = function handleAbort() { if (!request) { return; } reject(createError('Request aborted', config, 'ECONNABORTED', request)); // Clean up request request = null; }; // Handle low level network errors request.onerror = function handleError() { // Real errors are hidden from us by the browser // onerror should only fire if it's a network error reject(createError('Network Error', config, null, request)); // Clean up request request = null; }; // Handle timeout request.ontimeout = function handleTimeout() { var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded'; if (config.timeoutErrorMessage) { timeoutErrorMessage = config.timeoutErrorMessage; } reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', request)); // Clean up request request = null; }; // Add xsrf header // This is only done if running in a standard browser environment. // Specifically not if we're in a web worker, or react-native. if (utils.isStandardBrowserEnv()) { // Add xsrf header var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ? cookies.read(config.xsrfCookieName) : undefined; if (xsrfValue) { requestHeaders[config.xsrfHeaderName] = xsrfValue; } } // Add headers to the request if ('setRequestHeader' in request) { utils.forEach(requestHeaders, function setRequestHeader(val, key) { if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { // Remove Content-Type if data is undefined delete requestHeaders[key]; } else { // Otherwise add header to the request request.setRequestHeader(key, val); } }); } // Add withCredentials to request if needed if (!utils.isUndefined(config.withCredentials)) { request.withCredentials = !!config.withCredentials; } // Add responseType to request if needed if (config.responseType) { try { request.responseType = config.responseType; } catch (e) { // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. if (config.responseType !== 'json') { throw e; } } } // Handle progress if needed if (typeof config.onDownloadProgress === 'function') { request.addEventListener('progress', config.onDownloadProgress); } // Not all browsers support upload events if (typeof config.onUploadProgress === 'function' && request.upload) { request.upload.addEventListener('progress', config.onUploadProgress); } if (config.cancelToken) { // Handle cancellation config.cancelToken.promise.then(function onCanceled(cancel) { if (!request) { return; } request.abort(); reject(cancel); // Clean up request request = null; }); } if (!requestData) { requestData = null; } // Send the request request.send(requestData); }); }; var DEFAULT_CONTENT_TYPE = { 'Content-Type': 'application/x-www-form-urlencoded' }; function setContentTypeIfUnset(headers, value) { if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { headers['Content-Type'] = value; } } function getDefaultAdapter() { var adapter; if (typeof XMLHttpRequest !== 'undefined') { // For browsers use XHR adapter adapter = xhr; } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') { // For node use HTTP adapter adapter = xhr; } return adapter; } var defaults = { adapter: getDefaultAdapter(), transformRequest: [function transformRequest(data, headers) { normalizeHeaderName(headers, 'Accept'); normalizeHeaderName(headers, 'Content-Type'); if (utils.isFormData(data) || utils.isArrayBuffer(data) || utils.isBuffer(data) || utils.isStream(data) || utils.isFile(data) || utils.isBlob(data)) { return data; } if (utils.isArrayBufferView(data)) { return data.buffer; } if (utils.isURLSearchParams(data)) { setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); return data.toString(); } if (utils.isObject(data)) { setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); return JSON.stringify(data); } return data; }], transformResponse: [function transformResponse(data) { /*eslint no-param-reassign:0*/ if (typeof data === 'string') { try { data = JSON.parse(data); } catch (e) { /* Ignore */ } } return data; }], /** * A timeout in milliseconds to abort a request. If set to 0 (default) a * timeout is not created. */ timeout: 0, xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, validateStatus: function validateStatus(status) { return status >= 200 && status < 300; } }; defaults.headers = { common: { 'Accept': 'application/json, text/plain, */*' } }; utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) { defaults.headers[method] = {}; }); utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE); }); var defaults_1 = defaults; /** * Throws a `Cancel` if cancellation has been requested. */ function throwIfCancellationRequested(config) { if (config.cancelToken) { config.cancelToken.throwIfRequested(); } } /** * Dispatch a request to the server using the configured adapter. * * @param {object} config The config that is to be used for the request * @returns {Promise} The Promise to be fulfilled */ var dispatchRequest = function dispatchRequest(config) { throwIfCancellationRequested(config); // Ensure headers exist config.headers = config.headers || {}; // Transform request data config.data = transformData(config.data, config.headers, config.transformRequest); // Flatten headers config.headers = utils.merge(config.headers.common || {}, config.headers[config.method] || {}, config.headers); utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], function cleanHeaderConfig(method) { delete config.headers[method]; }); var adapter = config.adapter || defaults_1.adapter; return adapter(config).then(function onAdapterResolution(response) { throwIfCancellationRequested(config); // Transform response data response.data = transformData(response.data, response.headers, config.transformResponse); return response; }, function onAdapterRejection(reason) { if (!isCancel(reason)) { throwIfCancellationRequested(config); // Transform response data if (reason && reason.response) { reason.response.data = transformData(reason.response.data, reason.response.headers, config.transformResponse); } } return Promise.reject(reason); }); }; /** * Config-specific merge-function which creates a new config-object * by merging two configuration objects together. * * @param {Object} config1 * @param {Object} config2 * @returns {Object} New object resulting from merging config2 to config1 */ var mergeConfig = function mergeConfig(config1, config2) { // eslint-disable-next-line no-param-reassign config2 = config2 || {}; var config = {}; var valueFromConfig2Keys = ['url', 'method', 'data']; var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params']; var defaultToConfig2Keys = ['baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer', 'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress', 'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent', 'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding']; var directMergeKeys = ['validateStatus']; function getMergedValue(target, source) { if (utils.isPlainObject(target) && utils.isPlainObject(source)) { return utils.merge(target, source); } else if (utils.isPlainObject(source)) { return utils.merge({}, source); } else if (utils.isArray(source)) { return source.slice(); } return source; } function mergeDeepProperties(prop) { if (!utils.isUndefined(config2[prop])) { config[prop] = getMergedValue(config1[prop], config2[prop]); } else if (!utils.isUndefined(config1[prop])) { config[prop] = getMergedValue(undefined, config1[prop]); } } utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) { if (!utils.isUndefined(config2[prop])) { config[prop] = getMergedValue(undefined, config2[prop]); } }); utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties); utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) { if (!utils.isUndefined(config2[prop])) { config[prop] = getMergedValue(undefined, config2[prop]); } else if (!utils.isUndefined(config1[prop])) { config[prop] = getMergedValue(undefined, config1[prop]); } }); utils.forEach(directMergeKeys, function merge(prop) { if (prop in config2) { config[prop] = getMergedValue(config1[prop], config2[prop]); } else if (prop in config1) { config[prop] = getMergedValue(undefined, config1[prop]); } }); var axiosKeys = valueFromConfig2Keys.concat(mergeDeepPropertiesKeys).concat(defaultToConfig2Keys).concat(directMergeKeys); var otherKeys = Object.keys(config1).concat(Object.keys(config2)).filter(function filterAxiosKeys(key) { return axiosKeys.indexOf(key) === -1; }); utils.forEach(otherKeys, mergeDeepProperties); return config; }; /** * Create a new instance of Axios * * @param {Object} instanceConfig The default config for the instance */ function Axios(instanceConfig) { this.defaults = instanceConfig; this.interceptors = { request: new InterceptorManager_1(), response: new InterceptorManager_1() }; } /** * Dispatch a request * * @param {Object} config The config specific for this request (merged with this.defaults) */ Axios.prototype.request = function request(config) { /*eslint no-param-reassign:0*/ // Allow for axios('example/url'[, config]) a la fetch API if (typeof config === 'string') { config = arguments[1] || {}; config.url = arguments[0]; } else { config = config || {}; } config = mergeConfig(this.defaults, config); // Set config.method if (config.method) { config.method = config.method.toLowerCase(); } else if (this.defaults.method) { config.method = this.defaults.method.toLowerCase(); } else { config.method = 'get'; } // Hook up interceptors middleware var chain = [dispatchRequest, undefined]; var promise = Promise.resolve(config); this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { chain.unshift(interceptor.fulfilled, interceptor.rejected); }); this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { chain.push(interceptor.fulfilled, interceptor.rejected); }); while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } return promise; }; Axios.prototype.getUri = function getUri(config) { config = mergeConfig(this.defaults, config); return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); }; // Provide aliases for supported request methods utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { /*eslint func-names:0*/ Axios.prototype[method] = function (url, config) { return this.request(mergeConfig(config || {}, { method: method, url: url, data: (config || {}).data })); }; }); utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { /*eslint func-names:0*/ Axios.prototype[method] = function (url, data, config) { return this.request(mergeConfig(config || {}, { method: method, url: url, data: data })); }; }); var Axios_1 = Axios; /** * A `Cancel` is an object that is thrown when an operation is canceled. * * @class * @param {string=} message The message. */ function Cancel(message) { this.message = message; } Cancel.prototype.toString = function toString() { return 'Cancel' + (this.message ? ': ' + this.message : ''); }; Cancel.prototype.__CANCEL__ = true; var Cancel_1 = Cancel; /** * A `CancelToken` is an object that can be used to request cancellation of an operation. * * @class * @param {Function} executor The executor function. */ function CancelToken(executor) { if (typeof executor !== 'function') { throw new TypeError('executor must be a function.'); } var resolvePromise; this.promise = new Promise(function promiseExecutor(resolve) { resolvePromise = resolve; }); var token = this; executor(function cancel(message) { if (token.reason) { // Cancellation has already been requested return; } token.reason = new Cancel_1(message); resolvePromise(token.reason); }); } /** * Throws a `Cancel` if cancellation has been requested. */ CancelToken.prototype.throwIfRequested = function throwIfRequested() { if (this.reason) { throw this.reason; } }; /** * Returns an object that contains a new `CancelToken` and a function that, when called, * cancels the `CancelToken`. */ CancelToken.source = function source() { var cancel; var token = new CancelToken(function executor(c) { cancel = c; }); return { token: token, cancel: cancel }; }; var CancelToken_1 = CancelToken; /** * Syntactic sugar for invoking a function and expanding an array for arguments. * * Common use case would be to use `Function.prototype.apply`. * * ```js * function f(x, y, z) {} * var args = [1, 2, 3]; * f.apply(null, args); * ``` * * With `spread` this example can be re-written. * * ```js * spread(function(x, y, z) {})([1, 2, 3]); * ``` * * @param {Function} callback * @returns {Function} */ var spread = function spread(callback) { return function wrap(arr) { return callback.apply(null, arr); }; }; /** * Determines whether the payload is an error thrown by Axios * * @param {*} payload The value to test * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false */ var isAxiosError = function isAxiosError(payload) { return typeof payload === 'object' && payload.isAxiosError === true; }; /** * Create an instance of Axios * * @param {Object} defaultConfig The default config for the instance * @return {Axios} A new instance of Axios */ function createInstance(defaultConfig) { var context = new Axios_1(defaultConfig); var instance = bind$1(Axios_1.prototype.request, context); // Copy axios.prototype to instance utils.extend(instance, Axios_1.prototype, context); // Copy context to instance utils.extend(instance, context); return instance; } // Create the default instance to be exported var axios$1 = createInstance(defaults_1); // Expose Axios class to allow class inheritance axios$1.Axios = Axios_1; // Factory for creating new instances axios$1.create = function create(instanceConfig) { return createInstance(mergeConfig(axios$1.defaults, instanceConfig)); }; // Expose Cancel & CancelToken axios$1.Cancel = Cancel_1; axios$1.CancelToken = CancelToken_1; axios$1.isCancel = isCancel; // Expose all/spread axios$1.all = function all(promises) { return Promise.all(promises); }; axios$1.spread = spread; // Expose isAxiosError axios$1.isAxiosError = isAxiosError; var axios_1 = axios$1; // Allow use of default import syntax in TypeScript var _default$1 = axios$1; axios_1.default = _default$1; var axios = axios_1; var fetch$1 = null; var config$3 = null; var instance = null; Promise.prototype.done = Promise.prototype.then; Promise.prototype.fail = Promise.prototype.catch; // TextDecoder polyfills for lower browser if (undefined === window.TextEncoder) { window.TextEncoder = /*#__PURE__*/function () { function _TextEncoder() { _classCallCheck(this, _TextEncoder); } _createClass(_TextEncoder, [{ key: "encode", value: function encode(s) { return unescape(encodeURIComponent(s)).split('').map(function (val) { return val.charCodeAt(); }); } }]); return _TextEncoder; }(); window.TextDecoder = /*#__PURE__*/function () { function _TextDecoder() { _classCallCheck(this, _TextDecoder); } _createClass(_TextDecoder, [{ key: "decode", value: function decode(code_arr) { return decodeURIComponent(escape(String.fromCharCode.apply(null, code_arr))); } }]); return _TextDecoder; }(); } var http = { retry(func) { var retries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000; return new Promise(function (resolve, reject) { func().then(resolve).catch(function (error) { if (retries <= 1) { reject(error); } else { setTimeout(function () { http.retry(func, retries - 1, delay).then(resolve).catch(reject); }, delay); } }); }); }, get(url, data) { if (data && typeof data === 'object') { if (url.indexOf('?') == -1) { url += '?'; } else { url += '&'; } url += new URLSearchParams(data).toString(); } return fetch$1.get(url); }, getImage(url) { var retries = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3; if (config$3.region == 'aws') { if (url.indexOf('x-oss-process=image') != -1) { var arr = url.split('?'); url = arr[0] + encodeURIComponent('?' + arr[1].replace(/\//g, '@')); } } return http.retry(function () { return new Promise(function (resolve, reject) { var img = new Image(); img.crossOrigin = 'anonymous'; img.src = url; img.onload = function () { resolve(img); }; img.onerror = function () { reject("[".concat(url, "] load fail")); }; }); }, retries); }, getText(url) { return fetch$1.get(url, { responseType: 'text' }); }, getBueffer(url) { return fetch$1.get(url, { responseType: 'arraybuffer' }); }, getBlob(url) { return fetch$1.get(url, { responseType: 'blob' }); }, post(url, data) { return fetch$1.post(url, data); }, postFile(url, data) { var form = new FormData(); var cb = null; if (data.onUploadProgress) { cb = data.onUploadProgress; delete data.onUploadProgress; } for (var key in data) { if (key === 'files' && data[key].length > 0) { for (var i = 0; i < data[key].length; i++) { var file = data[key][i]; if (file instanceof File) { form.append(key, file); } else if (file.file) { if (file.filename) { form.append(key, file.file, file.filename); } else { form.append(key, file.file); } } else { console.warn('file is wong !', data); } } } else if (key == 'file' || key === 'filename') { if (key == 'file') { if (data.filename) { form.append('file', data[key], data.filename); } else { form.append('file', data[key]); } } } else { form.append(key, data[key]); } } return fetch$1.post(url, form, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: cb }); } }; function setup$1(app) { if (!app || instance) { return; } config$3 = app.config; instance = app; fetch$1 = axios.create({ // baseURL: 'https://v4-test.4dkankan.com', // baseURL: 'http://192.168.0.47', baseURL: config$3.server || '' }); fetch$1.interceptors.request.use(function (config) { if (config.url.indexOf('/service/') != -1) { var token = browser$1.valueFromUrl('token') || localStorage.getItem('token') || ''; if (token) { config.headers['token'] = token; } } return config; }, function (error) { return Promise.reject(error); }); fetch$1.interceptors.response.use(function (response) { // 正常的文件流 if (!/json/gi.test(response.headers['content-type'])) { return response.data; } // 以文件流方式请求但是返回json,需要解析为JSON对象 if (response.request.responseType === 'arraybuffer') { var enc = new TextDecoder('utf-8'); var res = JSON.parse(enc.decode(new Uint8Array(response.data))); return res; } if (instance && response.data.success === false) { instance.Scene.emit('error', { type: 'network', code: response.data.code, message: response.data.message }); } return response.data; }, function (error) { if (instance) { var data = null; if (error.response && error.response.data) { data = error.response.data; } else { data = { code: 500, message: error }; } if (error.config && error.config.url.indexOf('data/mapping') == -1 && error.config.url.indexOf('floorplan.json') == -1 && error.config.url.indexOf('vision2.modeldata') == -1) { instance.Scene.emit('error', { type: 'network', code: data.code, message: data.message }); } } if (error.response && error.response.data) { return Promise.reject(error.response); } return Promise.reject(error); }); } var sdk_domain = getScriptURL(); //.match(/^http(s)?:\/\/(.*?)\//)[0] var texture = { data: {} }; texture.load = function (imgUrl, addTextureFunc, failFnc) { var _texture = texture.data[imgUrl]; if (_texture) { addTextureFunc && setTimeout(function () { addTextureFunc(_texture); }, 1); return _texture; } else { _texture = new THREE.Texture(); if (settings$3.minimalMemoryMode) { _texture.minFilter = THREE.LinearFilter; _texture.magFilter = THREE.LinearFilter; _texture.generateMipmaps = !1; } _texture.sourceFile = imgUrl; texture.data[imgUrl] = _texture; http.getImage(imgUrl).then(function (img) { _texture.image = img; _texture.needsUpdate = !0; addTextureFunc && addTextureFunc(_texture); }).catch(failFnc); return _texture; } }; texture.loadWithoutUpdate = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(imgUrl, addTextureFunc, failFnc) { var _texture; return regenerator.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _texture = texture.data[imgUrl.split('?')[0]]; if (!_texture) { _context.next = 6; break; } addTextureFunc && addTextureFunc(_texture); return _context.abrupt("return", _texture); case 6: _texture = new THREE.Texture(); if (settings$3.minimalMemoryMode) { _texture.minFilter = THREE.LinearFilter; _texture.magFilter = THREE.LinearFilter; _texture.generateMipmaps = !1; } _texture.sourceFile = imgUrl; texture.data[imgUrl.split('?')[0]] = _texture; _context.next = 12; return http.getImage(imgUrl).then(function (img) { _texture.image = img; _texture.needsUpdate = !0; addTextureFunc && addTextureFunc(_texture); }).catch(failFnc); case 12: return _context.abrupt("return", _texture); case 13: case "end": return _context.stop(); } } }, _callee); })); return function (_x, _x2, _x3) { return _ref.apply(this, arguments); }; }(); texture.loadBase64 = function (base64, fileType) { fileType = fileType || 'png'; var _texture = new THREE.Texture(); _texture.image = document.createElement('img'); _texture.image.setAttribute('src', 'data:image/' + fileType + ';base64,' + base64); if (settings$3.minimalMemoryMode) { _texture.minFilter = THREE.LinearFilter; _texture.magFilter = THREE.LinearFilter; _texture.generateMipmaps = !1; } _texture.needsUpdate = !0; return _texture; }; texture.isLoaded = function (imgUrl) { return !!texture.data[imgUrl]; }; texture.getImageURL = function (path) { if (path && path.indexOf('http') === 0) { return path; } return sdk_domain + path; }; function _createSuper$1x(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1x(); 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 _isNativeReflectConstruct$1x() { 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; } } /** * @author WestLangley / http://github.com/WestLangley * * parameters = { * color: , * lineWidth: , * dashed: , * dashScale: , * dashSize: , * gapSize: , * resolution: , // to be set by renderer * } */ var line = { lineWidth: { value: 1, type: 'f' }, resolution: { value: new THREE.Vector2(1, 1), type: 'v2' }, dashScale: { value: 1, type: 'f' }, dashSize: { value: 1, type: 'f' }, gapSize: { value: 1, type: 'f' } // todo FIX - maybe change to totalSize }; var shaderLib = { uniforms: THREE.UniformsUtils.merge([THREE.UniformsLib.common, THREE.UniformsLib.fog, line]), vertexShader: '#include \n#include \n \n#include \n \nuniform float lineWidth;\nuniform vec2 resolution;\nattribute vec3 instanceStart;\nattribute vec3 instanceEnd;\nattribute vec3 instanceColorStart;\nattribute vec3 instanceColorEnd;\nvarying vec2 vUv;\n#ifdef USE_DASH\n uniform float dashScale;\n attribute float instanceDistanceStart;\n attribute float instanceDistanceEnd;\n varying float vLineDistance;\n#endif\nvoid trimSegment( const in vec4 start, inout vec4 end ) {\n float a = projectionMatrix[ 2 ][ 2 ]; \n float b = projectionMatrix[ 3 ][ 2 ]; \n float nearEstimate = - 0.5 * b / a;\n float alpha = ( nearEstimate - start.z ) / ( end.z - start.z );\n end.xyz = mix( start.xyz, end.xyz, alpha );\n}\nvoid main() {\n #ifdef USE_COLOR\n vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;\n #endif\n #ifdef USE_DASH\n vLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;\n #endif\n float aspect = resolution.x / resolution.y;\n vUv = uv;\n vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );\n vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );\n bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); \n if ( perspective ) {\n if ( start.z < 0.0 && end.z >= 0.0 ) {\n trimSegment( start, end );\n } else if ( end.z < 0.0 && start.z >= 0.0 ) {\n trimSegment( end, start );\n }\n }\n vec4 clipStart = projectionMatrix * start;\n vec4 clipEnd = projectionMatrix * end;\n vec2 ndcStart = clipStart.xy / clipStart.w;\n vec2 ndcEnd = clipEnd.xy / clipEnd.w;\n vec2 dir = ndcEnd - ndcStart;\n dir.x *= aspect;\n dir = normalize( dir );\n vec2 offset = vec2( dir.y, - dir.x );\n dir.x /= aspect;\n offset.x /= aspect;\n if ( position.x < 0.0 ) offset *= - 1.0;\n if ( position.y < 0.0 ) {\n offset += - dir;\n } else if ( position.y > 1.0 ) {\n offset += dir;\n }\n offset *= lineWidth;\n offset /= resolution.y;\n vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;\n offset *= clip.w;\n clip.xy += offset;\n gl_Position = clip;\n vec4 mvPosition = ( position.y < 0.5 ) ? start : end; \n #include \n \n \n} ', fragmentShader: 'uniform vec3 diffuse;\n uniform float opacity;\n #ifdef USE_DASH\n uniform float dashSize;\n uniform float gapSize;\n #endif\n varying float vLineDistance;\n #include \n #include \n #include \n #include \n \n varying vec2 vUv;\n void main() {\n \n #ifdef USE_DASH\n\nif ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; \n\nif ( mod( vLineDistance, dashSize + gapSize ) > dashSize ) discard; \n #endif\n if ( abs( vUv.y ) > 1.0 ) {\n\nfloat a = vUv.x;\n\nfloat b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;\n\nfloat len2 = a * a + b * b;\n\nif ( len2 > 1.0 ) discard;\n }\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n gl_FragColor = vec4( diffuseColor.rgb, diffuseColor.a );\n #include \n #include \n #include \n #include \n }' }; var lineMats = []; var LineMaterial = /*#__PURE__*/function (_THREE$ShaderMaterial) { _inherits(LineMaterial, _THREE$ShaderMaterial); var _super = _createSuper$1x(LineMaterial); function LineMaterial(parameters) { var _this; _classCallCheck(this, LineMaterial); _this = _super.call(this, { type: 'LineMaterial', uniforms: THREE.UniformsUtils.clone(shaderLib.uniforms), vertexShader: shaderLib.vertexShader, fragmentShader: shaderLib.fragmentShader }); // 因为opacity会与ShaderMaterial.opacity冲突,所以必须放在super之后 Object.defineProperties(_assertThisInitialized(_this), { opacity: { enumerable: true, get: function get() { return this.uniforms.opacity.value; }, set: function set(value) { this.uniforms.opacity.value = value; } } }); _this.isLineMaterial = true; _this.dashed = false; _this.setValues(parameters); //add: lineMats.push(_assertThisInitialized(_this)); _this.addEventListener('dispose', function () { var i = lineMats.indexOf(_assertThisInitialized(_this)); i > -1 && lineMats.splice(i, 1); }); return _this; } _createClass(LineMaterial, [{ key: "color", get: function get() { return this.uniforms.diffuse.value; }, set: function set(value) { this.uniforms.diffuse.value = value; } }, { key: "lineWidth", get: function get() { return this.uniforms.lineWidth.value; }, set: function set(value) { this.uniforms.lineWidth.value = value; } }, { key: "dashScale", get: function get() { return this.uniforms.dashScale.value; }, set: function set(value) { this.uniforms.dashScale.value = value; } }, { key: "dashSize", get: function get() { return this.uniforms.dashSize.value; }, set: function set(value) { this.uniforms.dashSize.value = value; } }, { key: "gapSize", get: function get() { return this.uniforms.gapSize.value; }, set: function set(value) { this.uniforms.gapSize.value = value; } }, { key: "resolution", get: function get() { return this.uniforms.resolution.value; }, set: function set(value) { this.uniforms.resolution.value.copy(value); } }, { key: "dashed", get: function get() { return 'USE_DASH' in this.defines; }, set: function set(value) { if (value) { this.defines.USE_DASH = ''; } else { delete this.defines.USE_DASH; } this.needsUpdate = true; } }, { key: "copy", value: function copy(source) { THREE.ShaderMaterial.prototype.copy.call(this, source); this.color.copy(source.color); this.lineWidth = source.lineWidth; this.resolution = source.resolution; // todo return this; } }], [{ key: "init", value: function init(app) { app.core.get('SceneRenderer').addComponent(this); } }, { key: "setSize", value: function setSize(x, y) { lineMats.forEach(function (e) { e.resolution = new THREE.Vector2(x, y); }); } }]); return LineMaterial; }(THREE.ShaderMaterial); // LineMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype) // LineMaterial.prototype.constructor = THREE.LineMaterial // LineMaterial.prototype.isLineMaterial = true /** * @author WestLangley / http://github.com/WestLangley * */ var LineSegmentsGeometry = /*#__PURE__*/function (_THREE$InstancedBuffe) { _inherits(LineSegmentsGeometry, _THREE$InstancedBuffe); var _super2 = _createSuper$1x(LineSegmentsGeometry); function LineSegmentsGeometry() { var _this2; _classCallCheck(this, LineSegmentsGeometry); _this2 = _super2.call(this); _this2.computeBoundingBox = function () { var box = new THREE.Box3(); return function () { if (_this2.boundingBox === null) { _this2.boundingBox = new THREE.Box3(); } var start = _this2.attributes.instanceStart; var end = _this2.attributes.instanceEnd; if (start !== undefined && end !== undefined) { _this2.boundingBox.setFromBufferAttribute(start); box.setFromBufferAttribute(end); _this2.boundingBox.union(box); } }; }(); _this2.computeBoundingSphere = function () { var vector = new THREE.Vector3(); return function () { if (_this2.boundingSphere === null) { _this2.boundingSphere = new THREE.Sphere(); } if (_this2.boundingBox === null) { _this2.computeBoundingBox(); } var start = _this2.attributes.instanceStart; var end = _this2.attributes.instanceEnd; if (start !== undefined && end !== undefined) { var center = _this2.boundingSphere.center; _this2.boundingBox.getCenter(center); var maxRadiusSq = 0; for (var i = 0, il = start.count; i < il; i++) { vector.fromBufferAttribute(start, i); maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(vector)); vector.fromBufferAttribute(end, i); maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(vector)); } _this2.boundingSphere.radius = Math.sqrt(maxRadiusSq); if (isNaN(_this2.boundingSphere.radius)) { console.error('LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', _assertThisInitialized(_this2)); } } }; }(); _this2.type = 'LineSegmentsGeometry'; new THREE.BufferGeometry(); var positions = [-1, 2, 0, 1, 2, 0, -1, 1, 0, 1, 1, 0, -1, 0, 0, 1, 0, 0, -1, -1, 0, 1, -1, 0]; var uvs = [-1, 2, 1, 2, -1, 1, 1, 1, -1, -1, 1, -1, -1, -2, 1, -2]; var index = new THREE.BufferAttribute(new Uint16Array([0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5]), 1); _this2.setIndex(index); _this2.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); _this2.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2)); _this2.isLineSegmentsGeometry = true; return _this2; } _createClass(LineSegmentsGeometry, [{ key: "applyMatrix", value: function applyMatrix(matrix) { var start = this.attributes.instanceStart; var end = this.attributes.instanceEnd; if (start !== undefined) { matrix.applyToBufferAttribute(start); matrix.applyToBufferAttribute(end); start.data.needsUpdate = true; } if (this.boundingBox !== null) { this.computeBoundingBox(); } if (this.boundingSphere !== null) { this.computeBoundingSphere(); } return this; } }, { key: "setPositions", value: function setPositions(array) { var lineSegments; if (array instanceof Float32Array) { lineSegments = array; } else if (Array.isArray(array)) { lineSegments = new Float32Array(array); } var instanceBuffer = new THREE.InstancedInterleavedBuffer(lineSegments, 6, 1); // xyz, xyz this.setAttribute('instanceStart', new THREE.InterleavedBufferAttribute(instanceBuffer, 3, 0)); // xyz this.setAttribute('instanceEnd', new THREE.InterleavedBufferAttribute(instanceBuffer, 3, 3)); // xyz // this.computeBoundingBox(); this.computeBoundingSphere(); return this; } }, { key: "setColors", value: function setColors(array) { var colors; if (array instanceof Float32Array) { colors = array; } else if (Array.isArray(array)) { colors = new Float32Array(array); } var instanceColorBuffer = new THREE.InstancedInterleavedBuffer(colors, 6, 1); // rgb, rgb this.setAttribute('instanceColorStart', new THREE.InterleavedBufferAttribute(instanceColorBuffer, 3, 0)); // rgb this.setAttribute('instanceColorEnd', new THREE.InterleavedBufferAttribute(instanceColorBuffer, 3, 3)); // rgb return this; } }, { key: "fromWireframeGeometry", value: function fromWireframeGeometry(geometry) { this.setPositions(geometry.attributes.position.array); return this; } }, { key: "fromEdgesGeometry", value: function fromEdgesGeometry(geometry) { this.setPositions(geometry.attributes.position.array); return this; } }, { key: "fromMesh", value: function fromMesh(mesh) { this.fromWireframeGeometry(new THREE.WireframeGeometry(mesh.geometry)); // set colors, maybe return this; } }, { key: "fromLineSegements", value: function fromLineSegements(lineSegments) { var geometry = lineSegments.geometry; if (geometry.isGeometry) { this.setPositions(geometry.vertices); } else if (geometry.isBufferGeometry) { this.setPositions(geometry.position.array); // assumes non-indexed } // set colors, maybe return this; } }, { key: "toJSON", value: function toJSON() {// todo } }, { key: "clone", value: function clone() {// todo } }, { key: "copy", value: function copy(source) { // todo return this; } }]); return LineSegmentsGeometry; }(THREE.InstancedBufferGeometry); /** * @author WestLangley / http://github.com/WestLangley * */ var LineGeometry = /*#__PURE__*/function (_LineSegmentsGeometry) { _inherits(LineGeometry, _LineSegmentsGeometry); var _super3 = _createSuper$1x(LineGeometry); function LineGeometry() { var _this3; _classCallCheck(this, LineGeometry); _this3 = _super3.call(this); _this3.type = 'LineGeometry'; _this3.isLineGeometry = true; return _this3; } _createClass(LineGeometry, [{ key: "setPositions", value: function setPositions(arr) { // converts [ x1, y1, z1, x2, y2, z2, ... ] to pairs format var length = arr.length - 3; var points = new Float32Array(2 * length); for (var i = 0; i < length; i += 3) { points[2 * i] = arr[i]; points[2 * i + 1] = arr[i + 1]; points[2 * i + 2] = arr[i + 2]; points[2 * i + 3] = arr[i + 3]; points[2 * i + 4] = arr[i + 4]; points[2 * i + 5] = arr[i + 5]; } _get(_getPrototypeOf(LineGeometry.prototype), "setPositions", this).call(this, points); return this; } }, { key: "setColors", value: function setColors(array) { // converts [ r1, g1, b1, r2, g2, b2, ... ] to pairs format var length = array.length - 3; var colors = new Float32Array(2 * length); for (var i = 0; i < length; i += 3) { colors[2 * i] = array[i]; colors[2 * i + 1] = array[i + 1]; colors[2 * i + 2] = array[i + 2]; colors[2 * i + 3] = array[i + 3]; colors[2 * i + 4] = array[i + 4]; colors[2 * i + 5] = array[i + 5]; } _get(_getPrototypeOf(LineGeometry.prototype), "setColors", this).call(this, colors); return this; } }, { key: "fromLine", value: function fromLine(line) { var geometry = line.geometry; if (geometry.isGeometry) { this.setPositions(geometry.vertices); } else if (geometry.isBufferGeometry) { this.setPositions(geometry.position.array); // assumes non-indexed } // set colors, maybe return this; } }, { key: "copy", value: function copy(source) { // todo return this; } }]); return LineGeometry; }(LineSegmentsGeometry); /** * @author WestLangley / http://github.com/WestLangley * */ var LineSegments2 = /*#__PURE__*/function (_THREE$Mesh) { _inherits(LineSegments2, _THREE$Mesh); var _super4 = _createSuper$1x(LineSegments2); function LineSegments2(_geometry, material) { var _this4; _classCallCheck(this, LineSegments2); _this4 = _super4.call(this, _geometry, material); _this4.computeLineDistances = function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry... var start = new THREE.Vector3(); var end = new THREE.Vector3(); return function () { var geometry = _this4.geometry; var instanceStart = geometry.attributes.instanceStart; var instanceEnd = geometry.attributes.instanceEnd; var lineDistances = new Float32Array(2 * instanceStart.data.count); for (var i = 0, j = 0, l = instanceStart.data.count; i < l; i++, j += 2) { start.fromBufferAttribute(instanceStart, i); end.fromBufferAttribute(instanceEnd, i); lineDistances[j] = j === 0 ? 0 : lineDistances[j - 1]; lineDistances[j + 1] = lineDistances[j] + start.distanceTo(end); } var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer(lineDistances, 2, 1); // d0, d1 geometry.setAttribute('instanceDistanceStart', new THREE.InterleavedBufferAttribute(instanceDistanceBuffer, 1, 0)); // d0 geometry.setAttribute('instanceDistanceEnd', new THREE.InterleavedBufferAttribute(instanceDistanceBuffer, 1, 1)); // d1 return _assertThisInitialized(_this4); }; }(); _this4.type = 'LineSegments2'; _this4.isLineSegments2 = true; _this4.geometry = _geometry !== undefined ? _geometry : new LineSegmentsGeometry(); _this4.material = material !== undefined ? material : new LineMaterial({ color: Math.random() * 0xffffff }); return _this4; } _createClass(LineSegments2, [{ key: "copy", value: function copy(source) { // todo return this; } }]); return LineSegments2; }(THREE.Mesh); var Fatline = /*#__PURE__*/function (_LineSegments) { _inherits(Fatline, _LineSegments); var _super5 = _createSuper$1x(Fatline); function Fatline(geometry, material) { var _this5; _classCallCheck(this, Fatline); _this5 = _super5.call(this, geometry, material); _this5.type = 'Fatline'; _this5.isFatline = true; _this5.geometry = geometry !== undefined ? geometry : new LineGeometry(); _this5.material = material !== undefined ? material : new LineMaterial({ color: Math.random() * 0xffffff }); return _this5; } _createClass(Fatline, [{ key: "copy", value: function copy(source) { // todo return this; } }]); return Fatline; }(LineSegments2); var defaultColor$1 = Colors.lightGreen; var player$c = null; var LineDraw = { /* 多段普通线 (第二个点和第三个点之间是没有线段的, 所以不用在意线段顺序) */ createLine: function createLine(posArr) { var o = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var mat; if (o.mat) { mat = o.mat; } else { var prop = { color: o.color || defaultColor$1, transparent: o.dontAlwaysSeen ? false : true, depthTest: o.dontAlwaysSeen ? true : false }; if (o.deshed) { prop.lineWidth = o.lineWidth || 1; //windows无效。 似乎mac/ios上粗细有效 ? prop.dashSize = o.dashSize || 0.1; prop.gapSize = o.gapSize || 0.1; } mat = new THREE[o.deshed ? 'LineDashedMaterial' : 'LineBasicMaterial'](prop); } var line = new THREE.LineSegments(new THREE.BufferGeometry(), mat); line.renderOrder = o.renderOrder || 4; this.moveLine(line, posArr); return line; }, moveLine: function moveLine(line, posArr) { if (posArr.length == 0) { return console.log(1); } var position = []; posArr.forEach(function (e) { return position.push(e.x, e.y, e.z); }); line.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(position), 3)); line.geometry.attributes.position.needsUpdate = true; line.geometry.computeBoundingSphere(); if (line.material instanceof THREE.LineDashedMaterial) { line.computeLineDistances(); } }, createFatLineMat: function createFatLineMat(o) { var matParam = Object.assign({}, { //默认 lineWidth: 5, color: 0xffffff, transparent: true, depthWrite: false, depthTest: false, dashSize: 0.1, gapSize: 0.1 }, o, {//修正覆盖: // dashed /* polygonOffset: true, //是否开启多边形偏移 for not cover the lineMesh polygonOffsetFactor: -o.width * 2.5 || -5, //多边形偏移因子 polygonOffsetUnits: -4.0, //多边形偏移单位 */ }); var mat = new LineMaterial(matParam); return mat; }, /* 创建可以改变粗细的线。 */ createFatLine: function createFatLine(posArr, o) { var geometry = new LineGeometry(); geometry.setColors(o.color || [1, 1, 1]); var matLine = o.material || this.createFatLineMat(o); var line = new Fatline(geometry, matLine); //line.computeLineDistances(); line.scale.set(1, 1, 1); line.renderOrder = 2; this.moveFatLine(line, posArr); return line; }, /* createFatLine: function (posArr, o) { var geometry = new THREE.BufferGeometry() geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(posArr), 3)) geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(o.color || [1, 1, 1]), 3)) var matLine = o.material || this.createFatLineMat(o) var line = new THREE.Line(geometry, matLine) line.computeLineDistances() line.scale.set(1, 1, 1) line.renderOrder = 2 return line }, */ moveFatLine: function moveFatLine(line, posArr) { var geometry = line.geometry; var positions = []; posArr.forEach(function (e) { return positions.push(e.x, e.y, e.z); }); if (positions.length > 0) { if (!geometry) { geometry = line.geometry = new LineGeometry(); } if (geometry.attributes.instanceEnd && geometry.attributes.instanceEnd.data.array.length != positions.length) { //positions个数改变会有部分显示不出来,所以重建 geometry.dispose(); geometry = new LineGeometry(); line.geometry = geometry; } geometry.setPositions(positions); if (line.material.dashed) { //line.geometry.computeBoundingSphere(); line.computeLineDistances(); } } else { geometry.dispose(); line.geometry = new LineGeometry(); } }, /* moveFatLine: function (line, posArr) { var geometry = line.geometry geometry.setPositions(posArr) }, */ /* 为line创建用于检测鼠标的透明mesh,实际是个1-2段圆台。 由于近大远小的原因,假设没有透视畸变、创建的是等粗的圆柱的话, 所看到的线上每个位置的粗细应该和距离成反比。所以将圆柱改为根据距离线性渐变其截面半径的圆台,在最近点(相机到线的垂足)最细。如果最近点在线段上,则分成两段圆台,否则一段。 */ createBoldLine: function createBoldLine(points, o, p) { player$c = p; o = o || {}; var cylinder = o && o.cylinder; var CD = points[1].clone().sub(points[0]); var rotate = function rotate() { //根据端点旋转好模型 cylinder.lastVector = CD; //记录本次的端点向量 var AB = new THREE.Vector3(0, -1, 0); var axisVec = AB.clone().cross(CD).normalize(); //得到垂直于它们的向量,也就是旋转轴 var rotationAngle = AB.angleTo(CD); cylinder.quaternion.setFromAxisAngle(axisVec, rotationAngle); }; if (o && o.type == 'init') { cylinder = new THREE.Mesh(); cylinder.material = o.mat; if (CD.length() == 0) return cylinder; rotate(); } if (CD.length() == 0) return cylinder; if (o.type != 'update') { var CDcenter = points[0].clone().add(points[1]).multiplyScalar(0.5); cylinder.position.copy(CDcenter); if (!cylinder.lastVector || o.type == 'moveAndRotate') rotate();else if (cylinder.lastVector && CD.angleTo(cylinder.lastVector) > 0) rotate(); //线方向改了or线反向了 重新旋转一下模型 // if (config.isEdit && !objects.mainDesign.editing) return cylinder //节省初始加载时间? } //为了保证线段任何地方的可检测点击范围看起来一样大,更新圆台的结构(但是在镜头边缘会比中心看起来大) var height = points[0].distanceTo(points[1]); var standPos = o && o.standPos || player$c.position; var k = config$4.isMobile ? 20 : 40; var dis1 = points[0].distanceTo(standPos); var dis2 = points[1].distanceTo(standPos); var foot = math$1.getFootPoint(standPos, points[0], points[1]); //垂足 if (o.constantBold || player$c.mode != 'panorama') { var width = 0.1; //0.08; var pts = [new THREE.Vector2(width, height / 2), new THREE.Vector2(width, -height / 2)]; } else if (foot.clone().sub(points[0]).dot(foot.clone().sub(points[1])) > 0) { //foot不在线段上 var pts = [new THREE.Vector2(dis1 / k, height / 2), new THREE.Vector2(dis2 / k, -height / 2)]; } else { //在线段上的话,要在垂足这加一个节点,因它距离站位最近,而两端较远 var dis3 = foot.distanceTo(standPos); var len = foot.distanceTo(points[0]); var pts = [new THREE.Vector2(dis1 / k, height / 2), new THREE.Vector2(dis3 / k, height / 2 - len), new THREE.Vector2(dis2 / k, -height / 2)]; } cylinder.geometry && cylinder.geometry.dispose(); //若不删除会占用内存 cylinder.geometry = new THREE.LatheBufferGeometry(pts, 4 /* Math.min(dis1,dis2)<10?4:3 */ ); cylinder.renderOrder = 2; return cylinder; }, updateBoldLine: function updateBoldLine(cylinder, points, type, standPos, constantBold) { this.createBoldLine(points, { type: type, cylinder: cylinder, standPos: standPos, constantBold }, player$c); //type:move:平移 会改长短 , type:update根据距离和角度更新 不改长短 }, Fatline, fatLineGeometry: LineGeometry }; function _createSuper$1w(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1w(); 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 _isNativeReflectConstruct$1w() { 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; } } var markerGeometry = new THREE.PlaneBufferGeometry(0.4, 0.4, 1, 1); var stemLineLen = 0.5; var config$2, player$b; var videoPanoTags = []; var getStemMat = function () { var stemMat; return function () { return stemMat || (stemMat = new VideoLineMaterial(), stemMat); }; }(); var getVideoSpotMat = function () { var spotMat; return function () { return spotMat || (spotMat = new VideoPlayerMaterial(), spotMat); }; }(); var getVideoMarkerMat = function () { var mat; return function () { return mat || (mat = new VideoPanoMarkerMaterial(), mat); }; }(); var getMarkerTex = function () { var markerTex; return function (name) { if (!markerTex) { markerTex = common.loadTextureFromCache(texture.getImageURL(config$2.scene.markerURL || 'images/marker.png')); markerTex.minFilter = THREE.LinearMipMapLinearFilter; markerTex.generateMipmaps = true; markerTex.anisotropy = 4; // 各向异性过滤 .防止倾斜模糊 } return markerTex; }; }(); /* var getVideTex = (function () { let markerTex return function (name) { if (!markerTex) { markerTex = common.loadTextureFromCache(texture.getImageURL(config.scene.markerURL || 'images/marker.png')) markerTex.minFilter = THREE.LinearMipMapLinearFilter markerTex.generateMipmaps = true markerTex.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊 } return markerTex })() */ var initOpacityProp = function initOpacityProp(material, marker) { var opa = material.opacity; Object.defineProperty(material, 'opacity', { get: function get() { return opa; }, set: function set(o) { if (material instanceof VideoPanoMarkerMaterial) { marker = material.marker; //仅有一个,切换到不同pano上 } opa = o; //if(o>0)console.log('o>0',this.pano.id) common.updateVisible(marker, 'hideWhenZeroOpa', o != 0); } }); }; var Marker = /*#__PURE__*/function (_THREE$Mesh) { _inherits(Marker, _THREE$Mesh); var _super = _createSuper$1w(Marker); function Marker(pano) { var _this; _classCallCheck(this, Marker); _this = _super.call(this); player$b = pano.$app.core.get('Player'); _this.pano = pano; _this.config = config$2 = pano.$app.config; _this.geometry = markerGeometry; _this.widget = null; _this.material = new THREE.MeshBasicMaterial({ map: getMarkerTex('normalMarker'), side: THREE.DoubleSide, opacity: 0, //许钟文 change transparent: !0, depthWrite: !1, depthTest: false }); _this.visible = false; //add 加速加载 _this.renderOrder = RenderOrder.panoMarker; _this.name = 'marker'; _this.layers.set(RenderLayers.PANOMARKERS); _this.updateMatrixWorld(); _this.initAnimate(); settings$3.colorMarkerOnLoad && _this.on('load', function () { this.marker.material.color.set(65280); }); //xzw { initOpacityProp(_this.material, _assertThisInitialized(_this)); var vis = _this.visible; Object.defineProperty(_assertThisInitialized(_this), 'visible', { get: function get() { return vis; }, set: function set(v) { if (pano.flagSpot) { v ? pano.flagSpot.show() : pano.flagSpot.hide(); //console.log('marker Visi', pano.id, v) } vis = v; } }); } return _this; } _createClass(Marker, [{ key: "updateStyle", value: function updateStyle(model, type) { //console.log('updateStyle', this.pano.id, type) var oldOpacity = this.material.opacity; if (type == 'animate') { var videoMarkerMat = getVideoMarkerMat(); videoMarkerMat.marker = this; if (this.material != videoMarkerMat) { this.normalMaterial = this.material; this.material = videoMarkerMat; } } else { this.normalMaterial && (this.material = this.normalMaterial); if (type == 'video') { this.setWidget(model, this.pano, type); } else { this.pano.oldFlagSpot = this.pano.flagSpot; this.pano.flagSpot = null; this.pano.oldFlagSpot && this.pano.oldFlagSpot.hide(); } } this.material.opacity = oldOpacity; } }, { key: "setWidget", value: function setWidget(model, pano, type) { // 球幕播放图标 if (type == 'video') { if (pano.oldFlagSpot) { pano.flagSpot = pano.oldFlagSpot; } else if (!pano.flagSpot) { var tag = new VideoPanoTag(model, 'flagSpot___' + pano.id, { position: pano.position.clone(), state: 'videoPanoFlag', sid: 'flagSpot___' + pano.id, style: 'videoMarker', pano }); tag.style = 'videoMarker'; // 球幕图标线 var line = tag.createMarkLine({ type: 'flagSpot', stemLineLen, markerPos: this.position }); line.marker = this; tag.rePos(tag.markLine.groundPoint.clone().add(new THREE.Vector3(0, stemLineLen, 0))); //tag.rePos(tag.markLine.position.clone().add(new THREE.Vector3(0, stemLineLen/2, 0))) videoPanoTags.push(tag); // 用于animate pano.flagSpot = tag; if (!this.visible) tag.hide(); //初始化可见性 } } } }, { key: "initAnimate", value: function initAnimate() { if (animateInited) return; player$b.on('update', function () { animate(); }); animateInited = true; } }]); return Marker; }(THREE.Mesh); var animateMaterialQuene = []; var progress = 0; //let minProgress = 0; //let maxProgress = 0; var bigCircleProgress = 0; var smallCircleProgress0 = -0.12; //间隔 var smallCircleProgress = smallCircleProgress0; var animateInited; var speed = 0.0045; var noGif = true; function animate() { for (var i = 0; i < animateMaterialQuene.length; i++) { animateMaterialQuene[i].uniforms['progress'].value = progress; animateMaterialQuene[i].uniforms['bigCircleProgress'].value = bigCircleProgress; animateMaterialQuene[i].uniforms['smallCircleProgress'].value = smallCircleProgress; } videoPanoTags.forEach(function (tag) { return tag.update(); }); if (progress > 1) { progress = 0; } progress += speed; if (bigCircleProgress > 1.0) { if (noGif) { //为false的话在别处调控 bigCircleProgress = 0; smallCircleProgress = smallCircleProgress0; //间隔 } } else { bigCircleProgress += speed; smallCircleProgress += speed; } } var VideoPanoTag = /*#__PURE__*/function (_EventEmitter) { _inherits(VideoPanoTag, _EventEmitter); var _super2 = _createSuper$1w(VideoPanoTag); function VideoPanoTag(model, sid, tagData) { var _this2; _classCallCheck(this, VideoPanoTag); _this2 = _super2.call(this); _this2.model = model; _this2.sid = sid; _this2.floor = null; _this2.floors = []; _this2.position = new THREE.Vector3().copy(tagData.position); //position最好提到外面,像pano的position一样,因为有的计算函数就是这么用的 _this2.content = {}; _this2.initContent(tagData); _this2.snapInfo = tagData.snapInfo; _this2.style = tagData.style || 'default'; _this2.color = new THREE.Color().setRGB(0.0, 0.7843137254901961, 0.6862745098039216); tagData.color && _this2.color.setStyle(tagData.color); _this2.styleImageURL = tagData.styleImageURL; _this2.hoverColor = Colors._darken(_this2.content.color, 0.2); _this2.animTime = 0; _this2.animated = false; _this2.openning = 0; _this2.openTransition = null; _this2.mode = Viewmode$1.PANORAMA; _this2.obj3d = null; //THREE.Object3D 类型 _this2.disc = null; //mesh类型 _this2.discWorldPosition = null; _this2.discScale = 0.06; _this2.floorIndex = tagData.floorIndex; _this2.visibleTransition = null; _this2.hoveringDisc = !1; _this2.state = tagData.state; _this2.videoPano = tagData.pano; _this2.build(); return _this2; } _createClass(VideoPanoTag, [{ key: "initContent", value: function initContent(tagData) { //和billboard有关 this.content.description = tagData.description; this.content.label = tagData.label; this.content.link = tagData.link; this.content.outLink = tagData.outLink; this.content.color = new THREE.Color().set(tagData.color || Colors.tagDefault); //this.content.floorIndex = tagData.floorIndex || 0; this.content.fileName = tagData.fileName || {}; //存储音频视频原文件名 this.content.fileSrc = tagData.fileSrc || {}; //存储音频视频的完整地址。原先是七牛,现在是阿里云的oss了 this.content.media = tagData.media || []; } }, { key: "getFloors", value: function getFloors() { var _this3 = this; //根据floor和visiblePanos 得到热点所在的所有可能楼层。 包括原先所在的floor和所有可见点所在楼层。 this.floors = []; //拥有多楼层的原因: 热点会在tagVisibleOnCurrentFloor来隐藏热点,会使楼道间的热点只在部分位置可见。 this.visiblePanos && this.visiblePanos.forEach(function (id) { if (_this3.model.panos.index[id]) { if (!_this3.floors.includes(_this3.model.panos.index[id].floor)) { _this3.floors.push(_this3.model.panos.index[id].floor); } } }); if (this.floor && !this.floors.includes(this.floor)) this.floors.push(this.floor); } }, { key: "rePos", value: function rePos(pos) { //add by xzw 重新定位置 this.position.copy(pos); this.obj3d.position.copy(pos); } }, { key: "createMarkLine", value: function createMarkLine(o) { this.markLine = new VideoMarkLine({ type: o.type, stemLineLen: o.stemLineLen, markerPos: o.markerPos, tag: this, model: this.model }); return this.markLine; } }, { key: "build", value: function build() { this.floor = this.videoPano.floor; this.floorIndex = this.floor.floorIndex; if (this.floor) { this.obj3d = this.buildObject3D(); this.floor.add(this.obj3d); } this.getFloors(); return this; } }, { key: "buildObject3D", value: function buildObject3D() { var _this4 = this; var group = new THREE.Object3D(); group.position.copy(this.position); var config = this.model.$app.config; this.animated = true; var planeGeo = config.isMobile ? new THREE.PlaneBufferGeometry(2.4, 2.4) : new THREE.PlaneBufferGeometry(1, 1); this.disc = new THREE.Mesh(planeGeo, getVideoSpotMat()); this.disc.layers.set(RenderLayers.PANOMARKERS); this.disc.renderOrder = RenderOrder.panoMarker; //tagDisc 不要遮住overlay等 player$b.on('mode.changing', function (from, to) { _this4.disc.renderOrder = to != 'floorplan' ? RenderOrder.panoMarker : 5; //floorplan时需要提高,其他时候需要比透明楼层低 }); this.disc.tag = this; this.disc.pano = this.videoPano; this.disc.name = 'disc'; group.add(this.disc); group.name = 'tagGroup'; return group; } }, { key: "hide", value: function hide(e, t) { if (this.hidden) return;else this.hidden = true; // var i = KanKan.Deferred() // if (0 === this.disc.material.uniforms.opacity.value && !transitions.isRunning(this.visibleTransition)) return i.resolve().promise() // ;(e = e || 0), (t = t || 0), transitions.cancel(this.visibleTransition) if (this.markLine) this.markLine.hide(); //add //xst if (this.disc) { this.disc.visible = false; } } }, { key: "show", value: function show(e, t) { if (!this.hidden) return;else this.hidden = false; // var i = KanKan.Deferred() // if (this.disc.material.uniforms.opacity.value === 1 && !transitions.isRunning(this.visibleTransition)) return i.resolve().promise() // ;(e = e || 0), (t = t || 0), transitions.cancel(this.visibleTransition) if (this.markLine) this.markLine.show(); //add //xst if (this.disc) { this.disc.visible = true; } } }, { key: "update", value: function update() { if (!this.disc) return; this.discWorldPosition = this.disc.getWorldPosition(new THREE.Vector3()); this.updateDisc(); } /* 更新disc的大小和朝向 朝向: billboard的效果,只需要mesh.quaternion = camera.quaternion 大小:在保证距离不变的情况下,要消除屏幕边缘放大的效果,需要结合camera和屏幕(应该和projection有关),如下一顿操作 然后再考虑距离,smoothstep化近大远小 */ }, { key: "updateDisc", value: function updateDisc() { var mode = this.model.mode; var camera = this.model.player.mode == 'floorplan' ? this.model.player.cameraControls.activeControl.camera : this.model.player.camera; //floorplan 时要用到OrthographicCamera var u = settings$3.tags.visibility, d = settings$3.tags.disc.scale, p = mode === Viewmode$1.DOLLHOUSE || mode === Viewmode$1.FLOORPLAN ? settings$3.tags.visibility.visibleDistance : camera.position.distanceTo(this.discWorldPosition); //改 许钟文 // 只是用来设置obj3d.visible。显隐控制要设置marker this.obj3d.visible = 0 !== this.disc.material.opacity && (u.anyDistance || p <= u.visibleDistance || mode === Viewmode$1.TRANSITIONING) && (!u.hideViaFloor || this.tagVisibleOnCurrentFloor(mode)) && (!u.hideOffScreenDisc || !this.offScreen(this.disc, camera)) && (!u.hideOffScreenObject || !this.offScreen(this.obj3d, camera)); if (this.obj3d.visible && this.disc.visible) { //add this.disc.visible //this.markLine.stemLine.quaternion.copy(camera.quaternion) this.markLine.stemLine.rotation.y = -new THREE.Vector2(this.markLine.stemLine.position.x - camera.position.x, this.markLine.stemLine.position.z - camera.position.z).angle() + Math.PI / 2; //this.disc.quaternion.copy(camera.quaternion) var _player = this.model.$app.core.get('Player'); if (_player.modeTran.split('-')[1] == 'floorplan') { this.disc.quaternion.copy(camera.quaternion); } else { this.disc.lookAt(camera.position); //for video tag 看起来和marker一样有点歪斜、立体点 } //this.disc.rotation.y = -new THREE.Vector2(this.obj3d.position.x - camera.position.x, this.obj3d.position.z - camera.position.z).angle() + Math.PI / 2 //scale: var scale = math$1.getScaleForConstantSize({ maxSize: d.maxSize, minSize: this.state == 'videoPanoFlag' && mode != Viewmode$1.PANORAMA ? 30 : d.minSize, nearBound: d.nearBound, farBound: d.farBound, camera: camera, position: this.discWorldPosition, dom: this.model.$app.dom }); var response = 1 + settings$3.tags.disc.scale.responsiveness / 100 * (VideoPanoTag.viewportScale() - 1); this.discScale = scale * response; try { //editor player可能还没有 if (this.model.player.linkEditor.setTagVisible) { //许钟文add 编辑热点可视时放大热点 this.discScale *= 1.5; // config.isMobile ? 2 : 1.5 } else if (this.isMeasurePoint) { this.discScale *= 0.9; } else if (this.model.$app.TagManager.editHandle && this.model.$app.TagManager.editHandle.editing) { this.discScale *= 2.5; } } catch (mode) {} this.disc.scale.set(2 * this.discScale, 2 * this.discScale, 2 * this.discScale); //使stem的顶部在圆圈底部 var circleRadius = this.discScale * 0.95; this.markLine.stemLine.scale.y = (stemLineLen - circleRadius) / stemLineLen; //不要覆盖住圆圈 this.markLine.stemLine.position.copy(this.markLine.stemLine.originPos); this.markLine.stemLine.position.y -= circleRadius / 2; // if (this.animated) { // this.animTime += 0.016 // this.disc.material.uniforms['uTime'].value = this.animTime // } } } }, { key: "tagVisibleOnCurrentFloor", value: function tagVisibleOnCurrentFloor(e) { return !(e === Viewmode$1.DOLLHOUSE || e === Viewmode$1.FLOORPLAN) || this.model.allFloorsVisible || !!this.floors.find(function (floor) { return !floor.hidden; }); } // updateVideoFlagVisible() { // if (!this.obj3d.visible || this.model.player.mode != 'dollhouse') return // if (this.model.allFloorsVisible && convertTool.ifShelter(this.position, this.model.player, null, null, this.model.currentFloor.floorIndex)) { // this.videoPano.marker.visible = false // } else { // this.videoPano.marker.visible = !!this.videoPano.marker.visibleOri // } // } }], [{ key: "viewportScale", value: function viewportScale() { var player = document.getElementsByClassName('player')[0]; return VideoPanoTag.viewportWidth === player.clientWidth && VideoPanoTag.viewportHeight === player.clientHeight || (VideoPanoTag.viewportWidth = player.clientWidth, VideoPanoTag.viewportHeight = player.clientHeight, VideoPanoTag.currentViewportScale = Math.sqrt(Math.min(VideoPanoTag.viewportWidth, VideoPanoTag.viewportHeight) / settings$3.tags.disc.scale.baseViewportSize)), VideoPanoTag.currentViewportScale; } }]); return VideoPanoTag; }(EventEmitter); var VideoMarkLine = /*#__PURE__*/function () { function VideoMarkLine(o) { _classCallCheck(this, VideoMarkLine); this.tag = o.tag; this.groundPoint = o.groundPoint || o.markerPos; //垂线和地面交点 // this.stemLine = LineDraw.createLine([o.stemLineLen ? this.groundPoint.clone().add(new THREE.Vector3(0, o.stemLineLen, 0)) : o.tag.position, this.groundPoint], { // width: 2, // color: o.stemLineColor || '#eee', // }) //垂线 this.stemLine = new THREE.Mesh(new THREE.PlaneBufferGeometry(0.006, o.stemLineLen), getStemMat()); this.stemLine.position.copy(this.groundPoint.clone().add(new THREE.Vector3(0, o.stemLineLen / 2, 0))); this.stemLine.originPos = this.stemLine.position.clone(); this.stemLine.name = 'markGroup-stemLine'; this.stemLine.layers.set(RenderLayers.PANOMARKERS); this.stemLine.renderOrder = RenderOrder.panoMarker; this.tag.obj3d.parent.add(this.stemLine); } _createClass(VideoMarkLine, [{ key: "hide", value: function hide() { this.stemLine.visible = false; } }, { key: "show", value: function show() { this.stemLine.visible = true; } }]); return VideoMarkLine; }(); //闪烁的marker var VideoPanoMarkerMaterial = /*#__PURE__*/function (_THREE$RawShaderMater) { _inherits(VideoPanoMarkerMaterial, _THREE$RawShaderMater); var _super3 = _createSuper$1w(VideoPanoMarkerMaterial); function VideoPanoMarkerMaterial() { var _this5; _classCallCheck(this, VideoPanoMarkerMaterial); _this5 = _super3.call(this); var u = THREE.UniformsUtils.clone(shaders.videoPanoMarker.uniforms); u.map.value = getMarkerTex('normalMarker'); u.opacity.value = 1; _this5.vertexShader = shaders.videoPanoMarker.vertexShader; _this5.fragmentShader = shaders.videoPanoMarker.fragmentShader; _this5.uniforms = u; _this5.transparent = true; _this5.depthTest = false; //browser.detectIOS() && (this.defines['useColor2'] = '') initOpacityProp(_assertThisInitialized(_this5)); animateMaterialQuene.push(_assertThisInitialized(_this5)); return _this5; } return VideoPanoMarkerMaterial; }(THREE.RawShaderMaterial); var VideoLineMaterial = /*#__PURE__*/function (_THREE$RawShaderMater2) { _inherits(VideoLineMaterial, _THREE$RawShaderMater2); var _super4 = _createSuper$1w(VideoLineMaterial); function VideoLineMaterial() { var _this6; _classCallCheck(this, VideoLineMaterial); _this6 = _super4.call(this); var u = THREE.UniformsUtils.clone(shaders.videoStemLine.uniforms); _this6.vertexShader = shaders.videoStemLine.vertexShader, _this6.fragmentShader = shaders.videoStemLine.fragmentShader, _this6.uniforms = u; _this6.transparent = true; _this6.depthTest = false; _this6.side = THREE.DoubleSide; animateMaterialQuene.push(_assertThisInitialized(_this6)); return _this6; } return VideoLineMaterial; }(THREE.RawShaderMaterial); /* //视频播放按钮 class VideoPlayerMaterial extends THREE.RawShaderMaterial { constructor() { super() var u = THREE.UniformsUtils.clone(shaders.tagVideoMarker.uniforms) ;(this.vertexShader = shaders.tagVideoMarker.vertexShader), (this.fragmentShader = shaders.tagVideoMarker.fragmentShader), (this.uniforms = u) this.transparent = true this.depthTest = false this.side = THREE.DoubleSide this.uniforms.map.value = getMarkerTex('shineMarker') animateMaterialQuene.push(this) } } */ var VideoPlayerMaterial = /*#__PURE__*/function (_THREE$MeshBasicMater) { _inherits(VideoPlayerMaterial, _THREE$MeshBasicMater); var _super5 = _createSuper$1w(VideoPlayerMaterial); function VideoPlayerMaterial() { var _this7; _classCallCheck(this, VideoPlayerMaterial); var map = texture.load(texture.getImageURL('images/videoTag.png')); var animateInfo = { cellXcount: 6, cellYcount: 5, voidCount: 0, loop: true, duration: 1200, //动画时长 delay: 600, //延迟 waitNextTime: 1700 //间隔 }; _this7 = _super5.call(this, { map, transparent: true, depthTest: false }); //飞出要被模型遮挡 _this7.animation = common.GifTexDeal.addAnimation(map, _assertThisInitialized(_this7), animateInfo, 0); _this7.animation.startCallback = function () { bigCircleProgress = 0; smallCircleProgress = smallCircleProgress0; //间隔 }; noGif = false; common.GifTexDeal.start(_this7.animation); player$b.on('mode.changing', function (from, to) { _this7.depthTest = to != 'floorplan' && to != 'panorama'; //因为即使提高了renderOrder还是会被透明的楼层遮住所以设置一下这个(renderOrder需要比透明楼层低才能不被遮,但又要比当前楼层高,而当前楼层要比透明的高,所以不可能) }); return _this7; } return VideoPlayerMaterial; }(THREE.MeshBasicMaterial); var GLCubeFaces$1 = { GL_TEXTURE_CUBE_MAP_POSITIVE_X: 0, GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1, GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 3, GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 4, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5 }; var TileUtils = {}; TileUtils.TILE_SIZE = 512, TileUtils.FACES_PER_PANO = 6, TileUtils.LocationOnTile = { Center: 0, UpperLeft: 1, UpperRight: 2, LowerRight: 3, LowerLeft: 4 }, TileUtils.getTileVector = function () { //获取某tile在cube中的方向 direction (向量起点在cube中心,终点在tile图的中心) return function (size, tileSize, cubeFace, tileX, tileY, Center, c, dir) { //c似乎是缩进百分比 Center = Center || TileUtils.LocationOnTile.Center; //假设该cube边长为2: var u = size / tileSize, d = tileX / u; tileY = -tileY + (u - 1); var p = tileY / u, f = tileSize / size, g = 2 * f, //一个tile的宽度 (乘以2是因为cube边长是2) m = g / 2, v = 2 * d - 1 + m, A = 2 * p - 1 + m; switch (Center //计算在tile中指定位置带来的偏移 ) { case TileUtils.LocationOnTile.UpperLeft: v -= m, A += m, v += c * g; //似乎是向内缩进 break; case TileUtils.LocationOnTile.UpperRight: v += m, A += m, A -= c * g; break; case TileUtils.LocationOnTile.LowerRight: v += m, A -= m, v -= c * g; break; case TileUtils.LocationOnTile.LowerLeft: v -= m, A -= m, A += c * g; break; case TileUtils.LocationOnTile.Center: //0 } switch (cubeFace) { case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_X: MathLight.setVector(dir, -1, A, -v); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_X: MathLight.setVector(dir, 1, A, v); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Y: //顶面 MathLight.setVector(dir, -v, 1, -A); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: MathLight.setVector(dir, -v, -1, A); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Z: MathLight.setVector(dir, -v, A, 1); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: MathLight.setVector(dir, v, A, -1); } MathLight.normalize(dir); }; }(), TileUtils.getFaceForTile = function (size, index) { //获取该tile在第几个面 var tileSize = TileUtils.TILE_SIZE; size < TileUtils.TILE_SIZE && (tileSize = size); var n = Math.floor(size / tileSize), sum = n * n; //得每个面tile总数 return Math.floor(index / sum); }, TileUtils.getTileLocation = function (size, t, result) { var tileSize = TileUtils.TILE_SIZE; size < TileUtils.TILE_SIZE && (tileSize = size); var r = TileUtils.getFaceForTile(size, t), a = Math.floor(size / tileSize), s = a * a, l = t - r * s; result.tileX = l % a; result.tileY = Math.floor(l / a); result.face = r; result.faceTileIndex = l; return result; //add }, TileUtils.getTileCountForSize = function (e) { if (e <= TileUtils.TILE_SIZE) return TileUtils.FACES_PER_PANO; var t = Math.floor(e / TileUtils.TILE_SIZE), i = t * t, n = i * TileUtils.FACES_PER_PANO; return n; }, TileUtils.getRelativeDirection = function () { var e = new MathLight.Matrix4(), t = new MathLight.Quaternion(); return function (i, n) { //i是pano.quaternion, n是camera的direction t.copy(i), t.inverse(), e.makeRotationFromQuaternion(t), e.applyToVector3(n), MathLight.normalize(n); }; }(), TileUtils.matchingTilesInDirection = function () { var e = new MathLight.Vector3(), t = new MathLight.Vector3(0, 0, -1), i = new MathLight.Quaternion(), n = function n(e, t) { e.push({ face: t.face, faceTileIndex: t.faceTileIndex, tileX: t.tileX, tileY: t.tileY }); }, a = function () { var e = { face: -1, faceTileIndex: -1, tileX: -1, tileY: -1 }; return function (size, i, r) { for (var a = TileUtils.getTileCountForSize(size), s = 0, l = 0; l < a; l++) { TileUtils.getTileLocation(size, l, e), i && !i(e) || (s++, r && n(r, e)); } return s; }; }(); return function (pano, size, dir, hFov, vFov, result) { var d = size < TileUtils.TILE_SIZE ? size : TileUtils.TILE_SIZE; //TileUtils.getTileCountForSize(size); if (!hFov && !vFov) return a(size, null, result); var p = !!vFov; vFov = vFov || hFov, vFov = Math.max(0, Math.min(vFov, 360)), hFov = Math.max(0, Math.min(hFov, 360)), MathLight.copyVector(dir, e), TileUtils.getRelativeDirection(pano.quaternion, e); if (p) { //如果有vFov hFov i.setFromUnitVectors(e, t); var f = function f(e) { return TileUtils.isTileWithinFrustum(size, d, e.face, e.tileX, e.tileY, i, hFov, vFov); //在视野中的 }; return a(size, f, result); } var g = function g(t) { //如果仅有hFov return TileUtils.isTileWithinFOV(size, d, t.face, t.tileX, t.tileY, e, hFov); }; return a(size, g, result); }; }(), TileUtils.isTileWithinFrustum = function () { var e = new MathLight.Vector3(), t = 1e-5; return function (i, n, a, s, l, c, h, u) { for (var d = Math.tan(0.5 * u * MathLight.RADIANS_PER_DEGREE), p = -d, f = Math.tan(0.5 * h * MathLight.RADIANS_PER_DEGREE), g = -f, m = TileUtils.mapFaceToCubemapFace(a), v = 0, A = 0, y = 0, C = 0, E = 0, b = TileUtils.LocationOnTile.Center; b <= TileUtils.LocationOnTile.LowerLeft; b++) { TileUtils.getTileVector(i, n, m, s, l, b, 0, e), //get e // size, tileSize, cubeFace, tileX, tileY, Center, c, dir MathLight.applyQuaternionToVector(c, e); if (e.z >= -t) //似乎是在相机背面 ;else { var w = -1 / e.z, _ = e.x * w, T = e.y * w; T > d ? v++ : T < p && A++, //这四种似乎代表在这个画框之外,如在左、在上、在下、在右 _ > f ? y++ : _ < g && C++, E++; } } return A !== E && v !== E && y !== E && C !== E; //如果有一项和E相等代表要么是在相机背面要么是tile的四个顶点都画在画布的同一边,所以肯定不在画布上 }; }(), TileUtils.isTileWithinFOV = function () { var e = new MathLight.Vector3(), t = new MathLight.Vector3(0, 1, 0), i = new MathLight.Vector3(1, 0, 0); return function (panoSize, tileSize, face, tileX, tileY, direction, fov) { //direction是作用了pano.quaternion的camera.direction var d = TileUtils.mapFaceToCubemapFace(face); MathLight.cross(direction, t, i); //get i 好像没用到 TileUtils.getTileVector(panoSize, tileSize, d, tileX, tileY, TileUtils.LocationOnTile.Center, 0, e); if (TileUtils.isWithinFOV(e, direction, fov, null)) //先判断tile中心在不在FOV内 return !0; for (var p = fov / 360, f = Math.floor(1 / p), g = 0, m = 0; m < f; m++) { for (var v = TileUtils.LocationOnTile.UpperLeft; v <= TileUtils.LocationOnTile.LowerLeft; v++) { if (TileUtils.getTileVector(panoSize, tileSize, d, tileX, tileY, v, g, e), TileUtils.isWithinFOV(e, direction, fov, null)) return !0; } g += p; //可能是考虑到有可能tile比fov覆盖了fov(虽然一般不可能,除非fov特别小),所以将tile分成若干段,取tile中的点再检测下 } return !1; }; }(), TileUtils.isWithinFOV = function () { var e = new MathLight.Vector3(), t = new MathLight.Vector3(); return function (dir, cameraDir, fov, a) { if (MathLight.copyVector(dir, t), a) { MathLight.copyVector(a, e), MathLight.normalize(e); var s = MathLight.dot(e, dir); e.x *= s, e.y *= s, e.z *= s, MathLight.subVector(t, e); } var l = fov / 2 * MathLight.RADIANS_PER_DEGREE, c = Math.cos(l), h = MathLight.dot(t, cameraDir); return h >= c; }; }(), TileUtils.mapFaceToCubemapFace = function () { var e = { 0: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 2: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 3: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 4: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 5: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y }; return function (t) { return e[t]; }; }(); function _createForOfIteratorHelper$7(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$7(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$7(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$7(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$7(o, minLen); } function _arrayLikeToArray$7(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _createSuper$1v(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1v(); 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 _isNativeReflectConstruct$1v() { 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; } } var player$a; var planeGeo$1 = new THREE.PlaneBufferGeometry(1, 1, 1, 1); var TextSprite = /*#__PURE__*/function (_THREE$Object3D) { _inherits(TextSprite, _THREE$Object3D); var _super = _createSuper$1v(TextSprite); function TextSprite() { var _this; var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, TextSprite); _this = _super.call(this); var map = new THREE.Texture(); _this.root = options.root || _assertThisInitialized(_this); //if (options.fixOrient) { _this.sprite = new THREE.Mesh(planeGeo$1, new THREE.MeshBasicMaterial({ map, color: 0xffffff, transparent: true, depthTest: false, depthWrite: false })); /*} else { this.sprite = new THREE.Sprite( new THREE.SpriteMaterial({ map, color: 0xffffff, transparent: true, depthTest: false, depthWrite: false, }) ) } */ _this.add(_this.sprite); _this.sprite.renderOrder = options.renderOrder != void 0 ? options.renderOrder : 2; _this.fontWeight = options.fontWeight == void 0 ? /* 'Bold' */ '' : options.fontWeight; _this.rectBorderThick = options.rectBorderThick || 0; _this.textBorderThick = options.textBorderThick || 0; _this.fontface = 'Arial'; _this.fontsize = options.fontsize || 16; _this.textBorderColor = options.textBorderColor || { r: 0, g: 0, b: 0, a: 0.0 }; _this.backgroundColor = options.backgroundColor || { r: 255, g: 255, b: 255, a: 1.0 }; _this.textColor = options.textColor || { r: 0, g: 0, b: 0, a: 1.0 }; _this.borderColor = options.borderColor || { r: 0, g: 0, b: 0, a: 0.0 }; _this.borderRadius = options.borderRadius == void 0 ? 6 : options.borderRadius; _this.margin = options.margin; _this.textshadowColor = options.textshadowColor; if (options.text != void 0) _this.setText(options.text); _this.name = options.name; _this.sizeInfo = options.sizeInfo; //this.setText(text); player$a = options.player; _this.addEventListener('dispose', _this.dispose.bind(_assertThisInitialized(_this))); _this.fixOrient = options.fixOrient; _this.events = { updatePose: _this.updatePose.bind(_assertThisInitialized(_this)) }; options.player.on('update', _this.events.updatePose); _this.addEventListener('isVisible', function (e) { if (e.visible) { _this.updatePose(); } }); _this.updatePose(); return _this; } _createClass(TextSprite, [{ key: "updatePose", value: function updatePose() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$lastFrameChanged = _ref.lastFrameChanged, lastFrameChanged = _ref$lastFrameChanged === void 0 ? true : _ref$lastFrameChanged; if (lastFrameChanged) this.needsUpdate = true; if (!common.realVisible(this) || !this.needsUpdate) return; this.needsUpdate = false; var camera = player$a.mode == 'floorplan' ? player$a.cameraControls.activeControl.camera : player$a.camera; //floorplan 时要用到OrthographicCamera if (!this.fixOrient) { var parentQua = this.root.parent.getWorldQuaternion(new THREE.Quaternion()); this.root.quaternion.multiplyQuaternions(parentQua.invert(), camera.quaternion); //乘上parentQua.invert()是为了中和掉父结点的qua,使只剩下camera.quaternion } if (this.sizeInfo) { var _player$cameraControl; var s = math$1.getScaleForConstantSize(Object.assign({ camera: ((_player$cameraControl = player$a.cameraControls.activeControl) === null || _player$cameraControl === void 0 ? void 0 : _player$cameraControl.camera) || player$a.cameraControls.cameras.panorama, dom: player$a.domElement }, this.sizeInfo, { farBound: player$a.mode == 'floorplan' ? this.sizeInfo.farBoundPlan || this.sizeInfo.farBound : this.sizeInfo.farBound, position: this.root.getWorldPosition(new THREE.Vector3()) })); this.scale.set(s, s, s); } } }, { key: "setText", value: function setText(text) { if (this.text !== text) { if (!(text instanceof Array)) { this.text = [text + '']; } else this.text = text; this.updateTexture(); this.needsUpdate = true; } } }, { key: "setPos", value: function setPos(pos) { this.position.copy(pos); this.needsUpdate = true; //updatePose } }, { key: "setTextColor", value: function setTextColor(color) { this.textColor = color; this.updateTexture(); } }, { key: "setBorderColor", value: function setBorderColor(color) { this.borderColor = color; this.updateTexture(); } }, { key: "setBackgroundColor", value: function setBackgroundColor(color) { this.backgroundColor = color; this.updateTexture(); } }, { key: "setVisible", value: function setVisible(v) { this.visible = v; } }, { key: "setUniforms", value: function setUniforms(name, value) { this.sprite.setUniforms(name, value); } }, { key: "updateTexture", value: function updateTexture() { var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.font = this.fontWeight + ' ' + this.fontsize + 'px ' + this.fontface; //context["font-weight"] = 100; //语法与 CSS font 属性相同。 // get size data (height depends only on font size) //this.text = 'f 啊啊啊 jg' var textMaxWidth = 0, infos = []; var _iterator = _createForOfIteratorHelper$7(this.text), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var text = _step.value; var metrics = context.measureText(text); var textWidth = metrics.width; infos.push(metrics); textMaxWidth = Math.max(textMaxWidth, textWidth); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } var margin = this.margin || new THREE.Vector2(this.fontsize, Math.max(this.fontsize * 0.4, 10)); var lineSpace = (this.fontsize + margin.y) * 0.5; var spriteWidth = 2 * margin.x + textMaxWidth + 2 * this.rectBorderThick; var spriteHeight = 2 * margin.y + this.fontsize * this.text.length + 2 * this.rectBorderThick + lineSpace * (this.text.length - 1); context.canvas.width = spriteWidth; context.canvas.height = spriteHeight; context.font = this.fontWeight + ' ' + this.fontsize + 'px ' + this.fontface; var expand = Math.max(1, Math.pow(this.fontsize / 12, 1.4)); // 针对英文大部分在baseLine之上所以降低一点,或者可以识别当不包含jgqp时才加这个值 //canvas原点在左上角 context.textBaseline = 'alphabetic'; // "middle" //设置文字基线。当起点y设置为0时,只有该线以下的部分被绘制出来。middle时文字显示一半(但是对该字体所有字的一半,有的字是不一定显示一半的,尤其汉字),alphabetic时是英文字母的那条基线。 // border color context.strokeStyle = 'rgba(' + this.borderColor.r + ',' + this.borderColor.g + ',' + this.borderColor.b + ',' + this.borderColor.a + ')'; context.lineWidth = this.rectBorderThick; // background color context.fillStyle = 'rgba(' + this.backgroundColor.r + ',' + this.backgroundColor.g + ',' + this.backgroundColor.b + ',' + this.backgroundColor.a + ')'; this.roundRect(context, this.rectBorderThick / 2, this.rectBorderThick / 2, spriteWidth - this.rectBorderThick, spriteHeight - this.rectBorderThick, this.borderRadius); context.fillStyle = 'rgba(' + this.textColor.r + ',' + this.textColor.g + ',' + this.textColor.b + ',' + this.textColor.a + ')'; var y = margin.y; for (var i = 0; i < this.text.length; i++) { //let actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent // 当前文本字符串在这个字体下用的实际高度 //文字y向距离从textBaseline向上算 var actualBoundingBoxAscent = infos[i].actualBoundingBoxAscent == void 0 ? this.fontsize * 0.8 : infos[i].actualBoundingBoxAscent; //有的流览器没有。只能大概给一个 y += actualBoundingBoxAscent + expand; //console.log(actualBoundingBoxAscent) //console.log(this.text, 'y' , y, 'actualBoundingBoxAscent', metrics.actualBoundingBoxAscent,'expand',expand ) var textLeftSpace = (textMaxWidth - infos[i].width) / 2; var x = this.rectBorderThick + margin.x + textLeftSpace; // text color if (this.textBorderThick) { context.strokeStyle = 'rgba(' + this.textBorderColor.r + ',' + this.textBorderColor.g + ',' + this.textBorderColor.b + ',' + this.textBorderColor.a + ')'; context.lineWidth = this.textBorderThick; context.strokeText(this.text[i], x, y); } if (this.textshadowColor) { context.shadowOffsetX = 0; context.shadowOffsetY = 0; context.shadowColor = this.textshadowColor; context.shadowBlur = 12; } context.fillText(this.text[i], x, y); y += lineSpace; } var texture = new THREE.Texture(canvas); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.anisotropy = 4; texture.needsUpdate = true; //this.material.needsUpdate = true; if (this.sprite.material.map) { this.sprite.material.map.dispose(); } this.sprite.material.map = texture; this.sprite.scale.set(spriteWidth * 0.01, spriteHeight * 0.01, 1.0); } }, { key: "roundRect", value: function roundRect(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x + r, y); ctx.lineTo(x + w - r, y); ctx.arcTo(x + w, y, x + w, y + r, r); //圆弧。前四个参数同quadraticCurveTo //ctx.quadraticCurveTo(x + w, y, x + w, y + r); //二次贝塞尔曲线需要两个点。第一个点是用于二次贝塞尔计算中的控制点,第二个点是曲线的结束点。 ctx.lineTo(x + w, y + h - r); ctx.arcTo(x + w, y + h, x + w - r, y + h, r); ctx.lineTo(x + r, y + h); ctx.arcTo(x, y + h, x, y + h - r, r); ctx.lineTo(x, y + r); ctx.arcTo(x, y, x + r, y, r); ctx.closePath(); ctx.fill(); ctx.stroke(); } }, { key: "dispose", value: function dispose() { this.sprite.material.map.dispose(); this.sprite.material.dispose(); this.parent && this.parent.remove(this); this.sprite.dispatchEvent({ type: 'dispose' }); this._listeners = []; this.events.updatePos && options.player.off('update', this.events.updatePose); } }]); return TextSprite; }(THREE.Object3D); var Vectors$1 = { UP: new THREE.Vector3(0, 1, 0), DOWN: new THREE.Vector3(0, -1, 0), LEFT: new THREE.Vector3(-1, 0, 0), RIGHT: new THREE.Vector3(1, 0, 0), FORWARD: new THREE.Vector3(0, 0, -1), BACK: new THREE.Vector3(0, 0, 1), ZERO: new THREE.Vector3(0, 0, 0) }; function _createSuper$1u(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1u(); 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 _isNativeReflectConstruct$1u() { 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; } } var rot90 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), -Math.PI / 2); var labelProp$1 = { backgroundColor: { r: 0, g: 0, b: 0, a: 0 }, textColor: { r: 255, g: 255, b: 255, a: 1 }, //textBorderColor:{r:30 , g:30, b: 30, a: 1 }, //textBorderThick:3, //textshadowColor: '#888', fixOrient: true, renderOrder: RenderOrder.panoMarker, //panoLabel, fontsize: 30 }; var labelProp2 = { backgroundColor: { r: 255, g: 255, b: 255, a: 0.4 }, textColor: { r: 0, g: 0, b: 0, a: 1 }, borderRadius: 15, renderOrder: RenderOrder.panoMarker }; // 显示点位 var addLabel$2 = browser$1.urlHasValue('panoLabel'); var Panorama = /*#__PURE__*/function (_EventEmitter) { _inherits(Panorama, _EventEmitter); var _super = _createSuper$1u(Panorama); function Panorama($app, sweepuuid, sweepLocation, videoInfo, supportsTiles) { var _this; _classCallCheck(this, Panorama); _this = _super.call(this); _this.raycastToFindFloor = function () { var e = [new THREE.Vector3(0, -1, 0), new THREE.Vector3(1, -1, 0), new THREE.Vector3(0, -1, 1), new THREE.Vector3(-1, -1, 0), new THREE.Vector3(0, -1, -1), new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 0, 1), new THREE.Vector3(-1, 0, 0), new THREE.Vector3(0, 0, -1)]; return function () { //logger.warn("Performance warning: Raycasting to find floor index"); for (var t = 0; t < e.length; t++) { var i = new THREE.Raycaster(this.position.clone(), e[t].clone()), n = i.intersectObjects(this.model.colliders); if (n.length) return n[0].object.parent.floor; } return null; }; }(); _this.findNeighourPanos = function () { return this.model.panos.setNeighbour(this.id, this.id, !1), this.model.panos.forEach(function (e) { if (e !== this && (!this.model.panos.neighbourMap[this.id] || void 0 === this.model.panos.neighbourMap[this.id][e.id])) { var t = this.position.distanceTo(e.position); if (t > settings$3.panoramaNeighbourMaxDistance) return this.model.panos.setNeighbour(this, e, !1), void Panorama.raycastsSkipped++; var i = e.position.clone().sub(this.position).normalize(), o = new THREE.Raycaster(this.position, i.clone(), 0, t), s = o.intersectObjects(this.model.colliders); Panorama.raycastsDone++, this.model.panos.setNeighbour(this, e, 0 === s.length), settings$3.showNeighbourRaycasts && (s.length ? this.floor.model.add(new THREE.ArrowHelper(i, this.position, s[0].distance, 16711680)) : this.floor.model.add(new THREE.ArrowHelper(i, this.position, t, 16777215, 0, 0))); } }.bind(this)), this.model.panos.neighbourMap[this.id]; }; _this.enter = function () { /* var e = null return function () { this.setZoomed(!1), this.emit('enter', { oldPano: e, newPano: this, }), (e = this) } */ var old = null; return function () { this.setZoomed(!1), this.emit(PanoramaEvents.Enter, old, this), old = this; this.model.setHighMap(this); //add this.model.dispatchEvent({ type: 'panoEntered' }); }; }(); _this.loadTiledPano = function () { var downloaded = {}, eventAdded = {}, latestPartialRequest = {}; //每个pano对应一组这些 return function (size, dir, fov, o, a, s) { null !== o && void 0 !== o || (o = !0), null !== a && void 0 !== a || (a = !0); var l = this.getWaitDeferred(size), c = l.deferred, h = null, u = null; fov && ('number' == typeof fov ? h = fov : (h = fov.hFov, u = fov.vFov)); if (!this.isLoaded(size)) { //console.log('开始加载贴图', this.id, size ) if (!l.active) { l.active = !0; var name = this.id + ':' + size; downloaded[name] = downloaded[name] || []; /* this.downloaded = downloaded this.latestPartialRequest = latestPartialRequest */ latestPartialRequest[name] = null; if (fov) { var tileArr = []; //add var d = TileUtils.matchingTilesInDirection(this, size, dir, h, u, tileArr); latestPartialRequest[name] = tileArr; downloaded[name].forEach(function (e) { var item = latestPartialRequest[name].find(function (a) { return e.faceTileIndex == a.faceTileIndex && e.face == a.face; }); if (item) { item.loaded = true; } }); if (!latestPartialRequest[name].some(function (e) { return !e.loaded; })) { //所需要的全部加载成功 //let total = TileUtils.getTileCountForSize(size) //this.onPanoRendered(this.id, size, total, !0); c.resolve(size /* , total */ ); this.resetWaitDeferred(size); //console.log('该部分早已经加载好了'+size, this.id) latestPartialRequest[name] = null; } logger$1.info('Loading partial pano: ' + this.id + ' with ' + d + ' tiles'); } if (!eventAdded[this.id]) { eventAdded[this.id] = !0; this.on(PanoramaEvents.LoadComplete, function (e, t) { //本次任务全部加载完毕 //console.warn('点位(可能部分)下载完成 ', 'id:' + this.id, 'count:' + t) var i = this.getWaitDeferred(e).deferred; //"pending"为还未完成 i && 'pending' === i.state() && this.highestPartialTileRenderOpCompleted >= e && (i.resolve(e, t), this.resetWaitDeferred(e)); //恢复active为false }.bind(this)); this.on(PanoramaEvents.LoadFailed, function (e) { var t = this.getWaitDeferred(e).deferred; t && 'pending' === t.state() && this.highestPartialTileRenderOpCompleted >= e && (t.reject(e), this.resetWaitDeferred(e)); //恢复active为false }.bind(this)); this.on(PanoramaEvents.TileLoaded, function (size, tileIndex, total) { //每张加载完时 //size == 512 && console.log('tileLoaded', 'id:' + this.id, 'size:' + size, 'index:' + tileIndex) var name = this.id + ':' + size; downloaded[name] = downloaded[name] || []; //不是所有的加载都是从loadTiledPano获取的所以会有未定义的情况 var _TileUtils$getTileLoc = TileUtils.getTileLocation(size, tileIndex, {}), faceTileIndex = _TileUtils$getTileLoc.faceTileIndex, face = _TileUtils$getTileLoc.face; downloaded[name].push({ faceTileIndex, face }); var r = this.getWaitDeferred(size).deferred; if (r && 'pending' === r.state()) { r.notify(size, tileIndex, total); if (latestPartialRequest[name]) { var item = latestPartialRequest[name].find(function (e) { return e.faceTileIndex == faceTileIndex && e.face == face; }); item && (item.loaded = true); if (!latestPartialRequest[name].some(function (e) { return !e.loaded; })) { //所需要的局部tiles全部加载成功 this.onPanoRendered(this.id, size, total, !0); //onPanoRendered还会触发 PanoramaEvents.LoadComplete r.resolve(size, total); this.resetWaitDeferred(size); //console.log('该部分加载好了'+size, this.id) latestPartialRequest[name] = null; } } } }.bind(this)); } } this.tileDownloader.clearForceQueue(); this.tileDownloader.forceQueueTilesForPano(this, size, dir, h, u, s); var quality = this.curTileQuality || this.qualityManager.getMaxNavPanoSize(); //xzw: add quality this.tiledPanoRenderTarget = this.panoRenderer.activateTiledPano(this, quality, o); this.panoRenderer.renderPanoTiles(this.id, dir, a, null, quality); } else { //console.log('早已经全加载好了' + size, this.id) c.resolve(size); } return c.promise(); }; }(); _this.id = sweepuuid; _this.panoType = sweepLocation.panoType; //标记特殊 如 'assistant'校准热点时的相机协助点 '360view' 独立全景 //alignmentType是用来标记户外的拍摄点是否校准了,这个数据存放在vision.modeldata里,我们四维看看没有这个数据 //UNKNOWN = 0;ALIGNED = 1;UNALIGNED = 2;MANUALLY_PLACED = 3; //this.alignmentType = sweepLocation.alignmentType || AlignmentType.ALIGNED; _this.neighbourUUIDs = sweepLocation.neighbours || []; //null _this.neighbourPanos = null; _this.floor = null; _this.floorIndex = sweepLocation.subgroup || 0; _this.failedLoadingAt = 0; _this.maxLoadRetries = 4; _this.origin = sweepLocation.position.clone(); //this.position = this.alignmentType === AlignmentType.UNALIGNED ? new THREE.Vector3(0,-5,0) : sweepLocation.position.clone(); _this.position = sweepLocation.position.clone(); _this.quaternion = sweepLocation.quaternion.clone(); _this.appId = sweepLocation.index + 1; _this.$app = $app; _this.model = _this.$app.core.get('Player').model; /* this.skyboxMesh = new THREE.Mesh(settings.sphereBufferGeometry) //skyboxMesh飞出后能表示当前position的小球 this.skyboxMesh.position.copy(this.position) this.skyboxMesh.name = 'skybox' */ _this.debugColor = new THREE.Color().setHSL(0.06 + 0.53 * Math.random(), 0.8 + 0.2 * Math.random(), 0.5 + 0.2 * Math.random()); _this.floorPosition = sweepLocation.puck ? sweepLocation.puck.clone() : null; _this.marker = null; //许钟文: _this.noBlockPanos = []; //不穿墙 sweepLocation.noBlocks,//算法很不准,不用了 _this.blocks = []; //会导致穿墙的mesh _this.seeMarkers = sweepLocation.seeMarkers; _this.tiled = sweepLocation.tiled != void 0 ? sweepLocation.tiled : _this.model.supportsTiles; if (_this.isAligned()) { _this.marker = new Marker(_assertThisInitialized(_this)); } var rot90qua = new THREE.Quaternion().multiplyQuaternions(_this.quaternion, rot90); //改 为球目全景照片而改 var rot90Matrix = new THREE.Matrix4().compose(_this.position, rot90qua, new THREE.Vector3(1, 1, 1)); //转90度后的 if (_this.tiled) { /*var quaternion = new THREE.Quaternion().multiplyQuaternions(this.quaternion, rot90) //改 为球目全景照片而改 this.skyboxMesh.quaternion.copy(quaternion) this.skyboxMesh.updateMatrix() this.skyboxMesh.updateMatrixWorld() this.rot90Matrix = this.skyboxMesh.matrixWorld.clone() */ //this.panoMatrix = new THREE.Matrix4().makeRotationFromQuaternion(this.quaternion) _this.rot90Matrix = rot90Matrix; // 给热点校准用 因为热点求点时所右乘的matrix必须是单张全景照片时用的转90度的matrix才行 _this.matrixWorld = new THREE.Matrix4().compose(_this.position, _this.quaternion, new THREE.Vector3(1, 1, 1)); } else { _this.solidSkybox = new THREE.Texture([null, null, null, null, null, null]); _this.solidSkybox.flipY = !1; if (settings$3.minimalMemoryMode) { _this.solidSkybox.minFilter = THREE.LinearFilter; _this.solidSkybox.magFilter = THREE.LinearFilter; _this.solidSkybox.generateMipmaps = !1; } //-------许钟文-----全景贴图的quaternion不同----- /* var quaternion = sweepLocation.quaternion.clone() //var rot90 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0), -Math.PI/2); this.quaternion = new THREE.Quaternion().multiplyQuaternions(quaternion, rot90) //改 为球目全景照片而改 */ _this.quaternion = rot90qua; _this.matrixWorld = rot90Matrix; } /* this.skyboxMesh.material.color = new THREE.Color(1, 1, 1) this.skyboxMesh.quaternion.copy(this.quaternion) this.skyboxMesh.name = 'skybox' this.skyboxMesh.visible = !1 this.skyboxMesh.updateMatrix() this.skyboxMesh.updateMatrixWorld() */ _this.zoomed = !1; _this.panoRenderer = null; _this.qualityManager = null; _this.tileDownloader = null; _this.tiledPanoRenderTarget = null; _this.resolutionPromise = {}; _this.minimumTiledPanoLoaded = !1; _this.highestPartialTileRenderOpCompleted = 0; _this.highestFullTileRenderOpCompleted = 0; _this.shouldRedrawOnBaseLoaded = !1; _this.lockUntilRenderingComplete = !1; if (videoInfo) { _this.hasVideo = true; //是否有球幕视频 _this.videoInfo = videoInfo; } else { _this.hasVideo = false; //是否有球幕视频 } _this.panoVideo = false; //是否有去绿布视频 /* settings.colorMarkerOnLoad && this.on('load', function () { this.marker.material.color.set(65280) }) */ _this.filterEffect = { brightness: 0, contrast: 0, saturation: 0, temperature: 0 }; return _this; } _createClass(Panorama, [{ key: "hasFilter", get: function get() { var _ref = this.$app.FilterManager.filterTemp[this.id] || this.filterEffect, brightness = _ref.brightness, contrast = _ref.contrast, saturation = _ref.saturation, temperature = _ref.temperature; return brightness !== 0 || contrast !== 0 || saturation !== 0 || temperature !== 0; } }, { key: "exit", value: function exit() { //console.log('exit', this.id) if (this.tiled) { this.clearWaitDeferreds(); this.minimumTiledPanoLoaded = !1; this.tiledPanoRenderTarget = null; this.setZoomed(!1); this.panoRenderer.deactivateTiledPano(this); this.highestPartialTileRenderOpCompleted = 0; this.highestFullTileRenderOpCompleted = 0; } else { if (!this.useAtScreenB) { this.solidSkybox.dispose(); this.solidSkybox.loaded = !1; this.solidSkybox.version = 0; } } this.emit('exit'); } }, { key: "hoverOn", value: function hoverOn(e) { if ( /* (this.hasVideo && this.panoVideoRenderer.ifEnable()) || */ settings$3[e].markerOpacityOnHover == 0 || this.$app.core.get('Player').locked) return; if (this.marker) { transitions$1.start(lerp.property(this.marker.material, 'opacity', settings$3[e].markerOpacityOnHover), 250); } } }, { key: "hoverOff", value: function hoverOff(e) { if ( /* (this.hasVideo && this.panoVideoRenderer.ifEnable()) || */ settings$3[e].markerOpacity == 0 || this.$app.core.get('Player').locked) return; this.marker && transitions$1.start(lerp.property(this.marker.material, 'opacity', settings$3[e].markerOpacity), 250); } }, { key: "build1", value: function build1() { this.floor = this.floor || this.model.floors.get(this.floorIndex) || this.raycastToFindFloor() || this.model.floors.list[0]; //this.model.getFloorAtPoint(this.position) this.floorIndex = this.floor.floorIndex; //xzw add 2023.12.28 否则wallManager错的楼层获取的错的data this.floor.addPano(this); this.floorPosition = this.floorPosition || this.raycastFloorPosition(); this.neighbourPanos = this.neighbourPanos || this.findNeighourPanos(); if (settings$3.colorMarkerByFloor && this.marker) { this.marker.material.color.set(this.floor.debugColor); } } }, { key: "build2", value: function build2() { var _this2 = this; this.floorPosition = this.floorPosition || this.interpolateFloorPosition(); this.height = this.position.distanceTo(this.floorPosition); this.placeMarker(); if (this.isAligned()) { this.$app.config.view || this.addLabel(); setTimeout(function () { addLabel$2 && _this2.addLabel2(); }, 1); } } }, { key: "placeMarker", value: function placeMarker() { if (this.marker) { this.marker.position.copy(this.floorPosition); this.marker.position.y += 0.01; this.marker.lookAt(new THREE.Vector3(0, 1, 0).add(this.marker.position)); } } }, { key: "attachToPanoRenderer", value: function attachToPanoRenderer(panoRenderer) { this.panoRenderer = panoRenderer; this.panoRenderer.on(PanoRendererEvents.TileRenderSuccess, this.onTileRendered.bind(this)); this.panoRenderer.on(PanoRendererEvents.PanoRenderComplete, this.onPanoRendered.bind(this)); this.panoRenderer.on(PanoRendererEvents.TileRenderFailure, this.onTileRenderFail.bind(this)); this.panoRenderer.on(PanoRendererEvents.UploadAttemptedForAllTiles, this.onUploadAttemptedForAllTiles.bind(this)); } }, { key: "updateMakerStyle", value: function updateMakerStyle(type) { if (!this.marker) return; if (type == 'animate') { this.marker.updateStyle(this.model, 'animate', this); } else if (this.hasVideo && this.panoVideoRenderer.ifEnable() || this.panoVideo) { this.marker.updateStyle(this.model, 'video', this); } else { this.marker.updateStyle(this.model, 'normal', this); } } /* updateMarkerVisible(ifShow, player) { //video if (!this.flagSpot) return if (!this.isAligned()) return // 强制隐藏 if (!ifShow) { this.marker.visible = false return } // 漫游可行时要全部显示 if (player.linkEditor && player.linkEditor.setPanoVisible) { this.marker.visible = true return } // 没有邻居点时隐藏 if (!player.linkEditor.checkHasNeighbor(this)) { this.marker.visible = false // if (player.mode != 'panorama') this.marker.visible = true // if (!this.flagSpot) this.marker.visible = false return } // PANORAMA时,当前点位不可视时隐藏 if (player.currentPano == Viewmode.PANORAMA && !this.neighbourPanos[player.currentPano.id]) { this.marker.visible = false return } this.marker.visible = true // if (this.flagSpot) this.flagSpot.updateVideoFlagVisible() //注:不用hasVideo来判断,因有的手机没有flagSpot } */ }, { key: "createVrMarker", value: function createVrMarker(vrTexture, player) { var _this3 = this; if (this.isAligned()) { this.vrMarker = new THREE.Sprite(new THREE.SpriteMaterial({ // color: new r.Color('#00c8af'),//16777215, transparent: !0, opacity: 0.75, map: vrTexture, depthTest: false })); this.vrMarker.name = 'vrMarker'; this.vrMarker.scale.set(0.16, 0.16, 1), this.vrMarker.boluoType = 'vr'; //this.vrMarker.position.z = 1, this.vrMarker.position.copy(this.position), this.vrMarker.position.y -= 0.2, this.vrMarker.enabled = !0; this.vrMarker.visible = !1; this.vrMarker.renderOrder = RenderOrder.panoMarker //add ; this.vrMarker.pano = this, //xzw add this.model.vrMarkers.push(this.vrMarker); this.model.add(this.vrMarker); this.vrMarker.addEventListener('click', function () { if (window.VRScreenType != 'portrait') { player.flyToPano({ pano: _this3 }); } }); } } }, { key: "hasNeighbor", value: function hasNeighbor() { var _this4 = this; return this.neighbourUUIDs.filter(function (id) { return id != _this4.id; }).length > 0; } /** * lv yuanyuan * 球幕视频 */ }, { key: "attachToPanoVideoRenderer", value: function attachToPanoVideoRenderer(panoVideoRenderer) { if (!this.hasVideo) return; this.panoVideoRenderer = panoVideoRenderer; //this.panoVideoRenderer.on(PanoVideoRendererEvents.ResumeRender, this.onVideoRendered.bind(this)); this.on(PanoramaEvents.Enter, panoVideoRenderer.onVideoPanoramasEnter.bind(panoVideoRenderer)); this.on(PanoramaEvents.Exit, panoVideoRenderer.onVideoPanoramasExit.bind(panoVideoRenderer)); } }, { key: "getWaitDeferred", value: function getWaitDeferred(size) { var t = this.resolutionPromise[this.id]; t || (t = {}, this.resolutionPromise[this.id] = t); var i = t[size]; return i || (i = { deferred: Deferred$1(), active: !1 }, t[size] = i), i; } }, { key: "resetWaitDeferred", value: function resetWaitDeferred(e) { var t = this.getWaitDeferred(e); t.active = !1; t.deferred = Deferred$1(); } }, { key: "clearWaitDeferreds", value: function clearWaitDeferreds() { var e = this.resolutionPromise[this.id]; e || (e = {}, this.resolutionPromise[this.id] = e); for (var t in e) { if (e.hasOwnProperty(t)) { var i = e[t]; i.active = !1, i.deferred = Deferred$1(); } } } }, { key: "onUploadAttemptedForAllTiles", value: function onUploadAttemptedForAllTiles(e, t, i) { if (e === this.id) { var n = this.qualityManager.getPanoSize(PanoSizeClass.BASE); if (t === n && this.shouldRedrawOnBaseLoaded) { this.shouldRedrawOnBaseLoaded = !1; this.panoRenderer.resetRenderStatus(this.id, !0, !1); this.panoRenderer.renderPanoTiles(this.id, null, !0, !0); } } } }, { key: "onTileRendered", value: function onTileRendered(e, t, i, n) { e === this.id && this.emit(PanoramaEvents.TileLoaded, t, i, n); } }, { key: "onPanoRendered", value: function onPanoRendered(e, t, i, n) { if (e === this.id) { //console.log('onPanoRendered', this.id) this.minimumTiledPanoLoaded = !0; this.updateSkyboxForZoomLevel(); t > this.highestPartialTileRenderOpCompleted && (this.highestPartialTileRenderOpCompleted = t); !n && t > this.highestFullTileRenderOpCompleted && (this.highestFullTileRenderOpCompleted = t); this.emit('load', t); this.model.emit('load', this); this.emit(PanoramaEvents.LoadComplete, t, i); } } }, { key: "setZoomed", value: function setZoomed(e) { this.zoomed = e; this.updateSkyboxForZoomLevel(); if (e) { //add if (this.$app.core.get('QualityManager').navTileClass != '1k') { this.model.showHighMap(); } } else { this.model.hideHighMap(); } } }, { key: "ensureSkyboxReadyForRender", value: function ensureSkyboxReadyForRender() { if (this.tiled) ; else { this.solidSkybox.loaded || (this.solidSkybox.needsUpdate = !0); this.solidSkybox.loaded = !0; } } }, { key: "updateSkyboxForZoomLevel", value: function updateSkyboxForZoomLevel() { this.minimumTiledPanoLoaded && this.model.updateProjectedPanos(this); //xzw add this } }, { key: "getSkyboxTexture", value: function getSkyboxTexture() { if (this.tiled) { if (this.minimumTiledPanoLoaded) { if (this.zoomed && this.qualityManager.maxRenderTargetSize > this.qualityManager.maxNavPanoSize) { //change 如果放大后和不放大都是2k就不用这个 return this.panoRenderer.zoomRenderTarget.texture; } else { return this.tiledPanoRenderTarget && this.tiledPanoRenderTarget.texture; } } else { return null; } } else { return this.solidSkybox; } } }, { key: "onTileRenderFail", value: function onTileRenderFail(e, t, i) { e === this.id && this.emit(PanoramaEvents.LoadFailed, t); } //e是'high'或者'low' /* isLoaded(e) { if (this.tiled) { if (e && 'string' == typeof e) throw new BasicException('Wrong panoSize given to Panorama.isLoaded(); a tiled pano uses PanoSizeClass') return !!this.minimumTiledPanoLoaded && (!e || this.highestPartialTileRenderOpCompleted >= e) } if (e && 'number' == typeof e) { console.error('Wrong panoSize given to Panorama.isLoaded(); a non-tiled pano uses high/low.') } return !!this.solidSkybox.high || e in this.solidSkybox } */ }, { key: "isLoaded", value: function isLoaded(e) { if (this.tiled) { if (e && 'string' == typeof e) console.error('Wrong panoSize given to Panorama.isLoaded(); a tiled pano uses PanoSizeClass'); return !!this.minimumTiledPanoLoaded && (!e || this.highestFullTileRenderOpCompleted >= e); //改:原本是:this.highestPartialTileRenderOpCompleted >= e, 希望这代表全部加载完 } if (e && 'number' == typeof e) console.error('Wrong panoSize given to Panorama.isLoaded(); a non-tiled pano uses high/low.'); return !!this.solidSkybox.high || e in this.solidSkybox; } /* loadCube(e) {//旧的加载六张 if (this.isLoaded(e)) { logger.info('Skipping load of pano, already loaded') return Deferred().when() } this.emit('loading', e) this.model.emit('loading', this) var t = this.getCubemapUrls(this.id, e), i = t.filter(function (e) { return !e }) if ('low' === e && i.length > 0) { logger.info('Pano', this.id, 'not available in low res, loading high res right away') e = 'high' t = this.getCubemapUrls(this.id, e) } var n = 0, r = [0, 1, 2, 3, 4, 5].map( function (e, i, n) { return this.loadCubeImage(t[i]) }.bind(this) ) return Deferred() .when(r[0], r[1], r[2], r[3], r[4], r[5]) .then( function (t, i, n, r, o, a) { return ( (this.solidSkybox[e] = [t, i, n, r, o, a]), ('high' !== e && this.solidSkybox.high) || ((this.solidSkybox.image = this.solidSkybox[e]), (this.solidSkybox.low = null)), (this.solidSkybox.needsUpdate = !0), this.emit('load', e), this.model.emit('load', this), this ) }.bind(this), function () { logger.error('Downloading cubemap for pano', this.id, 'failed'), (this.failedLoadingAt = Date.now()) }.bind(this), function () { return Deferred().when(++n, 6) } ) } */ }, { key: "loadCube", value: function loadCube(imgRatio) { //新的加载单张 if (this.isLoaded(imgRatio)) { logger$1.info('Skipping load of pano, already loaded'); return Defer.when(); } this.emit('loading', imgRatio); this.model.emit('loading', this); var cubeImgUrl = this.getCubemapUrls(this.id, imgRatio); if (this.panoType == '360view') { //xzw add //cubeImgUrl = cubeImgUrl.replace("tiles/", (config.isEdit ? ("panorama_edit/"+this.id) : ("panorama/"+this.id) ) + "/tiles/" ); var player = this.$app.core.get('Player'); if (!player.viewLinkManager.views[this.id]) return; var ext = player.viewLinkManager.views[this.id].panoImgVersion; ext && (cubeImgUrl += '&' + ext); } return http.getImage(cubeImgUrl).then(function (imgData) { this.solidSkybox[imgRatio] = imgData; this.solidSkybox.minFilter = THREE.LinearFilter; //1006 防止竖条纹 // "high" !== imgRatio && this.solidSkybox.high || (this.solidSkybox.image = this.solidSkybox[imgRatio], // this.solidSkybox.low = null), if ('high' !== imgRatio && this.solidSkybox.high) ; else { this.solidSkybox.image = this.solidSkybox[imgRatio]; this.solidSkybox.low = null; } this.solidSkybox.dispose(); //xzw add 需要加这句,否则在从外部飞入后,low无法切换为high,会警告Offset overflows texture dimensions. 似乎是因为在使用贴图时切换image尺寸造成的。 this.solidSkybox.needsUpdate = !0; this.emit('load', imgRatio); this.model.emit('load', this); //this.emit(PanoramaEvents.LoadComplete,/* t, i */) //? return this; }.bind(this), function () { logger$1.error('Downloading cubemap for pano', this.id, 'failed'), this.failedLoadingAt = Date.now(); }.bind(this), function () { console.log('load cubeTex 出现问题?'); //return $.when(++n, 6)//什么? }); } }, { key: "loadCubeImage", value: function loadCubeImage(c) { var h = Deferred$1(), i = new Image(); return i.onerror = function () { h.reject(); }, i.onload = function () { h.resolve(i); }, i.crossOrigin = THREE.ImageUtils.crossOrigin, i.src = c, h; } }, { key: "getCubemapUrls", value: function getCubemapUrls(id, type) { /* return [2, 4, 0, 5, 1, 3].map( function (h) { return config.getResourceImageURL(this.model.sid + '/pan/' + type + '/' + this.id + '_skybox' + h + '.jpg') }.bind(this) ) */ if (this.mapSrc) return this.mapSrc; // 360 edit // 判断随心装同屏需要降低全景图分辨率,否则过渡会卡顿 var splitup = false; if (browser$1.valueFromUrl('m') && browser$1.valueFromUrl('m2')) { var metadata = this.$app.store.getValue('metadata'); if (metadata.sceneFrom == 'sxz') { splitup = true; } } return this.$app.resource.getViewImagesURL("pan/".concat(type, "/").concat(id, ".jpg").concat(splitup ? '?x-oss-process=image/resize,m_lfit,w_4096' : '')); } }, { key: "worldPosition", value: function worldPosition() { return this.position; } }, { key: "isAligned", value: function isAligned() { return !this.panoType; //this.alignmentType === AlignmentType.ALIGNED } }, { key: "updateTileQuality", value: /* updateTileQuality(state, min) { let player = this.$app.core.get('Player') let navSize = this.qualityManager.getMaxNavPanoSize() if(typeof(state) == 'number'){ this.curTileQuality = state }else if (state == 'full') { this.curTileQuality = navSize } else if (state == 'standard') { this.curTileQuality = player.lowTile == 'level2' ? 512 : player.lowTile ? 1024 : 2048 } else if (state == 'low') { this.curTileQuality = 512 } this.curTileQuality = Math.min(this.curTileQuality, navSize) if (min) this.curTileQuality = Math.min(this.curTileQuality, min) return this.curTileQuality } */ function updateTileQuality(size) { this.$app.core.get('Player'); var navSize = this.qualityManager.getMaxNavPanoSize(); this.curTileQuality = Math.min(size, navSize); } }, { key: "getVideoFilter", value: function getVideoFilter(type) { var _this5 = this; //视频漫游点角度范围内隐藏遮挡物 var panoVideoFilter, angle, dir; if (this.hasVideo && this.$app.core.get('PanoVideoRenderer').ifEnable()) { if (this.videoInfo.dir) { dir = this.videoInfo.dir.clone(); angle = THREE.MathUtils.degToRad(this.videoInfo.hfov / 2); } else { var qua = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(this.model.supportsTiles ? 90 : 180)); var lookAtPoint = Vectors$1.FORWARD.clone().applyQuaternion(qua.multiply(this.quaternion)).add(this.position); dir = lookAtPoint.clone().sub(this.position); angle = THREE.MathUtils.degToRad(65 / 2); } } else if (this.panoVideo) { dir = this.panoVideo.dir.clone(); angle = THREE.MathUtils.degToRad(this.panoVideo.hfov / 2); } if (dir) { if (type == 'across') { //传送两个点,看是否在这两个点区间内包含视频 panoVideoFilter = function panoVideoFilter(p1, p2) { var dir1 = new THREE.Vector3().subVectors(p1, _this5.position).setY(0).normalize(); var dir2 = new THREE.Vector3().subVectors(p2, _this5.position).setY(0).normalize(); var midVec = new THREE.Vector3().addVectors(dir1, dir2).normalize(); //以此反向假扮视频区域 var angle_ = dir1.angleTo(midVec); var midPoint = new THREE.Vector3().addVectors(_this5.position, dir); //视频中点 return Panorama.filters.isInFanAngle(_this5.position, midVec, angle_)(midPoint); //看视频中点是否落在p1p2区间 }; } else { panoVideoFilter = Panorama.filters.isInFanAngle(this.position, dir, angle); } } return panoVideoFilter; } }, { key: "addLabel", value: function addLabel() { //圈内的数字 this.label = new TextSprite(Object.assign({ player: this.$app.core.get('Player') }, labelProp$1, { text: this.appId })); var s = math$1.linearClamp(this.label.text.length, 2, 6, 0.4, 0.2); //应该不会多于6位数 this.label.scale.set(s, s, s); this.marker.add(this.label); } }, { key: "addLabel2", value: function addLabel2() { //漂浮的数字 this.removeLabel(); this.label2 = new TextSprite(Object.assign({ player: this.$app.core.get('Player'), sizeInfo: { minSize: 50, maxSize: 300, nearBound: 0.2, farBound: Math.max(20, this.model.size.length() / 3), farBoundPlan: 250 } }, labelProp2, { text: "".concat(this.id, "-f").concat(this.floorIndex) })); //this.label2.sprite.material.depthTest = true var position = this.floorPosition.clone(); position.y += 0.4; this.label2.position.copy(position); this.floor.add(this.label2); } }, { key: "removeLabel", value: function removeLabel() { this.label2 && (this.floor.remove(this.label2), this.label2.material.dispose(), this.label2 = null); } }]); return Panorama; }(EventEmitter); Panorama.raycastsSkipped = 0; Panorama.raycastsDone = 0; Panorama.filters = { inDirection: function inDirection(e, t, i) { return function (n) { var r = n.position.clone().sub(e).normalize(); return r.dot(t) > i; }; }, inFloorDirection: function inFloorDirection(e, t, i) { return function (n) { var r = n.floorPosition.clone().sub(e).normalize(); return r.dot(t) > i; }; }, inFloorDirection_2d: function inFloorDirection_2d(e, t, i) { return function (n) { var origin = new THREE.Vector2(n.floorPosition.x, n.floorPosition.z); var target = new THREE.Vector2(e.x, e.z); //var r = n.floorPosition.clone().sub(e).normalize() var r = origin.sub(target).normalize(); return r.dot(new THREE.Vector2(t.x, t.z)) > i; }; }, inPanoDirection: function inPanoDirection(e, t, i) { return i = settings$3.navigation.panoScores ? settings$3.navigation.filterStrictness : i, function (n) { var r = n.floorPosition.clone().sub(e).normalize(), o = n.position.clone().sub(e).normalize(); return r.dot(t) > i || o.dot(t) > i; }; }, atFloor: function atFloor(e) { return function (t) { return !e || t.floor === e; }; }, not: function not(e) { return function (t) { return t !== e; }; }, notIn: function notIn(e) { return function (t) { return e.indexOf(t) === -1; }; }, isLoaded: function isLoaded() { return function (e) { return e.isLoaded(); }; }, isNotLoaded: function isNotLoaded() { return function (e) { return !e.isLoaded(); }; }, isCloseEnoughTo: function isCloseEnoughTo(e, t) { return function (i) { return e.distanceTo(i.floorPosition) < t; }; }, isClampDisSquaredTo: function isClampDisSquaredTo(e, min, max) { //add return function (i) { var dis = e.distanceToSquared(i.floorPosition); return dis > min && dis < max; }; }, hasMinimumHeightDifferenceTo: function hasMinimumHeightDifferenceTo(e, t) { return function (i) { return Math.abs(i.position.y - e.y) > t; }; }, isNotBehindNormal: function isNotBehindNormal(e, t) { var i = new THREE.Vector3(); return t = t.clone(), function (n) { var r = i.copy(n.position).sub(e).normalize(); return r.dot(t) > 0; }; }, isNeighbourPanoTo: function isNeighbourPanoTo(e) { return function (t) { return !e || !e.neighbourPanos || !!e.neighbourPanos[t.id]; }; }, isNeighbourOfNeighbourTo: function isNeighbourOfNeighbourTo(e) { return function (t) { return !!e.neighbourPanos[t.id] || e.neighbourUUIDs.some(function (i) { var n = e.model.panos.get(i); return !!n && n.neighbourPanos[t.id]; }); }; }, isNotRecentlyFailed: function isNotRecentlyFailed(e) { return function (t) { return Date.now() - t.failedLoadingAt > e; }; }, isOnVisibleFloor: function isOnVisibleFloor() { return function (e) { return !e.floor.hidden; }; }, isPanoAligned: function isPanoAligned() { return function (e) { return e.isAligned(); }; }, /* isInFanAngle: function (curPos, dir, maxAngle) { //是否和中心方向的dir的角度不超过maxAngle return function (position) { var v1 = dir.setY(0) var v2 = position.clone().sub(curPos).setY(0) return v1.angleTo(v2) <= maxAngle } }, */ isInFanAngle: function isInFanAngle(curPos, dir, maxAngle) { //是否和中心方向的dir的角度不超过maxAngle return function (position) { var v1 = dir.setY(0); var v2 = position.clone().sub(curPos).setY(0); return v1.angleTo(v2) <= maxAngle; }; } }; Panorama.sortFunctions = { distanceToPoint: function distanceToPoint(e) { return function (t, i) { return t.position.distanceTo(e) - i.position.distanceTo(e); }; }, floorDistanceToPoint: function floorDistanceToPoint(e) { return function (t, i) { return t.floorPosition.distanceTo(e) - i.floorPosition.distanceTo(e); }; }, choose: function choose(e) { return function (t, i) { return e.id === t.id ? -1 : e.id === i.id ? 1 : 0; }; } }; Panorama.scoreFunctions = { distance: function distance(e, t) { return t = t || settings$3.navigation.distanceFactor, function (i) { return e ? e.position.distanceTo(i.position) * t : 0; }; }, distanceSquared: function distanceSquared(e, t) { return t = t || settings$3.navigation.distanceFactor, function (i) { return e ? e.position.distanceToSquared(i.position) * t : 0; }; }, direction: function direction(e, t, r) { return function (i) { var n = i.position.clone().sub(e).normalize(); return n.dot(t) * (r || settings$3.navigation.directionFactor); }; }, directionFloor: function directionFloor(e, t) { //add return function (i) { var n = i.floorPosition.clone().sub(e).normalize(); return n.dot(t) * settings$3.navigation.directionFactor; }; }, angle: function angle(e, t) { return function (i) { var n = i.position.clone().sub(e).normalize(); return n.angleTo(t) * settings$3.navigation.angleFactor; }; }, inFieldOfView: function inFieldOfView(e, t) { return function (i) { var n = i.position.clone().sub(e).normalize(); return n.dot(t) > 0.75 ? 10 : -1; }; }, optionality: function optionality(e) { return function (t) { var i = t.neighbourUUIDs.filter(function (t) { return !(t in e.neighbourUUIDs) && t !== e.id; }); return i.length * settings$3.navigation.optionalityFactor; }; }, penalizeHeightDifferenceUnder: function penalizeHeightDifferenceUnder(e, t) { return function (i) { return e.y - i.position.y < t ? -20 : 0; }; } }; function _createSuper$1t(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1t(); 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 _isNativeReflectConstruct$1t() { 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; } } var PanoramaCollection = /*#__PURE__*/function (_IndexedCollection) { _inherits(PanoramaCollection, _IndexedCollection); var _super = _createSuper$1t(PanoramaCollection); function PanoramaCollection(app) { var _this; _classCallCheck(this, PanoramaCollection); _this = _super.call(this); _this.neighbourMap = {}; _this.map = null; _this.animatePanoId = null; app && app.TourManager.player.then(function (player) { player.on('play2', function () { _this.list.forEach(function (e) { e.label && common.updateVisible(e.label, 'recordTour', false); //为了防止录屏时将点位录入 2023.10.8 }); }); player.on('end', function () { _this.list.forEach(function (e) { e.label && common.updateVisible(e.label, 'recordTour', true); }); }); player.on('pause', function () { _this.list.forEach(function (e) { e.label && common.updateVisible(e.label, 'recordTour', true); }); }); }); return _this; } _createClass(PanoramaCollection, [{ key: "getIndex", value: function getIndex(pano) { return pano.id; } }, { key: "find", value: function find(e, t) { var i = common.filterAll(this.list, e); return 0 === i.length ? null : (t && t.forEach(function (e) { i = common.stableSort(i, e); }), i[0]); } /* sortByScore(e, t) { var i = common.filterAll(this.list, e) return 0 === i.length ? null : (i = i .map(function (e) { return { pano: e, score: t.reduce(function (t, i) { return t + i(e) }, 0), } }) .sort(function (e, t) { return t.score - e.score })) } */ }, { key: "lowestByScore", value: function lowestByScore(e, t, i) { return this.findRankedByScore(0, e, t, i); } }, { key: "findRankedByScore", value: function findRankedByScore(e, t, i, n) { n && (n.candidates = null, n.pano = null), e || (e = 0); var r = common.sortByScore(this.list, t, i); return !r || 0 === r.length || e >= r.length ? null : (n && (n.candidates = r, n.pano = r[e].item), r[e].item); } }, { key: "getNeighbours", value: function getNeighbours(pano) { return this.neighbourMap[pano.id]; } }, { key: "setNeighbour", value: function setNeighbour(pano, neighbourPano, isNeighbour) { this.neighbourMap[pano.id] || (this.neighbourMap[pano.id] = {}); this.neighbourMap[neighbourPano.id] || (this.neighbourMap[neighbourPano.id] = {}); this.neighbourMap[pano.id][pano.id] = !0; this.neighbourMap[neighbourPano.id][neighbourPano.id] = !0; this.neighbourMap[pano.id][neighbourPano.id] = isNeighbour; this.neighbourMap[neighbourPano.id][pano.id] = isNeighbour; return this.neighbourMap[pano.id]; } }, { key: "findClosest", value: function findClosest(position, t) { var func = [Panorama.filters.isPanoAligned()]; t && func.push(Panorama.filters.inDirection(position, t, 0.75)); return this.find(func, [Panorama.sortFunctions.distanceToPoint(position)]); } }, { key: "fadeMarkerOpacity", value: function fadeMarkerOpacity(e, t, gr) { //许钟文 改 transitions$1.cancelById('fadeMarkerOpacity'); var n = this.list.findIndex(function (e) { //why? 难道没有marker的pano吗 findeIndex:获取数组中函数返回值不为fasle的第一个元素索引位置 return e.marker; }); if (n < 0) { logger.info('marker findIndex<0'); return; } var group; var tran = function tran(list, index) { list.member = list.member.filter(function (m) { return m.marker && m.marker.material.opacity != list.toOp; }); transitions$1.trigger({ func: function (e, t) { //e:0-1 list.member.forEach(function (m) { var o = m.marker.oldOpacity; var i = o + e * (list.toOp - o); m.marker && (m.marker.material.opacity = i); }); }.bind(this), duration: void 0 == t ? settings$3.markerOpacityTransitionTime : t, name: '_fpm_' + index, id: 'fadeMarkerOpacity' }); }; this.forEach(function (e) { //先记录旧的opacity e.marker && (e.marker.oldOpacity = e.marker.material.opacity); }); e = void 0 == e ? settings$3.panorama.markerOpacity : e; if (e > 0 && gr) { group = gr; } else { group = [{ member: this.list, toOp: e }]; } for (var i = 0; i < group.length; i++) { tran(group[i], i); } } }, { key: "closestPanoTowardPoint", value: function closestPanoTowardPoint(o) { //改自closestPanoTowardTag by:xzw var point = o.point, require = o.require || [], temp = { position: point }, a = new THREE.Vector3(), rank = o.rank || [Panorama.scoreFunctions.distanceSquared(temp, -2)]; o.force; var getAll = o.getAll, angleTolerDecrease = o.angleTolerDecrease || 2; // let player = window.kankan.core.get('Player') // if (player.linkEditor && !player.linkEditor.noPanoHasNeighbor) { // //xzw add 如果不是全孤立点的话,就要避开孤立点 // require.push(pano => { // return player.linkEditor.checkHasNeighbor(pano) // }) // } require.push(Panorama.filters.isPanoAligned()); require.push(function (pano) { return pano.hasNeighbor(); /* || pano == this.$app.core.get('Scene').firstView.pano */ }); require.push(function (pano) { a.copy(point).sub(pano.position); var angle = -THREE.MathUtils.radToDeg(Math.atan(a.y / Math.sqrt(a.x * a.x + a.z * a.z))), tolerance = settings$3.insideFOV / 2 - angleTolerDecrease; var a1 = settings$3.insideLookLimitDown - tolerance; var a2 = settings$3.insideLookLimitUp + tolerance; return a1 < angle && angle < a2; /* if(angle < settings.insideLookLimitDown){ return -10 * (angle-settings.insideLookLimitDown) }else if(angle > settings.insideLookLimitUp){ return -10 * (angle-settings.insideLookLimitDown) } */ }); if (o.floor) require.push(Panorama.filters.atFloor(o.floor)); var g = common.sortByScore(this.list, require, rank); //console.log(g) if (getAll) return g; return g && g.length > 0 && g[0].item; } }]); return PanoramaCollection; }(IndexedCollection); function _createSuper$1s(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1s(); 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 _isNativeReflectConstruct$1s() { 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; } } //skybox var BoundingMesh = /*#__PURE__*/function (_THREE$Mesh) { _inherits(BoundingMesh, _THREE$Mesh); var _super = _createSuper$1s(BoundingMesh); function BoundingMesh(boundingBox, material) { var _this; var skyHeight = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 50; _classCallCheck(this, BoundingMesh); //boundingBox = boundingBox.clone().expandByScalar(0.01) //许钟文改: 稍微放大了一丢丢的,避免和其他mesh冲突闪烁。尤其在飞入飞出时,地面闪烁一下,好像是和chunk冲突。过去是和marker冲突。 //大部分没有mesh的都是户外,所以放大些,作为天空盒背景. 另外地板因为可能破损,所以position向上提升使最低高度不变 boundingBox = boundingBox.clone().expandByVector(new THREE.Vector3(skyHeight, skyHeight, skyHeight)); var size = new THREE.Vector3(); boundingBox.getSize(size); var geometry = new THREE.BoxGeometry(size.x, size.y, size.z); //geometry.boundingBox = boundingBox; //xzw delete 较早:这句加上不对。因为后面算鼠标与skybox交点时 要用到的是boundingbox加上position才是真实skybox真实位置,所以boundingbox要居中的,而不应该是整体模型所在的位置。 geometry.computeBoundingBox(); //需要重新计算对称的bounding, 在获取鼠标交点时需要。否则热点加不上 _this = _super.call(this, geometry, material); var center = new THREE.Vector3(); boundingBox.getCenter(center); skyHeight && (center.y += skyHeight - 0.1); _this.position.copy(center); _this.frustumCulled = !1; //flag && this.add(new THREE.WireframeHelper(this)) return _this; } return BoundingMesh; }(THREE.Mesh); function _createSuper$1r(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1r(); 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 _isNativeReflectConstruct$1r() { 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; } } /** * 全景贴图材质 */ var ModelTextureMaterial = /*#__PURE__*/function (_THREE$RawShaderMater) { _inherits(ModelTextureMaterial, _THREE$RawShaderMater); var _super = _createSuper$1r(ModelTextureMaterial); /* constructor(parameters) { parameters = parameters || {} super( common.extendObject( { fragmentShader: shaders.model.fragmentShader, vertexShader: shaders.model.vertexShader, uniforms: THREE.UniformsUtils.clone(shaders.model.uniforms), name: 'ModelTextureMaterial', }, parameters ) ) } */ function ModelTextureMaterial(parameters, matName) { var _this; _classCallCheck(this, ModelTextureMaterial); parameters = parameters || {}; //使用的是单张全景图,不是cube型的 if (parameters.not_Cube) { var defines = parameters.defines || {}; defines.Not_Cube = ''; parameters.defines = defines; } var matName = matName || 'model'; _this = _super.call(this, common.extendObject({ fragmentShader: shaders[matName].fragmentShader, vertexShader: shaders[matName].vertexShader, uniforms: THREE.UniformsUtils.clone(shaders[matName].uniforms), name: 'ModelTextureMaterial' }, parameters)); if (_this.uniforms.progress) { var progress = 0; Object.defineProperty(_this.uniforms.progress, 'value', { get: function get() { return progress; }, set: function set(e) { if (e < 1) { if (!('usePanoMap0' in _this.defines)) { _this.defines.usePanoMap0 = ''; _this.needsUpdate = true; } } else { if ('usePanoMap0' in _this.defines) { delete _this.defines.usePanoMap0; _this.needsUpdate = true; } } progress = e; } }); } //------------------------------------- return _this; } /** * 用于点位跳转 * 跳转后,pano0和pano1都会被赋值为currentPano,uniforms.progress由0过渡为1 * @param {*} pano0 跳转前的点位 * @param {*} pano1 跳转后的点位 * @param {*} flag 将progress重置为0 */ _createClass(ModelTextureMaterial, [{ key: "setProjectedPanos", value: function setProjectedPanos(pano0, pano1, flag) { var _this2 = this; if (!('BasePanoMap' in this.defines)) { flag && (this.uniforms.progress.value = 0); // pano0的贴图、坐标、旋转 pano0.ensureSkyboxReadyForRender(); pano1.ensureSkyboxReadyForRender(); this.updateTexDefines(pano0, pano1); // 判断是全景图还是六面图 } this.uniforms.pano0Map.value = pano0.getSkyboxTexture(); this.uniforms.pano0Position.value.copy(pano0.position); this.uniforms.pano0Matrix.value.copy(pano0.matrixWorld); this.uniforms.pano1Map.value = pano1.getSkyboxTexture(); this.uniforms.pano1Position.value.copy(pano1.position); this.uniforms.pano1Matrix.value.copy(pano1.matrixWorld); delete this.defines['HasVideo']; if (pano1.hasVideo) { // 存在球幕视频 this.uniforms.exposure.value = pano1.videoInfo.exposure || 1; // 曝光 this.uniforms.blendFov.value = pano1.videoInfo.blendFov || 5; // 目前全都取默认值 // 球幕区域 pano1.videoInfo.clipRect && this.uniforms.clipRect.value.set(pano1.videoInfo.clipRect.leftBottom.x, pano1.videoInfo.clipRect.leftBottom.y, pano1.videoInfo.clipRect.rightTop.x, pano1.videoInfo.clipRect.rightTop.y); this.defines['VideoMapping'] = pano1.videoInfo.mapping || 0; // 球幕视频与全景图混合方式 this.defines['HasVideo'] = pano1.videoInfo.cameraType || 8; // 业务需求:bFlag用于判断当球幕视频宽大于高时,需要翻转90度 var videoPlayer = pano1.panoVideoRenderer.videoPlayer; var video = videoPlayer._resource ? videoPlayer._resource.get(pano1.id).video : videoPlayer.instances.get(pano1.id).videoElement; if (video.readyState == 0) { video.addEventListener('resize', function (ev) { _this2.uniforms.bFlag.value = video.videoWidth > video.videoHeight ? 1 : 0; }, false); } else this.uniforms.bFlag.value = video.videoWidth > video.videoHeight ? 1 : 0; } // 没有hasFilter时,会绕过滤镜相关代码,节省gpu // 考虑到过渡效果,pano1和pano0任意一个hasFilter,就要执行滤镜代码 if (pano1.hasFilter || pano0.hasFilter) { this.defines['hasFilter'] = true; } else { delete this.defines['hasFilter']; } this.needsUpdate = true; //console.log('setProjectedPanos', pano0.id, pano1.id) } // 判断pano贴图是全景图还是六面图 }, { key: "updateTexDefines", value: function updateTexDefines(pano0, pano1) { var _this3 = this; var hasChanged = false; var change = function change(pano, index) { if (!pano.tiled) { // 全景图 if (_this3.defines['Not_Cube_' + index] == void 0) { _this3.defines['Not_Cube_' + index] = ''; hasChanged = true; } } else { // 六面图 if (_this3.defines['Not_Cube_' + index] != void 0) { delete _this3.defines['Not_Cube_' + index]; hasChanged = true; } } }; change(pano0, 0); change(pano1, 1); hasChanged && (this.needsUpdate = true); } }]); return ModelTextureMaterial; }(THREE.RawShaderMaterial); function _createSuper$1q(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1q(); 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 _isNativeReflectConstruct$1q() { 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; } } var BoundingTextureSkybox = /*#__PURE__*/function (_BoundingMesh) { _inherits(BoundingTextureSkybox, _BoundingMesh); var _super = _createSuper$1q(BoundingTextureSkybox); function BoundingTextureSkybox(bounding, skyHeight) { var _this; _classCallCheck(this, BoundingTextureSkybox); logger$1.time('Computing a nice bounding cubemap'); var material = new ModelTextureMaterial({ side: THREE.BackSide, transparent: !0 }); material.uniforms.modelAlpha.value = 0; material.uniforms.opacity.value = 1 - settings$3.modelAlpha; _this = _super.call(this, bounding, material, skyHeight); _this.renderOrder = RenderOrder.boundingSkybox; logger$1.timeEnd('Computing a nice bounding cubemap'); return _this; } return BoundingTextureSkybox; }(BoundingMesh); function E$1() {// Keep this empty so it's easier to inherit from // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) } E$1.prototype = { on: function on(name, callback, ctx) { var e = this.e || (this.e = {}); (e[name] || (e[name] = [])).push({ fn: callback, ctx: ctx }); return this; }, once: function once(name, callback, ctx) { var self = this; function listener() { self.off(name, listener); callback.apply(ctx, arguments); } listener._ = callback; return this.on(name, listener, ctx); }, emit: function emit(name) { var data = [].slice.call(arguments, 1); var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); var i = 0; var len = evtArr.length; for (i; i < len; i++) { evtArr[i].fn.apply(evtArr[i].ctx, data); } return this; }, off: function off(name, callback) { var e = this.e || (this.e = {}); var evts = e[name]; var liveEvents = []; if (evts && callback) { for (var i = 0, len = evts.length; i < len; i++) { if (evts[i].fn !== callback && evts[i].fn._ !== callback) liveEvents.push(evts[i]); } } // Remove event from queue to prevent memory leak // Suggested by https://github.com/lazd // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 liveEvents.length ? e[name] = liveEvents : delete e[name]; return this; } }; var tinyEmitter = E$1; var TinyEmitter = E$1; tinyEmitter.TinyEmitter = TinyEmitter; /* * @Author: Rindy * @Date: 2021-05-07 15:52:29 * @LastEditors: Rindy * @LastEditTime: 2021-05-07 15:53:00 * @Description: 注释 */ /** * 地面logo */ var floorLogo = { uniforms: { map: { type: 't', value: null }, opacity: { type: 'f', value: 1 }, opaRadius: { //百分比 type: 'f', value: 0.2 } }, vertexShader: "\n varying vec2 vUv;\n void main() {\n vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }", fragmentShader: "uniform sampler2D map; \n uniform float opacity;\n uniform float opaRadius;\n varying vec2 vUv; \n void main() {\n vec2 vUv2 = vec2(vUv.x*2.0 - 1.0, vUv.y*2.0 - 1.0); \n vec4 colorFromTexture = texture2D( map, vUv ); \n float opa = 1.0; \n float r = vUv2.x*vUv2.x + vUv2.y*vUv2.y; \n if(r > 1.0) opa = 0.0; \n else if(r < opaRadius)opa = 1.0; \n else{\t\n float a = -1.0 / ((opaRadius - 1.0)*(opaRadius - 1.0));\n float b = -2.0 * a * opaRadius;\t\n float c = 1.0 + a * opaRadius * opaRadius; \n opa = a * r*r + b * r + c; \n } \n gl_FragColor = vec4(colorFromTexture.rgb, opacity * colorFromTexture.a * opa );\n }\n " }; function _createSuper$1p(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1p(); 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 _isNativeReflectConstruct$1p() { 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; } } var settings$1 = { floorLogo: { name: 'floorLogoImg.png', geometry: new THREE.Vector4(2.5, 2.5, 1, 1), size: 100, position: new THREE.Vector3(0, -1.49, 0), renderOrder: 99 } }; var FloorLogos = /*#__PURE__*/function (_Emiter) { _inherits(FloorLogos, _Emiter); var _super = _createSuper$1p(FloorLogos); function FloorLogos(app) { var _this; _classCallCheck(this, FloorLogos); _this = _super.call(this); _this.changefloorLogoOpa = function (o) { var logo = o.index == 0 ? this.firstLogo : this.secondLogo; transitions$1.cancelById('flOpa_' + o.index); //先停止之前该logo的透明度变化 if (o.from != void 0) logo.material.opacity = o.from; //初始透明度 if (!o.dur) { //立刻 logo.material.opacity = o.opa; } else { transitions$1.start(lerp.property(logo.material, 'opacity', o.opa), o.dur || 0, null, o.delay || 0, easing['easeInQuad'], 'changefloorLogoOpa', 'flOpa_' + o.index); } }; _this.updateFloorlogo = function () { var lastQ = new THREE.Quaternion(); return function (Q) { if (this.fixDirection) return; if (!Q || !this.ready) return; var sameQ, quaternion, visible; if (this.firstLogo.visible || this.firstLogo.material.opacity != 0 || this.secondLogo.visible || this.secondLogo.material.opacity != 0) { visible = true; } if (!visible) { return; //如果两个都不可见,就不更改,如果有一个可见,就都改 } //因为导览时有直接更改quaternion而不是lon的情况 所以更改为下面的 var q = this.app.core.get('Player').camera.quaternion; var sameQ = MathLight.closeTo(q, lastQ, 5); sameQ || (lastQ = q.clone()); //相机旋转是否改变了 if (!sameQ) { if (!quaternion) { //将camera的朝向转化成vector并去掉y上的分量: var a = new THREE.Vector3(0, 0, -1).applyQuaternion(Q).setY(0); //这是把方向转化成matrix的方法: var _ = new THREE.Matrix4().lookAt(a, new THREE.Vector3(), new THREE.Vector3(0, 1, 0)); // new Matrix().lookAt(from, aim, Vectors.UP); 前两个参数代表位置和朝向(顺序反过来应该就是反向的),第三个默认这个axis //转化为quaternion: quaternion = new THREE.Quaternion().setFromRotationMatrix(_); //最后考虑一下最初lookAt上方的旋转: var b = new THREE.Quaternion(0, 0.7071067811865476, 0.7071067811865476, 0); //计算得(logo面朝上的旋转) quaternion.multiply(b); //等同b.premultiply(quaternion), b变换在先,左乘之后的quaternion。 } this.firstLogo.quaternion.copy(quaternion); this.secondLogo.quaternion.copy(quaternion); //console.log('floorlogo changed') } }; }(); _this.setDir = function (angle) { //根据compass设置北方向 if (!this.fixDirection) return; this.firstLogo.rotation.z = THREE.MathUtils.degToRad(-angle); this.secondLogo.rotation.z = THREE.MathUtils.degToRad(-angle); }; _this.app = app; _this.ready = false; _this.fixDirection = false; //固定东南西北朝向 _this.firstLogo = new THREE.Mesh(new THREE.PlaneGeometry(2.5, 2.5, 1, 1), new THREE.MeshBasicMaterial({ transparent: true, depthWrite: !1, depthTest: false //改 在chunk\skybox外也可看到 })); _this.secondLogo = _this.firstLogo.clone(); _this.secondLogo.material = _this.firstLogo.material.clone(); return _this; } _createClass(FloorLogos, [{ key: "bindEvents", value: function bindEvents() {} }, { key: "createFloorLogo", value: function createFloorLogo() { var _this2 = this; //const { url, scale = size / 100 } = this.getLogo() var logoMeta = this.getLogo(); var url = logoMeta.url; var scale = logoMeta.size / 100; this.setLogoMesh(this.firstLogo, scale); this.setLogoMesh(this.secondLogo, scale); var map = texture.load(url, function () { var outputTex = _this2.getTex(map); _this2.firstLogo.material.map = outputTex; _this2.secondLogo.material.map = outputTex; _this2.firstLogo.material.needsUpdate = true; _this2.secondLogo.material.needsUpdate = true; common.updateVisible(_this2.firstLogo, 'unready', true); common.updateVisible(_this2.secondLogo, 'unready', true); _this2.emit('ready'); _this2.ready = true; }); } }, { key: "setLogoMesh", value: function setLogoMesh(logo, scale) { logo.name = 'floorlogo'; logo.scale.set(scale, scale, scale); logo.position.set(settings$1.floorLogo.position.x, settings$1.floorLogo.position.y, settings$1.floorLogo.position.z); logo.lookAt(logo.position.clone().add(new THREE.Vector3(0, 1, 0))); logo.renderOrder = settings$1.floorLogo.renderOrder; //cover the videoSkybox common.updateVisible(logo, 'unready', false); common.updateVisible(logo, 'outside', false); return logo; } }, { key: "getTex", value: function getTex(map) { var uniforms = THREE.UniformsUtils.clone(floorLogo.uniforms); uniforms.map.value = map; var materialFirst = new THREE.ShaderMaterial({ fragmentShader: floorLogo.fragmentShader, vertexShader: floorLogo.vertexShader, uniforms: uniforms, side: THREE.DoubleSide, transparent: !0, premultipliedAlpha: true // !!! 不加这句的话透明部分会变黑 }); materialFirst.needsUpdate = true; var tex = common.renderTex(materialFirst, this.app.core.get('SceneRenderer').renderer, { x: 512, y: 512 }); materialFirst.dispose(); tex.anisotropy = 5; //防止倾斜模糊 return tex; } }, { key: "getLogo", value: function getLogo() { var metadata = this.app.store.getValue('metadata'); var url = ''; var logo = this.app.config.scene.floorlogoId || metadata.floorLogo || '0'; if (this.app.config.lang != 'zh') { logo = 'en/' + logo; } if (this.app.config.region == 'aws') { logo = 'aws/' + logo; } var size = metadata.floorLogoSize || 100; if (metadata.floorLogo === 'user') { url = this.app.resource.getUserResourceURL(metadata.floorLogoFile); } else { url = this.app.resource.getAppURL("images/floorlogos/".concat(logo, ".png")); } return { url, size }; } }, { key: "changeFloorLogo", value: function changeFloorLogo(logo) { var _this3 = this; if (!this.ready) { return; } var material = this.firstLogo.material; var changeTex = function changeTex(tex) { material.map && material.map.dispose(); var outputTex = _this3.getTex(tex); _this3.firstLogo.material.map = outputTex; _this3.secondLogo.material.map = outputTex; }; if (logo.url) { texture.load(logo.url, changeTex); } else if (logo.id) { texture.load(this.app.resource.getAppURL("images/floorlogos/".concat(logo.id, ".png")), changeTex); } else if (logo.image) { var tex = new THREE.Texture(logo.image); tex.needsUpdate = !0; changeTex(tex); } if (logo.size) { var scale = logo.size / 100; this.firstLogo.scale.set(scale, scale, scale); this.secondLogo.scale.set(scale, scale, scale); } } //渐变opacity }]); return FloorLogos; }(tinyEmitter); function _createSuper$1o(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1o(); 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 _isNativeReflectConstruct$1o() { 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; } } var BoxBufferGeometry = THREE.BoxBufferGeometry, BufferGeometry = THREE.BufferGeometry, Color = THREE.Color, CylinderBufferGeometry = THREE.CylinderBufferGeometry, DoubleSide = THREE.DoubleSide, Euler = THREE.Euler, Float32BufferAttribute = THREE.Float32BufferAttribute, Line$1 = THREE.Line; THREE.LineBasicMaterial; var Matrix4$1 = THREE.Matrix4, Mesh = THREE.Mesh, MeshBasicMaterial = THREE.MeshBasicMaterial, Object3D = THREE.Object3D, OctahedronBufferGeometry = THREE.OctahedronBufferGeometry, PlaneBufferGeometry = THREE.PlaneBufferGeometry, Quaternion$1 = THREE.Quaternion; THREE.Raycaster; var TorusBufferGeometry = THREE.TorusBufferGeometry; var changeEvent, mouseDownEvent, mouseMoveEvent, mouseUpEvent, objectChangeEvent; // Reusable utility variables var ray$1 = new THREE.Raycaster(); var _tempVector = new THREE.Vector3(); var _tempVector2 = new THREE.Vector3(); var _tempQuaternion = new THREE.Quaternion(); var _unit = { X: new THREE.Vector3(1, 0, 0), Y: new THREE.Vector3(0, 1, 0), Z: new THREE.Vector3(0, 0, 1) }; var pointStart = new THREE.Vector3(); var pointEnd = new THREE.Vector3(); var offset = new THREE.Vector3(); var rotationAxis = new THREE.Vector3(); var startNorm = new THREE.Vector3(); var endNorm = new THREE.Vector3(); var rotationAngle = 0; var cameraPosition = new THREE.Vector3(); var cameraQuaternion = new THREE.Quaternion(); var cameraScale = new THREE.Vector3(); var parentPosition = new THREE.Vector3(); var parentQuaternion = new THREE.Quaternion(); var parentQuaternionInv = new THREE.Quaternion(); var parentScale = new THREE.Vector3(); var worldPositionStart = new THREE.Vector3(); var worldQuaternionStart = new THREE.Quaternion(); var worldScaleStart = new THREE.Vector3(); var worldPosition = new THREE.Vector3(); var worldQuaternion = new THREE.Quaternion(); var worldQuaternionInv = new THREE.Quaternion(); var worldScale = new THREE.Vector3(); var eye = new THREE.Vector3(); var positionStart = new THREE.Vector3(); var quaternionStart = new THREE.Quaternion(); var scaleStart = new THREE.Vector3(); var _gizmo, _plane; var lastRotationAngle = 0; // 用于计算旋转时的deltaAngle var TransformControls = /*#__PURE__*/function (_THREE$Object3D) { _inherits(TransformControls, _THREE$Object3D); var _super = _createSuper$1o(TransformControls); function TransformControls(camera, domElement, options) { var _this; _classCallCheck(this, TransformControls); _this = _super.call(this); if (domElement === undefined) { console.warn('THREE.TransformControls: The second parameter "domElement" is now mandatory.'); domElement = document; } _this.visible = false; _this.domElement = domElement; _gizmo = new TransformControlsGizmo(options); _this.add(_gizmo); _plane = new TransformControlsPlane(options); _this.add(_plane); _this.player = options.player; //xzw add _this.options = options; //xzw add changeEvent = { type: 'change' }; mouseDownEvent = { type: 'mouseDown' }; mouseUpEvent = { type: 'mouseUp', mode: _this.mode }; mouseMoveEvent = { type: 'mousing' }; objectChangeEvent = { type: 'objectChange' }; // Define properties with getters/setter // Setting the defined property will automatically trigger change event // Defined properties are passed down to gizmo and plane _this.defineProperty('camera', camera); _this.defineProperty('object', undefined); _this.defineProperty('enabled', true); _this.defineProperty('axis', null); _this.defineProperty('mode', 'translate'); _this.defineProperty('translationSnap', null); _this.defineProperty('rotationSnap', null); _this.defineProperty('scaleSnap', null); _this.defineProperty('space', 'world'); _this.defineProperty('spaceForRotate', null); _this.defineProperty('size', 1); _this.defineProperty('dragging', false); _this.defineProperty('showX', true); _this.defineProperty('showY', true); _this.defineProperty('showZ', true); // TODO: remove properties unused in plane and gizmo _this.defineProperty('worldPosition', worldPosition); _this.defineProperty('worldPositionStart', worldPositionStart); _this.defineProperty('worldQuaternion', worldQuaternion); _this.defineProperty('worldQuaternionStart', worldQuaternionStart); _this.defineProperty('cameraPosition', cameraPosition); _this.defineProperty('cameraQuaternion', cameraQuaternion); _this.defineProperty('pointStart', pointStart); _this.defineProperty('pointEnd', pointEnd); _this.defineProperty('rotationAxis', rotationAxis); _this.defineProperty('rotationAngle', rotationAngle); _this.defineProperty('eye', eye); domElement.addEventListener('mousedown', _this.onPointerDown.bind(_assertThisInitialized(_this)), false); domElement.addEventListener('touchstart', _this.onPointerDown.bind(_assertThisInitialized(_this)), false); domElement.addEventListener('mousemove', _this.onPointerHover.bind(_assertThisInitialized(_this)), false); domElement.addEventListener('touchmove', _this.onPointerHover.bind(_assertThisInitialized(_this)), false); domElement.addEventListener('touchmove', _this.onPointerMove.bind(_assertThisInitialized(_this)), false); window.addEventListener('mouseup', _this.onPointerUp.bind(_assertThisInitialized(_this)), false); window.addEventListener('pointerup', _this.onPointerUp.bind(_assertThisInitialized(_this)), false); domElement.addEventListener('touchend', _this.onPointerUp.bind(_assertThisInitialized(_this)), false); domElement.addEventListener('touchcancel', _this.onPointerUp.bind(_assertThisInitialized(_this)), false); domElement.addEventListener('touchleave', _this.onPointerUp.bind(_assertThisInitialized(_this)), false); // this.player.$app.core.get('SceneRenderer').addComponent(this) _this.isTransformControls = true; return _this; } _createClass(TransformControls, [{ key: "dispose", value: function dispose() { domElement.removeEventListener('mousedown', this.onPointerDown.bind(this)); domElement.removeEventListener('touchstart', this.onPointerDown.bind(this)); domElement.removeEventListener('mousemove', this.onPointerHover.bind(this)); document.removeEventListener('mousemove', this.onPointerMove.bind(this)); domElement.removeEventListener('touchmove', this.onPointerHover.bind(this)); domElement.removeEventListener('touchmove', this.onPointerMove.bind(this)); window.removeEventListener('mouseup', this.onPointerUp.bind(this), false); window.removeEventListener('pointerup', this.onPointerUp.bind(this), false); domElement.removeEventListener('touchend', this.onPointerUp.bind(this)); domElement.removeEventListener('touchcancel', this.onPointerUp.bind(this)); domElement.removeEventListener('touchleave', this.onPointerUp.bind(this)); this.traverse(function (child) { if (child.geometry) child.geometry.dispose(); if (child.material) child.material.dispose(); }); } // Set current object // 通过设置object的width和depth来设置箭头偏移 }, { key: "attach", value: function attach(object) { this.object = object; this.visible = true; config$4.isTyping = true; //add return this; } // Detatch from object }, { key: "detach", value: function detach() { this.object = undefined; this.visible = false; this.axis = null; config$4.isTyping = false; //add return this; } //add }, { key: "setSize", value: function setSize(x, y) {} }, { key: "switchEditState", value: function switchEditState(state) { var oldScaleAxis = JSON.stringify(this.options.scaleAxis); if (state == 'overlay') { this.options.NoScaleZ = true; this.options.scaleAxis = ['x', 'y']; } else if (state == 'panovideo') { this.mode = 'scale'; this.options.NoScaleZ = true; this.options.scaleAxis = ['x', 'y']; } else if (state == 'decoration') { this.options.NoScaleZ = false; this.options.scaleAxis = ['x', 'y', 'z']; } else if (state == 'clipbox') { this.options.NoScaleZ = false; this.options.scaleAxis = ['x', 'y', 'z']; } else if (state == 'css3dpanel') { this.options.NoScaleZ = false; this.options.scaleAxis = ['x', 'y']; } if (oldScaleAxis != JSON.stringify(this.options.scaleAxis)) { this.rebuildAxis('scale'); } this.editState = state; //this.visible = true } }, { key: "filterRotateAxis", value: function filterRotateAxis(axisArr) { var oldRotateAxis = JSON.stringify(this.options.rotateAxis); this.options.rotateAxis = axisArr; if (oldRotateAxis != JSON.stringify(this.options.rotateAxis)) { this.rebuildAxis('rotate'); } } }, { key: "rebuildAxis", value: function rebuildAxis(transType) { _gizmo.gizmo[transType].removeFromParent(); _gizmo.picker[transType].removeFromParent(); _gizmo.gizmo[transType].traverse(function (child) { if (child.geometry) child.geometry.dispose(); if (child.material) child.material.dispose(); }); _gizmo.picker[transType].traverse(function (child) { if (child.geometry) child.geometry.dispose(); if (child.material) child.material.dispose(); }); var _gizmo2 = _gizmo['update' + transType.charAt(0).toUpperCase() + transType.slice(1)](), gizmo = _gizmo2.gizmo, picker = _gizmo2.picker; // updateScale()、updateRotate() _gizmo.add(_gizmo.gizmo[transType] = _gizmo.setupGizmo(gizmo)); _gizmo.add(_gizmo.picker[transType] = _gizmo.setupGizmo(picker)); _gizmo.picker[transType].visible = false; } }, { key: "handleDragStart", value: function handleDragStart() { this.editState && this.onPointerDown(); } }, { key: "handleDragging", value: function handleDragging() { this.editState && this.onPointerMove(); } }, { key: "handleDragEnd", value: function handleDragEnd() { this.editState && this.onPointerUp(); } //------------------- // Defined getter, setter and store for a property }, { key: "defineProperty", value: function defineProperty(propName, defaultValue) { var propValue = defaultValue; Object.defineProperty(this, propName, { get: function get() { return propValue !== undefined ? propValue : defaultValue; }, set: function set(value) { if (propValue !== value) { propValue = value; _plane[propName] = value; _gizmo[propName] = value; this.dispatchEvent({ type: propName + '-changed', value: value }); this.dispatchEvent(changeEvent); } } }); this[propName] = defaultValue; _plane[propName] = defaultValue; _gizmo[propName] = defaultValue; } // updateMatrixWorld updates key transformation variables }, { key: "updateMatrixWorld", value: function updateMatrixWorld() { if (this.object !== undefined) { this.object.updateMatrixWorld(); this.object.parent.matrixWorld.decompose(parentPosition, parentQuaternion, parentScale); this.object.matrixWorld.decompose(worldPosition, worldQuaternion, worldScale); parentQuaternionInv.copy(parentQuaternion).invert(); worldQuaternionInv.copy(worldQuaternion).invert(); } this.camera.updateMatrixWorld(); this.camera.matrixWorld.decompose(cameraPosition, cameraQuaternion, cameraScale); eye.copy(cameraPosition).sub(worldPosition).normalize(); Object3D.prototype.updateMatrixWorld.call(this); } }, { key: "pointerHover", value: function pointerHover(pointer) { if (this.object === undefined || this.dragging === true || pointer.button !== undefined && pointer.button !== 0) return; //ray.setFromCamera( pointer, this.camera ); //������floorplanģʽget����intersect var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(this.camera); ray$1.set(origin, this.player.getMouseDirection(pointer)); var intersect = ray$1.intersectObjects(_gizmo.picker[this.mode].children, true)[0] || false; if (intersect) { this.axis = intersect.object.name; this.intersect = intersect.object; //add this.player.domElement.style.cursor = 'pointer'; } else { this.intersect = null; this.axis = null; this.player.domElement.style.cursor = ''; } } }, { key: "pointerDown", value: function pointerDown(pointer) { if (this.object === undefined || this.dragging === true || pointer.button !== undefined && pointer.button !== 0) return; if ((pointer.button === 0 || pointer.button === undefined) && this.axis !== null) { //ray.setFromCamera( pointer, this.camera ); //������floorplanģʽget����intersect var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(this.camera); ray$1.set(origin, this.player.getMouseDirection(pointer)); var planeIntersect = ray$1.intersectObjects([_plane], true)[0] || false; if (planeIntersect) { var space = this.space; if (this.mode === 'scale') { space = 'local'; } else if (this.axis === 'E' || this.axis === 'XYZE' || this.axis === 'XYZ') { space = 'world'; } if (space === 'local' && this.mode === 'rotate') { var snap = this.rotationSnap; if (this.axis === 'X' && snap) this.object.rotation.x = Math.round(this.object.rotation.x / snap) * snap; if (this.axis === 'Y' && snap) this.object.rotation.y = Math.round(this.object.rotation.y / snap) * snap; if (this.axis === 'Z' && snap) this.object.rotation.z = Math.round(this.object.rotation.z / snap) * snap; } this.object.updateMatrixWorld(); this.object.parent.updateMatrixWorld(); positionStart.copy(this.object.position); quaternionStart.copy(this.object.quaternion); scaleStart.copy(this.object.scale); this.object.matrixWorld.decompose(worldPositionStart, worldQuaternionStart, worldScaleStart); pointStart.copy(planeIntersect.point).sub(worldPositionStart); if (this.player.cameraControls.activeControl) { //this.player.cameraControls.activeControl.locked = true; //add this.player.cameraControls.activeControl.enabled = false; //add } } this.dragging = true; mouseDownEvent.mode = this.mode; this.dispatchEvent(mouseDownEvent); } } }, { key: "pointerMove", value: function pointerMove(pointer) { var axis = this.axis; var mode = this.mode; var object = this.object; var space = this.space; if (mode === 'scale') { space = 'local'; } else if (axis === 'E' || axis === 'XYZE' || axis === 'XYZ') { space = 'world'; } //console.log(axis) if (object === undefined || axis === null || this.dragging === false || pointer.button !== undefined && pointer.button !== 0) return; //ray.setFromCamera( pointer, this.camera ); //������floorplanģʽget����intersect var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(this.camera); ray$1.set(origin, this.player.getMouseDirection(pointer)); var planeIntersect = ray$1.intersectObjects([_plane], true)[0] || false; if (planeIntersect === false) return; pointEnd.copy(planeIntersect.point).sub(worldPositionStart); if (mode === 'translate') { // Apply translate offset.copy(pointEnd).sub(pointStart); if (space === 'local' && axis !== 'XYZ') { offset.applyQuaternion(worldQuaternionInv); } if (axis.indexOf('X') === -1) offset.x = 0; if (axis.indexOf('Y') === -1) offset.y = 0; if (axis.indexOf('Z') === -1) offset.z = 0; if (space === 'local' && axis !== 'XYZ') { offset.applyQuaternion(quaternionStart).divide(parentScale); } else { offset.applyQuaternion(parentQuaternionInv).divide(parentScale); } if (object.overlayType) { // overlay高度略小于地面高度时会出bug var heightProtect = object.floor.boundingBox.min.y - offset.y - positionStart.y; if (heightProtect > 0 && heightProtect < 0.024) offset.y = object.floor.boundingBox.min.y - positionStart.y; } // 当scale缩放为负时,offset得出的y、z值符号相反,原因不明,目前先打个补丁 offset.y *= Math.sign(object.scale.y); offset.z *= Math.sign(object.scale.z); object.position.copy(offset).add(positionStart); // Apply translation snap if (this.translationSnap) { if (space === 'local') { object.position.applyQuaternion(_tempQuaternion.copy(quaternionStart).invert()); if (axis.search('X') !== -1) { object.position.x = Math.round(object.position.x / this.translationSnap) * this.translationSnap; } if (axis.search('Y') !== -1) { object.position.y = Math.round(object.position.y / this.translationSnap) * this.translationSnap; } if (axis.search('Z') !== -1) { object.position.z = Math.round(object.position.z / this.translationSnap) * this.translationSnap; } object.position.applyQuaternion(quaternionStart); } if (space === 'world') { if (object.parent) { object.position.add(_tempVector.setFromMatrixPosition(object.parent.matrixWorld)); } if (axis.search('X') !== -1) { object.position.x = Math.round(object.position.x / this.translationSnap) * this.translationSnap; } if (axis.search('Y') !== -1) { object.position.y = Math.round(object.position.y / this.translationSnap) * this.translationSnap; } if (axis.search('Z') !== -1) { object.position.z = Math.round(object.position.z / this.translationSnap) * this.translationSnap; } if (object.parent) { object.position.sub(_tempVector.setFromMatrixPosition(object.parent.matrixWorld)); } } } } else if (mode === 'scale') { if (axis.search('XYZ') !== -1) { var d = pointEnd.length() / pointStart.length(); if (pointEnd.dot(pointStart) < 0) d *= -1; if (this.options.NoScaleZ) { //xzw add _tempVector2.set(d, d, 1); } else { _tempVector2.set(d, d, d); } } else if (axis.search('XY') !== -1) { //add 等比例for plane var d = pointEnd.length() / pointStart.length(); if (pointEnd.dot(pointStart) < 0) d *= -1; _tempVector2.set(d, d, 1); } else { _tempVector.copy(pointStart); _tempVector2.copy(pointEnd); _tempVector.applyQuaternion(worldQuaternionInv); _tempVector2.applyQuaternion(worldQuaternionInv); _tempVector2.divide(_tempVector); if (axis.search('X') === -1) { _tempVector2.x = 1; } if (axis.search('Y') === -1) { _tempVector2.y = 1; } if (axis.search('Z') === -1) { _tempVector2.z = 1; } } // Apply scale /*if (this.editState == 'overlay' ) { // 将视频缩放大小限制在0.1到10之间 if (Math.abs(scaleStart.x * _tempVector2.x * settings.overlay.width) < 0.1) return if (Math.abs(scaleStart.x * _tempVector2.x * settings.overlay.width) > 10) return if (Math.abs(scaleStart.y * _tempVector2.y * settings.overlay.height) < 0.1) return if (Math.abs(scaleStart.y * _tempVector2.y * settings.overlay.height) > 10) return } if (this.editState == 'decoration') { // 将模型缩放大小限制在0.1到10之间 if (Math.abs(scaleStart.x * _tempVector2.x) < 0.1) return if (Math.abs(scaleStart.x * _tempVector2.x) > 10) return if (Math.abs(scaleStart.y * _tempVector2.y) < 0.1) return if (Math.abs(scaleStart.y * _tempVector2.y) > 10) return if (Math.abs(scaleStart.z * _tempVector2.z) < 0.1) return if (Math.abs(scaleStart.z * _tempVector2.z) > 10) return } */ if (this.editState == 'overlay' || this.editState == 'decoration') { // 将模型缩放大小限制在0.1到10之间 var min = 0.1, max = 10; if (this.editState == 'overlay') { //先暂乘以geo长宽比率,修改为真实大小 scaleStart.x *= settings$3.overlay.width; scaleStart.y *= settings$3.overlay.height; } var axises = ['x', 'y', 'z']; var result = { min: { v: Infinity }, max: { v: -Infinity } }; axises.forEach(function (e) { _tempVector2[e] = Math.abs(_tempVector2[e]); //先保证都是非负 if (_tempVector2[e] != 1) { var v = _tempVector2[e] * scaleStart[e]; if (v < result.min.v) { result.min.axis = e, result.min.v = v; } else if (v > result.min.v) { result.max.axis = e, result.max.v = v; } } }); //已知_tempVector2 的三个轴的值除了1其他的都一样 var newS; if (result.min.v < min) { //用最小的得到最小比值 newS = min / scaleStart[result.min.axis]; } else if (result.max.v > max) { //用最大的得到最大比值 newS = max / scaleStart[result.max.axis]; } //newS && console.log('newS',newS,result) newS && axises.forEach(function (e) { if (_tempVector2[e] != 1) { //1的是绝对不能更改的轴 _tempVector2[e] = newS; } }); if (this.editState == 'overlay') { //恢复 scaleStart.x /= settings$3.overlay.width; scaleStart.y /= settings$3.overlay.height; } //注,拖拽缩小时,容易缩放不到0(如0.3)就直接变大,因为需要无限接近原点才行。 } if (this.editState == 'clipbox') ; object.scale.copy(scaleStart).multiply(_tempVector2); if (this.scaleSnap) { if (axis.search('X') !== -1) { object.scale.x = Math.round(object.scale.x / this.scaleSnap) * this.scaleSnap || this.scaleSnap; } if (axis.search('Y') !== -1) { object.scale.y = Math.round(object.scale.y / this.scaleSnap) * this.scaleSnap || this.scaleSnap; } if (axis.search('Z') !== -1) { object.scale.z = Math.round(object.scale.z / this.scaleSnap) * this.scaleSnap || this.scaleSnap; } } //add if (this.editState == 'overlay') { object.width = settings$3.overlay.width * object.scale.x; object.height = settings$3.overlay.height * object.scale.y; this.player.EditOverlay.updateOverlayScaleDisplay(); } } else if (mode === 'rotate') { offset.copy(pointEnd).sub(pointStart); if (this.player.mode == 'floorplan') { var flcamera = this.player.cameraControls.cameras.floorplan; var eyeDistance = (flcamera.right - flcamera.left) / flcamera.aspect; var ROTATION_SPEED = 5 / eyeDistance; } else var ROTATION_SPEED = 5 / worldPosition.distanceTo(_tempVector.setFromMatrixPosition(this.camera.matrixWorld)); if (axis === 'E') { rotationAxis.copy(eye); rotationAngle = pointEnd.angleTo(pointStart); startNorm.copy(pointStart).normalize(); endNorm.copy(pointEnd).normalize(); rotationAngle *= endNorm.cross(startNorm).dot(eye) < 0 ? 1 : -1; } else if (axis === 'XYZE') { rotationAxis.copy(offset).cross(eye).normalize(); rotationAngle = offset.dot(_tempVector.copy(rotationAxis).cross(this.eye)) * ROTATION_SPEED; } else if (axis === 'X' || axis === 'Y' || axis === 'Z') { rotationAxis.copy(_unit[axis]); _tempVector.copy(_unit[axis]); if (space === 'local') { _tempVector.applyQuaternion(worldQuaternion); } rotationAngle = offset.dot(_tempVector.cross(eye).normalize()) * ROTATION_SPEED; } // Apply rotation snap if (this.rotationSnap) rotationAngle = Math.round(rotationAngle / this.rotationSnap) * this.rotationSnap; this.rotationAngle = rotationAngle; // Apply rotate var isLocalSpace = space === 'local'; if (this.spaceForRotate) { if (axis === 'X') isLocalSpace = this.spaceForRotate.x === 'local'; if (axis === 'Y') isLocalSpace = this.spaceForRotate.y === 'local'; if (axis === 'Z') isLocalSpace = this.spaceForRotate.z === 'local'; } if (isLocalSpace && axis !== 'E' && axis !== 'XYZE') { object.quaternion.copy(quaternionStart); object.quaternion.multiply(_tempQuaternion.setFromAxisAngle(rotationAxis, rotationAngle)).normalize(); } else { rotationAxis.applyQuaternion(parentQuaternionInv); object.quaternion.copy(_tempQuaternion.setFromAxisAngle(rotationAxis, rotationAngle)); object.quaternion.multiply(quaternionStart).normalize(); } } this.dispatchEvent(Object.assign(mouseMoveEvent, { mode: this.mode, state: this.editState, axis, angle: rotationAngle, deltaAngle: rotationAngle - lastRotationAngle })); this.dispatchEvent(changeEvent); this.dispatchEvent(objectChangeEvent); lastRotationAngle = rotationAngle; } }, { key: "pointerUp", value: function pointerUp(pointer) { if (this.object === undefined) return; //if ( pointer.button !== undefined && pointer.button !== 0 ) return; if (this.dragging && this.axis !== null) { mouseUpEvent.mode = this.mode; this.dispatchEvent(mouseUpEvent); } this.dragging = false; if (pointer.button === undefined) this.axis = null; if (this.player.cameraControls.activeControl) { //this.player.cameraControls.activeControl.locked = false; //add this.player.cameraControls.activeControl.pointerDragOn = false; //add this.player.cameraControls.activeControl.enabled = true; } lastRotationAngle = 0; } // normalize mouse / touch pointer and remap {x,y} to view space. }, { key: "getPointer", value: function getPointer(event) { if (!event) { console.log('hhahhhahah'); return; } if (document.pointerLockElement) { return { x: 0, y: 0, button: event.button }; } else { var pointer = event.changedTouches ? event.changedTouches[0] : event; var rect = domElement.getBoundingClientRect(); return { x: (pointer.clientX - rect.left) / rect.width * 2 - 1, y: -(pointer.clientY - rect.top) / rect.height * 2 + 1, button: event.button }; } } // mouse / touch event handlers }, { key: "onPointerHover", value: function onPointerHover(event) { if (!this.enabled) return; //this.pointerHover( getPointer( event ) ); this.pointerHover(this.player.mouse); } }, { key: "onPointerDown", value: function onPointerDown(event) { if (!this.enabled) return; //document.addEventListener( "mousemove", onPointerMove, false ); /* this.pointerHover( getPointer( event ) ); this.pointerDown( getPointer( event ) ); */ this.pointerHover(this.player.mouse); this.pointerDown(this.player.mouse); } }, { key: "onPointerMove", value: function onPointerMove(event) { if (!this.enabled || !this.dragging) return; //xzw change //this.pointerMove( getPointer( event ) ); this.pointerMove(this.player.mouse); } }, { key: "onPointerUp", value: function onPointerUp(event) { if (!this.enabled) return; //document.removeEventListener( "mousemove", onPointerMove, false ); //this.pointerUp( getPointer( event ) ); this.pointerUp(this.player.mouse); } // TODO: deprecate }, { key: "getMode", value: function getMode() { return this.mode; } }, { key: "setMode", value: function setMode(mode) { this.mode = mode; } }, { key: "setTranslationSnap", value: function setTranslationSnap(translationSnap) { this.translationSnap = translationSnap; } }, { key: "setRotationSnap", value: function setRotationSnap(rotationSnap) { this.rotationSnap = rotationSnap; } }, { key: "setScaleSnap", value: function setScaleSnap(scaleSnap) { this.scaleSnap = scaleSnap; } /* this.setSize = function ( size ) { this.size = size; }; */ }, { key: "setSpace", value: function setSpace(space) { this.space = space; } }, { key: "update", value: function update() { console.warn('THREE.TransformControls: update function has no more functionality and therefore has been deprecated.'); } }]); return TransformControls; }(THREE.Object3D); // TransformControls.prototype = Object.assign(Object.create(Object3D.prototype), { // constructor: TransformControls, // isTransformControls: true, // }) var TransformControlsGizmo = /*#__PURE__*/function (_THREE$Object3D2) { _inherits(TransformControlsGizmo, _THREE$Object3D2); var _super2 = _createSuper$1o(TransformControlsGizmo); function TransformControlsGizmo(options) { var _this2; _classCallCheck(this, TransformControlsGizmo); _this2 = _super2.call(this); _this2.type = 'TransformControlsGizmo'; _this2.options = options; _this2.player = options.player; // shared materials var gizmoMaterial = new THREE.MeshBasicMaterial({ depthTest: false, depthWrite: false, transparent: true, side: DoubleSide, fog: false }); var gizmoLineMaterial = new THREE.LineBasicMaterial({ depthTest: false, depthWrite: false, transparent: true, linewidth: 1, fog: false }); // Make unique material for each axis/color var matInvisible = gizmoMaterial.clone(); matInvisible.opacity = 0.35; var matHelper = gizmoMaterial.clone(); matHelper.opacity = 0.1; //У׼�� var matRed = gizmoMaterial.clone(); matRed.color.set(0xff0000); var matGreen = gizmoMaterial.clone(); matGreen.color.set(0x00ff00); var matBlue = gizmoMaterial.clone(); matBlue.color.set(0x0000ff); var matWhiteTransparent = gizmoMaterial.clone(); matWhiteTransparent.opacity = 0.75; matWhiteTransparent.color.set(0xf0f0f0); // matWhiteTransparent.color.set(0x00d0fd) //xzw add var matYellowTransparent = matWhiteTransparent.clone(); matYellowTransparent.color.set(0xffff00); var matCyanTransparent = matWhiteTransparent.clone(); matCyanTransparent.color.set(0x00ffff); var matMagentaTransparent = matWhiteTransparent.clone(); matMagentaTransparent.color.set(0xff00ff); var matYellow = gizmoMaterial.clone(); matYellow.color.set(0xffff00); var matLineRed = gizmoLineMaterial.clone(); matLineRed.color.set(0xff0000); var matLineGreen = gizmoLineMaterial.clone(); matLineGreen.color.set(0x00ff00); var matLineBlue = gizmoLineMaterial.clone(); matLineBlue.color.set(0x0000ff); var matLineCyan = gizmoLineMaterial.clone(); matLineCyan.color.set(0x00ffff); var matLineMagenta = gizmoLineMaterial.clone(); matLineMagenta.color.set(0xff00ff); var matLineYellow = gizmoLineMaterial.clone(); matLineYellow.color.set(0xffff00); var matLineGray = gizmoLineMaterial.clone(); matLineGray.color.set(0x787878); var matLineYellowTransparent = matLineYellow.clone(); matLineYellowTransparent.opacity = 0.25; // reusable geometry var arrowGeometry = new CylinderBufferGeometry(0, 0.07, 0.2, 12, 1, false); var scaleHandleGeometry = new BoxBufferGeometry(0.125, 0.125, 0.125); var lineGeometry = new BufferGeometry(); lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 1, 0, 0], 3)); //--------------- xzw add fatLines: ----------------- var fatLinePoints = { 'x+': [{ x: 0, y: 0, z: 0 }, { x: 0.5, y: 0, z: 0 }], 'x-': [{ x: 0, y: 0, z: 0 }, { x: -0.5, y: 0, z: 0 }], 'y+': [{ x: 0, y: 0, z: 0 }, { x: 0, y: 0.5, z: 0 }], 'y-': [{ x: 0, y: 0, z: 0 }, { x: 0, y: -0.5, z: 0 }], 'z+': [{ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0.5 }], 'z-': [{ x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: -0.5 }] }; var fatLineGeos = {}; var fatLintMats = { x: LineDraw.createFatLineMat({ lineWidth: 3, color: 0xff0000, depthTest: false, opacity: 0.9 }), y: LineDraw.createFatLineMat({ lineWidth: 3, color: 0x00ff00, depthTest: false, opacity: 0.9 }), z: LineDraw.createFatLineMat({ lineWidth: 3, color: 0x0000ff, depthTest: false, opacity: 0.9 }) }; var getFatLine = function getFatLine(geoName, matName) { var points = fatLinePoints[geoName]; var material = fatLintMats[matName]; var line = LineDraw.createFatLine(points, { material }); fatLineGeos[geoName] = line.geometry; //record line.renderOrder = 4; return line; }; //-------------------------------------------------- var CircleGeometry = function CircleGeometry(radius, arc) { var geometry = new BufferGeometry(); var vertices = []; for (var i = 0; i <= 64 * arc; ++i) { vertices.push(0, Math.cos(i / 32 * Math.PI) * radius, Math.sin(i / 32 * Math.PI) * radius); } geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3)); return geometry; }; // Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position var TranslateHelperGeometry = function TranslateHelperGeometry() { var geometry = new BufferGeometry(); geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 1, 1, 1], 3)); return geometry; }; // Gizmo definitions - custom hierarchy definitions for setupGizmo() function var gizmoTranslate = { X: [[new Mesh(arrowGeometry, matRed), [0.5, 0, 0], [0, 0, -Math.PI / 2], null, 'fwd'], //[ new Mesh( arrowGeometry, matRed ), [ 1, 0, 0 ], [ 0, 0, Math.PI / 2 ], null, 'bwd' ], [getFatLine('x+', 'x') /* new Line( lineGeometry, matLineRed ) */ ]], Y: [[new Mesh(arrowGeometry, matGreen), [0, 0.5, 0], null, null, 'fwd'], //[ new Mesh( arrowGeometry, matGreen ), [ 0, 1, 0 ], [ Math.PI, 0, 0 ], null, 'bwd' ], [getFatLine('y+', 'y') /* new Line( lineGeometry, matLineGreen ) */ ]], Z: [[new Mesh(arrowGeometry, matBlue), [0, 0, 0.5], [Math.PI / 2, 0, 0], null, 'fwd'], //[ new Mesh( arrowGeometry, matBlue ), [ 0, 0, 1 ], [ - Math.PI / 2, 0, 0 ], null, 'bwd' ], [getFatLine('z+', 'z') /* new Line( lineGeometry, matLineBlue ) */ ]] /* XYZ: [ [ new Mesh( new OctahedronBufferGeometry( 0.1, 0 ), matWhiteTransparent.clone() ), [ 0, 0, 0 ], [ 0, 0, 0 ]] ], XY: [ [ new Mesh( new PlaneBufferGeometry( 0.295, 0.295 ), matYellowTransparent.clone() ), [ 0.15, 0.15, 0 ]], [ new Line( lineGeometry, matLineYellow ), [ 0.18, 0.3, 0 ], null, [ 0.125, 1, 1 ]], [ new Line( lineGeometry, matLineYellow ), [ 0.3, 0.18, 0 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]] ], YZ: [ [ new Mesh( new PlaneBufferGeometry( 0.295, 0.295 ), matCyanTransparent.clone() ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]], [ new Line( lineGeometry, matLineCyan ), [ 0, 0.18, 0.3 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]], [ new Line( lineGeometry, matLineCyan ), [ 0, 0.3, 0.18 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]] ], XZ: [ [ new Mesh( new PlaneBufferGeometry( 0.295, 0.295 ), matMagentaTransparent.clone() ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]], [ new Line( lineGeometry, matLineMagenta ), [ 0.18, 0, 0.3 ], null, [ 0.125, 1, 1 ]], [ new Line( lineGeometry, matLineMagenta ), [ 0.3, 0, 0.18 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]] ]*/ }; var pickerTranslate = { X: [[new Mesh(new CylinderBufferGeometry(0.2, 0, 0.5, 4, 1, false), matInvisible), [0.3, 0, 0], [0, 0, -Math.PI / 2]]], Y: [[new Mesh(new CylinderBufferGeometry(0.2, 0, 0.5, 4, 1, false), matInvisible), [0, 0.3, 0]]], Z: [[new Mesh(new CylinderBufferGeometry(0.2, 0, 0.5, 4, 1, false), matInvisible), [0, 0, 0.3], [Math.PI / 2, 0, 0]]] /* XYZ: [ [ new Mesh( new OctahedronBufferGeometry( 0.2, 0 ), matInvisible ) ] ], XY: [ [ new Mesh( new PlaneBufferGeometry( 0.4, 0.4 ), matInvisible ), [ 0.2, 0.2, 0 ]] ], YZ: [ [ new Mesh( new PlaneBufferGeometry( 0.4, 0.4 ), matInvisible ), [ 0, 0.2, 0.2 ], [ 0, Math.PI / 2, 0 ]] ], XZ: [ [ new Mesh( new PlaneBufferGeometry( 0.4, 0.4 ), matInvisible ), [ 0.2, 0, 0.2 ], [ - Math.PI / 2, 0, 0 ]] ]*/ }; var helperTranslate = { START: [[new Mesh(new OctahedronBufferGeometry(0.01, 2), matHelper), null, null, null, 'helper']], END: [[new Mesh(new OctahedronBufferGeometry(0.01, 2), matHelper), null, null, null, 'helper']], DELTA: [[new Line$1(TranslateHelperGeometry(), matHelper), null, null, null, 'helper']], X: [[new Line$1(lineGeometry, matHelper.clone()), [-1e3, 0, 0], null, [1e6, 1, 1], 'helper']], Y: [[new Line$1(lineGeometry, matHelper.clone()), [0, -1e3, 0], [0, 0, Math.PI / 2], [1e6, 1, 1], 'helper']], Z: [[new Line$1(lineGeometry, matHelper.clone()), [0, 0, -1e3], [0, -Math.PI / 2, 0], [1e6, 1, 1], 'helper']] }; _this2.updateRotate = function () { var gizmoRotate = { X: [[new Line$1(CircleGeometry(1, 0.5), matLineRed)], [new Mesh(new OctahedronBufferGeometry(0.04, 0), matRed), [0, 0, 0.99], null, [1, 3, 1]]], Y: [[new Line$1(CircleGeometry(1, 0.5), matLineGreen), null, [0, 0, -Math.PI / 2]], [new Mesh(new OctahedronBufferGeometry(0.04, 0), matGreen), [0, 0, 0.99], null, [3, 1, 1]]], Z: [[new Line$1(CircleGeometry(1, 0.5), matLineBlue), null, [0, Math.PI / 2, 0]], [new Mesh(new OctahedronBufferGeometry(0.04, 0), matBlue), [0.99, 0, 0], null, [1, 3, 1]]], /* E: [ [ new Line( CircleGeometry( 1.25, 1 ), matLineYellowTransparent ), null, [ 0, Math.PI / 2, 0 ]], [ new Mesh( new CylinderBufferGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ 1.17, 0, 0 ], [ 0, 0, - Math.PI / 2 ], [ 1, 1, 0.001 ]], [ new Mesh( new CylinderBufferGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ - 1.17, 0, 0 ], [ 0, 0, Math.PI / 2 ], [ 1, 1, 0.001 ]], [ new Mesh( new CylinderBufferGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ 0, - 1.17, 0 ], [ Math.PI, 0, 0 ], [ 1, 1, 0.001 ]], [ new Mesh( new CylinderBufferGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ 0, 1.17, 0 ], [ 0, 0, 0 ], [ 1, 1, 0.001 ]], ] , */ XYZE: [[new Line$1(CircleGeometry(1, 1), matLineGray), null, [0, Math.PI / 2, 0]]] }; var helperRotate = { AXIS: [[new Line$1(lineGeometry, matHelper.clone()), [-1e3, 0, 0], null, [1e6, 1, 1], 'helper']] }; var pickerRotate = { X: [[new Mesh(new TorusBufferGeometry(1, 0.1, 4, 24), matInvisible), [0, 0, 0], [0, -Math.PI / 2, -Math.PI / 2]]], Y: [[new Mesh(new TorusBufferGeometry(1, 0.1, 4, 24), matInvisible), [0, 0, 0], [Math.PI / 2, 0, 0]]], Z: [[new Mesh(new TorusBufferGeometry(1, 0.1, 4, 24), matInvisible), [0, 0, 0], [0, 0, -Math.PI / 2]]] /*E: [ [ new Mesh( new TorusBufferGeometry( 1.25, 0.1, 2, 24 ), matInvisible ) ] ] , XYZE: [ [ new Mesh( new SphereBufferGeometry( 0.7, 10, 8 ), matInvisible ) ] ] */ }; if (options.rotateAxis) { if (options.rotateAxis.indexOf('x') < 0) { delete gizmoRotate.X; delete gizmoRotate.XYZE; delete pickerRotate.X; } if (options.rotateAxis.indexOf('y') < 0) { delete gizmoRotate.Y; delete gizmoRotate.XYZE; delete pickerRotate.Y; } if (options.rotateAxis.indexOf('z') < 0) { delete gizmoRotate.Z; delete gizmoRotate.XYZE; delete pickerRotate.Z; } } return { gizmo: gizmoRotate, picker: pickerRotate, helper: helperRotate }; }; _this2.updateScale = function () { var gizmoScale = { X: [[new Mesh(scaleHandleGeometry, matRed), [0.5, 0, 0], [0, 0, -Math.PI / 2]], [getFatLine('x-', 'x')] //use x- instead of x+, cause need to get all axis lineGeos ], Y: [[new Mesh(scaleHandleGeometry, matGreen), [0, 0.5, 0]], [getFatLine('y-', 'y')]], Z: [[new Mesh(scaleHandleGeometry, matBlue), [0, 0, 0.5], [Math.PI / 2, 0, 0]], [getFatLine('z-', 'z'), null, [0, -Math.PI / 2, 0], [0.5, 1, 1]]], /*XY: [[ new Mesh( scaleHandleGeometry, matYellowTransparent ), [ 0.85, 0.85, 0 ], null, [ 2, 2, 0.2 ]], [ new Line( lineGeometry, matLineYellow ), [ 0.855, 0.98, 0 ], null, [ 0.125, 1, 1 ]], [ new Line( lineGeometry, matLineYellow ), [ 0.98, 0.855, 0 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]]], YZ: [[ new Mesh( scaleHandleGeometry, matCyanTransparent ), [ 0, 0.85, 0.85 ], null, [ 0.2, 2, 2 ]], [ new Line( lineGeometry, matLineCyan ), [ 0, 0.855, 0.98 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]], [ new Line( lineGeometry, matLineCyan ), [ 0, 0.98, 0.855 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]]], XZ: [[ new Mesh( scaleHandleGeometry, matMagentaTransparent ), [ 0.85, 0, 0.85 ], null, [ 2, 0.2, 2 ]], [ new Line( lineGeometry, matLineMagenta ), [ 0.855, 0, 0.98 ], null, [ 0.125, 1, 1 ]], [ new Line( lineGeometry, matLineMagenta ), [ 0.98, 0, 0.855 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]]], */ /*XYZX: [[ new Mesh( new BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 1.1, 0, 0 ]],], XYZY: [[ new Mesh( new BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 0, 1.1, 0 ]],] , XYZZ: [[ new Mesh( new BoxBufferGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 0, 0, 1.1 ]],] */ XY: [[new Mesh(scaleHandleGeometry, matYellowTransparent), [0.5, 0.5, 0]]], YZ: [[new Mesh(scaleHandleGeometry, matCyanTransparent), [0, 0.5, 0.5]]], XZ: [[new Mesh(scaleHandleGeometry, matMagentaTransparent), [0.5, 0, 0.5]]], XYZX: [[new Mesh(new BoxBufferGeometry(0.125, 0.125, 0.125), matWhiteTransparent.clone()), [0.5, 0.5, 0.5]]] }; var pickerScale = { X: [[new Mesh(new CylinderBufferGeometry(0.2, 0, 0.5, 4, 1, false), matInvisible), [0.3, 0, 0], [0, 0, -Math.PI / 2]]], Y: [[new Mesh(new CylinderBufferGeometry(0.2, 0, 0.5, 4, 1, false), matInvisible), [0, 0.3, 0]]], Z: [[new Mesh(new CylinderBufferGeometry(0.2, 0, 0.5, 4, 1, false), matInvisible), [0, 0, 0.3], [Math.PI / 2, 0, 0]]], /*XY: [[ new Mesh( scaleHandleGeometry, matInvisible ), [ 0.85, 0.85, 0 ], null, [ 3, 3, 0.2 ]],], YZ: [[ new Mesh( scaleHandleGeometry, matInvisible ), [ 0, 0.85, 0.85 ], null, [ 0.2, 3, 3 ]],], XZ: [[ new Mesh( scaleHandleGeometry, matInvisible ), [ 0.85, 0, 0.85 ], null, [ 3, 0.2, 3 ]],], */ /*XYZX: [[ new Mesh( new BoxBufferGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 1.1, 0, 0 ]],], XYZY: [[ new Mesh( new BoxBufferGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 1.1, 0 ]],] , XYZZ: [[ new Mesh( new BoxBufferGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 0, 1.1 ]],] */ XY: [[new Mesh(scaleHandleGeometry, matInvisible), [0.5, 0.5, 0]]], YZ: [[new Mesh(scaleHandleGeometry, matInvisible), [0, 0.5, 0.5]]], XZ: [[new Mesh(scaleHandleGeometry, matInvisible), [0.5, 0, 0.5]]], XYZX: [[new Mesh(new BoxBufferGeometry(0.2, 0.2, 0.2), matInvisible), [0.5, 0.5, 0.5]]] }; if (options.scaleAxis) { if (options.scaleAxis.indexOf('z') < 0) { delete gizmoScale.Z; delete gizmoScale.YZ; delete gizmoScale.XZ; delete gizmoScale.XYZX; delete pickerScale.Z; delete pickerScale.YZ; delete pickerScale.XZ; delete pickerScale.XYZX; } if (options.scaleAxis.indexOf('x') > -1 && options.scaleAxis.indexOf('y') > -1 && options.scaleAxis.indexOf('z') > -1) { delete gizmoScale.XY; delete gizmoScale.YZ; delete gizmoScale.XZ; delete pickerScale.XY; delete pickerScale.YZ; delete pickerScale.XZ; } } var helperScale = { X: [[new Line$1(lineGeometry, matHelper.clone()), [-1e3, 0, 0], null, [1e6, 1, 1], 'helper']], Y: [[new Line$1(lineGeometry, matHelper.clone()), [0, -1e3, 0], [0, 0, Math.PI / 2], [1e6, 1, 1], 'helper']], Z: [[new Line$1(lineGeometry, matHelper.clone()), [0, 0, -1e3], [0, -Math.PI / 2, 0], [1e6, 1, 1], 'helper']] }; return { gizmo: gizmoScale, picker: pickerScale, helper: helperScale }; }; // Creates an Object3D with gizmos described in custom hierarchy definition. _this2.setupGizmo = function (gizmoMap) { var gizmo = new Object3D(); for (var name in gizmoMap) { for (var i = gizmoMap[name].length; i--;) { var object = gizmoMap[name][i][0]; var position = gizmoMap[name][i][1]; var rotation = gizmoMap[name][i][2]; var scale = gizmoMap[name][i][3]; var tag = gizmoMap[name][i][4]; if (object.type != 'Fatline') { //xzw add for fatline object = object.clone(); } // name and tag properties are essential for picking and updating logic. object.name = name; object.tag = tag; if (position) { object.position.set(position[0], position[1], position[2]); } if (rotation) { object.rotation.set(rotation[0], rotation[1], rotation[2]); } if (scale) { object.scale.set(scale[0], scale[1], scale[2]); } object.updateMatrix(); if (object.geometry.clone()) { var tempGeometry = object.geometry.clone(); tempGeometry.applyMatrix4(object.matrix); object.geometry = tempGeometry; } else { object.geometry.applyMatrix4(object.matrix); } object.renderOrder = Infinity; object.position.set(0, 0, 0); object.rotation.set(0, 0, 0); object.scale.set(1, 1, 1); gizmo.add(object); } } return gizmo; }; // Reusable utility variables var tempVector = new THREE.Vector3(0, 0, 0); var tempEuler = new Euler(); var alignVector = new THREE.Vector3(0, 1, 0); var zeroVector = new THREE.Vector3(0, 0, 0); var lookAtMatrix = new Matrix4$1(); var tempQuaternion = new Quaternion$1(); var tempQuaternion2 = new Quaternion$1(); var identityQuaternion = new Quaternion$1(); var unitX = new THREE.Vector3(1, 0, 0); var unitY = new THREE.Vector3(0, 1, 0); var unitZ = new THREE.Vector3(0, 0, 1); // Gizmo creation _this2.gizmo = {}; _this2.picker = {}; _this2.helper = {}; _this2.add(_this2.gizmo['translate'] = _this2.setupGizmo(gizmoTranslate)); _this2.add(_this2.gizmo['rotate'] = _this2.setupGizmo(_this2.updateRotate().gizmo)); _this2.add(_this2.gizmo['scale'] = _this2.setupGizmo(_this2.updateScale().gizmo)); _this2.add(_this2.picker['translate'] = _this2.setupGizmo(pickerTranslate)); _this2.add(_this2.picker['rotate'] = _this2.setupGizmo(_this2.updateRotate().picker)); _this2.add(_this2.picker['scale'] = _this2.setupGizmo(_this2.updateScale().picker)); _this2.add(_this2.helper['translate'] = _this2.setupGizmo(helperTranslate)); _this2.add(_this2.helper['rotate'] = _this2.setupGizmo(_this2.updateRotate().helper)); _this2.add(_this2.helper['scale'] = _this2.setupGizmo(_this2.updateScale().helper)); // Pickers should be hidden always _this2.picker['translate'].visible = false; _this2.picker['rotate'].visible = false; _this2.picker['scale'].visible = false; // updateMatrixWorld will update transformations and appearance of individual handles _this2.updateMatrixWorld = function () { var space = this.space; if (this.mode === 'scale') space = 'local'; // scale always oriented to local rotation var quaternion = space === 'local' ? this.worldQuaternion : identityQuaternion; // Show only gizmos for current transform mode this.gizmo['translate'].visible = this.mode === 'translate'; this.gizmo['rotate'].visible = this.mode === 'rotate'; this.gizmo['scale'].visible = this.mode === 'scale'; this.helper['translate'].visible = this.mode === 'translate'; this.helper['rotate'].visible = this.mode === 'rotate'; this.helper['scale'].visible = this.mode === 'scale'; var handles = []; handles = handles.concat(this.picker[this.mode].children); handles = handles.concat(this.gizmo[this.mode].children); handles = handles.concat(this.helper[this.mode].children); var eyeDistance = this.worldPosition.distanceTo(this.cameraPosition); //俯视图的透视和距离无关,因此在两种相机切换切换时大小过渡比较困难 if (this.player.mode == 'transitioning' && (this.player.modeTran.split('-')[0] == 'floorplan' || this.player.modeTran.split('-')[1] == 'floorplan')) { var flcamera = this.player.cameraControls.cameras.floorplan; var min = (flcamera.right - flcamera.left) / flcamera.aspect; eyeDistance = Math.min(eyeDistance, min); } else if (this.player.mode == 'floorplan') { var flcamera = this.player.cameraControls.cameras.floorplan; eyeDistance = (flcamera.right - flcamera.left) / flcamera.aspect; } var scale = eyeDistance * this.size / 7; for (var i = 0; i < handles.length; i++) { var handle = handles[i]; // hide aligned to camera handle.visible = true; handle.rotation.set(0, 0, 0); handle.position.copy(this.worldPosition); handle.scale.set(1, 1, 1).multiplyScalar(scale); /* if(this.mode == "translate" && this.parent.object){ if(handle.name == "X"){ //handle.position.copy(handle.initPos || new THREE.Vector3).add(new THREE.Vector3( this.parent.object.width / 2 / scale, 0,0)); handle.position.add(new THREE.Vector3( this.parent.object.width / 2 , 0,0)); }else if(handle.name == "Y"){ //handle.position.set(0, this.parent.object.height / 2 / scale,0); }else if(handle.name == "Z"){ //handle.position.set( 0,0,this.parent.object.depth / scale); } } */ // TODO: simplify helpers and consider decoupling from gizmo if (handle.tag === 'helper') { handle.visible = false; if (handle.name === 'AXIS') { handle.position.copy(this.worldPositionStart); handle.visible = !!this.axis; if (this.axis === 'X') { tempQuaternion.setFromEuler(tempEuler.set(0, 0, 0)); handle.quaternion.copy(quaternion).multiply(tempQuaternion); if (Math.abs(alignVector.copy(unitX).applyQuaternion(quaternion).dot(this.eye)) > 0.9) { handle.visible = false; } } if (this.axis === 'Y') { tempQuaternion.setFromEuler(tempEuler.set(0, 0, Math.PI / 2)); handle.quaternion.copy(quaternion).multiply(tempQuaternion); if (Math.abs(alignVector.copy(unitY).applyQuaternion(quaternion).dot(this.eye)) > 0.9) { handle.visible = false; } } if (this.axis === 'Z') { tempQuaternion.setFromEuler(tempEuler.set(0, Math.PI / 2, 0)); handle.quaternion.copy(quaternion).multiply(tempQuaternion); if (Math.abs(alignVector.copy(unitZ).applyQuaternion(quaternion).dot(this.eye)) > 0.9) { handle.visible = false; } } if (this.axis === 'XYZE') { tempQuaternion.setFromEuler(tempEuler.set(0, Math.PI / 2, 0)); alignVector.copy(this.rotationAxis); handle.quaternion.setFromRotationMatrix(lookAtMatrix.lookAt(zeroVector, alignVector, unitY)); handle.quaternion.multiply(tempQuaternion); handle.visible = this.dragging; } if (this.axis === 'E') { handle.visible = false; } } else if (handle.name === 'START') { handle.position.copy(this.worldPositionStart); handle.visible = this.dragging; } else if (handle.name === 'END') { handle.position.copy(this.worldPosition); handle.visible = this.dragging; } else if (handle.name === 'DELTA') { handle.position.copy(this.worldPositionStart); handle.quaternion.copy(this.worldQuaternionStart); tempVector.set(1e-10, 1e-10, 1e-10).add(this.worldPositionStart).sub(this.worldPosition).multiplyScalar(-1); tempVector.applyQuaternion(this.worldQuaternionStart.clone().invert()); handle.scale.copy(tempVector); handle.visible = this.dragging; } else { handle.quaternion.copy(quaternion); if (this.dragging) { handle.position.copy(this.worldPositionStart); } else { handle.position.copy(this.worldPosition); } if (this.axis) { handle.visible = this.axis.search(handle.name) !== -1; } } // If updating helper, skip rest of the loop continue; } // Align handles to current local or world rotation handle.quaternion.copy(quaternion); if (this.mode === 'translate' || this.mode === 'scale') { // Hide translate and scale axis facing the camera var AXIS_HIDE_TRESHOLD = 0.99; var PLANE_HIDE_TRESHOLD = 0.2; var AXIS_FLIP_TRESHOLD = 0.0; if (options.dontHideWhenFaceCamera) ; else { if (handle.name === 'X' || handle.name === 'XYZX') { if (Math.abs(alignVector.copy(unitX).applyQuaternion(quaternion).dot(this.eye)) > AXIS_HIDE_TRESHOLD) { handle.scale.set(1e-10, 1e-10, 1e-10); handle.visible = false; } } if (handle.name === 'Y' || handle.name === 'XYZY') { if (Math.abs(alignVector.copy(unitY).applyQuaternion(quaternion).dot(this.eye)) > AXIS_HIDE_TRESHOLD) { handle.scale.set(1e-10, 1e-10, 1e-10); handle.visible = false; } } if (handle.name === 'Z' || handle.name === 'XYZZ') { if (Math.abs(alignVector.copy(unitZ).applyQuaternion(quaternion).dot(this.eye)) > AXIS_HIDE_TRESHOLD) { handle.scale.set(1e-10, 1e-10, 1e-10); handle.visible = false; } } if (handle.name === 'XY') { if (Math.abs(alignVector.copy(unitZ).applyQuaternion(quaternion).dot(this.eye)) < PLANE_HIDE_TRESHOLD) { handle.scale.set(1e-10, 1e-10, 1e-10); handle.visible = false; } } if (handle.name === 'YZ') { if (Math.abs(alignVector.copy(unitX).applyQuaternion(quaternion).dot(this.eye)) < PLANE_HIDE_TRESHOLD) { handle.scale.set(1e-10, 1e-10, 1e-10); handle.visible = false; } } if (handle.name === 'XZ') { if (Math.abs(alignVector.copy(unitY).applyQuaternion(quaternion).dot(this.eye)) < PLANE_HIDE_TRESHOLD) { handle.scale.set(1e-10, 1e-10, 1e-10); handle.visible = false; } } } // Flip translate and scale axis ocluded behind another axis var zReverse = false; if (alignVector.copy(unitZ).applyQuaternion(quaternion).dot(this.eye) < AXIS_FLIP_TRESHOLD) { zReverse = true; } //xzw modify : remove backward arrow if (handle.name.search('X') !== -1) { if (alignVector.copy(unitX).applyQuaternion(quaternion).dot(this.eye) < AXIS_FLIP_TRESHOLD) { /* if ( handle.tag === 'fwd' ) { handle.visible = false; } else { handle.scale.x *= - 1; } } else if ( handle.tag === 'bwd' ) { handle.visible = false;*/ //反向 if (handle.type == 'Fatline') { handle.geometry = fatLineGeos['x-']; } else { handle.scale.x *= -1; } if (this.space == 'world') { handle.position.add(new THREE.Vector3(-0.1, 0, 0)); } else { if (this.parent.object) { //放置在边缘 handle.position.add(new THREE.Vector3(-Math.abs(this.parent.object.width || 0.1) / 2, 0, zReverse || handle.name == 'XYZX' ? 0 : this.parent.object.depth || 0).applyQuaternion(handle.quaternion)); } } } else { if (handle.type == 'Fatline') { handle.geometry = fatLineGeos['x+']; } if (this.space == 'world') { handle.position.add(new THREE.Vector3(0.1, 0, 0)); } else { if (this.parent.object) { //放置在边缘 handle.position.add(new THREE.Vector3(Math.abs(this.parent.object.width || 0.1) / 2, 0, zReverse || handle.name == 'XYZX' ? 0 : this.parent.object.depth || 0).applyQuaternion(handle.quaternion)); } } } } if (handle.name.search('Y') !== -1) { if (alignVector.copy(unitY).applyQuaternion(quaternion).dot(this.eye) < AXIS_FLIP_TRESHOLD) { /* if ( handle.tag === 'fwd' ) { handle.visible = false; } else { handle.scale.y *= - 1; } } else if ( handle.tag === 'bwd' ) { handle.visible = false; */ if (handle.type == 'Fatline') { handle.geometry = fatLineGeos['y-']; } else handle.scale.y *= -1; if (this.space == 'world') handle.position.add(new THREE.Vector3(0, -0.1, 0));else this.parent.object && handle.position.add(new THREE.Vector3(0, -Math.abs(this.parent.object.height || 0.1) / 2, zReverse || handle.name == 'XYZX' ? 0 : this.parent.object.depth || 0).applyQuaternion(handle.quaternion)); } else { if (handle.type == 'Fatline') { handle.geometry = fatLineGeos['y+']; } if (this.space == 'world') handle.position.add(new THREE.Vector3(0, 0.1, 0));else this.parent.object && handle.position.add(new THREE.Vector3(0, Math.abs(this.parent.object.height || 0.1) / 2, zReverse || handle.name == 'XYZX' ? 0 : this.parent.object.depth || 0).applyQuaternion(handle.quaternion)); } } if (handle.name.search('Z') !== -1) { if (zReverse) { if (handle.type == 'Fatline') { handle.geometry = fatLineGeos['z-']; } else handle.scale.z *= -1; if (this.space == 'world') handle.position.add(new THREE.Vector3(0, 0, -0.1)); } else { if (handle.type == 'Fatline') { handle.geometry = fatLineGeos['z+']; } /* if(this.parent.object ){ if(this.mode != "scale" ){ handle.position.add(new THREE.Vector3(0, 0 , this.parent.object.depth).applyQuaternion( handle.quaternion )); }else{ handle.position.add(new THREE.Vector3(0, 0 , this.parent.object.depth).applyQuaternion( handle.quaternion )); } } */ if (this.space == 'world') handle.position.add(new THREE.Vector3(0, 0, 0.1));else this.parent.object && handle.position.add(new THREE.Vector3(0, 0, this.parent.object.depth || 0).applyQuaternion(handle.quaternion)); } } } else if (this.mode === 'rotate') { // Align handles to current local or world rotation tempQuaternion2.copy(quaternion); alignVector.copy(this.eye).applyQuaternion(tempQuaternion.copy(quaternion).invert()); if (handle.name.search('E') !== -1) { handle.quaternion.setFromRotationMatrix(lookAtMatrix.lookAt(this.eye, zeroVector, unitY)); } if (handle.name === 'X') { if (this.spaceForRotate) { quaternion = this.spaceForRotate.x === 'local' ? this.worldQuaternion : identityQuaternion; tempQuaternion2.copy(quaternion); alignVector.copy(this.eye).applyQuaternion(tempQuaternion.copy(quaternion).invert()); } tempQuaternion.setFromAxisAngle(unitX, Math.atan2(-alignVector.y, alignVector.z)); tempQuaternion.multiplyQuaternions(tempQuaternion2, tempQuaternion); handle.quaternion.copy(tempQuaternion); } if (handle.name === 'Y') { if (this.spaceForRotate) { quaternion = this.spaceForRotate.y === 'local' ? this.worldQuaternion : identityQuaternion; tempQuaternion2.copy(quaternion); alignVector.copy(this.eye).applyQuaternion(tempQuaternion.copy(quaternion).invert()); } tempQuaternion.setFromAxisAngle(unitY, Math.atan2(alignVector.x, alignVector.z)); tempQuaternion.multiplyQuaternions(tempQuaternion2, tempQuaternion); handle.quaternion.copy(tempQuaternion); } if (handle.name === 'Z') { if (this.spaceForRotate) { quaternion = this.spaceForRotate.z === 'local' ? this.worldQuaternion : identityQuaternion; tempQuaternion2.copy(quaternion); alignVector.copy(this.eye).applyQuaternion(tempQuaternion.copy(quaternion).invert()); } tempQuaternion.setFromAxisAngle(unitZ, Math.atan2(alignVector.y, alignVector.x)); tempQuaternion.multiplyQuaternions(tempQuaternion2, tempQuaternion); handle.quaternion.copy(tempQuaternion); } } // Hide disabled axes handle.visible = handle.visible && (handle.name.indexOf('X') === -1 || this.showX); handle.visible = handle.visible && (handle.name.indexOf('Y') === -1 || this.showY); handle.visible = handle.visible && (handle.name.indexOf('Z') === -1 || this.showZ); handle.visible = handle.visible && (handle.name.indexOf('E') === -1 || this.showX && this.showY && this.showZ); // highlight selected axis handle.material._opacity = handle.material._opacity || handle.material.opacity; handle.material._color = handle.material._color || handle.material.color.clone(); handle.material.color.copy(handle.material._color); handle.material.opacity = handle.material._opacity; if (!this.enabled) { handle.material.opacity *= 0.5; handle.material.color.lerp(new Color(1, 1, 1), 0.5); } else if (this.axis) { if (handle.name === this.axis) { handle.material.opacity = 1.0; handle.material.color.lerp(new Color(1, 1, 1), 0.5); } else if (this.axis.split('').some(function (a) { return handle.name === a; })) { handle.material.opacity = 1.0; handle.material.color.lerp(new Color(1, 1, 1), 0.5); } else { handle.material.opacity *= 0.25; handle.material.color.lerp(new Color(1, 1, 1), 0.5); } } } Object3D.prototype.updateMatrixWorld.call(this); }; return _this2; } return TransformControlsGizmo; }(THREE.Object3D); // TransformControlsGizmo.prototype = Object.assign(Object.create(Object3D.prototype), { // constructor: TransformControlsGizmo, // isTransformControlsGizmo: true, // }) var unitX = new THREE.Vector3(1, 0, 0); var unitY = new THREE.Vector3(0, 1, 0); var unitZ = new THREE.Vector3(0, 0, 1); var tempVector = new THREE.Vector3(); var dirVector = new THREE.Vector3(); var alignVector = new THREE.Vector3(); var tempMatrix = new THREE.Matrix4(); var identityQuaternion = new THREE.Quaternion(); var unitX = new THREE.Vector3(1, 0, 0); var unitY = new THREE.Vector3(0, 1, 0); var unitZ = new THREE.Vector3(0, 0, 1); var tempVector = new THREE.Vector3(); var dirVector = new THREE.Vector3(); var alignVector = new THREE.Vector3(); var tempMatrix = new THREE.Matrix4(); var identityQuaternion = new THREE.Quaternion(); var TransformControlsPlane = /*#__PURE__*/function (_THREE$Mesh) { _inherits(TransformControlsPlane, _THREE$Mesh); var _super3 = _createSuper$1o(TransformControlsPlane); function TransformControlsPlane(options) { var _this3; _classCallCheck(this, TransformControlsPlane); _this3 = _super3.call(this, new PlaneBufferGeometry(10000, 10000, 2, 2), new MeshBasicMaterial({ color: '#ff0000', visible: false, wireframe: false, side: DoubleSide, transparent: true, opacity: 0.6 })); _this3.type = 'TransformControlsPlane'; return _this3; } _createClass(TransformControlsPlane, [{ key: "updateMatrixWorld", value: function updateMatrixWorld() { var space = this.space; //this.position.copy( this.worldPosition );//xzw �� this.parent.intersect ? this.position.copy(this.parent.intersect.position) : this.position.copy(this.worldPosition); if (this.mode === 'scale') space = 'local'; // scale always oriented to local rotation unitX.set(1, 0, 0).applyQuaternion(space === 'local' ? this.worldQuaternion : identityQuaternion); unitY.set(0, 1, 0).applyQuaternion(space === 'local' ? this.worldQuaternion : identityQuaternion); unitZ.set(0, 0, 1).applyQuaternion(space === 'local' ? this.worldQuaternion : identityQuaternion); // Align the plane for current transform mode, axis and space. alignVector.copy(unitY); switch (this.mode) { case 'translate': case 'scale': switch (this.axis) { case 'X': alignVector.copy(this.eye).cross(unitX); dirVector.copy(unitX).cross(alignVector); //this.parent.object && this.position.add(new THREE.Vector3(0, 0, (zReverse||handle.name == "XYZX")?0:this.parent.object.depth).applyQuaternion( handle.quaternion )); break; case 'Y': alignVector.copy(this.eye).cross(unitY); dirVector.copy(unitY).cross(alignVector); break; case 'Z': alignVector.copy(this.eye).cross(unitZ); dirVector.copy(unitZ).cross(alignVector); break; case 'XY': dirVector.copy(unitZ); break; case 'YZ': dirVector.copy(unitX); break; case 'XZ': alignVector.copy(unitZ); dirVector.copy(unitY); break; case 'XYZ': case 'E': default: //xzw add for scale xyzz dirVector.set(0, 0, 0); break; } break; case 'rotate': default: // special case for rotate dirVector.set(0, 0, 0); } //this.axis && console.log(this.axis) if (dirVector.length() === 0) { // If in rotate mode, make the plane parallel to camera this.quaternion.copy(this.cameraQuaternion); } else { tempMatrix.lookAt(tempVector.set(0, 0, 0), dirVector, alignVector); this.quaternion.setFromRotationMatrix(tempMatrix); } Object3D.prototype.updateMatrixWorld.call(this); } }]); return TransformControlsPlane; }(THREE.Mesh); // TransformControlsPlane.prototype = Object.assign(Object.create(Mesh.prototype), { var PlayerEvents = { Move: 'move', Rotate: 'rotate', //xst Zoom: 'zoom', //xst EndRotation: 'endRotation', //xst MoveModel: 'moveModel', //xst MoveComplete: 'move.complete', ModeChanged: 'mode.changed', ModeChanging: 'mode.changing', PanoChosen: 'pano.chosen', ClosestPanoChanging: 'closest.pano.changing', WarpStarted: 'warp.started', WarpInterrupted: 'warp.interrupted', WarpEnded: 'warp.ended', FlyinFinished: 'flyin.finished', FlyingStarted: 'flying.started', FlyingInterrupted: 'flying.interrupted', FlyingEnded: 'flying.ended', Ready: 'ready', StartInside: 'start.inside', StartOutside: 'start.outside', ViewChanged: 'view.changed', WarpInterruptedWithFlyTo: 'warp.interrupted.flyto', InputStart: 'input.start' }; new THREE.TextureLoader(); var showForOpacity = 1; var hideForOpacity = 0; var planeGeo = new THREE.PlaneBufferGeometry(1, 1); var FloorplanCadImg = /*#__PURE__*/function () { function FloorplanCadImg(app) { _classCallCheck(this, FloorplanCadImg); this.app = app; this.config = this.app.config; this.show = true; this.done = 0; this.ready = false; this.center = new THREE.Vector3(); this.deferred = Deferred$1(); } _createClass(FloorplanCadImg, [{ key: "getCadInfo", value: function getCadInfo(index) { var cadInfo = this.app.store.getValue('flooruser').cadInfo; if (cadInfo instanceof Array) { //初始加载时没有id, 所以用下标;等保存时会有subgroup,一般就是单层的subgroup和下标不一样,所以使用subgroup if (this.model.floors.list.length == 1) { cadInfo = cadInfo[0]; } else { var info = cadInfo.find(function (info) { return info.subgroup == index; }); info || (info = cadInfo[index]); cadInfo = info; } } else if (!cadInfo) { //console.error('no cadInfo,可能是导入的平面图', index) return null; } return cadInfo; } //临时改变所有楼层的floorplane图的显示 }, { key: "changeCadVisible", value: function changeCadVisible(v) { var o = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (o.show != void 0) this.show = o.show; //编辑页面的设置开关控制show this.model.floors.forEach(function (floor) { if (floor.plane) { floor.plane.visible = !!v; } else { console.warn('还没有创建plane'); } }); } /****************************************************************************************************************************************************************/ }, { key: "deleteCustomFloorTexture", value: function deleteCustomFloorTexture(index) { console.log('deleteCustomFloorTexture!查看是否有问题', index); var floor = this.model.floors.index[index]; floor.plane.visible = false; floor.plane.material.opacity = hideForOpacity; floor.plane.material.map = null; floor.plane.material.needsUpdate = !0; } /* addCustomFloorTexture(index, url) { let floor = this.model.floors.index[index] floor.plane.material = new THREE.MeshBasicMaterial({ map: loader.load(url), opacity: showForOpacity, transparent: !0, side: THREE.DoubleSide, depthTest: false, //防止遮挡热点等物体 }) floor.plane.visible = true floor.plane.material.needsUpdate = !0 } */ }, { key: "updateCustomFloorTexture", value: function updateCustomFloorTexture(index, url) { console.log('updateCustomFloorTexture!', index); this.floorPlanImgUrls[index] = url; this.updateCadPlane(index); /* let floor = this.model.floors.index[index] let plane = floor.plane plane.material = new THREE.MeshBasicMaterial({ map: loader.load(url), opacity: showForOpacity, transparent: !0, side: THREE.DoubleSide, depthTest: false, //防止遮挡热点等物体 }) let boundingBox = floor.boundingBox let center = boundingBox.getCenter(this.center) plane.position.set(center.x, boundingBox.max.y + constants.planeHeightShift, center.z) let size = boundingBox.getSize(new THREE.Vector3()) plane.scale.set(Math.abs(size.x), Math.abs(size.z), 1) if (this.model.currentFloor.floorIndex != index) { floor.plane.visible = false floor.plane.material.opacity = hideForOpacity } else { floor.plane.visible = true floor.plane.material.opacity = showForOpacity } */ } /* createCustomPlane(index, url) { let floor = this.model.floors.index[index] let boundingBox = floor.boundingBox let center = boundingBox.getCenter(this.center) let size = boundingBox.getSize(new THREE.Vector3()) let plane = floor.plane if (!plane) { var geometry = new THREE.PlaneBufferGeometry(1, 1) var material = new THREE.MeshBasicMaterial({ //map: THREE.ImageUtils.loadTexture(url), map: texture.load(url), opacity: this.player.modeTran && this.player.modeTran.split('-')[1] == 'floorplan' ? showForOpacity : hideForOpacity, //opacity: 1, transparent: !0, side: THREE.DoubleSide, depthTest: false, //防止遮挡热点等物体 }) material.needsUpdate = !0 plane = new THREE.Mesh(geometry, material) plane.renderOrder = RenderOrder.cad //盖住模型,否则其他层模型会影响它 plane.name = 'floorplanImg' plane.rotateX(-Math.PI / 2) this.model.add(plane) } else { plane.material = new THREE.MeshBasicMaterial({ //map: THREE.ImageUtils.loadTexture(url), map: loader.load(url), opacity: showForOpacity, transparent: !0, side: THREE.DoubleSide, depthTest: false, //防止遮挡热点等物体 }) plane.visible = true plane.material.needsUpdate = !0 } plane.position.set(center.x, boundingBox.max.y + constants.planeHeightShift, center.z) plane.scale.set(Math.abs(size.x), Math.abs(size.z), 1) floor.plane = plane if (this.model.currentFloor.floorIndex != index) { floor.plane.visible = false } } */ }, { key: "createCustomPlane", value: function createCustomPlane(index, url) { this.floorPlanImgUrls[index] = url; this.updateCadPlane(index); /* if (this.model.currentFloor.floorIndex != index) { floor.plane.visible = false } */ } }, { key: "changeModelOpacity", value: function changeModelOpacity() { //console.log('changeModelOpacity', type) this.model.floors.list.forEach(function (floor) { return floor.setMaterial(); }); } /*changeModelOpacity(type) { let setOpacity = e => { // if (e.parent.hidden && value > 0.5) { // return // } // if (value == showForModelOpacity) { // e.visible = false // } else { // e.visible = true // } // ;(e.materialInside.uniforms.opacity.value = value), (e.materialOutside.uniforms.opacity.value = value) if (visible) { e.material.uniforms.opacity.value = 1 e.material.transparent = !1 } else { e.material.uniforms.opacity.value = 0 e.material.transparent = !0 } } if (this.player.modeTran.split('-')[1] === Viewmode.FLOORPLAN) { // FLOORPLAN模式下修改模型透明度,仅限当前楼层 this.model.currentFloor.chunks.forEach(setOpacity) } else { this.model.chunks.forEach(setOpacity) } }*/ /********************************************************************重构***************************************************************************************/ }, { key: "init", value: function init(model) { var _this = this; this.player = this.app.core.get('Player'); this.model = model; var floorplan = this.app.store.getValue('flooruser'); if (floorplan) { //获取所有楼层的cad图片的url this.getCadImgUrl(floorplan); //创建多楼层平面 //this.createCadAllPlanes(floorplan) } else { this.app.store.on('flooruser', function (floor) { //获取所有楼层的cad图片的url _this.getCadImgUrl(floor); //创建多楼层平面 //this.createCadAllPlanes(floor) }); } this.player.on(PlayerEvents.ModeChanging, function (lastMode, mode, pano, dur) { if (mode == Viewmode$1.FLOORPLAN) { var view360ShowDur = 1000; _this.shouldShowPlane = true; setTimeout(function () { _this.shouldShowPlane && _this.showCadPlane(); }, Math.min(view360ShowDur, dur)); } else { _this.shouldShowPlane = false; //console.log('mode',mode, 'hideCadPlane') _this.hideCadPlane(); _this.changeModelOpacity('hidePlane'); //恢复材质 } }); this.ready = true; } //创建多楼层平面 }, { key: "createCadAllPlanes", value: function createCadAllPlanes(cadData) { var _this2 = this; //采用用户上传的图片 if (cadData.type == 'image') { cadData.floors.forEach(function (floor) { _this2.createCustomPlane(floor.subgroup, _this2.app.resource.getUserResourceURL(floor.filename)); }); this.ready = true; } //采用矢量数据 else { // 初始数据,不能加载图片 if (!this.app.store.getValue('metadata').floorPlanUser) { this.ready = true; this.deferred.resolve(); return; } this.model.floors.forEach(function (floor) { //创建每个楼层的平面 _this2.createCadPlane(floor.floorIndex); }); } } }, { key: "createCadPlane", value: function createCadPlane(floorIndex) { this.updateCadPlane(floorIndex); } //更新某个户型图 }, { key: "updateCadPlane", value: function updateCadPlane(floorIndex) { var _this3 = this; var opacity = 0; var imgUrl = this.floorPlanImgUrls[floorIndex]; var floor = this.model.floors.index[floorIndex]; //有图片才会有plane console.log("\u5F00\u59CB\u52A0\u8F7Dfloorplan_".concat(floorIndex, ".png, imgUrl: ").concat(imgUrl)); if (imgUrl) { var deferred = floor.deferred = new Deferred$1(); opacity = this.player.modeTran && this.player.modeTran.split('-')[1] == 'floorplan' ? showForOpacity : hideForOpacity; texture.load(imgUrl, function (texture) { //加载完成: if (!texture.image || floor.deferred != deferred) return; //还没加载完或又重新加载了 floor.cadImg = texture.image; if (floor.shouldShowPlane) { texture.needsUpdate = !0; console.warn("\u52A0\u8F7D\u5B8C\u6BD5floorplan_".concat(floorIndex, ".png, ").concat(imgUrl)); } else { texture.dispose(); console.error('dispose Tex'); texture = null; } var plane = floor.plane; //之前没有plane的话,得创建 if (!plane) { var material = _this3.createCadPlaneMaterial(texture, opacity); plane = new THREE.Mesh(planeGeo, material); floor.shouldShowPlane || (plane.visible = false); } else { plane.material.map = texture; plane.material.needsUpdate = true; } _this3.model.add(plane); floor.plane = plane; _this3.setCadPlanePose(plane, floorIndex); //注意:图和模型吻合的前提是模型生成正确 且和cad图一致。比如不能模型多了一个房间或者修改过了添加了个东西导致boundingbox变化之类的 (所以以floor.json来重新算了次boundingbox) floor.deferred = null; deferred.resolve(true); }, function (xhr) { floor.deferred = null; floor.imgLoadFailed = true; deferred.resolve(false); //当显示户型图平面的时候,需要修改模型材质 _this3.changeModelOpacity('hidePlane'); console.warn("\u6CA1\u6709floorplan_".concat(floorIndex, ".png, ").concat(imgUrl)); }); return floor.deferred; } //没有图片,但是之前已经有了plane,这时候需要删除 else { this.deleteCadPlane(floor); floor.imgLoadFailed = true; //没有图也算加载失败 } } }, { key: "createCadPlaneMaterial", value: function createCadPlaneMaterial(floorTexture, opacity) { var material = new THREE.MeshBasicMaterial({ map: floorTexture, opacity: opacity, transparent: !0, side: THREE.DoubleSide, depthTest: false //防止遮挡热点等物体 }); return material; } //floorplanData表示户型数据 }, { key: "getCadImgUrl", value: function getCadImgUrl(cadData) { var _this4 = this; this.floorPlanImgUrls = []; if (this.app.store.getValue('metadata').floorPlanUser) { this.model.floors.forEach(function (floor) { var floorIndex = floor.floorIndex; //如果是用户自己上传的图片 if (cadData.type == 'image') { // 如果是颠倒楼层会出现楼层与图片不对应的bug,需要重新获取对应的图片 var findFloorIndex = cadData.floors.findIndex(function (c) { return c.subgroup == floorIndex; }); if (findFloorIndex == -1) { findFloorIndex = floorIndex; } if (!cadData.floors[findFloorIndex]) { return console.error('cad缺少此楼层数据,楼层:', findFloorIndex); } _this4.floorPlanImgUrls[floorIndex] = _this4.app.resource.getUserResourceURL(cadData.floors[findFloorIndex].filename); } else { _this4.floorPlanImgUrls[floorIndex] = _this4.app.resource.getUserResourceURL("floor-cad-".concat(floorIndex, ".png")); } }); } } //设置cad面的坐标,大小和角度,确保与模型对准 }, { key: "setCadPlanePose", value: function setCadPlanePose(plane, index) { var floor = this.model.floors.index[index]; var boundingBox = floor.boundingBox; var center = boundingBox.getCenter(this.center); var size = boundingBox.getSize(new THREE.Vector3()); //plane.rotateX(-Math.PI / 2) plane.rotation.x = -Math.PI / 2; //靠这参数设置plane的大小和位置 var cadInfo; //let info = this.app.store.getValue('metadata').floorPlanUser var data = this.app.store.getValue('flooruser'); if (data.type != 'image') { //非导入 cadInfo = this.getCadInfo(index); if (cadInfo && cadInfo.bound) { size.x = cadInfo.bound.right - cadInfo.bound.left; size.z = cadInfo.bound.bottom - cadInfo.bound.top; center.x = (cadInfo.bound.right + cadInfo.bound.left) / 2; center.z = (cadInfo.bound.bottom + cadInfo.bound.top) / 2; //本来不需要旋转的(导入的就不用),但cad那边转了之后也改了size,这里就要旋转 var metadata = this.app.store.getValue('metadata'); var floorPlanAngle = parseFloat(metadata.floorPlanAngle || 0); //plane.rotateZ(floorPlanAngle) plane.rotation.z = floorPlanAngle; } } plane.renderOrder = RenderOrder.cad; //盖住模型,否则其他层模型会影响它 plane.name = 'floorplanImg'; this.adjustModelForPlane(boundingBox, index, size, center, false, cadInfo); } }, { key: "adjustModelForPlane", value: function adjustModelForPlane(boundingBox, index, size, center, onlyHeight, cadInfo) { var floor = this.model.floors.index[index]; if (onlyHeight) { floor.plane.position.y = boundingBox.max.y + constants$4.planeHeightShift; return; } size = size || boundingBox.getSize(new THREE.Vector3()); center = center || boundingBox.getCenter(new THREE.Vector3()); if (cadInfo) { /* if (!floor.plane.material || !floor.plane.material.map || !floor.plane.material.map.image) { return } */ //为了让图片刚好和模型吻合(cadInfo包含的信息是像素为单位,表示出了图中从哪到哪为模型的部分,贴在plane上通过缩放位移就能调整好) var floorPlanImgWidth = floor.cadImg.width; var floorPlanImgHeight = floor.cadImg.height; //let floorPlanImgWidth = 3840 //let floorPlanImgHeight = 2160 var ratio = floor.cadImgRatio = size.x / (floorPlanImgWidth - cadInfo.left - cadInfo.right); //模型对于图片的换算比例,这里只用了宽度来及计算,默认高度和宽度比例一样 //var ratio = (floor.cadImgRatio = size.y / (floorPlanImgHeight - cadInfo.top - cadInfo.bottom)) //模型对于图片的换算比例,这里只用了宽度来及计算,默认高度和宽度比例一样 var width = ratio * floorPlanImgWidth; var height = ratio * floorPlanImgHeight; this.width = width; this.height = height; var shiftX = (cadInfo.left - cadInfo.right) / 2 * ratio; //偏移中心的距离 var shiftY = (cadInfo.top - cadInfo.bottom) / 2 * ratio; floor.plane.position.set(center.x - shiftX, boundingBox.max.y + constants$4.planeHeightShift, center.z - shiftY); floor.plane.scale.set(width, height, 1); //this.player.planLabels.forEach(label => label.update()) //因才获得cadImgRatio ,更新下 } else { //导入的平面图 floor.plane.scale.set(size.x, size.z, 1); floor.plane.position.copy(center).setY(boundingBox.max.y + constants$4.planeHeightShift); } } //设置是否可见 }, { key: "setVisibleForCadImg", value: function setVisibleForCadImg() { var _this5 = this; // 是否隐藏户型图 var hideBigMap = this.app.store.getValue('metadata').controls.showBigMap === 0; if (!this.show || hideBigMap) { return; } if (!this.ready) { return this.deferred.then(function () { return _this5.showCadPlane(); }); } // 不显示户型图 if (this.app.TagManager.showTagsVisible || // 热点可视 this.app.ViewLinkEdit.markView || // 编辑场景关联 this.player.EditOverlay.isAdding || this.player.EditOverlay.editPlane || // 编辑空间贴图 this.player.GLTFEditor.adding || this.player.GLTFEditor.selecting // 编辑空间模型 ) { this.hideCadPlane(); } } //显示某楼层的户型图 }, { key: "showCadPlane", value: function showCadPlane(floorIndex) { var _this6 = this; // 是否隐藏户型图 var hideBigMap = this.app.store.getValue('metadata').controls.showBigMap === 0; if (floorIndex == void 0) { floorIndex = this.model.currentFloor.floorIndex; } var floor = this.model.floors.index[floorIndex]; // 这些情况下,即使调用了也不显示户型图 if (!this.show || hideBigMap || this.app.TagManager.showTagsVisible || // 热点可视 this.app.ViewLinkEdit.markView || // 编辑场景关联 this.player.EditOverlay.isAdding || this.player.EditOverlay.editPlane || // 编辑空间贴图 this.player.GLTFEditor.adding || this.player.GLTFEditor.selecting || this.model.$app.Plugins.EditCAD && this.model.$app.Plugins.EditCAD.display && !this.app.store.getValue('flooruser').type == 'image' //在编辑cad且非导入的平面图 ) return floor.shouldShowPlane = false; if (floor.deferred) { //仍在加载 return; /* floor.deferred.then(() => { //done就不重复写了,加载完会执行原先的 this.showCadPlane(floorIndex) }) */ } //先隐藏其他楼层的cad if (this.model.floors.list.length > 1) { this.hideCadPlane({ ignoreFloor: floor }); } floor.shouldShowPlane = true; var plane = floor.plane; if (!plane && !floor.imgLoadFailed) { var deferred = this.updateCadPlane(floorIndex); if (deferred) { return deferred.then(function () { floor.shouldShowPlane && _this6.showCadPlane(floorIndex); }); } else { return this.changeModelOpacity(); //改为普通材质 } } //当显示户型图平面的时候,需要修改模型材质 this.changeModelOpacity(); if (plane) { plane.material.opacity = showForOpacity; plane.visible = true; //console.log(' plane.visible = true') if (!plane.material.map) { //恢复 plane.material.map = new THREE.Texture(floor.cadImg); plane.material.map.needsUpdate = true; //为什么不加这句显示不出 plane.material.needsUpdate = true; } } } //隐藏户型图 }, { key: "hideCadPlane", value: function hideCadPlane() { var _this7 = this; var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, ignoreFloor = _ref.ignoreFloor; if (!this.ready) { return this.deferred.then(function () { return _this7.hideCadPlane(); }); } this.model.floors.forEach(function (floor) { if (ignoreFloor == floor) return; floor.shouldShowPlane = false; if (floor.plane) { //if(floor.plane.visible)console.log('visible = false') floor.plane.visible = false; //floor.plane.material.opacity = hideForOpacity if (floor.plane.material.map) { //dispose floor.plane.material.map.dispose(); floor.plane.material.map = null; floor.plane.material.needsUpdate = true; } } }); this.changeModelOpacity(); } /** * 手动显示/隐藏户型图 * @param {*} show */ }, { key: "displayCadPlane", value: function displayCadPlane(show) { this.setVisible(show); show ? this.showCadPlane() : this.hideCadPlane(); } //cad编辑模块那里,因为允许用户重置,所以这里可以删除cad图片 }, { key: "deleteAllCadPlanes", value: function deleteAllCadPlanes() { var _this8 = this; this.model.floors.forEach( /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(floor) { return regenerator.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _this8.deleteCadPlane(floor); case 1: case "end": return _context.stop(); } } }, _callee); })); return function (_x) { return _ref2.apply(this, arguments); }; }()); } }, { key: "deleteCadPlane", value: function deleteCadPlane(floor) { if (floor.plane) { floor.plane.geometry.dispose(); floor.plane.material.map && floor.plane.material.map.dispose(); floor.plane.material.dispose(); this.model.remove(floor.plane); floor.plane = null; } floor.cadImg = null; floor.imgLoadFailed = false; } //更新全部楼层的户型图 //cad编辑模块那里,有时候会重新载入数据,这时候等于重新执行createCadAllPlanes,但是plane可能已经创建好了,只是需要更新图片即可 }, { key: "updateAllCadPlanes", value: function updateAllCadPlanes() { var _this9 = this; //重新获取cad矢量数据 var floorplan = this.app.store.getValue('flooruser'); this.getCadImgUrl(floorplan); this.model.floors.forEach(function (floor) { //创建每个楼层的平面 /* floor.cadImg = null floor.imgLoadFailed = false this.updateCadPlane(floor.floorIndex) */ _this9.deleteCadPlane(floor); }); } //设置模型的透明度 }, { key: "setModelOpacity", value: function setModelOpacity(floorIndex) {} }, { key: "getVisible", value: function getVisible() { return this.show; } }, { key: "setVisible", value: function setVisible(value) { this.show = value; } }]); return FloorplanCadImg; }(); // init2(model) { // this.player = this.app.core.get('Player') // this.model = model // // 保证数据加载后调用 // if (this.app.store.getValue('flooruser')) { // this.createCad(this.app.store.getValue('flooruser')) // } else { // this.app.store.on('flooruser', floor => this.createCad(floor)) // } // this.player.on(PlayerEvents.ModeChanging, (lastMode, mode, pano, dur) => { // if (mode == Viewmode.FLOORPLAN) { // let view360ShowDur = 1000 // setTimeout(this.showCad.bind(this), Math.min(view360ShowDur, dur)) // } else { // this.hideCad() // } // }) // } // /** // * 显示户型图 // * @returns // */ // showCad() { // // 是否隐藏户型图 // const hideBigMap = this.app.store.getValue('metadata').controls.showBigMap === 0 // if (!this.show || hideBigMap) { // return // } // if (!this.ready) { // return this.deferred.then(() => this.showCad()) // } // // 不显示户型图 // if ( // this.app.TagManager.showTagsVisible || // 热点可视 // this.app.ViewLinkEdit.markView || // 编辑场景关联 // this.player.EditOverlay.isAdding || // this.player.EditOverlay.editPlane || // 编辑空间贴图 // this.player.GLTFEditor.adding || // this.player.GLTFEditor.selecting // 编辑空间模型 // ) // return // this.hideCad() // // console.log('showCad ' + this.model.currentFloor.floorIndex) // let plane = this.model.floors.index[this.model.currentFloor.floorIndex].plane // if (plane) { // plane.material.opacity = showForOpacity // plane.visible = true // this.changeModelOpacity(showForModelOpacity) // } // } // /** // * 隐藏户型图 // * @returns // */ // hideCad() { // if (!this.ready) { // return this.deferred.then(() => this.hideCad()) // } // // console.log('hideCad ' + this.model.currentFloor.floorIndex) // this.model.floors.forEach(floor => { // if (floor.plane) { // floor.plane.visible = false // floor.plane.material.opacity = hideForOpacity // } else { // console.warn('还没有创建plane') // } // }) // this.changeModelOpacity(hideForModelOpacity) // } // /** // * 手动显示/隐藏户型图 // * @param {*} show // */ // displayCad(show) { // this.show = show // this.show ? this.showCad() : this.hideCad() // } // /** // * 创建户型图的贴图 // */ // createCad(floor) { // if (floor.type == 'image') { // // 图片模式 // floor.floors.forEach(floor => { // this.createCustomPlane(floor.subgroup, this.app.resource.getUserResourceURL(floor.filename)) // }) // this.ready = true // } else { // // CAD模式 // if (!this.app.store.getValue('metadata').floorPlanUser) { // this.ready = true // this.deferred.resolve() // return // } // this.model.floors.forEach(floor => { // floor.floorTexture && (floor.floorTexture.dispose(), (floor.floorTexture = null)) // texture.load( // this.app.resource.getUserResourceURL(`floor-cad-${floor.floorIndex}.png`), // texture => { // //加载完成: // texture.needsUpdate = !0 // floor.floorTexture = texture // this.createPlane(floor.floorIndex) // }, // xhr => { // if (++this.done == this.model.floors.length) { // this.ready = true // this.deferred.resolve() // } // console.warn(`没有floorplan_${floor.floorIndex}.png`) // } // ) // }) // } // } // createPlane(index) { // var floor = this.model.floors.index[index] // var needAdjust = false // var boundingBox = floor.boundingBox // needAdjust = true // var center = boundingBox.getCenter(this.center) // var size = boundingBox.getSize(new THREE.Vector3()) // var geometry = new THREE.PlaneBufferGeometry(1, 1) // var plane = null // var cadInfo = this.getCadInfo(index) // if (!cadInfo || this.app.store.getValue('flooruser').vesion) { // plane = new THREE.Mesh( // geometry, // new THREE.MeshBasicMaterial({ // map: null, // opacity: 0, // transparent: !0, // side: THREE.DoubleSide, // depthTest: false, //防止遮挡热点等物体 // visible: false, // }) // ) // } else { // var material = new THREE.MeshBasicMaterial({ // map: floor.floorTexture, // opacity: this.player.modeTran && this.player.modeTran.split('-')[1] == 'floorplan' ? showForOpacity : hideForOpacity, // //opacity: 1, // transparent: !0, // side: THREE.DoubleSide, // depthTest: false, //防止遮挡热点等物体 // }) // material.needsUpdate = !0 // plane = new THREE.Mesh(geometry, material) // if (cadInfo.bound) { // size.x = cadInfo.bound.right - cadInfo.bound.left // size.z = cadInfo.bound.bottom - cadInfo.bound.top // center.x = (cadInfo.bound.right + cadInfo.bound.left) / 2 // center.z = (cadInfo.bound.bottom + cadInfo.bound.top) / 2 // } // } // // TRANSITIONING时add会造成动画卡顿 // //if (this.player.mode !== Viewmode.TRANSITIONING) this.model.add(plane) // //else this.player.once('mode.afterChange', () => this.model.add(plane)) // this.model.add(plane) // floor.plane = plane // plane.rotateX(-Math.PI / 2) // const metadata = this.app.store.getValue('metadata') // var floorPlanAngle = parseFloat(metadata.floorPlanAngle || 0) // plane.rotateZ(floorPlanAngle) // plane.renderOrder = RenderOrder.cad //盖住模型,否则其他层模型会影响它 // plane.name = 'floorplanImg' // if (cadInfo) { // this.adjustPlane(boundingBox, index, size, center, false, cadInfo) // } // //注意:图和模型吻合的前提是模型生成正确 且和cad图一致。比如不能模型多了一个房间或者修改过了添加了个东西导致boundingbox变化之类的 (所以以floor.json来重新算了次boundingbox) // this.changeCadVisible(null, { autoJudge: true }) // if (++this.done == this.model.floors.length) { // this.ready = true // this.deferred.resolve() // if (this.player.mode == Viewmode.FLOORPLAN) { // this.showCad() // } // } // } // deletePlanes() { // this.model.floors.forEach(async floor => { // floor.plane.geometry.dispose() // floor.plane.material.dispose() // this.model.remove(floor.plane) // floor.plane = null // }) // } // updatePlanes() { // this.model.floors.forEach(async floor => { // floor.floorTexture && (floor.floorTexture.dispose(), (floor.floorTexture = null)) // if (!floor.plane) { // this.createCad(floor.floorIndex) // } // if (floor.plane) { // floor.plane.material.opacity = hideForOpacity // floor.plane.material.map = null // floor.plane.material.needsUpdate = !0 // floor.plane.material.visible = false // let imgName = null // let flooruser = this.app.store.getValue('flooruser') // //cad绘图保存的时候 // if (flooruser.type != 'image') { // imgName = `floor-cad-${floor.floorIndex}.png` // loader.load( // this.app.resource.getUserResourceURL(imgName, true), // //this.app.resource.getUserResourceURL(imgName, true), // texture => { // //加载完成: // texture.needsUpdate = !0 // floor.floorTexture = texture // this.updatePlane(floor.floorIndex, texture) // }, // xhr => { // if (++this.done == this.model.floors.length) { // this.ready = true // this.deferred.resolve() // } // console.warn(`没有 floorplan_${floor.floorIndex}.png`) // } // ) // } else { // let data = flooruser.floors.find(c => c.subgroup == floor.floorIndex) // imgName = data.filename // floor.plane.material = new THREE.MeshBasicMaterial({ // map: loader.load(this.app.resource.getUserResourceURL(imgName, true)), // opacity: showForOpacity, // transparent: !0, // side: THREE.DoubleSide, // depthTest: false, //防止遮挡热点等物体 // }) // floor.plane.material.needsUpdate = !0 // } // } // }) // } // updatePlane(index, texture) { // var floor = this.model.floors.index[index] // var needAdjust = false // var boundingBox = floor.boundingBox // needAdjust = true // var center = boundingBox.getCenter(this.center) // var size = boundingBox.getSize(new THREE.Vector3()) // if (floor.plane) { // floor.plane.renderOrder = RenderOrder.cad //盖住模型,否则其他层模型会影响它 // floor.plane.name = 'floorplanImg' // const metadata = this.app.store.getValue('metadata') // var floorPlanAngle = parseFloat(metadata.floorPlanAngle || 0) // floor.plane.rotation.z = 0 // floor.plane.rotateZ(floorPlanAngle) // } // var cadInfo = this.getCadInfo(index) // console.log(cadInfo, '----after') // if (!cadInfo || this.app.store.getValue('flooruser').vesion) { // if (floor.plane) { // floor.plane.material.opacity = hideForOpacity // floor.plane.material.map = null // floor.plane.material.needsUpdate = !0 // floor.plane.material.visible = false // } // } else if (cadInfo.bound) { // size.x = cadInfo.bound.right - cadInfo.bound.left // size.z = cadInfo.bound.bottom - cadInfo.bound.top // center.x = (cadInfo.bound.right + cadInfo.bound.left) / 2 // center.z = (cadInfo.bound.bottom + cadInfo.bound.top) / 2 // if (floor.plane) { // floor.plane.material.map = texture // floor.plane.material.needsUpdate = !0 // floor.plane.material.visible = true // } // this.adjustPlane(boundingBox, index, size, center, false, cadInfo) // } // //注意:图和模型吻合的前提是模型生成正确 且和cad图一致。比如不能模型多了一个房间或者修改过了添加了个东西导致boundingbox变化之类的 (所以以floor.json来重新算了次boundingbox) // this.changeCadVisible(null, { autoJudge: true }) // if (++this.done == this.model.floors.length) { // this.ready = true // this.deferred.resolve() // } // } // adjustPlane(boundingBox, index, size, center, onlyHeight, cadInfo) { // var floor = this.model.floors.index[index] // if (onlyHeight) { // floor.plane.position.y = boundingBox.max.y + constants.planeHeightShift // return // } // size = size || boundingBox.getSize(new THREE.Vector3()) // center = center || boundingBox.getCenter(new THREE.Vector3()) // if (floor.floorTexture.image == null) { // return // } // //为了让图片刚好和模型吻合(cadInfo包含的信息是像素为单位,表示出了图中从哪到哪为模型的部分,贴在plane上通过缩放位移就能调整好) // let floorPlanImgWidth = floor.floorTexture.image.width // let floorPlanImgHeight = floor.floorTexture.image.height // //let floorPlanImgWidth = 3840 // //let floorPlanImgHeight = 2160 // var ratio = (floor.cadImgRatio = size.x / (floorPlanImgWidth - cadInfo.left - cadInfo.right)) //模型对于图片的换算比例,这里只用了宽度来及计算,默认高度和宽度比例一样 // //var ratio = (floor.cadImgRatio = size.y / (floorPlanImgHeight - cadInfo.top - cadInfo.bottom)) //模型对于图片的换算比例,这里只用了宽度来及计算,默认高度和宽度比例一样 // var width = ratio * floorPlanImgWidth // var height = ratio * floorPlanImgHeight // this.width = width // this.height = height // var shiftX = ((cadInfo.left - cadInfo.right) / 2) * ratio //偏移中心的距离 // var shiftY = ((cadInfo.top - cadInfo.bottom) / 2) * ratio // floor.plane.position.set(center.x - shiftX, boundingBox.max.y + constants.planeHeightShift, center.z - shiftY) // floor.plane.scale.set(width, height, 1) // this.player.planLabels.forEach(label => label.update()) //因才获得cadImgRatio ,更新下 // } var cameraLight = { clampVFOV: function clampVFOV(currentFov, maxHFov, width, height) { //限制currentFov, 使之造成的横向fov不大于指定值maxHFov var r = cameraLight.getHFOVFromVFOV(currentFov, width, height); return r > maxHFov ? cameraLight.getVFOVFromHFOV(maxHFov, width, height) : currentFov; }, getHFOVForCamera: function getHFOVForCamera(camera, width, height, getRad) { if (!width) width = camera.aspect, height = width / camera.aspect; return cameraLight.getHFOVFromVFOV(camera.fov, width, height, getRad); }, getHFOVFromVFOV: function getHFOVFromVFOV(fov, width, height, getRad) { var hfov = 2 * Math.atan(Math.tan(fov * MathLight.RADIANS_PER_DEGREE / 2) * (width / height)); return getRad ? hfov : hfov * MathLight.DEGREES_PER_RADIAN; }, getVFOVFromHFOV: function getVFOVFromHFOV(fov, width, height, getRad) { var vfov = 2 * Math.atan(Math.tan(fov * MathLight.RADIANS_PER_DEGREE / 2) * (height / width)); return getRad ? vfov : vfov * MathLight.DEGREES_PER_RADIAN; } /* clampVFOV: function(fov, t, i, n) { var r = cameraLight.getHFOVFromVFOV(fov, i, n); return r > t ? cameraLight.getVFOVFromHFOV(t, i, n) : fov }, getHFOVForCamera: function(e, t, i) { return cameraLight.getHFOVFromVFOV(e.fov, t, i) }, getHFOVFromVFOV: function(fov, t, i) { var n = t , o = i , a = 2 * Math.atan(Math.tan(fov * MathLight.RADIANS_PER_DEGREE / 2) * (n / o)) * MathLight.DEGREES_PER_RADIAN; return a }, getVFOVFromHFOV: function(e, t, i) { var n = t , o = i , a = 2 * Math.atan(Math.tan(e * MathLight.RADIANS_PER_DEGREE / 2) * (o / n)) * MathLight.DEGREES_PER_RADIAN; return a } */ }; /* 二维的标尺。 主要难度是将三维线段转化为二维。 因此需要知道三维线段两个端点对应的二维点。 但是它们不一定同时可求。 如果两个端点都不可求,姑且不显示这条线段(因为概率很小,虽然利用线上任意两点) 如果一个可求一个不可求,可以利用可求点和线上任意一个可求点作一条直线,和屏幕边缘求交点,即可画出。 目前使用的是线段中点,如果中点不可求,继续尝试可求点到中点的中点…… 求出二维点后,算出和某个基准线的夹角,即可用transfrom来变换element。 */ function CornerRuler(o, player) { var _this = this; this.sid = o.sid; this.showSid = o.showSid; this.text = o.text || ''; this.state = o.state || 'active'; this.player = player; this.app = player.$app; this.elem = document.createElement('div'); this.elem.className = 'ruler'; this.elem.setAttribute('data-name', ''); this.elem.style.display = 'none'; this.elem.innerHTML = "\n\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t".concat(this.text, "\n\t\t\t
\n\t\t
\n\t"); this.setPoints(o.points); this.player.cornerRulers.push(this); var count = 0; var tryAppend = function tryAppend() { if (document.querySelector('.widgets-rulers')) { document.querySelector('.widgets-rulers').append(_this.elem); } else if (count++ < 4) { setTimeout(tryAppend, 500); } }; tryAppend(); } CornerRuler.prototype.setPoints = function (p) { if (this.points && this.points[0].equals(p[0]) && this.points[1].equals(p[1])) return; this.points = p; this.updateText(); }; CornerRuler.prototype.updateText = function () { { //试试自动计算长度 在mp的场景应该很准确 this.length = Math.round(this.points[0].distanceTo(this.points[1]) * 100) / 100; this.text = this.app.config.i18n('common.about') + this.length + this.app.config.i18n('common.meter') + (this.showSid ? ' | ' + this.sid : ''); } this.elem.querySelector('.ruler-label-name').innerText = this.text; }; CornerRuler.prototype.remove = function () { this.elem.remove(); }; CornerRuler.prototype.getCrossPoint = function (posIn, posOut) { //求posOut在屏幕的可见端点,也就是从posOut到posIn的射线和屏幕边界的交点。 其中posIn只是另一个端点,并不是一定在屏幕内;而posOut是一定要在屏幕外,否则..没试过。 var W = this.player.domElement.clientWidth; var H = this.player.domElement.clientHeight; var x, y, border; var r = (posOut.x - posIn.x) / (posOut.y - posIn.y); //根据相似三角形原理先求出这个比值 var getX = function getX(y) { return r * (y - posIn.y) + posIn.x; }; var getY = function getY(x) { return 1 / r * (x - posIn.x) + posIn.y; }; if (posOut.x > W || posOut.x < 0) { //x超出的情况 if (posOut.x > W) border = W;else border = 0; if (posOut.y < 0 || posOut.y > H) { //y也超出 if (posOut.y < 0) y = 0;else y = H; x = getX(y); if (x > W || x < 0) { x = border; y = getY(x); } } else { x = border; y = getY(x); } } else { //只有y超出,x没有超出 if (posOut.y < 0) y = 0;else y = H; x = getX(y); } return new THREE.Vector2(x, y); }; //getCrossPoint的posIn版本 CornerRuler.prototype.getPosInCrossPoint = function (p1, aim) { //求aim在边界上的交点,其中aim在屏幕范围内,p1则不一定 var W = this.player.domElement.clientWidth; var H = this.player.domElement.clientHeight; return math$1.getCrossPointAtRect(p1, aim, W, H, 0, 0); }; CornerRuler.prototype.getPosAtSphere = function (toPos) { //fish this.fishPoints = []; this.points.forEach(function (p) { var pos = convertTool.getPosAtSphere(p.clone(), toPos); this.fishPoints.push(pos); }.bind(this)); }; var reTryCount$1 = 1; CornerRuler.prototype.getPosInScreen = function (p1, p2, count) { // p1 p2中一个是trueSide一个不是, 目的是得到两个trueSide var center = p1.point.clone().add(p2.point).multiplyScalar(0.5); //二分法 var pos2d = convertTool.getPos2d(center, this.player); if (pos2d.trueSide) { var visi = p1.pos2d.trueSide ? p1.pos2d : p2.pos2d; if (pos2d.inSight) { pos2d.pos = this.getPosInCrossPoint(visi.pos, pos2d.pos); pos2d.vector = null; /* console.log("pos2d.inSight") */ } //要求它在边界上的点才行,否则范围被缩小 return { result: 'p1p2', p1: visi, p2: pos2d }; } else { if (count + 1 > reTryCount$1) return; //最多重复次数 var trueSide = p1.pos2d.trueSide ? p1 : p2; return this.getPosInScreen(trueSide, { point: center, pos2d: pos2d }, ++count); } }; CornerRuler.prototype.update = function () { // Todo 有bug 先注释 if (this.player.mode != 'panorama' || this.state != 'active') { this.elem.style.display = 'none'; return; } //似乎不能根据遮挡来取消显示,因为家具就是会遮住靠墙的尺子。所以只能根据编辑的可视点? var p1 = convertTool.getPos2d(this.points[0], this.player); var p2 = convertTool.getPos2d(this.points[1], this.player); if (!p1.trueSide || !p2.trueSide) { //背面点处理 if (!p1.trueSide && !p2.trueSide) { //这种情况一般都是线段背离相机了,基本不用考虑 this.elem.style.display = 'none'; return; } var retry = this.getPosInScreen( //如果线太长了,在很多倾斜点的角度只有一个端点trueSide,那么去到线段中点找trueSide的点,化作新的端点。 { point: this.points[0], pos2d: p1 }, { point: this.points[1], pos2d: p2 }, 0); if (!retry) { this.elem.style.display = 'none'; return; } p1 = retry.p1; p2 = retry.p2; } var pos1 = p1.pos, pos2 = p2.pos; var len = pos1.distanceTo(pos2); if (len == 0) { console.warn('ruler间距为0!'); return; } //计算BA和水平向右的向量间的夹角0-180 var angle = Math.acos((pos1.x - pos2.x) / len); angle %= 360; angle *= 180 / Math.PI; //计算angle方向是顺时针还是逆时针(画出4种情况即可发现有这两个方向) var BA1 = pos1.clone().sub(pos2); var BA = new THREE.Vector3(BA1.x, BA1.y, 0); var BC = new THREE.Vector3(1, 0, 0); var dir = BA.cross(BC).z > 0 ? 1 : -1; angle *= dir; //更新尺子的位置 具体绘图见笔记 //以第二个点B为基准 { var lineElem = this.elem.querySelector('.ruler-line'); lineElem.style.width = len + 'px', lineElem.style.left = p2.pos.x + 'px'; lineElem.style.top = p2.pos.y + 'px', lineElem.style.transform = 'rotate(' + -angle + 'deg)'; } //更新label箭头的中心位置 var centerX, centerY, ratio = 0.5, W = this.player.domElement.clientWidth, H = this.player.domElement.clientHeight; if (!p1.inSight || !p2.inSight) { var pos1inSight, pos2inSight; //屏幕可见线段端点。 if (!p1.inSight) { //在屏幕外的端点要求出在和屏幕边界的交点作为可见线段端点 pos1inSight = this.getCrossPoint(pos2, pos1); } else { pos1inSight = pos1.clone(); } if (!p2.inSight) { pos2inSight = this.getCrossPoint(pos1, pos2); } else { pos2inSight = pos2.clone(); } var center = pos1inSight.clone().add(pos2inSight).multiplyScalar(0.5); //在屏幕上的可见中心点 centerX = center.x; centerY = center.y; if (center.x > W || center.x < 0 || center.y > H || center.y < 0) { //可见中心不在屏幕范围内,那么这条线也一定不在范围内。(似乎是,想象的..因为是可见中心) this.elem.style.display = 'none'; return; } //ratio是center到div旋转中心(原始B点)的距离 和 线段长度 的比例 if (pos2.x == pos1.x) { if (pos2.y == pos1.y) { console.warn('pos1和2一样???'); return; } else { if (pos2.y < pos1.y) ratio = (centerY - pos2.y) / (pos1.y - pos2.y);else ratio = (pos2.y - centerY) / (pos2.y - pos1.y); } } else { if (pos2.x < pos1.x) ratio = (centerX - pos2.x) / (pos1.x - pos2.x); //if B在右 else ratio = (pos2.x - centerX) / (pos2.x - pos1.x); //if B在左 } if (ratio < 0 || ratio > 1) { this.elem.style.display = 'none'; return; } //如果ratio超出范围,说明可见中心脱离线段 } else { centerX = (pos1.x + pos2.x) / 2; } this.elem.style.display = ''; //更新label的方向是左侧还是右侧 var labelElem = this.elem.querySelector('.ruler-label'); if (this.dir != 'left' && centerX < W / 2 || this.dir == 'right') { labelElem.classList.add('reverse'); } else { labelElem.classList.remove('reverse'); } labelElem.style.transform = 'rotate(' + angle + 'deg)'; labelElem.style.left = ratio * 100 + '%'; }; var SceneRendererEvents = { ContextCreated: 'scene-renderer-context-created', AfterRender: 'after-render', MemoryUsageUpdated: 'scene-renderer-memory-usage-updated' }; var addLabel$1 = browser$1.urlHasValue('pointLabel'); var horRulerShowSid = addLabel$1; var labelProp = { backgroundColor: { r: 255, g: 255, b: 255, a: 0.4 }, textColor: { r: 0, g: 0, b: 0, a: 1 }, borderRadius: 15, renderOrder: 50 }; var player$9; var WallManager = /*#__PURE__*/function () { function WallManager(app) { _classCallCheck(this, WallManager); this.app = app; this.roomInfo = {}; this.rulerVisi = false; this.version = 2; this.cad = null; this.planeNeedAdjust = []; this.appType = null; this.showRulers = addLabel$1; //true this.updateList = []; } _createClass(WallManager, [{ key: "init", value: function init(model) { this.model = model; player$9 = this.app.core.get('Player'); if (Object.keys(this.roomInfo).length && this.roomInfo[Object.keys(this.roomInfo)[0]].rooms.length) { return false; //已经创建了? } var metadata = this.app.store.getValue('metadata'); var floorJson = this.app.store.getValue('flooruser'); this.initRoomInfo(common.CloneJson(floorJson)); if (metadata && metadata.controls.showScale) { this.showRulers = true; return true; } } }, { key: "switchDisplay", value: function switchDisplay(ifShow) { this.showRulers = !!ifShow; this.updateRulersVisi(); } // 加额外显示的label 如房间名 标尺 }, { key: "initRoomInfo", value: function initRoomInfo(floorJson) { var _this = this; new THREE.MeshBasicMaterial({ transparent: true, wireframe: true, opacity: 0.3, color: '#ff9999', depthTest: false, side: THREE.DoubleSide }); var oriRoomGroup = new THREE.Object3D(); this.model.add(oriRoomGroup); oriRoomGroup.visible = false; this.cad = floorJson; this.initFloorPlan(floorJson); /* performance.mark('ifPanoSeePoints-start') this.model.panos.list.forEach((pano)=>{ this.ifPanoSeePoints(pano); }) performance.mark('ifPanoSeePoints-end') performance.measure('ifPanoSeePoints', 'ifPanoSeePoints-start', 'ifPanoSeePoints-end') */ { var update = function update() { //console.log('update', this.updateList.length) _this.updateList.forEach(function (ruler) { ruler.update(); }); }; this.app.core.get('SceneRenderer').on(SceneRendererEvents.AfterRender, function (e) { if (player$9.lastFrameChanged) { common.intervalTool.isWaiting('updateRulersVisi_' + _this.app.resource.num, function () { _this.updateRulersVisi(); }, 500); update(); } }); } } }, { key: "initFloorPlan", value: function initFloorPlan(floorCad) { var _this2 = this; common.timeMeasuring.addTimeMark('initFloorPlan', 'start'); floorCad.floors.forEach(function (floorJson, floorIndex) { var floor = player$9.model.floors.index[floorIndex]; if (!floor) { console.error('没找到floor', floorJson); return; } var bottom = floor.boundingBox.min.y; var top = floor.boundingBox.max.y; floorJson.bottom = bottom; floorJson.top = top; for (var id in floorJson.points) { var point = floorJson.points[id]; var walls = point.parent; var btmPos = _this2.getPos3dFrom2d(point, bottom); var topPos = _this2.getPos3dFrom2d(point, top); var pointRulerInfo = { point, horizons: [], verti: null }; pointRulerInfo.verti = _this2.addRuler(btmPos, topPos, "floor".concat(floorIndex, "-p").concat(id, "-verti")); for (var wall in walls) { //这个不准 /* let p2type = walls[wall] == 'start' ? 'end' : 'start' let rulerInfo = this.getHorRuler(id, floorJson.walls[wall][p2type], floorIndex, bottom) */ //监控错误: if (wall == 'null' || !floorJson.walls[wall]) { console.warn('该点有wall == null的walls', point); continue; } walls[wall] == 'start' ? 'end' : 'start'; var realp2Type = floorJson.walls[wall].start == id ? 'end' : 'start'; //if (p2type != realp2Type) console.error('p2type != realp2Type', wall, id) var p2Id = floorJson.walls[wall][realp2Type]; var rulerInfo = _this2.getHorRuler(id, p2Id, floorIndex, bottom); // pointRulerInfo.horizons.push(rulerInfo); } pointRulerInfo.horizons = pointRulerInfo.horizons.sort(function (r1, r2) { return r1.angle - r2.angle; }); point.pointRulerInfo = pointRulerInfo; addLabel$1 && _this2.addLabel(point, btmPos, floor); } }); common.timeMeasuring.addTimeMark('initFloorPlan', 'end', true); } }, { key: "getHorRuler", value: function getHorRuler(p1Id, p2Id, floorIndex, bottom) { if (p1Id == p2Id) { console.error('p1Id == p2Id'); } var id1 = p1Id.split('Point')[1]; var id2 = p2Id.split('Point')[1]; var sid1 = "f".concat(floorIndex, "-").concat(id1, "-").concat(id2, "-hor"); var sid2 = "f".concat(floorIndex, "-").concat(id2, "-").concat(id1, "-hor"); var ruler = player$9.cornerRulers.find(function (e) { return e.sid == sid1; }); if (ruler) return { ruler, angle: ruler.angle }; //多半找不到,因为一条线最多只能从两个点找到,getHorRuler应该是创建完就从反方向get了 else ruler = player$9.cornerRulers.find(function (e) { return e.sid == sid2; }); if (ruler) return { ruler, angle: (ruler.angle + Math.PI) % (2 * Math.PI) };else { var json = this.cad.floors[floorIndex]; var p1 = json.points[p1Id]; var p2 = json.points[p2Id]; ruler = this.addRuler(this.getPos3dFrom2d(p1, bottom), this.getPos3dFrom2d(p2, bottom), sid1, horRulerShowSid); ruler.angle = new THREE.Vector2().subVectors(p2, p1).angle(); //用来排序角度 ruler.pointIds = [p1Id, p2Id]; return { ruler, angle: ruler.angle }; } } }, { key: "addRuler", value: function addRuler(startPos, endPos, sid, showSid) { var ruler = new CornerRuler({ sid, points: [startPos, endPos], state: 'unable', showSid }, player$9); return ruler; } }, { key: "addLabel", value: function addLabel(point, pos, model) { //this.removeLabel() var label = new TextSprite(Object.assign({}, labelProp, { text: point.vectorId.split('Point')[1], player: player$9 })); label.sprite.material.depthTest = true; var position = pos.clone(); position.y += 0.2; label.position.copy(position); model.add(label); labelProp.scale || (labelProp.scale = math$1.linearClamp(this.model.size.length(), 10, 500, 0.5, 7)); var s = labelProp.scale; label.scale.set(s, s, s); } }, { key: "getPos3dFrom2d", value: function getPos3dFrom2d(point2d, height) { return new THREE.Vector3(point2d.x, height, -point2d.y); } }, { key: "getPos2dFrom3d", value: function getPos2dFrom3d(point3d) { return new THREE.Vector2(point3d.x, -point3d.z); } }, { key: "isShelter", value: function isShelter(floorJson, point1, point2) { //walls数量多时耗时 var line1 = [point1, point2]; var atWalls = []; point1.parent && atWalls.push.apply(atWalls, _toConsumableArray(Object.keys(point1.parent))); point2.parent && atWalls.push.apply(atWalls, _toConsumableArray(Object.keys(point2.parent))); var intersecPoint; var intersectLine = Object.values(floorJson.walls).find(function (wall) { if (atWalls.some(function (e) { return e == wall.vectorId; })) return; var point1_ = floorJson.points[wall.start]; var point2_ = floorJson.points[wall.end]; var line2 = [point1_, point2_]; intersecPoint = math$1.isLineIntersect(line1, line2); if (intersecPoint) { if (math$1.closeTo(intersecPoint.x, point1.x, 0.01) && math$1.closeTo(intersecPoint.y, point1.y, 0.01) || math$1.closeTo(intersecPoint.x, point2.x, 0.01) && math$1.closeTo(intersecPoint.y, point2.y, 0.01)) { //console.log('a',point1_.vectorId, point2_.vectorId) return; //点在线上,不算, 相当于atWall } else return intersecPoint; } }); return !!intersectLine; } //注:如果有两条线看起来相交,但其实没有共用交点;或线重叠了一部分。这样很容易识别为true,导致ruler不显示。如果要根据点是否在线上来排除,要计算getFootPoint,太复杂了。所以需要人为把cad调整规范 /* !假定: 1 每个漫游点只能看到一个point的一组边,且这两条边相邻。 可推断: 1 pano的可见group可以提前得到,因为和视角无关,只和位置有关 */ }, { key: "ifPanoSeePoints", value: function ifPanoSeePoints(pano) { var _this3 = this; //差不多每个pano用时0.5-2ms(在无console时)。很大的场景可能达到100ms, 还好连续漫游时只要加载不停顿就不会触发计算 common.timeMeasuring.addTimeMark('ifPanoSeePoints', 'start'); var panoVideoFilter = pano.getVideoFilter(); //视频漫游点角度范围内隐藏ruler pano.visibleRulerInfos = []; var panoPos2d = this.getPos2dFrom3d(pano.position); var floor = this.cad.floors[pano.floorIndex]; if (!floor) { if (!player$9.model.floors.index[pano.floorIndex] && player$9.model.floors.length == 1) { floor = player$9.model.floors.list[0]; } else { console.error('ifPanoSeePoints 没找到楼层'); return; } } var bottom = floor.bottom; var r1 = 1 / (2 * Math.sin(THREE.MathUtils.degToRad(5))); //5是最小可见deg的一半。假设只有一个horizon且和panoToPoint垂直 var minRad = THREE.MathUtils.degToRad(5); var _loop = function _loop(id) { var point = floor.points[id]; var horizons = point.pointRulerInfo.horizons; //angle已经从小到大排序 var panoAngle = new THREE.Vector2().subVectors(panoPos2d, point).angle(); //类同horizons求角度,用来排序 var neibourHorizons = []; //要挑选的在当前pano能见的该point的边 if (horizons.length > 2) { //选择两条在pano两边最近的线 var h1 = horizons.find(function (e) { return e.angle > panoAngle; }); if (h1) { var h1Index = horizons.indexOf(h1); if (h1Index == 0) { //pano在第一个之前 neibourHorizons = [h1, horizons[horizons.length - 1]]; //选择第一个和最后一个 } else { neibourHorizons = [horizons[h1Index - 1], h1]; //选择h1和它前面那个 } } else { //在最后一个之后 neibourHorizons = [horizons[0], horizons[horizons.length - 1]]; //也是选择第一个和最后一个 } //选完后依旧是从小到大 } else { neibourHorizons = horizons; } if (panoPos2d.distanceTo(point) > neibourHorizons.reduce(function (w, c) { return w + c.ruler.length; }, 0) * r1) { //console.log('排除'/* , point.vectorId, pano.id */); //提前排除一些距离远的,基本看不到。但可能误伤 return "continue"; } var mid = _this3.getPos3dFrom2d(point, bottom); if (panoVideoFilter && panoVideoFilter(mid)) { //遮住pano视频了 addLabel$1 && console.log('点在视频区域内', point); return "continue"; } /* if(this.isShelter(floor, point, panoPos2d ) ){//墙角容易遮挡,不算了(尤其是特意编辑好的户型里) addLabel && console.log('isShelter', id, pano.id) continue } */ var info = []; neibourHorizons.forEach(function (r, i) { info[i] = {}; r.anotherPoint2d = floor.points[r.ruler.pointIds.find(function (pid) { return pid != id; })]; r.anotherPoint = _this3.getPos3dFrom2d(r.anotherPoint2d, bottom); var mid2 = new THREE.Vector2().addVectors(r.anotherPoint2d, point).multiplyScalar(0.5); //用中点而不是端点是因为端点容易被遮住,如点靠在别的线上,或仅被墙角遮住一点点 if (_this3.isShelter(floor, mid2, /* r.anotherPoint2d, */ panoPos2d)) { addLabel$1 && console.log('isShelter线段中点被遮挡', r.ruler.pointIds, pano.id); info[i].lineShelter = true; return; } if (panoVideoFilter && panoVideoFilter(r.anotherPoint)) { //点在视频区域内 addLabel$1 && console.log('端点在视频区域内', r); info[i].coverVideo = true; return; } if (panoVideoFilter && pano.getVideoFilter('across').apply(void 0, _toConsumableArray(r.ruler.points))) { //线横跨视频区域 addLabel$1 && console.log('线横跨视频区域', r); info[i].coverVideo = true; return; } info[i].panoToSidePoint = new THREE.Vector3().subVectors(r.anotherPoint, pano.position).setY(0); //端点方向 info[i].panoToSidePoint.normalize(); }); neibourHorizons = neibourHorizons.filter(function (r, i) { return !info[i].coverVideo && !info[i].lineShelter; }); if (neibourHorizons.length == 0) return "continue"; info = info.filter(function (r, i) { return !r.coverVideo && !r.lineShelter; }); panoToPoint = new THREE.Vector3().subVectors(mid, pano.position).setY(0); //方向 var disSquaredToPano = panoToPoint.lengthSq(); panoToPoint.normalize(); var backSide = void 0, coverRad = void 0, midVec = void 0, sidePanoVec1 = void 0, sidePanoVec2 = void 0; //pano到两端的向量 if (neibourHorizons.length == 2) { ruler1Vec = new THREE.Vector3().subVectors(mid, neibourHorizons[0].anotherPoint).setY(0); ruler2Vec = new THREE.Vector3().subVectors(mid, neibourHorizons[1].anotherPoint).setY(0); panoToPoint.clone().cross(ruler1Vec).y; panoToPoint.clone().cross(ruler2Vec).y; /*backSide = axis1 * axis2 > 0 if(axis1 * axis2 > 0){//必须一个顺时针一个逆时针才能两个墙壁都看到 (但是这样遇到柱子经常只能看到远的那边)//已计算遮挡这段不需要了 continue; } if(axis1>0){ neibourHorizons = [neibourHorizons[1], neibourHorizons[0] ]//调换顺序,使第一个在左边,第二个在右边 } */ //已知:0的angle小于1的angle,所以当pano在两个angle之间时就是正常的0为左1为右;但若pano在包含角度为0的这边就要反一下 if (panoAngle >= 0 && panoAngle < neibourHorizons[0].angle || panoAngle > neibourHorizons[1].angle && panoAngle < Math.PI * 2) { neibourHorizons = [neibourHorizons[1], neibourHorizons[0]]; //调换顺序,使第一个在左边,第二个在右边 } sidePanoVec1 = info[0].panoToSidePoint; sidePanoVec2 = info[1].panoToSidePoint; } else { sidePanoVec1 = info[0].panoToSidePoint; sidePanoVec2 = panoToPoint; } //计算覆盖角度 midVec = new THREE.Vector3().addVectors(sidePanoVec1, sidePanoVec2).normalize(); //到两端方向的中间方向 coverRad = Math.acos(sidePanoVec1.dot(sidePanoVec2)); //在界面上覆盖的角度 if (panoToPoint.dot(midVec) < 0) { //中心方向和panoToPoint夹角大于90度,需要反向 midVec.negate(); coverRad = 2 * Math.PI - coverRad; } if (coverRad < minRad) { addLabel$1 && console.log('coverRad过小', id, pano.id, coverRad.toFixed(3)); return "continue"; //在界面上覆盖的角度过小 } pano.visibleRulerInfos.push({ pId: point.vectorId, point, neibourHorizons, coverRad, panoToPoint, disSquaredToPano, backSide, midVec }); }; for (var id in floor.points) { var panoToPoint; var ruler1Vec; var ruler2Vec; var _ret = _loop(id); if (_ret === "continue") continue; } common.timeMeasuring.addTimeMark('ifPanoSeePoints', 'end', true); } }, { key: "updateRulersVisi", value: function updateRulersVisi() { this.lastShowRulers && this.lastShowRulers.forEach(function (ruler) { ruler.state = 'unable'; }); var pano = player$9.currentPano; this.updateList = this.lastShowRulers || []; //player.cornerRulers if (this.showRulers && !player$9.flying && player$9.mode == 'panorama' && pano.isAligned() && !(settings$3.vrEnabled && settings$3.vrSplitScreen)) { if (!pano.visibleRulerInfos) { this.ifPanoSeePoints(pano); } var playerDir = player$9.getDirection().setY(0).normalize(); player$9.position; var playerPos2d = this.getPos2dFrom3d(player$9.position); var hfov = cameraLight.getHFOVForCamera(player$9.cameraControls.activeControl.camera, null, null, true); var results = common.sortByScore(pano.visibleRulerInfos, [], [function (group) { //离相机方向角度越小越好, ruler角度跨越越大越好 var shiftRad = Math.acos(group.midVec.dot(playerDir)); //ruler中心偏移屏幕(相机)水平中心方向的角度 //计算在屏幕中(水平)所占的fov, 它由镜头方向左侧和右侧部分组成, 假设镜头相对标尺中心偏左边(实际偏哪边结果都一样) var leftRad = Math.min(group.coverRad / 2 + shiftRad, hfov / 2); var righRad = Math.min(group.coverRad / 2 - shiftRad, hfov / 2); var v = leftRad + righRad; //由于有的墙角很小,比不上旁边墙所占的fov,但focus它的时候还是希望显示它,所以加一点奖励 var v2 = (Math.PI - shiftRad) * 0.5; var d = 5 + group.disSquaredToPano / 30; var a = Math.pow(1 + v + v2, 3) * 3; //(+1是因为底数要大于1 . 另外所有参数都要是正数) var w = a / d; //if(group.backSide) w = Math.min(w-2, w *= 0.8) group.logMsg = "v ".concat(v, ", v2 ").concat(v2, ", v\u590D\u5408").concat(a, ", dis\u590D\u5408 ").concat(d, ", "); return w; }]); addLabel$1 && console.log(results); if (results[0]) { { //矫正高度,因模型崎岖不平,之前使用的最低点一般都低于真实值 results[0].item.neibourHorizons.forEach(function (e) { return e.ruler.points.forEach(function (p) { return p.y = pano.floorPosition.y; }); }); results[0].item.point.pointRulerInfo.verti.points[0].y = pano.floorPosition.y; results[0].item.point.pointRulerInfo.verti.updateText(); //这样房间高度会一直变会不会很奇怪?虽然可以计算所有相同neibourHorizon的pano的低高中位数,但是因为是走一个算一个所以也在变。 } var visiRulers = results[0].item.neibourHorizons.map(function (e) { return e.ruler; }).concat(results[0].item.point.pointRulerInfo.verti); visiRulers.forEach(function (ruler) { ruler.dir = null, ruler.state = 'active'; }); this.lastShowRulers = visiRulers; this.updateList = common.getUnionSet(this.updateList, visiRulers); //有些字靠的近容易打架。 故左边的朝左,右边的朝右 if (results[0].item.neibourHorizons.length == 2) { var dis = playerPos2d.distanceTo(results[0].item.point); var left = results[0].item.neibourHorizons[0].ruler; var right = results[0].item.neibourHorizons[1].ruler; if (left.length < dis / 2) left.dir = 'left'; if (right.length < dis / 2) right.dir = 'right'; } } } else this.lastShowRulers = []; this.updateList.forEach(function (ruler) { ruler.update(); }); } }]); return WallManager; }(); // const wallManager = new WallManager() function _createSuper$1n(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1n(); 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 _isNativeReflectConstruct$1n() { 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; } } /* z | | | | x <-------| 中心为点云position加boudingbox中心 / / y */ var lineLen = 3, stemLen = 1.5, arrowLen = 0.5, lineDisToStem = 0.5; var Axis = /*#__PURE__*/function (_THREE$Object3D) { _inherits(Axis, _THREE$Object3D); var _super = _createSuper$1n(Axis); // 坐标轴 function Axis(app) { var _this; _classCallCheck(this, Axis); _this = _super.call(this); _this.app = app; _this.getArrow(); _this.createArrows(); return _this; } _createClass(Axis, [{ key: "getArrow", value: function getArrow() { var arrowGroup = new THREE.Object3D(); var line = LineDraw.createLine([new THREE.Vector3(), new THREE.Vector3(0, 0, lineLen)]); var stem = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, stemLen)); stem.position.set(0, 0, lineLen + lineDisToStem + stemLen / 2); var arrow = new THREE.Mesh(new THREE.CylinderBufferGeometry(0, 0.3, arrowLen, 12, 1, false)); //radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 arrow.position.set(0, 0, lineLen + lineDisToStem + stemLen + arrowLen / 2); arrow.rotation.set(Math.PI / 2, 0, 0); arrowGroup.add(stem); arrowGroup.add(line); arrowGroup.add(arrow); this.arrowGroup = arrowGroup; } }, { key: "createArrows", value: function createArrows() { var _this2 = this; new THREE.MeshBasicMaterial({ color: '#00d7df', side: 2, transparent: true, opacity: 0.8, depthWrite: false }); var colors = { x: '#ea3f3f', y: '#86c215', z: '#3396f8' }; ['x', 'y', 'z'].forEach(function (axisText) { var color = new THREE.Color().set(colors[axisText]); var group = _this2.arrowGroup.clone(); group.children.forEach(function (e) { e.material = e.material.clone(); /* e.material.opacity = opacity e.material.transparent = true */ e.material.color.copy(color); }); var label = _this2.createLabel(axisText, color); label.position.set(0, 0, (lineLen + stemLen + arrowLen + lineDisToStem + 0.5) * 1.05); group.add(label); var meter = _this2.createLabel('1m', color, 20, 0.4); meter.position.set(0, 0, 1); group.add(meter); if (axisText == 'y') { group.rotation.x = -Math.PI / 2; } else if (axisText == 'x') { group.rotation.y = Math.PI / 2; } _this2.add(group); }); } }, { key: "createLabel", value: function createLabel(text, color) { var fontsize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 120; var scale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1.2; var label = new TextSprite({ //无法解决 因其祖先有设定quaternion, 无法对着镜头 backgroundColor: { r: 0, g: 0, b: 0, a: 0 }, textColor: { r: color.r * 255, g: color.g * 255, b: color.b * 255, a: 1 }, fontsize, //useDepth : true , renderOrder: 5, // pickOrder:5, player: this.app.core.get('Player'), text, name: 'axis' }); label.scale.set(scale, scale, scale); return label; } }]); return Axis; }(THREE.Object3D); var _class; function _createSuper$1m(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1m(); 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 _isNativeReflectConstruct$1m() { 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; } } var highMapAddColor = browser$1.urlHasValue('highMapColor'); var Model = Emitter(_class = /*#__PURE__*/function (_THREE$Object3D) { _inherits(Model, _THREE$Object3D); var _super = _createSuper$1m(Model); function Model(app) { var _this; _classCallCheck(this, Model); _this = _super.call(this); _this.setupCustomProperties = function () { var e = settings$3.modelAlpha; Object.defineProperty(this, 'alpha', { get: function get() { return e; }, set: function set(t) { e = t; //console.log('modelalpha', t) this.chunks.forEach(function (chunk) { if (chunk.material && chunk.material.uniforms.modelAlpha) { chunk.material.uniforms.modelAlpha.value = e; //修改一下defines,为了在不需要map时不加载map。 by xzw if (e) { if (!('useModelMap' in chunk.material.defines)) { chunk.material.defines.useModelMap = ''; chunk.material.needsUpdate = true; } } else { if ('useModelMap' in chunk.material.defines) { delete chunk.material.defines.useModelMap; chunk.material.needsUpdate = true; //chunk.material.uniforms.map.value.dispose() //防止崩溃(但是因为这样飞出要等待时间所以被去掉了) } } } }); } }); }; _this.build = function () { var _this2 = this; this.currentFloor = this.floors.last(); this.floors.build(); this.colliders = this.floors.reduce(function (array, floor) { return array.concat(floor.collider.children); }, []); this.panos.forEach(function (pano) { pano.build1(), pano.on('enter', function () { pano.floor !== _this2.currentFloor && _this2.setFloor(pano.floor); }); }); this.panos.forEach(function (pano) { pano.build2(); }); this.floors.forEach(function (floor) { this.boundingBox.union(floor.boundingBox); }.bind(this)); var size = new THREE.Vector3(); var center = new THREE.Vector3(); this.boundingBox.getSize(size); this.boundingBox.getCenter(center); this.size = size; this.center = center; this.floors.forEach(function (floor) { logger$1.info('Floor ' + floor + ': ' + floor.children.length + ' chunks, ' + floor.panos.length + ' panos.'); }.bind(this)); //this.panos.populate_path_graph(); this.skybox = new BoundingTextureSkybox(this.boundingBox); this.skybox.matrixWorldNeedsUpdate = !0; this.add(this.skybox); { this.skyBoxTight = new BoundingTextureSkybox(this.boundingBox, 2); /* this.skyBoxTight = new THREE.Mesh(new THREE.BoxGeometry(size.x, size.y, size.z)) this.skyBoxTight.computeBoundingBox() //需要重新计算对称的bounding, 在获取鼠标交点时需要。否则热点加不上 this.skyBoxTight.position.copy(center) */ } logger$1.debug('Done building model'); if (Panorama.raycastsDone > 0) { logger$1.warn('raycasts: ' + Panorama.raycastsDone); logger$1.warn('raycasts skipped: ' + Panorama.raycastsSkipped); } //创建floorLogo this.floorLogos.createFloorLogo(); this.add(this.floorLogos.firstLogo); this.add(this.floorLogos.secondLogo); if (browser$1.urlHasValue('axis')) { this.add(new Axis(this.$app)); } setTimeout(function () { _this2.floorplanCadImg.init(_this2); _this2.wallManager.init(_this2); }, 100); this.addHighMapCube(); var videoInfo = this.$app.core.get('PanoVideoRenderer').videosInfo; if (videoInfo) { var parameters = videoInfo.parameters; this.updateVideoRenderParameters(parameters); } this.builded = true; //xzw this.dispatchEvent({ type: 'builded' }); this.texSizeBlock = this.chunks.reduce(function (w, e) { var tex = e.material.uniforms.map.value; return w + Math.pow(tex.image.width / 512, 2); }, 0).toFixed(1); //注:初始时还没有_listeners if (this.$app.config.mobile && browser$1.urlHasValue('vlog')) { setInterval(function () { var count = _this2.getDrawedTexCount().toFixed(1); var title = document.querySelector('#app .information .title span'); if (title) { title.innerText = count + '|' + _this2.$app.core.get('Player').lowTile; } }, 1000); var right = document.querySelector('#app .information .right'); if (right) { right.addEventListener('click', function () { window.logEnable = !window.logEnable; }); } } if (this.texSizeBlock > 40) { setTimeout(function () { //防止大的场景在首次飞出时卡顿一下,提前渲染 。控制未dispose的贴图块数 var player = _this2.$app.core.get('Player'); //虽然渲染的和没渲染的都有一个期望值,但是因为它们必须满足 和大于总数,所以不能随意设置。优先考虑满足飞出不卡顿,那么只考虑没渲染即可。在保证当前未渲染小于某个值的情况下向总数的一半靠拢。 var maxHasnt = _this2.$app.config.mobile ? 100 : 60; //最大能接受的飞出时不停顿的数字(大的场景稍微等待半秒、pc可以加载多点尽量不等待) var hopeHas = _this2.texSizeBlock - Math.min(_this2.texSizeBlock * 0.5, maxHasnt); //console.log('hopeHas', hopeHas) var lastChunkToRender, historyRen = []; var update = { update: function update() { if (player.mode == 'panorama' && !player.flying && !player.lastFrameChanged) { if (lastChunkToRender) { delete lastChunkToRender.material.defines.useModelMap; lastChunkToRender.material.needsUpdate = true; lastChunkToRender = null; } var c = _this2.getDrawedTexCount(); var chunk; if (c > hopeHas) { chunk = _this2.chunks.find(function (e) { var tex = e.material.uniforms.map.value; return tex && tex._listeners && tex._listeners.dispose && tex._listeners.dispose.length > 0; }); if (chunk) { chunk.material.uniforms.map.value.dispose(); //console.log('dispose', c) } } else if (c < hopeHas) { var r = common.sortByScore(_this2.chunks, [function (e) { if (historyRen.includes(e)) return; //historyRen用于记录这一次尝试渲染的chunk,万一哪个不成功就不要重复渲染 var tex = e.material.uniforms.map.value; return tex && !(tex._listeners && tex._listeners.dispose && tex._listeners.dispose.length > 0) && Math.pow(tex.image.width / 512, 2) + c <= hopeHas; }], [function (e) { var s = 0; if (e.floor == _this2.currentFloor) { s += 1; } if (math$1.isInsideFrustum(e.geometry.boundingBox, player.camera)) { s += 1; } return s; }]); if (r.length) { chunk = r[0].item; chunk.material.defines.useModelMap = ''; //暂时放开,使渲染 chunk.material.needsUpdate = true; lastChunkToRender = chunk; historyRen.push(chunk); //console.log('render', c, chunk.tileId ? chunk.tileId.split('3dtiles/')[1] : chunk.name) } } } else { historyRen.length = 0; //清空 } } }; _this2.$app.core.get('SceneRenderer').addComponent(update); }, 1000); } return Promise.resolve(this); }; _this.toggleAlpha = function () { this.alpha < 1 ? this.alpha = 1 : this.alpha = 0; }; _this.waitForLoad = function (pano, isLoadedCallbackFunc) { if (!isLoadedCallbackFunc()) { this.waitQueue.push({ object: pano, isLoadedCallback: isLoadedCallbackFunc }), 1 === this.waitQueue.length && this.emit('waiting'); } }; _this.hide = function () { this.floors.hide(); }; _this.show = function () { this.floors.show(); }; _this.floorNames = function () { return this.floors.names(); }; _this.setFloor = function (floor, mode) { this.allFloorsVisible && this.emit('allfloors.toggled', !1, this.currentFloor); this.allFloorsVisible = !1; this._setFloor(floor, mode); }; _this.toggleAllFloors = function (e) { this.allFloorsVisible = void 0 !== e ? e : !this.allFloorsVisible; this.emit('allfloors.toggled', this.allFloorsVisible, this.currentFloor); this._setFloor(this.currentFloor); }; _this._setFloor = function (floor, mode) { var _this3 = this; mode = mode || this.mode; var old = this.currentFloor; this.currentFloor = floor; this.$app.core.get('Player').mode; if (mode === Viewmode$1.PANORAMA) { this.show(); } else if ( // mode === Viewmode.FLOORPLAN || // (mode === Viewmode.DOLLHOUSE && lastMode == mode) // UI在setMode时已让DOLLHOUSE楼层全显示,所以这里不做更改 mode === Viewmode$1.FLOORPLAN || mode === Viewmode$1.DOLLHOUSE) { this.floors.list.forEach(function (floor, index) { var flag = floor === this.currentFloor || this.allFloorsVisible; floor.toggle(flag); }.bind(this)); } this.emit('floor.changed', this.currentFloor, mode, old); // 楼层显隐tile需要改变,要更新一下 setTimeout(function () { return _this3.$app.core.get('SceneRenderer').update3dTiles({ force: true }); }, 10); }; _this.toggleExplode = function () { this.floors.toggleExplodeHorizontal(); }; _this.toggleExplodeUp = function () { this.floors.toggleExplodeVertical(); }; _this.nextFloor = function (nextfloor) { return this.floors.nextFloor(this.currentFloor, nextfloor); }; _this.addFloor = function (floor) { this.floors.add(floor); }; _this.getFloorAtPoint = function (position) { return this.floors.getFloorAtPoint(position); }; _this.addTile = function (floorIndex, tileContent) { this.floors.getOrMakeFloor(floorIndex).addTile(tileContent); }; _this.removeTile = function (tileContent) { this.floors.getOrMakeFloor(tileContent.floorIndex).removeTile(tileContent); }; _this.addChunk = function (floorIndex, chunk) { this.floors.getOrMakeFloor(floorIndex).addChunk(chunk); // this.chunks.push(chunk) }; _this.setMode = function (mode) { var _this4 = this; if (!this.supportedModes[mode]) { throw new BasicException('Mode not supported for this model: ' + mode); } this.mode = mode; this.chunks.forEach(function (chunk) { chunk.setMode(mode, _this4.player.modeTran); // 根据mode选择materialInside/materialOutside以及单双面显隐 }); }; _this.updateProjectedPanos = function (pano) { //xzw 改 for 无缝过渡 if (this.projectedPano0 && this.projectedPano1 && (pano == this.projectedPano0 || pano == this.projectedPano1)) { this.setProjectedPanos(this.projectedPano0, this.projectedPano1, !1); } }; _this.setProjectedPanos = function (pano0, pano1, restoreFlag) { void 0 !== restoreFlag && null !== restoreFlag || (restoreFlag = !0); restoreFlag = !!restoreFlag; this.projectedPano0 = pano0; this.projectedPano1 = pano1; this.skybox.material.setProjectedPanos(pano0, pano1, restoreFlag); this.chunks.forEach(function (chunk) { chunk.materialInside.setProjectedPanos(pano0, pano1, restoreFlag); }); this.highMapCube && this.highMapCube.tiles.forEach(function (tile) { tile.material.setProjectedPanos(pano0, pano1, restoreFlag); }); }; _this.setSide = function (side) { this.floors.forEach(function (floor) { floor.collider.material.side = side; }); }; _this.fadePanoMarkers = function (opacity, dur) { var _this5 = this; var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, mode = _ref.mode, hideVideoFlag = _ref.hideVideoFlag; if (!this.player) return; var currentPano = this.player.currentPano; if (settings$3.vrEnabled && window.VRScreenType != 'portrait') { this.updateVrMarker(); return; } //console.log("fadePanoMarkers", opacity,dur,o.vrCustomer) // // customer时保持marker隐藏 // let role = location.search.match(new RegExp('[\\?,&]role=(.*?)[&,$]')) // if (role && role[1] == 'customer') { // // zeg 这部分如无必要只在customer时用,否则影响正常player的lock // if (o.vrCustomer != void 0) { // //vr被带看的走动时不显示marker // this.markerUnable = !!o.vrCustomer // } // if (this.markerUnable && o.vrCustomer == void 0) { // return // } // return // } var canShowVideoMarker = this.$app.core.get('PanoVideoRenderer').canShowMarker(); var hideWhenFlyOut = function hideWhenFlyOut() { var shows = [], hides = []; _this5.player.model.panos.forEach(function (pano) { if (pano.hasVideo || pano.panoVideo) { if (hideVideoFlag || !pano.hasNeighbor() || pano.floor.hidden || !canShowVideoMarker) { hides.push(pano); } else { //console.log('show',pano.id) shows.push(pano); } } else hides.push(pano); }); _this5.panos.fadeMarkerOpacity(1, dur, [{ toOp: 0, member: hides }, { toOp: settings$3.panorama.markerOpacity, member: shows }]); }; if (opacity == 0) { hideWhenFlyOut(); } else { if ((mode || this.player.mode) == Viewmode$1.PANORAMA && currentPano) { var shows = [], //shows2 = [], hides = [], panoVideoFilter = currentPano.getVideoFilter(); //视频漫游点角度范围内隐藏marker this.player.model.panos.forEach(function (pano) { //是邻近点就显示否则隐藏 if ((!panoVideoFilter || !panoVideoFilter(pano.position)) && currentPano.seeMarkers.indexOf(pano.id) > -1) { /* if (pano.hasVideo || pano.panoVideo) {//videomarker已经改为普通的,所以删除 // if (objects.panoVideoRenderer.ifEnable()) if (this.$app.core.get('PanoVideoRenderer').ifEnable()) pano.marker.visible = true } else { */ shows.push(pano); //} } else { /* if (pano.hasVideo || pano.panoVideo) pano.marker.visible = false else */ hides.push(pano); } }); this.panos.fadeMarkerOpacity(opacity, dur, [{ toOp: settings$3.panorama.markerOpacity, member: shows }, { toOp: 0, member: hides }]); } else if (this.player.modeTran.split('-')[1] != 'panorama') { //飞出后marker隐藏 hideWhenFlyOut(); } } }; _this.outsideAllowed = function () { return this.supportedModes[Viewmode$1.DOLLHOUSE] && this.supportedModes[Viewmode$1.FLOORPLAN]; }; _this.getOption = function ($app) { return { autoload: false, floors: true, local: false, url: $app.config.num, urlFiles: 'http://www.4dage.com/BigScene7niu/api/player/models/' + $app.config.num + '/files', useVisionModelData: true }; }; _this.getModelMeta = function ($app) { return { sid: $app.config.num, name: '四维时代', status: 'viewable', floors: '', metainfo: { allowed_methods: ['GET', 'OPTIONS', 'HEAD'] }, image: 'http://7xo6he.com2.z0.glb.qiniucdn.com/images/images1/07.13.2015_16.22.30.jpg', images: [], job: { uuid: 'dacf7dfa24ae47fab8fcebfe4dc41ab9' }, layers: [] }; }; var options = _this.getOption(app); var modelData = _this.getModelMeta(app); _this.$app = app; _this.sid = modelData.sid; _this.data = modelData; _this.options = options; _this.urls = new ModelUrls(_this.sid, app); /* this.images = new ImageCollection(this) this.images.extend(modelData.images) this.heroImage = this.images.getImage(modelData.icon) this.heroLocations = [] */ _this.outdoorPanoLocations = []; _this.floors = new FloorCollection(_assertThisInitialized(_this)); _this.floorsEnabled = void 0 === options.floors || options.floors; _this.changingFloor = !1; // this.chunks = [] _this.panos = new PanoramaCollection(app); _this.colliders = []; _this.loadPanosPromise = null; _this.loadMeshTexturesPromise = null; _this.auxDataPromise = null; _this.mesh3dTilesLoaded = !1; _this.meshTexturesLoaded = !1; _this.meshTextures = []; _this.mattertags = {}; _this.tagsShown = !1; _this.shouldShowMattertags = !1; _this.has360Views = !1; _this.showingLabels = settings$3.labels.enabled && modelData.player_options.labels; _this.supportedModes = {}; _this.supportedModes[Viewmode$1.PANORAMA] = !0; _this.supportedModes[Viewmode$1.DOLLHOUSE] = !modelData.player_options || modelData.player_options.dollhouse && browser$1.valueFromHash('dh', 1); _this.supportedModes[Viewmode$1.FLOORPLAN] = !modelData.player_options || modelData.player_options.floor_plan && browser$1.valueFromHash('dh', 1); _this.supportedModes[Viewmode$1.TRANSITIONING] = !0; _this.supportsTiles = true; _this.supportsVR = modelData.is_vr; _this.mode = Viewmode$1.DOLLHOUSE; _this.size = null; _this.center = null; _this.boundingBox = new THREE.Box3(); _this.currentFloor = null; _this.allFloorsVisible = !0; _this.projectedPano0 = null; _this.projectedPano1 = null; _this.floorsEnabled && modelData.floors && modelData.floors.indexOf(',') !== -1 && modelData.floors.split(',').forEach(function (e, t) { this.addFloor(new Floor(this, t, e.trim())); }.bind(_assertThisInitialized(_this))); _this.waitQueue = []; _this.on('load', function (e) { 0 !== this.waitQueue.length && (this.waitQueue = this.waitQueue.filter(function (e) { return !e.isLoadedCallback(); }), 0 === this.waitQueue.length && this.emit('waiting-done')); }.bind(_assertThisInitialized(_this))); _this.setupCustomProperties(); //this.labels = new LabelCollection(this); //other: _this.vrMarkers = []; _this.floorLogos = new FloorLogos(_this.$app); _this.floorplanCadImg = new FloorplanCadImg(_this.$app); _this.wallManager = new WallManager(_this.$app); return _this; } _createClass(Model, [{ key: "chunks", get: function get() { var chunks = []; this.floors.forEach(function (floor) { return chunks.push.apply(chunks, _toConsumableArray(floor.chunks)); }); return chunks; } }, { key: "getDrawedTexCount", value: function getDrawedTexCount() { return this.chunks.reduce(function (w, e) { var tex = e.material.uniforms.map.value; if (!tex) return w; return w + (tex._listeners && tex._listeners.dispose && tex._listeners.dispose.length > 0 ? Math.pow(tex.image.width / 512, 2) : 0); }, 0); } }, { key: "createTranControl", value: function createTranControl(player) { //初始化控件 var options = { player, dontHideWhenFaceCamera: true, scaleAxis: ['x', 'y'], //隐藏了z轴。虽然参数没用上 NoScaleZ: true //整体缩放时只缩放xy轴。 }; this.transformControls = new TransformControls(player.camera, player.domElement, options); this.transformControls.space = 'local'; this.transformControls.setSize(1.2); this.add(this.transformControls); this.transformControls.visible = false; } }, { key: "updateVideoTexture", value: function updateVideoTexture(texture) { if (this.skybox) { this.skybox.material.uniforms.videoTexture.value = texture; } this.chunks.forEach(function (item) { item.materialInside.uniforms.videoTexture.value = texture; }); this.highMapCube && this.highMapCube.tiles.forEach(function (tile) { tile.material.uniforms.videoTexture.value = texture; }); } }, { key: "suspendVideoRender", value: function suspendVideoRender() { if (this.skybox) { this.skybox.material.uniforms.videoReady.value = 0; } this.chunks.forEach(function (item) { item.materialInside.uniforms.videoReady.value = 0; }); this.highMapCube && this.highMapCube.tiles.forEach(function (tile) { tile.material.uniforms.videoReady.value = 0; }); } }, { key: "resumeVideoRender", value: function resumeVideoRender() { if (this.skybox) { this.skybox.material.uniforms.videoReady.value = 1; this.skybox.material.uniforms.progress.value = 1; } this.chunks.forEach(function (item) { item.materialInside.uniforms.videoReady.value = 1; item.materialInside.uniforms.progress.value = 1; }); this.highMapCube && this.highMapCube.tiles.forEach(function (tile) { tile.material.uniforms.videoReady.value = 1; tile.material.uniforms.progress.value = 1; }); } /* updateVideoRenderParameters(parameters) { this.skybox.material.uniforms.parameters.value.set( parameters.inputWidth, parameters.inputHeight, parameters.outputWidth, parameters.outputHeight, parameters.focal, parameters.pixel, parameters.centerX, parameters.centerY, parameters.translateX, parameters.translateY, parameters.translateZ, 0, parameters.lenOffsetX, parameters.lenOffsetY, parameters.videoWidth, parameters.videoHeight ) if (parameters.cameraType == 8) { this.skybox.material.defines.HasVideo = 8 //8目 } else if (parameters.cameraType == 2) { this.skybox.material.defines.HasVideo = 2 //2目 } else if (parameters.cameraType == 3) { //转台双目 this.skybox.material.defines.HasVideo = 3 } this.skybox.material.defines.VideoMapping = parameters.mapping this.skybox.material.needsUpdate = true this.chunks.forEach(item => { item.materialInside.uniforms.parameters.value.set( parameters.inputWidth, parameters.inputHeight, parameters.outputWidth, parameters.outputHeight, parameters.focal, parameters.pixel, parameters.centerX, parameters.centerY, parameters.translateX, parameters.translateY, parameters.translateZ, 0, parameters.lenOffsetX, parameters.lenOffsetY, parameters.videoWidth, parameters.videoHeight ) if (parameters.cameraType == 8) { item.materialInside.defines.HasVideo = 8 //8目 } else if (parameters.cameraType == 2) { item.materialInside.defines.HasVideo = 2 //2目 } else if (parameters.cameraType == 3) { //转台双目 this.skybox.material.defines.HasVideo = 3 } item.materialInside.defines.VideoMapping = parameters.mapping item.materialInside.needsUpdate = true }) } */ }, { key: "updateVideoRenderParameters", value: function updateVideoRenderParameters(parameters) { var mats = [this.skybox.material].concat(_toConsumableArray(this.chunks.map(function (e) { return e.materialInside; }))); this.highMapCube && this.highMapCube.tiles.forEach(function (tile) { mats.push(tile.material); }); mats.forEach(function (material) { material.uniforms.parameters.value.set(parameters.inputWidth, parameters.inputHeight, parameters.outputWidth, parameters.outputHeight, parameters.focal, parameters.pixel, parameters.centerX, parameters.centerY, parameters.translateX, parameters.translateY, parameters.translateZ, 0, parameters.lenOffsetX, parameters.lenOffsetY, parameters.videoWidth, parameters.videoHeight); if (parameters.cameraType == 8) { material.defines.HasVideo = 8; //8目 } else if (parameters.cameraType == 2) { material.defines.HasVideo = 2; //2目 } else if (parameters.cameraType == 3) { //转台双目 material.defines.HasVideo = 3; } material.defines.VideoMapping = parameters.mapping; material.needsUpdate = true; }); } }, { key: "updateVrMarker", value: //更新vr的漂浮球位置 function updateVrMarker(enable) { var _this6 = this; //enable代表vrEnable if (!this.player.currentPano.isAligned()) return; //在全景图里的话会先出来再updateVrMarker enable = enable == void 0 ? settings$3.vrEnabled : enable; if (enable) { for (var i in this.panos.index) { var pano = this.panos.index[i]; if (pano.isAligned()) pano.marker.opacity = 0; } } else { this.fadePanoMarkers(null, null); } this.vrMarkers.forEach(function (v) { v.visible = enable && _this6.player.currentPano.id != v.pano.id && !!_this6.player.currentPano.neighbourPanos[v.pano.id]; //!! 是防止undefined }); } }, { key: "addHighMapCube", value: function addHighMapCube() { var _this7 = this; //创建8*8的tile cube if (this.$app.core.get('QualityManager').tileClass == '4k' && this.$app.core.get('QualityManager').maxRenderTargetSize == 2048) { //this.$app.store.getValue('metadata').sceneResolution == 'tiles/4k' var geo = new THREE.PlaneGeometry(1, 1, 1, 1); var cube = new THREE.Object3D(); cube.tiles = []; for (var cubeIndex = 0; cubeIndex < 6; cubeIndex++) { var face = new THREE.Object3D(); for (var i = 0; i < 8; i++) { for (var j = 0; j < 8; j++) { var tile = new THREE.Mesh(geo, //new THREE.MeshBasicMaterial({ side: 2, depthTest: false, depthWrite: false })) new ModelTextureMaterial({ side: THREE.DoubleSide, depthTest: false, //防止chunk比cube近从而被遮 且能不遮住box视频和viewlink等 transparent: true, //遮蔽 defines: { BasePanoMap: '' //普通贴图当做全景图 } })); tile.material.uniforms.progress.value = 1; tile.material.uniforms.modelAlpha.value = 0; tile.position.set(i - 3.5, j - 3.5, -4); if (highMapAddColor) { tile.material.uniforms.opacity.value = 0.4; var colorHue = Math.random(); tile.material.uniforms.baseColor.value = new THREE.Color().setHSL(colorHue, 0.8, 0.9); /* 0.5, 0.95) */ /* tile.scoreLabel = new TextSprite( { backgroundColor: { r: 0, g: 0, b: 0, a: 0 }, textColor: { r: 0, g: 0, b: 0, a: 1 }, borderRadius: 15, renderOrder: 50, fontsize : 13, text: '' }) tile.add(tile.scoreLabel) */ } tile.visible = false; tile.tileX = i; tile.tileY = j; tile.cubeFace = cubeIndex; tile.renderOrder = RenderOrder.highTileCube; cube.tiles.push(tile); face.add(tile); } } switch (cubeIndex) { case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_X: face.rotation.set(0, Math.PI / 2, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_X: face.rotation.set(0, -Math.PI / 2, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Y: var rot1 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI); var rot2 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), Math.PI / 2); face.quaternion.copy(rot1).multiply(rot2); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: var rot1 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI); var rot2 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), -Math.PI / 2); face.quaternion.copy(rot1).multiply(rot2); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Z: face.rotation.set(0, Math.PI, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: face.rotation.set(0, 0, 0); } face.scale.set(1, -1, 1); face.cubeFace = cubeIndex; cube.add(face); } cube.name = 'highMapCube'; this.highMapCube = cube; this.add(cube); cube.scale.set(0.21, 0.21, 0.21); //camera.near is 0.1 this.highMapCube.visible = false; this.highMapCube.texLoadedCount = 0; this.$app.core.get('SceneRenderer').on(SceneRendererEvents.AfterRender, function (e) { if (_this7.highMapCube.visibleTiles) { _this7.updateTiles(); //逐步将visibleTiles加载完 } if (_this7.player && _this7.player.lastFrameChanged) { //重新获取visibleTiles common.intervalTool.isWaiting('update4kTiles_' + _this7.$app.resource.num, function () { var vectorForward = _this7.player.getDirection(); _this7.updateTiles(vectorForward); }, 500); } }); } } /* highMapCube会遮住场景中所有物体, 如果一定要显示的话,只能类似potree中的那样渲染一个深度贴图出来(model无需贴图),然后其他所有物体的shader中都加入一段代码。(貌似本身已经支持了?) */ }, { key: "isHighMapLoaded", value: function isHighMapLoaded(cubeFace, tileX, tileY) { var tile = this.highMapCube.children[cubeFace].children[tileX * 8 + tileY]; return !!tile.material.uniforms.map.value; } }, { key: "updateTiles", value: function updateTiles(direction) { var _this8 = this; if (!this.highMapCube || !this.highMapCube.visible) return; if (this.highMapCube.tiles.filter(function (e) { return e.image; }).length <= 10) return; //加载的太少了 //performance.mark('updateTiles-start') if (direction) { var camera = this.player.cameraControls.cameras.panorama; var hfov = cameraLight.getHFOVForCamera(camera, null, null, true) / 2; var vfov = THREE.MathUtils.degToRad(camera.fov) / 2; /* let hcos = Math.cos(hfov / 2) let vcos = Math.cos(vfov / 2) */ var list = this.highMapCube.tiles; list.forEach(function (e) { //屏幕外的不显示 var pos = e.getWorldPosition(new THREE.Vector3()); var dir = new THREE.Vector3().subVectors(pos, _this8.highMapCube.position).normalize(); var hcos_ = dir.clone().setY(direction.y).normalize().dot(direction); //在direction的斜面上水平角度差 var hRad = Math.acos(hcos_); var vRad = -200; if (hRad > hfov + 0.08) { e.score = -100; } else { vRad = Math.abs(Math.acos(dir.y) - Math.acos(direction.y)); if (vRad > vfov + 0.08) { e.score = -100; } else { e.score = -(hRad / hfov + vRad / vfov); } } e.scores = hRad.toFixed(3) + ', ' + vRad.toFixed(3); if (e.score == -100) { _this8.resetTile(e); } }); this.highMapCube.visibleTiles = list.filter(function (e) { return e.score > -100; }); //list.forEach(e=>e.scoreLabel.setText(e.scores)) } var needRecover = this.highMapCube.visibleTiles.filter(function (e) { return !e.material.uniforms.map.value; }); if (needRecover.length) { var maxCount = common.getBestCount({ name: '4kmaxTileRecover', minCount: 0, maxCount: 2, durBound1: 1.5, durBound2: 6, ifLog: false, maxHistory: 2 }); var count = 0; needRecover.forEach(function (e, i) { //只更新若干个,因为太耗时了, 其余的等下帧更新 if (count >= maxCount) return; var r = _this8.recoverTile(e); if (r) count++; }); } /*if(recoverList.length == 0)this.highMapCube.restNeedRecover = [] else{ let maxCount = common.getBestCount({name:'4kmaxTileRecover', minCount : 0, maxCount : 2, durBound1 : 1.5, durBound2 : 6, ifLog:false, maxHistory:2 } ) let count = 0,index = -1 recoverList.forEach((e,i)=>{ //只更新若干个,因为太耗时了 if(count>=maxCount)return let r = this.recoverTile(e) if(r) count ++ index = i }) this.highMapCube.restNeedRecover = recoverList.slice(index+1) //其余的等下帧更新 }*/ /* performance.mark('updateTiles-end') let measure = performance.measure('updateTiles', 'updateTiles-start', 'updateTiles-end') console.log('updateTiles', measure.duration.toFixed(3)) */ } }, { key: "getHighImage", value: function getHighImage(image, cubeFace, tileX, tileY) { var tile = this.highMapCube.children[cubeFace].children[tileX * 8 + tileY]; tile.image = image; //先记录下来 } }, { key: "updateHighMap", value: function updateHighMap(image, cubeFace, tileX, tileY) { var tile = this.highMapCube.children[cubeFace].children[tileX * 8 + tileY]; if (image) tile.image = image; //先记录下来 var uniforms = tile.material.uniforms; if (uniforms.map.value) return; if (this.highMapCube.visibleTiles && !this.highMapCube.visibleTiles.includes(tile) /* this.highMapCube.texLoadedCount >= this.getMaxTileCount() */ ) { return; } //简易创建贴图 /* var tex = this.$app.core.get('SceneRenderer').initSizedTexture2D(512, THREE.ClampToEdgeWrapping) //var loaded = this.$app.core.get('Player').model.isHighMapLoaded(tile.cubeFace, tile.tileX, tile.tileY) this.$app.core.get('SceneRenderer').uploadTexture2D(image, tex, 0, 0, 512, 512) //只替换tex对应的img,不新建 */ var tex = new THREE.Texture(); tex.image = image; tex.flipY = false; tex.wrapS = tex.wrapT = THREE.ClampToEdgeWrapping; tex.generateMipmaps = false; tex.minFilter = THREE.LinearFilter; tex.needsUpdate = true; uniforms.map.value = tex; if (highMapAddColor) { uniforms.opacity.value = 1; } tile.visible = true; tile.material.needsUpdate = true; //发现每次开始放大但还未放大到4k时也会把之前加载过的4k加载 //console.log('updateHighMap',cubeFace, tileX, tileY) } }, { key: "recoverTile", value: function recoverTile(tile) { if (tile.material.uniforms.map.value) return; if (tile.image) { this.updateHighMap(tile.image, tile.cubeFace, tile.tileX, tile.tileY); return true; } } }, { key: "resetTile", value: function resetTile(tile, kill) { if (kill) { //完全消灭 tile.image = null; } var map = tile.material.uniforms.map.value; if (map) { map.dispose(); //这句执行了以后,h.__webglTexture一直就是undefined map.loaded = !1; map.version = 0; //保底再执行一下这个,类似app.sceneRenderer.deallocateCubeTexture(tile.material.map) var h = this.$app.core.get('SceneRenderer').renderer.properties.get(map); //console.log('__webglTexture',!!h.__webglTexture) this.$app.core.get('SceneRenderer').renderer.getContext().deleteTexture(h.__webglTexture); tile.material.uniforms.map.value = null; if (highMapAddColor) { tile.material.uniforms.opacity.value = 0.4; } tile.material.needsUpdate = true; tile.visible = false; //this.highMapCube.texLoadedCount -- //console.log('resetTile'/* , tile.cubeFace, tile.tileX, tile.tileY */) } } }, { key: "resetHighMap", value: function resetHighMap() { var _this9 = this; if (!this.highMapCube) return; this.highMapCube.children.forEach(function (e) { return e.children.forEach(function (tile) { _this9.resetTile(tile, true); }); }); //this.highMapCube.texLoadedCount = 0 this.highMapCube.visibleTiles = null; this.hideHighMap(); //console.log('resetHighMap') } }, { key: "setHighMap", value: function setHighMap(pano) { if (!this.highMapCube) return; this.highMapCube.position.copy(pano.position); this.highMapCube.quaternion.copy(pano.quaternion); } }, { key: "showHighMap", value: function showHighMap() { if (!this.highMapCube) return; this.highMapCube.visible = true; //console.log('showHighMap') } }, { key: "hideHighMap", value: function hideHighMap() { if (!this.highMapCube) return; this.highMapCube.visible = false; //console.log('hideHighMap') } //缩小后继续显示cube呢还是不显示? 不显示的话,就要把cube上的复制到renderTarget上……会不会又崩溃,or没加载的显示??? }, { key: "showLowestTile", value: function showLowestTile(isLowest) { // 只显示最低精度的瓦片 if (this._3dTilesRuntime) { this._3dTilesRuntime.pauseTilesetUpdate(false); // 最低精度时,暂停_3dTilesRuntime的update var sceneRenderer = this.$app.core.get('SceneRenderer'); sceneRenderer.autoUpdate3dTiles = !isLowest; sceneRenderer.autoUpdate3dTiles && sceneRenderer.update3dTiles({ force: true }); // 立即更新一次相机位置 this._3dTilesRuntime.limit2lowestDepth(isLowest); // 只显示最低瓦片精度 this._3dTilesRuntime.ingoreVisibleCompute(isLowest); // 最低精度时,忽略瓦片是否在屏幕外 this._3dTilesRuntime.pauseTilesetUpdate(isLowest); } } }]); return Model; }(THREE.Object3D)) || _class; /* note: 目前highMap 4k放大 是会遮住所有marker、viewLink等mesh的 */ function _createSuper$1l(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1l(); 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 _isNativeReflectConstruct$1l() { 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; } } var View = /*#__PURE__*/function (_EventEmitter) { _inherits(View, _EventEmitter); var _super = _createSuper$1l(View); function View(e) { var _this; _classCallCheck(this, View); _this = _super.call(this); e = e || {}; _this.position = new THREE.Vector3(); _this.quaternion = new THREE.Quaternion(); _this.update(e); return _this; } _createClass(View, [{ key: "isValid", value: function isValid() { return !!this.cameraMode; } }, { key: "update", value: function update(e) { return this.cameraMode = e.cameraMode || this.cameraMode, this.pano = e.pano || this.pano, e.position && this.position.copy(e.position), e.quaternion && this.quaternion.copy(e.quaternion), this; } }]); return View; }(EventEmitter); function _createSuper$1k(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1k(); 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 _isNativeReflectConstruct$1k() { 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; } } var Reticule = /*#__PURE__*/function (_THREE$Mesh) { _inherits(Reticule, _THREE$Mesh); var _super = _createSuper$1k(Reticule); function Reticule(player) { var _this; _classCallCheck(this, Reticule); _this = _super.call(this); var uniform = THREE.UniformsUtils.clone(shaders.waypoint.uniforms); //uniform.map.value = settings.blueReticule; uniform.map.value = common.loadTextureFromCache(texture.getImageURL('images/blueReticle.png')); uniform.map.value.minFilter = THREE.LinearMipMapLinearFilter; uniform.map.value.anisotropy = 4; uniform.opacity.value = 0; //uniform.color.value.set(settings.reticuleColor) _this = _super.call(this, new THREE.PlaneBufferGeometry(0.4, 0.4, 1, 1), new THREE.RawShaderMaterial({ side: THREE.DoubleSide, depthWrite: !1, depthTest: !1, transparent: !0, vertexShader: shaders.waypoint.vertexShader, fragmentShader: shaders.waypoint.fragmentShader, uniforms: uniform, name: 'waypoint', opacity: 0 })); _this.layers.set(RenderLayers.RETICULE); _this.renderOrder = RenderOrder.reticule; _this.player = player; _this.direction = new THREE.Vector3(); _this.hidden = !0; _this.mouseLastMoveTime = Date.now(); //this.alwaysShow = true //for test return _this; } _createClass(Reticule, [{ key: "move", value: function move(e, t, i) { this.hidden = i, this.mouseLastMoveTime = Date.now(); } }, { key: "hide", value: function hide() { this.hidden || (this.hidden = !0, transitions$1.start(lerp.property(this.material.uniforms.opacity, 'value', 0), settings$3.reticuleOpacityTransitionTime)); } }, { key: "show", value: function show() { this.hidden = !1, this.material.opacity <= 0 && transitions$1.start(lerp.property(this.material.uniforms.opacity, 'value', settings$3[this.player.mode].reticuleOpacity), settings$3.reticuleOpacityTransitionTime); } }, { key: "update", value: function update() { Date.now() - this.mouseLastMoveTime > settings$3.hideReticuleTimeout && !this.hidden && this.hide(); } }, { key: "updatePosition", value: function updatePosition(e, t) { if (!this.hidden) { if (!t) return this.hide(); var i = t.point, n = e.distanceTo(i), r = 1 + 0.01 * n; n < 1 && (r -= 1 - n), this.show(); this.scale.set(r, r, r); this.direction = this.direction.multiplyScalar(0.8); this.direction.add(t.face.normal.clone().multiplyScalar(0.2)); this.position.copy(i).add(t.face.normal.clone().multiplyScalar(0.01)); this.lookAt(this.position.clone().add(this.direction)); } } }]); return Reticule; }(THREE.Mesh); var ControlEvents = { Move: 'move', InteractionDirect: 'interaction.direct', InteractionKey: 'interaction.key', InteractionGui: 'interaction.gui', FlyInDirection: 'fly.direction', InputStart: 'input.start', Pinch: 'input.pinch', Scroll: 'input.scroll', AutoPanInterrupt: 'autopan.interrupt', AutoPanComplete: 'autopan.complete', AutoPanClamped: 'autopan.clamped', LongTap: 'longtap' }; var DownloadStatus = Object.freeze({ None: 0, Queued: 1, ForceQueued: 2, Downloading: 3, Downloaded: 4, DownloadFailed: 5 }); var h$1 = Object.freeze({ None: 0, DirectionalFOV: 1 }); var u$1 = function () { var e = function e(t, i) { var n = e._panoSpaceDir, r = e._fovThreshold, o = e._fovThresholdNarrow, a = Math.max(Math.min(n.dot(t.direction), 1), -1), s = Math.max(Math.min(n.dot(i.direction), 1), -1); return t._dot = a, i._dot = s, a >= r && s < r ? -1 : a < r && s >= r ? 1 : a >= o && s < o ? -1 : a < o && s >= o ? 1 : t.panoSize > i.panoSize ? 1 : i.panoSize > t.panoSize ? -1 : -(a - s); }; return e._panoSpaceDir = new THREE.Vector3(), e._fovThreshold = -1, e._fovThresholdNarrow = -1, e; }(); var TilePrioritizer = /*#__PURE__*/function () { function TilePrioritizer(_e, _t, _i, _o, _a) { _classCallCheck(this, TilePrioritizer); this.filterAndPrioritize = function () { var e = [], t = [], i = []; return function (r, o, a) { var maxCount = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 10; //console.log('filterAndPrioritize', this.priorityCriteria.pano.model.sid) if (this.priorityCriteria.pano.panoType != '360view') { //没有相邻(如果加上了visibleView, 使用upcomingPanos) this.populateNeighborPanos(this.priorityCriteria.pano, o, e); this.populateScoredPanos(this.priorityCriteria.pano, o, t, this.priorityCriteria.cameraDir, TilePrioritizer.MAX_SCORED_PANOS_TOCONSIDER); } var s = this.baseSize, //512 l = this.standardSize, //1024 c = this.highSize, //2048 h = this.ultraHighSize; //4096 this.queueTilesForPano(r, a, this.priorityCriteria.pano, s); if (this.priorityCriteria.upcomingPanos) { this.queueTilesForPanos(r, this.priorityCriteria.upcomingPanos, a, s, TilePrioritizer.MAX_UPCOMING_PANOS_TOADD); } i.length = 0; if (this.canDownloadSize(l) && r.length < maxCount) { this.queueTilesInDirectionForPano(i, a, this.priorityCriteria.pano, l, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDir, TilePrioritizer.DIRECTIONAL_FOV_NARROW); } TilePrioritizer.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDir); TilePrioritizer.appendQueue(r, i); this.queueTilesForPanos(r, t, a, s, TilePrioritizer.MAX_SCORED_PANOS_TOADD); i.length = 0; if (r.length < maxCount) { if (this.canDownloadSize(c) && r.length + i.length < maxCount) { this.queueTilesInDirectionForPano(i, a, this.priorityCriteria.pano, c, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDir, TilePrioritizer.DIRECTIONAL_FOV_NARROW); } if (this.canDownloadSize(h) && r.length + i.length < maxCount) { this.queueTilesInDirectionForPano(i, a, this.priorityCriteria.pano, h, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDir, TilePrioritizer.DIRECTIONAL_FOV_NARROW); } TilePrioritizer.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDir); TilePrioritizer.appendQueue(r, i); i.length = 0; } if (r.length < maxCount) { if (this.canDownloadSize(l) && r.length + i.length < maxCount) { this.queueTilesInDirectionForPano(i, a, this.priorityCriteria.pano, l, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDir, TilePrioritizer.DIRECTIONAL_FOV); } if (this.canDownloadSize(c) && r.length + i.length < maxCount) { this.queueTilesInDirectionForPano(i, a, this.priorityCriteria.pano, c, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDir, TilePrioritizer.DIRECTIONAL_FOV); } if (this.canDownloadSize(h) && r.length + i.length < maxCount) { this.queueTilesInDirectionForPano(i, a, this.priorityCriteria.pano, h, this.priorityCriteria.cameraPosition, this.priorityCriteria.cameraDir, TilePrioritizer.DIRECTIONAL_FOV); } TilePrioritizer.sortPanoTiles(i, this.priorityCriteria.pano, this.priorityCriteria.cameraDir); TilePrioritizer.appendQueue(r, i); } //r.length && console.log(r.map(e=>e.pano.id + '-' + e.panoSize)) this.queueTilesForPanos(r, e, a, s); }; }(); this.queueTilesForPano = function () { var e = { filter: h$1.None }; return function (t, i, n, r) { if (!n.tiled) return; //xzw add return this.filterAndQueueTileDownloadDescriptors(t, i, n, r, e); }; }(); this.queueTilesForPanosInDirection = function () { var e = new THREE.Vector3(); return function (t, i, n, r, o, a, s, l) { for (var h = 0, u = 0; u < n.length; u++) { var d = n[u]; e.copy(d.position), e.sub(o), e.normalize(); var p = Math.max(Math.min(a.dot(e), 1), -1), f = c.getFOVDotThreshold(s); if (p >= f) { var g = this.queueTilesInDirectionForPano(t, i, d, r, o, a, s); if (h += g > 0 ? 1 : 0, l && h >= l) break; } } return h; }; }(); this.queueTilesInDirectionForPano = function () { var e = { filter: h$1.DirectionalFOV, direction: new THREE.Vector3(), fov: 60 }, t = new THREE.Vector3(); return function (i, n, r, o, a, s, c) { if (!r.tiled) return; //xzw add t.copy(s); TileUtils.getRelativeDirection(r.quaternion, t); e.direction.copy(t); e.fov = c; return this.filterAndQueueTileDownloadDescriptors(i, n, r, o, e); }; }(); this.filterAndQueueTileDownloadDescriptors = function () { var e = []; return function (t, i, n, r, o) { var a = i.getTileDownloadDescriptors(n, r); e.length = 0, this.filterTileDownloadDescriptors(n, a, e, o); for (var s = 0, l = 0; l < e.length; l++) { var c = e[l]; if (c) { t.push(c); s++; } } return s; }; }(); this.filterTileDownloadDescriptors = function () { new THREE.Vector3(); return function (e, t, i, n) { var r, o; switch (n.filter) { case h$1.DirectionalFOV: for (r = 0; r < t.length; r++) { o = t[r], TileUtils.isTileWithinFOV(o.panoSize, o.tileSize, o.face, o.tileX, o.tileY, n.direction, n.fov) && i.push(o); } break; default: for (r = 0; r < t.length; r++) { o = t[r], i.push(o); } } for (r = 0; r < i.length; r++) { o = i[r], this.canIncludeDescriptor(o) || (i[r] = null); } }; }(); this.qualityManager = _e; this.maxNavQuality = this.qualityManager.getMaxNavPanoSize(); this.maxZoomQuality = this.qualityManager.getMaxZoomPanoSize(); this.baseSize = _t; this.standardSize = _i; this.highSize = _o; this.ultraHighSize = _a; this.priorityCriteria = new TilePrioritizer.PriorityCriteria(null, new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 0, -1)); } _createClass(TilePrioritizer, [{ key: "updateCriteria", value: function updateCriteria(pano, t, i, n) { this.priorityCriteria.pano = pano; this.priorityCriteria.cameraPosition.copy(t); this.priorityCriteria.cameraDir.copy(i); this.priorityCriteria.upcomingPanos = n; this.maxNavQuality = this.qualityManager.limitQuality && pano.curTileQuality ? pano.curTileQuality : this.qualityManager.getMaxNavPanoSize(); //xzw : quality 表示在漫游过程中手机端先只加载低质量,静止片刻后再加载2k this.maxZoomQuality = this.qualityManager.getMaxZoomPanoSize(); } }, { key: "canDownloadSize", value: function canDownloadSize(e) { return this.maxNavQuality >= e || this.maxZoomQuality >= e && this.zoomingActive; } }, { key: "populateNeighborPanos", value: function populateNeighborPanos(e, t, i) { i = i || [], i.length = 0; var n = t.getNeighbours(e); for (var r in n) { if (n.hasOwnProperty(r)) { var o = t.get(r); i.push(o); } } return i; } }, { key: "populateScoredPanos", value: function populateScoredPanos(e, t, i, r, a) { i = i || [], i.length = 0; var s = [Panorama.filters.inPanoDirection(e.position, r, TilePrioritizer.DIRECTION_SCORE_STRICTNESS), Panorama.filters.not(e)], l = [Panorama.scoreFunctions.distanceSquared(e), Panorama.scoreFunctions.direction(e.position, r)], c = common.sortByScore(t.list, s, l); if (c) for (var h = 0; h < c.length && h < a; h++) { var u = c[h].item; i.push(u); } return i; } }, { key: "queueTilesForPanos", value: function queueTilesForPanos(e, t, i, n, r) { for (var o = 0, a = 0; a < t.length; a++) { var s = t[a], l = this.queueTilesForPano(e, i, s, n); if (o += l > 0 ? 1 : 0, r && o >= r) break; } return o; } }, { key: "queueTilesInDirectionForPanos", value: function queueTilesInDirectionForPanos(e, t, i, n, r, o, a, s) { for (var l = 0, c = 0; c < i.length; c++) { var h = i[c], u = this.queueTilesInDirectionForPano(e, t, h, n, o, a); if (l += u > 0 ? 1 : 0, s && l >= s) break; } return l; } }, { key: "canIncludeDescriptor", value: function canIncludeDescriptor(e) { return e.status !== DownloadStatus.Downloading && e.status !== DownloadStatus.Downloaded; } }, { key: "canIncludePano", value: function canIncludePano(e, t) { return !e.isLoaded(t); } }, { key: "setZoomingActive", value: function setZoomingActive(e) { e !== this.zoomingActive && (this.zoomingActive = e); } }], [{ key: "PriorityCriteria", value: function PriorityCriteria(e, t, i, n, o) { this.pano = e; this.cameraPosition = new THREE.Vector3().copy(t); this.cameraDir = new THREE.Vector3().copy(i); this.panoSpaceDir = new THREE.Vector3().copy(n); this.upcomingPanos = o; this.copy = function (e) { this.pano = e.pano; this.cameraPosition.copy(e.cameraPosition); this.cameraDir.copy(e.cameraDir); this.panoSpaceDir.copy(e.panoSpaceDir); this.upcomingPanos = o; }, this.zoomingActive = !1; } }, { key: "appendQueue", value: function appendQueue(e, t) { if (e && t) for (var i = 0; i < t.length; i++) { e.push(t[i]); } } }, { key: "getFOVDotThreshold", value: function getFOVDotThreshold(e) { return Math.cos(THREE.MathUtils.degToRad(e / 2)); } }, { key: "sortPanoTiles", value: function sortPanoTiles(e, t, i) { u$1._panoSpaceDir.copy(i), TileUtils.getRelativeDirection(t.quaternion, u$1._panoSpaceDir), u$1._fovThresholdNarrow = math$1.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV_NARROW), u$1._fovThreshold = math$1.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV), e.sort(u$1); } }, { key: "insertSortedPanoTile", value: function insertSortedPanoTile(e, t, i, r) { u$1._panoSpaceDir.copy(r), TileUtils.getRelativeDirection(i.quaternion, u$1._panoSpaceDir), u$1._fovThresholdNarrow = math$1.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV_NARROW), u$1._fovThreshold = math$1.getFOVDotThreshold(TilePrioritizer.DIRECTIONAL_FOV); for (var o = -1, a = 0; a < e.length; a++) { var s = u$1(t, e[a]); if (s <= 0) { o = a; break; } } if (o === -1) e[e.length] = t;else { for (var h = e.length; h > o; h--) { e[h] = e[h - 1]; } e[o] = t; } } }]); return TilePrioritizer; }(); TilePrioritizer.DIRECTIONAL_FOV = 180; TilePrioritizer.DIRECTIONAL_FOV_NARROW = 120; TilePrioritizer.MAX_SCORED_PANOS_TOCONSIDER = 6; TilePrioritizer.MAX_SCORED_PANOS_TOADD = 2; TilePrioritizer.MAX_UPCOMING_PANOS_TOADD = 3; TilePrioritizer.DIRECTION_SCORE_STRICTNESS = 0.75; var Keys = { ZERO: 48, ONE: 49, TWO: 50, THREE: 51, FOUR: 52, FIVE: 53, SIX: 54, SEVEN: 55, EIGHT: 56, NINE: 57, LEFTARROW: 37, UPARROW: 38, RIGHTARROW: 39, DOWNARROW: 40, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90, SPACE: 32, RETURN: 13, SEMICOLON: 186, PLUSEQUALS: 187, DASHUNDERSCORE: 189, OPENBRACKET: 219 }; if (browser$1.detectFirefox()) { Keys.SEMICOLON = 59; Keys.PLUSEQUALS = 61; Keys.DASHUNDERSCORE = 173; } var ModelManagerEvents = { ModelAdded: 'model-added', ActiveModelChanged: 'active-model-changed' }; function _createSuper$1j(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1j(); 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 _isNativeReflectConstruct$1j() { 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; } } var Snapshot = /*#__PURE__*/function (_View) { _inherits(Snapshot, _View); var _super = _createSuper$1j(Snapshot); function Snapshot(objectSet) { var _this; _classCallCheck(this, Snapshot); _this = _super.call(this, objectSet); _this.panoId = objectSet.panoId; _this.orthoZoom = objectSet.orthoZoom; _this.floorVisibility = objectSet.floorVisibility; _this.thumbUrl = objectSet.thumbUrl; _this.name = objectSet.name; return _this; } _createClass(Snapshot, [{ key: "isPano", value: function isPano() { return this.panoId && '' !== this.panoId; } }]); return Snapshot; }(View); //导览时路径上出现的mesh 现在只用到了currentPanoMarker var ShowPath = /*#__PURE__*/function () { function ShowPath(director, player, controls) { _classCallCheck(this, ShowPath); this.flightStepWalk = function (e, t, i) { var n = 0.001, o = 1, a = 1.2, s = new THREE.Vector3(), h = new THREE.Vector3(), u = function u(e, t) { var i = Math.min(this.player.position.distanceTo(e.position), settings$3.transition.flytimeMaxDistanceThreshold), r = i * settings$3.transition.flytimeDistanceMultiplier + settings$3.transition.flyTime; h.copy(Vectors$1.FORWARD), this.player.getDirection(h), s.copy(t).sub(e.position).normalize(); var l = s.dot(h), u = Math.acos(l), d = u / r; return d > n && (r *= d / n, u < o && (r *= a)), r; }; return function (e, t, i) { if (this.warpInterrupted) i && i();else if (this.activeTransType !== l.WALK) this._clearWarpShading(), this._warpStopFlying(), this.player.spider.draw(), this.placeCpm(), i && i();else if (this.player.currentPano !== e) { var n = { pano: e, lookAtPoint: t, duration: null, maxDistanceOverride: settings$3.warp.walkMaxDist, skipWarpingCheck: !1, constantMoveSpeed: !0 }; n.duration = u.call(this, e, t), this.player.nonInterruptingFlyToPano(n, i); } else i && i(); }; }(); this.warpTravel_WALK = function () { var e = []; return function (t) { var i = this.player.model.panos; e.length = 0; for (var n = null, o = !1, a = 0; a < this.nodes.length; a++) { var s = this.nodes[a], l = i.get(s); a === this.nodes.length - 1; o = n && l.position.distanceTo(n.position) < settings$3.warp.walkMinDist, n && o || (e.push(s), n = l); } o && this.nodes.length > 1 && (e[e.length - 1] = this.nodes[this.nodes.length - 1]); var h = e.length, u = i.get(e[h - 1]), d = new Array(h + 1); d[d.length - 1] = function () { t && t(); }.bind(this); for (var p = h - 1, f = d.length - 1; f > 0; f -= 1) { var g = e[p]; u = i.get(g); var m = new THREE.Vector3(); this.getLookAtForWalkingTourNode(e, p, m), d[f - 1] = this.makeWalkFlightFunc(u, m, d[f]), p--; } d[0](); }; }(); this.getLookAtForWalkingTourNode = function () { var e = new THREE.Vector3(), t = new THREE.Vector3(), i = new THREE.Vector3(), n = new THREE.Vector3(), o = new THREE.Vector3(), a = 0.65, s = 0.75, l = 0.2, c = 0.4, h = 0.2, u = 3; return function (r, d, p) { var f = r.length; if (d >= f) return !1; var g = 1, m = 1; t.set(0, 0, 0), o.set(0, 0, 0); for (var v = null, A = d; A < d + u && !(A >= f); A++) { if (v = this.player.model.panos.get(r[A]), this.getOrientationForWalkingTourNode(r, A, i), A === d && e.copy(i), n.copy(i), A > d) { var y = n.dot(e) < a; g *= y ? l : s, m *= y ? h : c; } i.multiplyScalar(g), t.add(i), o.lerp(v.position, m); } return t.normalize(), p.copy(o), p.add(t), !0; }; }(); this.obj3d = null, this.nodes = [], this.colorHull = [], this.shortPaths = {}, this.floorHull = null, this.cameraHull = null, this.floorPathDistance = 0, this.floorCurvePoints = null, this.floorCurveColors = null, this.camCurvePoints = null, this.warpDestHeroLoc = null, this.warpDestPano = null, this.warpPathPoints = null, this.warpPathLengths = [0], this.warpLength = 0, this.closeWarpDistance = 4, this.UP = Vectors$1.UP.clone(), this.longestStep = 0, this.upcomingTransType = null, this.burnsDir = 1, this.prevNextDist = 0, this.nextI = 0, this.activeTransType = null, this.lastTransType = null, this.bunnyObj = null, this.director = director, this.player = player, this.playerControls = controls, this.modelManager = player.modelManager, this.updateModel(), this.bindEvents(), this.warping = !1, this.waitingToWarp = !1, this.warpInterrupted = !1, this.warpInterruptionBlackoutStyle = null, this.warpInterruptionTravelTime = null; this.pathImg = {}; this.brushPrefs = { linewidth: 7, strokeWidth: 15, cvSegments: 48, paveStep: 0.1, paveWidth: 0.2, lookBlendDist: 3, maxTurn: THREE.MathUtils.degToRad(2) }; this.hintPrefs = { rad: 0.18, width: 0.0125, depth: 0.0625, setBack: -0.04, markRad: 0.25, markInnerRad: 0.16 }; this.init(); } _createClass(ShowPath, [{ key: "init", value: function init() { //this.pathImg.path = common.loadTextureFromCache(config.path);//没用到 this.pathImg.pathEnd = common.loadTextureFromCache(texture.getImageURL('images/pathEnd.png')); //this.pathImg.pathStart = common.loadTextureFromCache(config.pathStart);//没用到 } }, { key: "setScene", value: function setScene(scene) { this.createCpm(scene); //this.createBunnyObj(scene); } }, { key: "updateModel", value: function updateModel() { this.model = this.modelManager.getActiveModel(); } }, { key: "bindEvents", value: function bindEvents() { this.modelManager.on(ModelManagerEvents.ActiveModelChanged, this.updateModel.bind(this)); } }, { key: "pointPathDistance", value: function pointPathDistance(points) { for (var distance = 0, i = 1; i < points.length; i += 1) { distance += points[i - 1].distanceTo(points[i]); } return distance; } }, { key: "pointPathLengths", value: function pointPathLengths(points) { for (var t = [0], i = 1; i < points.length; i += 1) { t.push(t[i - 1] + points[i - 1].distanceTo(points[i])); } return t; } }, { key: "interpAlongPath", value: function interpAlongPath(e, t, i) { var n, o = new THREE.Vector3(), a = t[t.length - 1]; if (i < 1) { n = i * a; for (var s = 1; s < t.length; s += 1) { if (t[s] > n) { var l = (n - t[s - 1]) / (t[s] - t[s - 1]); return o.copy(e[s]), o.sub(e[s - 1]), o.multiplyScalar(l), o.add(e[s - 1]), o; } } } else o.copy(e[e.length - 1]); return o; } }, { key: "pathHeight", value: function pathHeight() { return settings$3.path.height; //this.player.mode !== ViewMode.FLOORPLAN ? settings.path.height : settings.path.outsideHeight //outsideHeight为0.5, 导致floorplan->dollhouse下升高很多 ( 原版也是 ) } }, { key: "createBunnyObj", value: function createBunnyObj(e) { this.bunnyObj || (this.bunnyObj = new THREE.AxesHelper(0.1), this.bunnyObj.visible = settings$3.warp.showBunny), this.bunnyObj.parent && this.bunnyObj.parent.remove(this.bunnyObj), e.add(this.bunnyObj); } }, { key: "createCpm", value: function createCpm(e) { if (!this.currentPanoMarker) { var t = this.makeWaypointObj(this.pathImg.pathEnd, 'Current'); t.material.uniforms.opacity.value = 0, this.currentPanoMarker = { mesh: t, placed: !1 }; } this.currentPanoMarker.mesh.parent && this.currentPanoMarker.mesh.parent.remove(this.currentPanoMarker.mesh), this.placeCpm(), this.currentPanoMarker.mesh.parent || e.add(this.currentPanoMarker.mesh); } }, { key: "placeCpm", value: function placeCpm() { if (settings$3.path.mapGuides && this.player.currentPano && this.player.currentPano.isAligned()) { var e = this.player.currentPano.floor; this.currentPanoMarker.mesh.parent !== this.player.currentPano.floor && (this.currentPanoMarker.mesh.parent && this.currentPanoMarker.mesh.parent.remove(this.currentPanoMarker.mesh), e.add(this.currentPanoMarker.mesh)), this.currentPanoMarker.mesh.position.copy(this.player.currentPano.floorPosition).sub(e.position); /* if(edit && publicObjectSet.editor.mainDesign.editing){//如果底部高度不一致 另说 var mainDesign = publicObjectSet.editor.mainDesign; mainDesign.atRoom && this.currentPanoMarker.mesh.position.setY(mainDesign.rooms[mainDesign.atRoom].bottom); } */ this.currentPanoMarker.mesh.position.y += this.pathHeight(); this.currentPanoMarker.placed = !0; } else { this.popOutCpm(); } } }, { key: "fadeInCpm", value: function fadeInCpm(e) { this.player.mode === Viewmode$1.PANORAMA && this.player.currentPano && !this.player.currentPano.isAligned() || settings$3.path.mapGuides && this.currentPanoMarker.placed && transitions$1.start(lerp.property(this.currentPanoMarker.mesh.material.uniforms.opacity, 'value', 1), e); } }, { key: "fadeOutCpm", value: function fadeOutCpm(e) { transitions$1.start(lerp.property(this.currentPanoMarker.mesh.material.uniforms.opacity, 'value', 0), e); } }, { key: "popInCpm", value: function popInCpm() { settings$3.path.mapGuides && this.currentPanoMarker.placed && this.fadeInCpm(2); } }, { key: "popOutCpm", value: function popOutCpm() { this.fadeOutCpm(2); } /* panoPathDistance(e){ var t = this.model.panos; if (!e || e.length < 2) return 0; for (var i = [], n = 0; n < e.length; n += 1) i.push(t.get(e[n]).floorPosition); return this.pointPathDistance(i) } loadTileTexture(e){ var t = texture.load(e, function(t) { t.wrapS = THREE.RepeatWrapping, t.wrapT = THREE.RepeatWrapping, t.needsUpdate = !0, logger.debug('path texture "' + e + '" is ready') }, function() { logger.error('path texture "' + e + '" failed') }); return t.mapping = THREE.UVMapping, t } */ }, { key: "buildWarpDestinationDescriptor", value: function buildWarpDestinationDescriptor(e, t, i, n, r, o) { var a = { cameraMode: n, position: e, quaternion: t, panoId: i, orthoZoom: o, floorVisibility: r, thumbUrl: null, name: null }; return new Snapshot(a); } }, { key: "buildWarpDestinationDescriptorFromHero", value: function buildWarpDestinationDescriptorFromHero(e) { return this.buildWarpDestinationDescriptor(e.position, e.quaternion, this.getHeroId(e), e.cameraMode, e.floorVisibility, e.orthoZoom); } }, { key: "setWarpDestination", value: function setWarpDestination(e) { this.warpDestHeroLoc = e; } }, { key: "setWarpDestinationByHeroIndex", value: function setWarpDestinationByHeroIndex(e) { var t = this.getHeroDescriptorByHeroIndex(e); return null !== t && (this.setWarpDestination(t), !0); } }, { key: "setWarpDestinationByPano", value: function setWarpDestinationByPano(e, t) { var i = this.model.panos.get(e.id); return !!i && this.setWarpDestinationByPanoId(e.id, t); } }, { key: "setWarpDestinationByPanoId", value: function setWarpDestinationByPanoId(e, t) { var i = this.model.panos.get(e); if (i) { t = t || new THREE.Quaternion(); var n = this.buildWarpDestinationDescriptor(i.position, t, i.id, 'panorama', [], -1); return this.setWarpDestination(n), !0; } return !1; } }, { key: "getHeroDescriptorByHeroIndex", value: function getHeroDescriptorByHeroIndex(e) { var t = objects.play.heroCount(); if (null !== this.warpDestHeroLoc && t < 2) return logger$1.info('ShowPath.getHeroDescriptorByHeroIndex() -> Only one hero location is available.'), this.model.getHeroDescriptorByIndex(0); var hero = this.model.getHeroDescriptorByIndex(e); hero = util.getPlayDataItem(e); var playData = objects.store.getters['guide/plays']; if (playData[e].type == 1) { hero = util.getPlayDataItem(e, 0); } var obj = util.convertHighlight(hero); var i = new Snapshot(obj); if (i) { var n = i.isPano() ? i.panoId : i.cameraMode; logger$1.debug('ShowPath.getHeroDescriptorByHeroIndex() -> New brush/warp destination: "' + n + '" out of ' + t + ' choices.'); } return i; } }, { key: "getHeroDescriptorByPano", value: function getHeroDescriptorByPano(e) { var t = this.model.panos.get(e.id); return t ? this.getHeroDescriptorByPanoId(e.id) : null; } }, { key: "getHeroDescriptorByPanoId", value: function getHeroDescriptorByPanoId(e) { var t = this.getHeroIndexFromPanoId(e); return this.getHeroDescriptorByHeroIndex(t); } }, { key: "getHeroIndexFromPanoId", value: function getHeroIndexFromPanoId(e) { for (var t = 0; t < this.model.heroLocations.length; t++) { var i = this.model.heroLocations[t], n = this.getHeroId(i); if (n && n === e) return t; } return -1; } }, { key: "getHeroPano", value: function getHeroPano(e) { if (null === e) return logger$1.warn('getHeroPano(): no destination'), null; var t = this.getHeroId(e), i = this.model.panos.get(t); return void 0 === i && (i = null, '' !== t && logger$1.debug('unable to find pano "' + t + '"')), i; } }, { key: "getHeroId", value: function getHeroId(e) { return e.panoId; } }, { key: "setWarpDestPano", value: function setWarpDestPano() { return this.warpDestPano = this.getHeroPano(this.warpDestHeroLoc), this.warpDestPano; } /* brushToWarpPano(e,t){ if (this.discardPathObject(), !this.setWarpDestPano()) return !1; if (this.warpDestHeroLoc.cameraMode !== ViewMode.PANORAMA && logger.warn("Can only brush from pano to pano"), !this.warpDestPano) return logger.info("No brush"), !1; if (!this.player.currentPano) return logger.debug("No current pano, visibility undefined"), !1; if (!this.warpDestPano) return logger.info("No wPano, visibility undefined"), !1; if (!this.warpDestPano.isAligned()) return logger.debug("Cannot brush to unaligned pano"), !1; var i = (e === WarpStyle.STD || e === WarpStyle.WALK) && settings.path.mapGuides , n = !0; if (this.player.currentPano.id === this.warpDestPano.id) logger.debug("Already at destination pano"); else { this.nodes = this.findShortestPath(this.player.currentPano, this.warpDestPano), n = void 0 === this.nodes || null === this.nodes || this.nodes.length < 1, this.obj3d = new THREE.Object3D, logger.debug('Brushing from "' + this.player.currentPano.id + '" to "' + this.warpDestPano.id + '" (' + (this.nodes ? this.nodes.length : 0) + ")"), n ? (logger.info('No "walkable" route, using fall-back warp style transition'), e = t) : (this.setPathHulls(this.nodes), this.setFloorCurves(), i && ("chevron" === settings.path.style ? this.obj3d.add(this.drawPathPavement(this.floorCurvePoints)) : "ribbon" === settings.path.style && this.obj3d.add(this.drawPathRibbon(this.floorCurvePoints, this.floorCurveColors)))), this.player.currentPano.floor.add(this.obj3d); var o = this.player.mode === ViewMode.DOLLHOUSE || this.player.mode === ViewMode.FLOORPLAN , s = e === WarpStyle.STD; if (!n && (i || s)) { if (o) { var h = this.makeStartMarker(this.floorHull[0], this.floorCurvePoints); this.obj3d.add(h) } var u = this.makeEndMarker(this.floorHull[this.floorHull.length - 1]); this.obj3d.add(u) } this.appearSlow() } return this.upcomingTransType = e, !n } */ }, { key: "findShortestPath", value: function findShortestPath(e, t) { if (!e || !t) return null; var i = settings$3.warp.walkExtraPanosDistance, n = e.id + ':' + t.id + ':' + i; if (this.shortPaths.hasOwnProperty(n)) return this.shortPaths[n] ? this.shortPaths[n].slice() : null; var r = t.id + ':' + e.id + ':' + i; if (this.shortPaths.hasOwnProperty(r)) return this.shortPaths[r] ? this.shortPaths[r].slice().reverse() : null; var o = this.model.panos.aStarSearch(e, t); return this.model.panos.includeNodesNearPath(o, i), this.shortPaths[n] = o ? o.slice() : null, o; } }, { key: "makePathHulls", value: function makePathHulls(e) { var t, i, n, r, o, a = 0, s = [], l = [], h = [], u = this.model.panos; t = u.get(e[0]), r = t.floor.floorIndex; for (var d = 0; d < e.length; d += 1) { t = u.get(e[d]), i = t.floorPosition.clone().sub(this.model.position), i.y += this.pathHeight(), s.push(i), l.push(t.position.clone()), n = t.floor.floorIndex, h.push(n > r ? settings$3.path.colorUp : n < r ? settings$3.path.colorDown : settings$3.path.color), d > 0 && (o = l[d].distanceTo(l[d - 1]), o > a && (a = o)); } return a > this.longestStep && (this.longestStep = a, logger$1.debug('path contains ' + a + ' meter segment')), { floor: s, camera: l, color: h }; } }, { key: "makeFloorCurves", value: function makeFloorCurves(points, colors, i) { var radius = this.player.mode === Viewmode$1.PANORAMA ? settings$3.path.waypointIndoorRadius : settings$3.path.waypointRadius, distance = this.pointPathDistance(points) - 2 * radius, s = points.slice(0), l = s[1].clone().sub(s[0]); l.y = 0, l.normalize().multiplyScalar(radius), s[0] = new THREE.Vector3().copy(s[0]).add(l), l = s[s.length - 2].clone().sub(s[s.length - 1]), l.y = 0, l.normalize().multiplyScalar(radius), s[s.length - 1] = new THREE.Vector3().copy(s[s.length - 1]).add(l); var h = new THREE.CatmullRomCurve3(s), u = Math.floor(distance / i); u = 4 * Math.floor(u / 4), u = Math.max(4, u); for (var d, p, f, g = h.getSpacedPoints(u), m = [], v = new THREE.Vector3(), A = 0; A < g.length; A += 1) { f = 0, d = g[A].distanceTo(points[0]); for (var y = 1; y < points.length; y += 1) { v.copy(g[A]).sub(points[y]), v.y *= 4, p = v.length(), p < d && (f = y); } m.push(colors[f]); } return { distance: distance, points: g, colors: m }; } }, { key: "makeCameraCurvePoints", value: function makeCameraCurvePoints(points, t) { var distance = this.pointPathDistance(points), n = new THREE.CatmullRomCurve3(points); return n.getSpacedPoints(Math.max(2, Math.floor(distance / t))); } }, { key: "setPathHulls", value: function setPathHulls(e) { var t = this.makePathHulls(e); this.floorHull = t.floor, this.cameraHull = t.camera, this.colorHull = t.color; } }, { key: "setFloorCurves", value: function setFloorCurves() { var e = this.makeFloorCurves(this.floorHull, this.colorHull, this.brushPrefs.paveStep); this.floorPathDistance = e.distance, this.floorCurvePoints = e.points, this.floorCurveColors = e.colors; } }, { key: "setCameraCurvePoints", value: function setCameraCurvePoints() { this.camCurvePoints = this.makeCameraCurvePoints(this.cameraHull, settings$3.warp.stepFactor * this.brushPrefs.paveStep); } }, { key: "chooseWarpPath", value: function chooseWarpPath(e) { var t, i, n, o = this.playerControls.cameras[Viewmode$1.PANORAMA]; if (this.player.currentPano === this.warpDestPano || !e) { this.warpPathPoints = null; this.warpLength = 0; return !1; } this.nodes = this.findShortestPath(this.player.currentPano, this.warpDestPano); this.setPathHulls(this.nodes); if (void 0 === this.nodes || null === this.nodes || this.nodes.length < 1) { logger$1.debug('warp path to unreachable node'); t = this.warpDestPano.position.clone().sub(o.position); i = t.clone().negate(); t.multiplyScalar(0.15).add(o.position); i.multiplyScalar(0.15).add(this.warpDestPano.position); t.y = o.position.y; i.y = this.warpDestPano.position.y; n = new THREE.CubicBezierCurve3(o.position.clone(), t, i, this.warpDestPano.position.clone()); this.warpPathPoints = n.getSpacedPoints(this.brushPrefs.cvSegments); } else { logger$1.debug('follow warp path (path distance was ' + this.nodes.length + ' nodes, ' + this.floorPathDistance + ')'); this.setCameraCurvePoints(); this.warpPathPoints = this.camCurvePoints.slice(0); } this.warpLength = 0, this.warpPathLengths = [0]; for (var s = new THREE.Vector3(), l = new THREE.Vector3(), h = Math.cos(THREE.MathUtils.degToRad(settings$3.warp.minBrakeAngle)), u = Math.cos(THREE.MathUtils.degToRad(settings$3.warp.maxBrakeAngle)), d = 1; d < this.warpPathPoints.length; d += 1) { s.copy(this.warpPathPoints[d - 1]).sub(this.warpPathPoints[d]); var p = s.length(); s.y *= settings$3.warp.climbEffort; var f = s.length() / p; if (d > 1) { s.setY(0).normalize(), l.copy(this.warpPathPoints[d - 2]).sub(this.warpPathPoints[d - 1]).setY(0).normalize(); var g = Math.min(1, s.dot(l)), m = 1 + (settings$3.warp.brakeStrength - 1) * (1 - THREE.MathUtils.smoothstep(g, u, h)); f = Math.max(m, f); } this.warpLength += p * f, this.warpPathLengths[d] = this.warpLength; } return !0; } }, { key: "drawPathRibbon", value: function drawPathRibbon(e, t) { this.bunnyObj.visible = settings$3.warp.showBunny; for (var i = 0.6 * settings$3.path.ribbonWidth * 0.5, n = new THREE.Vector3(), o = new THREE.Vector3(0, this.pathHeight(), 0), l = new THREE.BufferGeometry(), h = new THREE.Vector3(), u = 0; u < e.length; u += 1) { h.copy(e[u]), 0 === u ? h.sub(e[u + 1]) : h.sub(e[u - 1]).negate(), h.normalize(), n.crossVectors(h, Vectors$1.UP), n.multiplyScalar(i); var d = new THREE.Vector3().copy(e[u]).add(o); d.sub(n), l.vertices.push(d), d = new THREE.Vector3().copy(e[u]).add(o), d.add(n), l.vertices.push(d); } var p, f = 0; for (u = 0; u < e.length - 1; u += 1) { var g = 2 * u, v = f; f += e[u + 1].distanceTo(e[u]); var y = f, C = t[u], I = t[u + 1]; p = new THREE.Face3(g, g + 1, g + 2), p.vertexColors = [new THREE.Color(C), new THREE.Color(C), new THREE.Color(I)], l.faces.push(p), l.faceVertexUvs[0].push([new THREE.Vector2(0, v), new THREE.Vector2(1, v), new THREE.Vector2(0, y)]), p = new THREE.Face3(g + 2, g + 1, g + 3), p.vertexColors = [new THREE.Color(I), new THREE.Color(C), new THREE.Color(I)], l.faces.push(p), l.faceVertexUvs[0].push([new THREE.Vector2(0, y), new THREE.Vector2(1, v), new THREE.Vector2(1, y)]); } l.computeFaceNormals(), l.computeVertexNormals(); var E, b; this.player.mode === Viewmode$1.PANORAMA ? (b = THREE.UniformsUtils.clone(shaders.ribbon.uniforms), b.map.value = this.pathImg.path, b.opacity.value = 0, b.color.value.set(settings$3.path.color), E = new THREE.RawShaderMaterial({ side: THREE.DoubleSide, depthWrite: !1, transparent: !0, vertexShader: shaders.ribbon.vertexShader, fragmentShader: shaders.ribbon.fragmentShader, uniforms: b, name: 'ribbonT', opacity: 0 })) : E = new THREE.MeshBasicMaterial({ color: 16777215, side: THREE.DoubleSide, name: 'ribbonOut', vertexColors: THREE.VertexColors }); var _ = new THREE.Mesh(l, E); return _.name = 'ribbon', this.player.mode === Viewmode$1.PANORAMA && (_.renderOrder = RenderOrder.ribbon), _; } }, { key: "drawPathPavement", value: function drawPathPavement(e) { for (var t, i = 0.25, n = new THREE.Vector3(), o = new THREE.BufferGeometry(), s = new THREE.Vector3(), l = 0; l < e.length; l += 1) { s.copy(e[l]), 0 === l ? s.sub(e[l + 1]).negate() : s.sub(e[l - 1]), s.normalize(), n.crossVectors(s, Vectors$1.UP), n.multiplyScalar(this.brushPrefs.paveWidth), t = new THREE.Vector3().copy(e[l]), t.sub(n), o.vertices.push(t), o.vertices.push(new THREE.Vector3().copy(e[l])), t = new THREE.Vector3().copy(e[l]), t.add(n), o.vertices.push(t); } var h, u, d; for (l = 0; l < e.length - 1; l += 1) { h = 3 * l + 1, u = l * i, d = u + i, o.faces.push(new THREE.Face3(h - 1, h, h + 3)), o.faceVertexUvs[0].push([new THREE.Vector2(0, u), new THREE.Vector2(0.5, u), new THREE.Vector2(0.5, d)]), o.faces.push(new THREE.Face3(h + 3, h + 2, h - 1)), o.faceVertexUvs[0].push([new THREE.Vector2(0.5, d), new THREE.Vector2(0, d), new THREE.Vector2(0, u)]), o.faces.push(new THREE.Face3(h + 3, h, h + 1)), o.faceVertexUvs[0].push([new THREE.Vector2(0.5, d), new THREE.Vector2(0.5, u), new THREE.Vector2(1, u)]), o.faces.push(new THREE.Face3(h + 3, h + 1, h + 4)), o.faceVertexUvs[0].push([new THREE.Vector2(0.5, d), new THREE.Vector2(1, u), new THREE.Vector2(1, d)]); } var p = this.player.mode === Viewmode$1.PANORAMA ? new THREE.MeshBasicMaterial({ color: settings$3.path.color, side: THREE.DoubleSide, transparent: !0, depthWrite: !1, opacity: 0, name: 'paveT', map: this.pathImg.path }) : new THREE.MeshBasicMaterial({ color: settings$3.path.color, side: THREE.DoubleSide, transparent: !0, depthWrite: !1, opacity: 1, name: 'paveO', map: this.pathImg.path }); return new THREE.Mesh(o, p); } }, { key: "makeWaypointObj", value: function makeWaypointObj(e, t) { var n = this.player.mode === Viewmode$1.PANORAMA ? settings$3.path.waypointIndoorRadius : settings$3.path.waypointRadius, o = this.pathHeight(), i = new THREE.CylinderGeometry(n, n, o, 32); // i.setAttribute('position', new THREE.BufferAttribute(new Float32Array([-n, o, n, -n, o, -n, n, o, -n, n, o, n], 0, 3), 3)) // i.setAttribute('uv', new THREE.BufferAttribute(new Float32Array([0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0], 0, 2), 2)) // i.setIndex(new THREE.BufferAttribute(new Uint32Array([0, 1, 2, 2, 3, 0], 0, 1), 1)) var s = THREE.UniformsUtils.clone(shaders.waypoint.uniforms); s.map.value = e, s.opacity.value = 0, s.color.value.set(settings$3.path.color); var l = { side: THREE.DoubleSide, depthWrite: !1, depthTest: false, //许钟文 加 transparent: !0, vertexShader: shaders.waypoint.vertexShader, fragmentShader: shaders.waypoint.fragmentShader, uniforms: s, name: 'waypoint', opacity: 0 }; this.player.mode !== Viewmode$1.PANORAMA && (l.depthTest = !1, l.name = 'wayPtOut'); var h = new THREE.RawShaderMaterial(l), u = new THREE.Mesh(i, h); u.renderOrder = RenderOrder.panoMarker; //.ribbon//许钟文加 否则在编辑模型时会时隐时现 return u.name = t, u; } }, { key: "makeStartMarker", value: function makeStartMarker(e, t) { var i = new THREE.Vector3().copy(t[1]).sub(t[0]); i.y = 0, i.normalize(); var n = Math.acos(i.x), o = this.makeWaypointObj(this.pathImg.pathStart, 'Start'); return o.rotateOnAxis(new THREE.Vector3(0, 1, 0), n), o.position.copy(e), o; } }, { key: "makeEndMarker", value: function makeEndMarker(e) { var t = this.makeWaypointObj(this.pathImg.pathEnd, 'End'), i = this.model.panos.get(this.nodes[0]).floor.floorIndex, n = this.model.panos.get(this.nodes[this.nodes.length - 1]).floor.floorIndex; return i < n ? t.material.uniforms.color.value.set(settings$3.path.colorUp) : i > n && t.material.uniforms.color.value.set(settings$3.path.colorDown), t.position.copy(e), t; } }, { key: "pathClean", value: function pathClean(e) { if (e) { for (var t in e.children) { this.pathClean(e.children[t]); } e.geometry && e.geometry.dispose(), e.material && e.material.dispose(); } } }, { key: "discardPathObject", value: function discardPathObject() { if (this.obj3d) { var e = this.obj3d.parent; e && e.remove(this.obj3d), this.pathClean(this.obj3d); } this.obj3d = null, this.popInCpm(); } }, { key: "discardSlow", value: function discardSlow() { if (this.obj3d) { if (this.player.mode !== Viewmode$1.PANORAMA) return void this.discardPathObject(); for (var e, t = this, i = 0, n = function () { this.discardPathObject(); }.bind(this), r = 0; r < t.obj3d.children.length; r += 1) { e = t.obj3d.children[r], void 0 !== e.material && e.material.transparent === !0 && (void 0 !== e.material.uniforms ? transitions$1.start(lerp.property(e.material.uniforms.opacity, 'value', 0), settings$3.path.fadeOutTime, n, 0, easing[settings$3.warp.blendEasing]) : transitions$1.start(lerp.property(e.material, 'opacity', 0), settings$3.path.fadeOutTime, n, 0, easing[settings$3.warp.blendEasing]), i += 1, n = null); } 0 === i && this.discardPathObject(), this.player.mode !== Viewmode$1.PANORAMA && this.fadeInCpm(settings$3.path.fadeInTime - 3); } } }, { key: "appearSlow", value: function appearSlow() { var e, t = this; this.fadeOutCpm(settings$3.path.fadeInTime); for (var i = this.player.mode === Viewmode$1.PANORAMA ? settings$3.path.opacity : 1, n = 0; n < t.obj3d.children.length; n += 1) { e = t.obj3d.children[n], void 0 !== e.material && e.material.transparent === !0 && (void 0 !== e.material.uniforms ? transitions$1.start(lerp.property(e.material.uniforms.opacity, 'value', i), settings$3.path.fadeInTime, null, 0, easing[settings$3.warp.blendEasing]) : transitions$1.start(lerp.property(e.material, 'opacity', i), settings$3.path.fadeInTime, null, 0, easing[settings$3.warp.blendEasing])); } } }, { key: "update", value: function update() { this.obj3d && this.obj3d.updateMatrixWorld(); } }, { key: "calcBurnsAmount", value: function calcBurnsAmount(e) { var t = THREE.MathUtils.degToRad(settings$3.warp.burnsAngle); if (this.player.mode === Viewmode$1.PANORAMA) { var i = this.burnsDir * t; if (this.upcomingTransType === WarpStyle.BLACK) return i; var n = e; if (null === n) return logger$1.warn('Transition request for non-highlight'), i; var o = this.getHeroDescriptorByHeroIndex(n); if (null === o) return i; if (!o.isPano()) return i; var s = this.getHeroPano(o), h = this.playerControls.cameras[Viewmode$1.PANORAMA], u = Vectors$1.FORWARD.clone().applyQuaternion(h.quaternion).setY(0).normalize(), d = Math.min(THREE.MathUtils.degToRad(settings$3.warp.minBurnsAngle), t), p = function p(e) { var i = Math.acos(Math.min(1, e.dot(u))), n = new THREE.Vector3().crossVectors(u, e); return Math.max(d, Math.min(Math.abs(i), t)) * Math.sign(n.y); }; if (s === this.player.currentPano) return i = p(Vectors$1.FORWARD.clone().applyQuaternion(o.quaternion).setY(0).normalize()); var f = this.findShortestPath(this.player.currentPano, s); if (void 0 === f || null === f || f.length < 1) return logger$1.debug('Empty path ahead...'), i; var g = this.makePathHulls(f), m = new THREE.CatmullRomCurve3(g.camera), v = Math.min(0.1, settings$3.warp.lookAheadDist / m.getLength()); return i = p(m.getPointAt(v).clone().sub(h.position).setY(0).normalize()); } return this.player.mode === Viewmode$1.DOLLHOUSE ? 0.02 * this.burnsDir : this.burnsDir; } }, { key: "waitNextStep", value: function waitNextStep(e, t) { var i = settings$3.warp.tourStepDelay; i || (i = this.lastTransType === WarpStyle.BLACK ? constants.tourStepDelaySlideShow : constants.tourStepDelayDefault); var n = new THREE.Euler(), o = new THREE.Vector3(); logger$1.debug('Starting wait: ' + (void 0 !== t)); var s = this.calcBurnsAmount(e), h = function () { this.endWarpState(), this.player.mode === Viewmode$1.DOLLHOUSE && (this.playerControls.cameras[Viewmode$1.DOLLHOUSE].controls.rotationAcceleration.x = 0), t && t(); }.bind(this), u = function (e, t) { if (this.warpInterrupted) return h(), !0; var r = t || 1e3 / 60; if (settings$3.warp.doBurns) if (this.player.mode === Viewmode$1.PANORAMA) { var camera = this.playerControls.cameras[Viewmode$1.PANORAMA]; n.setFromQuaternion(WarpcameraStyle.quaternion, settings$3.warp.eOrder); var u = r * s / i; n.y += u, o.set(0, 0, -1), o.applyEuler(n), o.add(camera.position), camera.controls.lookAt(o), camera.controls.lookVector.copy(o), camera.lookAt(o); } else this.player.mode === Viewmode$1.DOLLHOUSE ? this.playerControls.controls[Viewmode$1.DOLLHOUSE].rotationAcceleration.x = s : this.playerControls.controls[Viewmode$1.FLOORPLAN].absoluteScale *= 0.9996; }.bind(this); this.startWarpState(), transitions$1.start(u, i, h, 0, easing.easeInOutQuad, 'wait'); } }, { key: "warpToNonPano", value: function warpToNonPano(e) { if (this.discardPathObject(), this.warpDestHeroLoc.cameraMode === Viewmode$1.DOLLHOUSE || this.warpDestHeroLoc.cameraMode === Viewmode$1.FLOORPLAN) { var t = function () { e && e(); }.bind(this); this.player.flyToNewMode({ mode: this.warpDestHeroLoc.cameraMode, duration: settings$3.warp.outsideTime, warpDest: this.warpDestHeroLoc, callback: t, force: !0 }); } else logger$1.warn('no warp destination!!!'), e && e(); } }, { key: "_resetWarpShaderParams", value: function _resetWarpShaderParams(e) { this.player.mode === Viewmode$1.PANORAMA && (void 0 !== e.material.uniforms.blackout && (e.material.uniforms.blackout.value = 0), void 0 !== e.material.uniforms.modelAlpha && (e.material.uniforms.modelAlpha.value = 0)); } }, { key: "_clearWarpShading", value: function _clearWarpShading() { for (var e = this.model.chunks, t = 0; t < e.length; t += 1) { this._resetWarpShaderParams(e[t]), e[t].visible = !0; } this._resetWarpShaderParams(this.model.skybox); } }, { key: "_warpStopFlying", value: function _warpStopFlying() { this.activeTransType = null, this.placeCpm(); } }, { key: "_wrapupTravelOnlyBits", value: function _wrapupTravelOnlyBits() { this._warpStopFlying(), this.warpPathPoints && (this.player.currentPano.exit(), this.warpDestPano.enter(), this.player.currentPano = this.warpDestPano), //this.player.spider.draw(), this.placeCpm(); } }, { key: "_wrapupTravel", value: function _wrapupTravel(e) { this._wrapupTravelOnlyBits(), this.warpCameraAim(e); } }, { key: "_wrapupWarpShading", value: function _wrapupWarpShading(e) { this._clearWarpShading(), this._wrapupTravel(e); } }, { key: "wrapupWarpShadingOnly", value: function wrapupWarpShadingOnly(e, t) { t !== BlackoutStyle$1.END && this._clearWarpShading(), this._wrapupTravelOnlyBits(), this.upcomingTransType = null, e && e(); } }, { key: "_warpCameraAim", value: function _warpCameraAim(e, t) { var i = this.warpDestHeroLoc.quaternion, n = this.playerControls.cameras[Viewmode$1.PANORAMA], o = new THREE.Vector3(0, 0, 1).applyQuaternion(i).normalize(), s = new THREE.Vector3(0, 0, 1).applyQuaternion(n.quaternion).normalize(), l = s.dot(o), u = THREE.MathUtils.radToDeg(Math.acos(l)), f = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder).setFromQuaternion(i, settings$3.warp.eOrder), g = new THREE.Euler().setFromQuaternion(n.quaternion, settings$3.warp.eOrder), m = new THREE.Euler(f.x - g.x, f.y - g.y, f.z - g.z, settings$3.warp.eOrder); m.y = math$1.constrainedTurn(m.y), this.burnsDir = Math.sign(m.y); var v = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder), A = new THREE.Vector3(), C = function (e, t) { return !!this.warpInterrupted || (v.x = g.x + e * m.x, v.y = g.y + e * m.y, v.z = g.z + e * m.z, A.set(0, 0, -1), A.applyEuler(v), A.add(n.position), n.controls.lookAt(A), n.controls.lookVector.copy(A), void n.lookAt(A)); }.bind(this); if (u > settings$3.warp.minRotation) { return transitions$1.start(C, e, t, 0, easing[settings$3.warp.movementEasing]); } else { logger$1.debug('Aim angle only is ' + u.toPrecision(3) + ' degrees, skipping explicit re-aim'); return void (t && t()); } } }, { key: "_warpBendAim", value: function _warpBendAim(e, t, i, n) { var o = n || 0, s = this.playerControls.cameras[Viewmode$1.PANORAMA], l = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder).setFromQuaternion(this.warpDestHeroLoc.quaternion, settings$3.warp.eOrder), u = new THREE.Euler().setFromQuaternion(s.quaternion, settings$3.warp.eOrder), f = new THREE.Euler(l.x - u.x, l.y - u.y, l.z - u.z, settings$3.warp.eOrder); f.y = math$1.constrainedTurn(f.y); var g = Math.min(THREE.MathUtils.degToRad(settings$3.warp.softBendTilt), Math.abs(f.x)); f.x = g * Math.sign(f.x), g = Math.min(THREE.MathUtils.degToRad(Math.max(0, settings$3.warp.softBendAngle)), g), this.burnsDir = Math.sign(f.y), g *= Math.sign(f.y), f.y = g; var m = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder), v = new THREE.Vector3(), A = function (e, t) { if (e < 0.5) m.x = u.x + e * f.x, m.y = u.y + e * f.y, m.z = u.z + e * f.z;else { var i = (1 - e) * settings$3.warp.softBendEnd; m.x = l.x - i * f.x, m.y = l.y - i * f.y, m.z = l.z - i * f.z; } v.set(0, 0, -1), v.applyEuler(m), v.add(s.position), s.controls.lookAt(v), s.controls.lookVector.copy(v), s.lookAt(v); }.bind(this); return transitions$1.start(A, t, i, o, easing[settings$3.warp.movementEasing]); } }, { key: "_warpStepCameraAim", value: function _warpStepCameraAim(e, t, i) { var n = this.playerControls.cameras[Viewmode$1.PANORAMA], o = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder).setFromQuaternion(this.warpDestHeroLoc.quaternion, settings$3.warp.eOrder), s = new THREE.Euler().setFromQuaternion(n.quaternion, settings$3.warp.eOrder), l = new THREE.Euler(o.x - s.x, o.y - s.y, o.z - s.z, settings$3.warp.eOrder); l.y = math$1.constrainedTurn(l.y), this.burnsDir = Math.sign(l.y); var u = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder), f = new THREE.Vector3(), g = function (e, t) { e < 0.5 ? u.copy(s) : u.copy(o), f.set(0, 0, -1), f.applyEuler(u), f.add(n.position), n.controls.lookAt(f), n.controls.lookVector.copy(f), n.lookAt(f); }.bind(this); return transitions$1.start(g, t, i, 0, easing[settings$3.warp.movementEasing]); } }, { key: "setBurnsDir", value: function setBurnsDir() { var e = this.playerControls.cameras[Viewmode$1.PANORAMA], t = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder).setFromQuaternion(this.warpDestHeroLoc.quaternion, settings$3.warp.eOrder), i = new THREE.Euler().setFromQuaternion(e.quaternion, settings$3.warp.eOrder), n = new THREE.Euler(t.x - i.x, t.y - i.y, t.z - i.z, settings$3.warp.eOrder); n.y = math$1.constrainedTurn(n.y), this.burnsDir = Math.sign(n.y); } }, { key: "stepWarpPath", value: function stepWarpPath(firstPos, e /* t */ ) { //black过渡时的camera位置过渡 var i = this.playerControls.cameras[Viewmode$1.PANORAMA]; var n = this.warpPathPoints ? this.warpPathPoints[0] : firstPos; //xzw add firstPos if (!n) { return i.position.copy(this.warpDestPano.position), !0; } /* if (!this.warpPathPoints) { i.position.copy(this.warpDestPano.position) return !0 } */ var o = this.warpDestPano.position; if (null !== this.nodes && this.cameraHull && this.cameraHull.length > 1) { var s = new THREE.Vector3(); e < 0.5 ? s.copy(this.cameraHull[1]).sub(n).normalize().multiplyScalar(settings$3.warp.softPushDist * e).add(n) : s.copy(this.cameraHull[this.cameraHull.length - 2]).sub(o).normalize().multiplyScalar(settings$3.warp.softPushDist * settings$3.warp.softPushEnd * (1 - e)).add(o); i.position.copy(s); } else { e < 0.5 ? i.position.copy(n) : i.position.copy(o); } } }, { key: "interruptAndFastForward", value: function interruptAndFastForward(e, t) { this.warping && (this.warpInterrupted = !0, this.warpInterruptionBlackoutStyle = e, this.warpInterruptionTravelTime = t, null !== this.warpInterruptionBlackoutStyle && void 0 !== this.warpInterruptionBlackoutStyle || (this.warpInterruptionBlackoutStyle = BlackoutStyle$1.MIDDLE), null !== this.warpInterruptionTravelTime && void 0 !== this.warpInterruptionTravelTime || (this.warpInterruptionTravelTime = settings$3.minWarpTime)); } }, { key: "warpCameraAim", value: function warpCameraAim(e) { var t = settings$3.warp.minWarpTime; if (this.upcomingTransType === WarpStyle.BLACK) t = settings$3.warp.teleportTime;else { var i = this.playerControls.cameras[Viewmode$1.PANORAMA], n = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder).setFromQuaternion(this.warpDestHeroLoc.quaternion, settings$3.warp.eOrder), o = new THREE.Euler().setFromQuaternion(i.quaternion, settings$3.warp.eOrder), s = new THREE.Euler(n.x - o.x, n.y - o.y, n.z - o.z, settings$3.warp.eOrder); s.y = math$1.constrainedTurn(s.y); var u = 1e3 * Math.abs(s.y) / THREE.MathUtils.degToRad(settings$3.warp.maxAimPerSec); t = Math.max(t, u); } var d = function () { this._warpStopFlying(), this.discardSlow(), e && e(); }.bind(this); this._warpCameraAim(t, d); } }, { key: "warpCommonParameters", value: function warpCommonParameters(e, t, i, n) { this.model.skybox.material.uniforms.blackout.value = n; var r = lerp.uniform(this.model.skybox, 'progress', 1), o = lerp.allUniforms(this.model.chunks, 'progress', 1), a = !1, s = function () { if (this.warpInterrupted) return a = !0, !0; }.bind(this), l = function (e, t) { return i && a ? (this.model.skybox.material.uniforms.progress.value = 0, !0) : void r(e, t); }.bind(this), h = function (e, t) { return i && a ? (o(0), !0) : void o(e, t); }.bind(this); transitions$1.start(s, e, null, t, null, 'safeHaltWatch'), transitions$1.start(l, e, null, t, easing[settings$3.warp.blendEasing], 'skyboxProgress'), transitions$1.start(h, e, null, t, easing[settings$3.warp.blendEasing], 'chunkProgress'); } }, { key: "warpTravel_STD", value: function warpTravel_STD(e) { var t, i = Math.min(settings$3.warp.lookAheadMax, settings$3.warp.lookAheadDist / this.warpLength), n = this.playerControls.cameras[a.PANORAMA], o = (Math.min(0.25, 3 / this.warpLength), Math.min(0.35, 7 / this.warpLength)), s = new THREE.Euler(0, 0, 0, settings$3.warp.eOrder), f = new THREE.Vector3(), m = new THREE.Euler().setFromQuaternion(n.quaternion, settings$3.warp.eOrder), v = new THREE.Euler().copy(m), C = n.position.clone(), E = new THREE.Matrix4(), b = new THREE.Euler(), w = settings$3.warp.minWarpTime; w += this.warpLength * settings$3.warp.timePerMeter, settings$3.warp.flySpeed > 0.01 && (w = 1e3 * this.warpLength / settings$3.warp.flySpeed); var _ = !1, T = this.warpDestHeroLoc.quaternion, x = new THREE.Vector3(0, 0, -1).applyQuaternion(T).normalize(), S = this.warpPathPoints[this.warpPathPoints.length - 1].clone().sub(this.warpPathPoints[this.warpPathPoints.length - 2]).normalize(), M = S.dot(x), R = THREE.MathUtils.radToDeg(Math.acos(M)), P = function P(e) { var t = o, i = THREE.MathUtils.smoothstep(e, 0, t) * (1 - THREE.MathUtils.smoothstep(e, 1 - t, 1)); return i; }, O = function () { return E.lookAt(C, t, Vectors$1.UP), s.setFromRotationMatrix(E, settings$3.warp.eOrder), m.setFromQuaternion(n.quaternion, settings$3.warp.eOrder), b.set(s.x - m.x, s.y - m.y, s.z - m.z, settings$3.warp.eOrder), math$1.constrainedTurn(b.y); }.bind(this), L = function (e, t) { if (this.warpInterrupted) return _ = !0, !0; }.bind(this), D = function (e, t) { return _ || !this.warpPathPoints ? (effects.blur(0), !0) : void effects.blur(e); }.bind(this), N = lerp.allUniforms(this.model.chunks, 'modelAlpha', 1), B = function (e, t) { return _ || !this.warpPathPoints ? (N(0), !0) : void N(e, t); }.bind(this), F = function (e, t) { if (!this.warpPathPoints) return n.position.copy(this.warpDestPano.position), !0; if (_) return !0; var i = this.interpAlongPath(this.warpPathPoints, this.warpPathLengths, e); n.position.copy(i), C = this.interpAlongPath(this.warpPathPoints, this.warpPathLengths, 0.99 * e); }.bind(this), V = function (e, n) { return this.warpPathPoints ? !!_ || void (t = this.interpAlongPath(this.warpPathPoints, this.warpPathLengths, Math.min(e + i, 1))) : (logger$1.debug('Lost bunny.'), !0); }.bind(this), U = function (e, o) { if (_) return logger$1.debug('>>>> Walkthrough interupted at t=' + e), !0; if (!this.warpPathPoints) return !0; var a = this.warpLength * e, l = THREE.MathUtils.smoothstep(a, 0, this.brushPrefs.lookBlendDist), u = THREE.MathUtils.smoothstep(a, this.warpLength - this.brushPrefs.lookBlendDist, this.warpLength); settings$3.warp.matchCam && (l *= 1 - u), E.lookAt(C, t, Vectors$1.UP), s.setFromRotationMatrix(E, settings$3.warp.eOrder), m.setFromQuaternion(n.quaternion, settings$3.warp.eOrder), b.set(s.x - m.x, s.y - m.y, s.z - m.z, settings$3.warp.eOrder), b.y = math$1.constrainedTurn(b.y), s.x = m.x + l * b.x, s.y = m.y + l * b.y, s.z = m.z + l * b.z, b.set(s.x - v.x, s.y - v.y, s.z - v.z, settings$3.warp.eOrder), b.y = math$1.constrainedTurn(b.y); var d = THREE.MathUtils.degToRad(settings$3.warp.maxTurnPerSec) * o / 1e3; b.y = Math.sign(b.y) * Math.min(d, Math.abs(b.y)), v.x = v.x + b.x * settings$3.warp.turnFriction, v.y = v.y + b.y * settings$3.warp.turnFriction, v.z = v.z + b.z * settings$3.warp.turnFriction, v.x = Math.max(THREE.MathUtils.degToRad(settings$3.warp.minDownAngle), v.x); var p = t.clone().sub(C).normalize(); if (R < settings$3.warp.maxAimRotation && u > 0) { var g = 1 - u; p.x = p.x * g + u * S.x, p.y = p.y * g + u * S.y, p.z = p.z * g + u * S.z, p.normalize(); } this.bunnyObj.position.copy(n.position).add(p), f.set(0, 0, -1).applyEuler(v).normalize(), f.multiplyScalar(8), f.add(n.position), e > 1 - i && settings$3.warp.matchCam || (n.controls.lookAt(f), n.controls.lookVector.copy(f), n.lookAt(f)); }.bind(this), k = function () { _ ? (this.discardSlow(), this.upcomingTransType = l.BLACK, this.warpTravel_BLACK(-0.5, this.warpInterruptionTravelTime, BlackoutStyle$1.BEGINNING, e)) : this._wrapupWarpShading(e); }.bind(this); V(0); var H = settings$3.warp.motionLeadTime + 1e3 * Math.abs(O()) / THREE.MathUtils.degToRad(settings$3.warp.maxTurnPerSec); w += H; var G = H / w; this.warpCommonParameters(w, G, !0, BlackoutStyle$1.NONE), transitions$1.start(L, w, null, 0, null, '_haltWatcher'), settings$3.warp.blur > 0 && (g.blurStrength = settings$3.warp.blur, transitions$1.start(D, w, null, G, P, 'blurring')), transitions$1.start(B, w, null, G, P, 'modelAlpha'), transitions$1.start(F, w, null, G, d[settings$3.warp.blendEasing], 'followPath'), transitions$1.start(V, w, null, G, d[settings$3.warp.blendEasing], 'goBunny'), transitions$1.start(U, w, k, 0, d[settings$3.warp.blendEasing], 'lookAtBunny'); } }, { key: "warpTravel_BLACK", value: function warpTravel_BLACK(e, t, i, n) { this.player.model.floorLogos.firstLogo.visible = false; this.player.model.floorLogos.secondLogo.visible = false; //this.player.tagManager.hideAllTags(); var r = e || 0; void 0 !== t && null !== t || (t = settings$3.warp.teleportTime), this.warpCommonParameters(t, r, !1, i), this.model.chunks.forEach(function (e) { e.material.uniforms.blackout.value = i; }), this._warpBendAim(null, t, null, r); var o = function () { this.wrapupWarpShadingOnly(n, i); }.bind(this); var firstPos = this.player.position.clone(); //add transitions$1.start(this.stepWarpPath.bind(this, firstPos), t, o, r, easing[settings$3.warp.blendEasing], 'stepMotion'); } }, { key: "makeWalkFlightFunc", value: function makeWalkFlightFunc(e, t, i) { return this.flightStepWalk.bind(this, e, t, i); } }, { key: "getOrientationForWalkingTourNode", value: function getOrientationForWalkingTourNode(e, t, i) { var n = e.length; if (t >= n) return !1; if (t === n - 1) i.copy(Vectors$1.FORWARD).applyQuaternion(this.warpDestHeroLoc.quaternion);else { var r = this.player.model.panos.get(e[t]), o = this.player.model.panos.get(e[t + 1]); i.copy(o.position).sub(r.position); } return i.normalize(), !0; } }, { key: "warpCameraTravel", value: function warpCameraTravel(e, t, i, n) { if (this.activeTransType = this.upcomingTransType, this.lastTransType = this.activeTransType, this.upcomingTransType = null, !e) { var r = function () { this._wrapupTravel(n); }.bind(this), o = { pano: this.warpDestPano, lookAtPoint: null, duration: null, maxDistanceOverride: null, skipWarpingCheck: !1 }; return void this.player.flyToPano(o, r); } this.activeTransType === WarpStyle.BLACK ? this.warpTravel_BLACK(null, i, t, n) : this.activeTransType === WarpStyle.WALK ? this.warpTravel_WALK(function () { this._clearWarpShading(), this._warpStopFlying(), this.player.spider.draw(), this.placeCpm(), n && n(); }.bind(this)) : this.warpTravel_STD(n); } }, { key: "startWarpState", value: function startWarpState() { this.warping = !0, this.warpInterrupted = !1, this.warpInterruptionBlackoutStyle = null, this.warpInterruptionTravelTime = null; } }, { key: "endWarpState", value: function endWarpState() { this.warping = !1; } }, { key: "warpToPano", value: function warpToPano(e, t, i, n) { if (this.warping) return void logger$1.warn('Cannot warp when already warping'); if (this.upcomingTransType = e, this.activeTransType = null, !this.setWarpDestPano()) return this.upcomingTransType = null, void this.warpToNonPano(n); if (this.player.mode !== Viewmode$1.PANORAMA) return this.upcomingTransType = null, this.discardSlow(), void this.player.flyToNewMode({ mode: Viewmode$1.PANORAMA, pano: this.warpDestPano, duration: settings$3.warp.outsideTime, warpDest: this.warpDestHeroLoc, callback: n, force: !0 }); if (!this.warpDestPano) return logger$1.warn('no warp destination, callback dropped'), void (this.upcomingTransType = null); var r = !(this.model.panos.isNeighbour(this.player.currentPano, this.warpDestPano) && this.warpDestPano !== this.player.currentPano && this.warpDestPano.position.distanceTo(this.player.currentPano.position) < settings$3.warp.nearPanoDist), o = this.chooseWarpPath(r); if (o && this.upcomingTransType !== WarpStyle.WALK) { var s = function () { this.waitingToWarp = !1, this.warpToPano(e, t, i, n); }.bind(this); if (this.player.checkAndWaitForPanoLoad(this.warpDestPano, 'high', 'low', this.player.basePanoSize, s)) return void (this.waitingToWarp = !0); } this.player.currentPano || (logger$1.warn('Arrived at a very strange spot!'), this.player.currentPano = this.warpDestPano, this.placeCpm(), this.fadeOutCpm(settings$3.path.fadeOutTime), this.player.spider.draw()), logger$1.debug('Warping to pano ', this.warpDestPano.position); if (this.upcomingTransType !== WarpStyle.WALK) { this.player.emit(PlayerEvents.PanoChosen, this.player.currentPano, this.warpDestPano); } this.startWarpState(); var h = function () { this.endWarpState(), n && n(); }.bind(this); o ? this.warpCameraTravel(r, t, i, h) : this.warpCameraAim(h); this.player.smoothZoomToDefault(settings$3.zoom.restoreTime); } }]); return ShowPath; }(); var ZoomEvents = { ZoomIn: 'zoom.in', ZoomOut: 'zoom.out', ZoomMax: 'zoom.max', ZoomMin: 'zoom.min' }; function _createSuper$1i(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1i(); 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 _isNativeReflectConstruct$1i() { 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; } } var _taskCache$1 = new WeakMap(); var DRACOLoader = /*#__PURE__*/function (_Loader) { _inherits(DRACOLoader, _Loader); var _super = _createSuper$1i(DRACOLoader); function DRACOLoader(manager) { var _this; _classCallCheck(this, DRACOLoader); _this = _super.call(this, manager); _this.decoderPath = ''; _this.decoderConfig = {}; _this.decoderBinary = null; _this.decoderPending = null; _this.workerLimit = 4; _this.workerPool = []; _this.workerNextTaskID = 1; _this.workerSourceURL = ''; _this.defaultAttributeIDs = { position: 'POSITION', normal: 'NORMAL', color: 'COLOR', uv: 'TEX_COORD' }; _this.defaultAttributeTypes = { position: 'Float32Array', normal: 'Float32Array', color: 'Float32Array', uv: 'Float32Array' }; return _this; } _createClass(DRACOLoader, [{ key: "setDecoderPath", value: function setDecoderPath(path) { this.decoderPath = path; return this; } }, { key: "setDecoderConfig", value: function setDecoderConfig(config) { this.decoderConfig = config; return this; } }, { key: "setWorkerLimit", value: function setWorkerLimit(workerLimit) { this.workerLimit = workerLimit; return this; } }, { key: "load", value: function load(url, onLoad, onProgress, onError) { var _this2 = this; var loader = new THREE$1.FileLoader(this.manager); loader.setPath(this.path); loader.setResponseType('arraybuffer'); loader.setRequestHeader(this.requestHeader); loader.setWithCredentials(this.withCredentials); loader.load(url, function (buffer) { _this2.decodeDracoFile(buffer, onLoad).catch(onError); }, onProgress, onError); } }, { key: "decodeDracoFile", value: function decodeDracoFile(buffer, callback, attributeIDs, attributeTypes) { var taskConfig = { attributeIDs: attributeIDs || this.defaultAttributeIDs, attributeTypes: attributeTypes || this.defaultAttributeTypes, useUniqueIDs: !!attributeIDs }; return this.decodeGeometry(buffer, taskConfig).then(callback); } }, { key: "decodeGeometry", value: function decodeGeometry(buffer, taskConfig) { var _this3 = this; var taskKey = JSON.stringify(taskConfig); // Check for an existing task using this buffer. A transferred buffer cannot be transferred // again from this thread. if (_taskCache$1.has(buffer)) { var cachedTask = _taskCache$1.get(buffer); if (cachedTask.key === taskKey) { return cachedTask.promise; } else if (buffer.byteLength === 0) { // Technically, it would be possible to wait for the previous task to complete, // transfer the buffer back, and decode again with the second configuration. That // is complex, and I don't know of any reason to decode a Draco buffer twice in // different ways, so this is left unimplemented. throw new Error('THREE.DRACOLoader: Unable to re-decode a buffer with different ' + 'settings. Buffer has already been transferred.'); } } // var worker; var taskID = this.workerNextTaskID++; var taskCost = buffer.byteLength; // Obtain a worker and assign a task, and construct a geometry instance // when the task completes. var geometryPending = this._getWorker(taskID, taskCost).then(function (_worker) { worker = _worker; return new Promise(function (resolve, reject) { worker._callbacks[taskID] = { resolve, reject }; worker.postMessage({ type: 'decode', id: taskID, taskConfig, buffer }, [buffer]); // this.debug(); }); }).then(function (message) { return _this3._createGeometry(message.geometry); }); // Remove task from the task list. // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416) geometryPending.catch(function () { return true; }).then(function () { if (worker && taskID) { _this3._releaseTask(worker, taskID); // this.debug(); } }); // Cache the task result. _taskCache$1.set(buffer, { key: taskKey, promise: geometryPending }); return geometryPending; } }, { key: "_createGeometry", value: function _createGeometry(geometryData) { var geometry = new THREE$1.BufferGeometry(); if (geometryData.index) { geometry.setIndex(new THREE$1.BufferAttribute(geometryData.index.array, 1)); } for (var i = 0; i < geometryData.attributes.length; i++) { var attribute = geometryData.attributes[i]; var name = attribute.name; var array = attribute.array; var itemSize = attribute.itemSize; geometry.setAttribute(name, new THREE$1.BufferAttribute(array, itemSize)); } return geometry; } }, { key: "_loadLibrary", value: function _loadLibrary(url, responseType) { var loader = new THREE$1.FileLoader(this.manager); loader.setPath(this.decoderPath); loader.setResponseType(responseType); loader.setWithCredentials(this.withCredentials); return new Promise(function (resolve, reject) { loader.load(url, resolve, undefined, reject); }); } }, { key: "preload", value: function preload() { this._initDecoder(); return this; } }, { key: "_initDecoder", value: function _initDecoder() { var _this4 = this; if (this.decoderPending) return this.decoderPending; var useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js'; var librariesPending = []; if (useJS) { librariesPending.push(this._loadLibrary('draco_decoder.js', 'text')); } else { librariesPending.push(this._loadLibrary('draco_wasm_wrapper.js', 'text')); librariesPending.push(this._loadLibrary('draco_decoder.wasm', 'arraybuffer')); } this.decoderPending = Promise.all(librariesPending).then(function (libraries) { var jsContent = libraries[0]; if (!useJS) { _this4.decoderConfig.wasmBinary = libraries[1]; } var fn = DRACOWorker.toString(); var body = ['/* draco decoder */', jsContent, '', '/* worker */', fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))].join('\n'); _this4.workerSourceURL = URL.createObjectURL(new Blob([body])); }); return this.decoderPending; } }, { key: "_getWorker", value: function _getWorker(taskID, taskCost) { var _this5 = this; return this._initDecoder().then(function () { if (_this5.workerPool.length < _this5.workerLimit) { var _worker2 = new Worker(_this5.workerSourceURL); _worker2._callbacks = {}; _worker2._taskCosts = {}; _worker2._taskLoad = 0; _worker2.postMessage({ type: 'init', decoderConfig: _this5.decoderConfig }); _worker2.onmessage = function (e) { var message = e.data; switch (message.type) { case 'decode': _worker2._callbacks[message.id].resolve(message); break; case 'error': _worker2._callbacks[message.id].reject(message); break; default: console.error('THREE.DRACOLoader: Unexpected message, "' + message.type + '"'); } }; _this5.workerPool.push(_worker2); } else { _this5.workerPool.sort(function (a, b) { return a._taskLoad > b._taskLoad ? -1 : 1; }); } var worker = _this5.workerPool[_this5.workerPool.length - 1]; worker._taskCosts[taskID] = taskCost; worker._taskLoad += taskCost; return worker; }); } }, { key: "_releaseTask", value: function _releaseTask(worker, taskID) { worker._taskLoad -= worker._taskCosts[taskID]; delete worker._callbacks[taskID]; delete worker._taskCosts[taskID]; } }, { key: "debug", value: function debug() { console.log('Task load: ', this.workerPool.map(function (worker) { return worker._taskLoad; })); } }, { key: "dispose", value: function dispose() { for (var i = 0; i < this.workerPool.length; ++i) { this.workerPool[i].terminate(); } this.workerPool.length = 0; return this; } }]); return DRACOLoader; }(THREE$1.Loader); /* WEB WORKER */ function DRACOWorker() { var decoderConfig; var decoderPending; onmessage = function onmessage(e) { var message = e.data; switch (message.type) { case 'init': decoderConfig = message.decoderConfig; decoderPending = new Promise(function (resolve /*, reject*/ ) { decoderConfig.onModuleLoaded = function (draco) { // Module is Promise-like. Wrap before resolving to avoid loop. resolve({ draco: draco }); }; DracoDecoderModule(decoderConfig); // eslint-disable-line no-undef }); break; case 'decode': var buffer = message.buffer; var taskConfig = message.taskConfig; decoderPending.then(function (module) { var draco = module.draco; var decoder = new draco.Decoder(); var decoderBuffer = new draco.DecoderBuffer(); decoderBuffer.Init(new Int8Array(buffer), buffer.byteLength); try { var geometry = decodeGeometry(draco, decoder, decoderBuffer, taskConfig); var buffers = geometry.attributes.map(function (attr) { return attr.array.buffer; }); if (geometry.index) buffers.push(geometry.index.array.buffer); self.postMessage({ type: 'decode', id: message.id, geometry }, buffers); } catch (error) { console.error(error); self.postMessage({ type: 'error', id: message.id, error: error.message }); } finally { draco.destroy(decoderBuffer); draco.destroy(decoder); } }); break; } }; function decodeGeometry(draco, decoder, decoderBuffer, taskConfig) { var attributeIDs = taskConfig.attributeIDs; var attributeTypes = taskConfig.attributeTypes; var dracoGeometry; var decodingStatus; var geometryType = decoder.GetEncodedGeometryType(decoderBuffer); if (geometryType === draco.TRIANGULAR_MESH) { dracoGeometry = new draco.Mesh(); decodingStatus = decoder.DecodeBufferToMesh(decoderBuffer, dracoGeometry); } else if (geometryType === draco.POINT_CLOUD) { dracoGeometry = new draco.PointCloud(); decodingStatus = decoder.DecodeBufferToPointCloud(decoderBuffer, dracoGeometry); } else { throw new Error('THREE.DRACOLoader: Unexpected geometry type.'); } if (!decodingStatus.ok() || dracoGeometry.ptr === 0) { throw new Error('THREE.DRACOLoader: Decoding failed: ' + decodingStatus.error_msg()); } var geometry = { index: null, attributes: [] }; // Gather all vertex attributes. for (var attributeName in attributeIDs) { var attributeType = self[attributeTypes[attributeName]]; var attribute = void 0; var attributeID = void 0; // A Draco file may be created with default vertex attributes, whose attribute IDs // are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively, // a Draco file may contain a custom set of attributes, identified by known unique // IDs. glTF files always do the latter, and `.drc` files typically do the former. if (taskConfig.useUniqueIDs) { attributeID = attributeIDs[attributeName]; attribute = decoder.GetAttributeByUniqueId(dracoGeometry, attributeID); } else { attributeID = decoder.GetAttributeId(dracoGeometry, draco[attributeIDs[attributeName]]); if (attributeID === -1) continue; attribute = decoder.GetAttribute(dracoGeometry, attributeID); } geometry.attributes.push(decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute)); } // Add index. if (geometryType === draco.TRIANGULAR_MESH) { geometry.index = decodeIndex(draco, decoder, dracoGeometry); } draco.destroy(dracoGeometry); return geometry; } function decodeIndex(draco, decoder, dracoGeometry) { var numFaces = dracoGeometry.num_faces(); var numIndices = numFaces * 3; var byteLength = numIndices * 4; var ptr = draco._malloc(byteLength); decoder.GetTrianglesUInt32Array(dracoGeometry, byteLength, ptr); var index = new Uint32Array(draco.HEAPF32.buffer, ptr, numIndices).slice(); draco._free(ptr); return { array: index, itemSize: 1 }; } function decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute) { var numComponents = attribute.num_components(); var numPoints = dracoGeometry.num_points(); var numValues = numPoints * numComponents; var byteLength = numValues * attributeType.BYTES_PER_ELEMENT; var dataType = getDracoDataType(draco, attributeType); var ptr = draco._malloc(byteLength); decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, attribute, dataType, byteLength, ptr); var array = new attributeType(draco.HEAPF32.buffer, ptr, numValues).slice(); draco._free(ptr); return { name: attributeName, array: array, itemSize: numComponents }; } function getDracoDataType(draco, attributeType) { switch (attributeType) { case Float32Array: return draco.DT_FLOAT32; case Int8Array: return draco.DT_INT8; case Int16Array: return draco.DT_INT16; case Int32Array: return draco.DT_INT32; case Uint8Array: return draco.DT_UINT8; case Uint16Array: return draco.DT_UINT16; case Uint32Array: return draco.DT_UINT32; } } } var GLTFLoader$2 = new THREE.GLTFLoader(); var dracoLoader = new DRACOLoader(); dracoLoader.setDecoderPath(texture.getImageURL('images/loaders/DRACOLoader/draco/')); GLTFLoader$2.setDRACOLoader(dracoLoader); var loaders = { gltf: function gltf(url, func) { GLTFLoader$2.load(url, func); } }; function _createSuper$1h(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1h(); 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 _isNativeReflectConstruct$1h() { 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; } } var bracketModels = {}; // 支架模型数据 /** * 空间贴图边框 */ var OverlayFrame = /*#__PURE__*/function (_THREE$Object3D) { _inherits(OverlayFrame, _THREE$Object3D); var _super = _createSuper$1h(OverlayFrame); function OverlayFrame(type) { var _this; _classCallCheck(this, OverlayFrame); _this = _super.call(this); _this.parts = { body: null, // 随overlay缩放或旋转的部分 foot: null, // 不随overlay缩放或旋转的部分 line: null // 线框 }; /** * 目前有: * 边框:wall1, wall2, wall3, * 支架:ground1, ground2 */ _this.type = type; _this.addEventListener('createDone', function () { _this.traverse(function (e) { if (e.isMesh) { e.renderOrder = RenderOrder.overlay - 1; //低于plane的,为了让plane的透明部分不会遮住画框。若要相反的效果需要保证完全重叠 e.material.transparent = true; } }); //xzw:遮住marker }); if (_this.type.indexOf('ground') > -1) { _this.createBracket(); } else { _this.createFrame(); } return _this; } // // 用于TransfromControl // get width() { // if (this.overlay && this.type.indexOf('wall') > -1) return this.overlay.width // else return // } // get height() { // if (this.overlay && this.type.indexOf('wall') > -1) return this.overlay.height // else return // } // get depth() { // if (this.overlay && this.type.indexOf('wall') > -1) return this.overlay.depth // else return // } _createClass(OverlayFrame, [{ key: "show", value: function show() { // overlay隐藏时不显示 if (!this.overlay.visible) { this.visible = false; return; } // wall_1厚度为0时不显示 if (this.type == 'wall_1' && this.overlay.depthTemp == 0) { this.visible = false; return; } this.visible = true; } }, { key: "hide", value: function hide() { this.visible = false; } // 设置厚度 }, { key: "setFrameThickness", value: function setFrameThickness(thickness) { if (this.type == 'wall_1') { isNaN(thickness) && (thickness = 0); /* settings.overlay.depth */ this.overlay.depthTemp = thickness; // 当厚度为0时隐藏frame !!thickness ? this.show() : this.hide(); } else if (this.type.indexOf('wall') > -1) { thickness = settings$3.overlay.depth; // 其他贴墙固定0.04 } else { thickness = 0; // 贴地默认无厚度 } this.overlay.depth = thickness; this.overlay.plane.position.set(0, 0, thickness); this.update({ mode: 'scale' }); } }, { key: "setOverlay", value: function setOverlay(overlay, isFromInfo) { this.overlay = overlay; overlay.frame = this; this.visible = overlay.visible; if (!isFromInfo) { this.position.copy(this.overlay.position); this.quaternion.copy(this.overlay.quaternion); // 根据overlayFrame修正overlay坐标 var _this$computeOverlayT = this.computeOverlayTransform(), position = _this$computeOverlayT.position, quaternion = _this$computeOverlayT.quaternion; this.overlay.position.copy(position); this.overlay.quaternion.copy(quaternion); } else { // 初始化数据库数据时,倒推出overlay修正前坐标,作为overlayFrame位置 var _this$computeOverlayT2 = this.computeOverlayTransform({ reverse: true }), _position = _this$computeOverlayT2.position, _quaternion = _this$computeOverlayT2.quaternion; this.position.copy(_position); this.quaternion.copy(_quaternion); } this.update({ mode: 'scale' }); } /** * 改变overlay坐标和旋转使它适应overlayFrame * @param {*} options * @returns */ }, { key: "computeOverlayTransform", value: function computeOverlayTransform() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var position = this.overlay.position.clone(); var quaternion = this.overlay.quaternion.clone(); var reverse = options.reverse ? -1 : 1; var height = settings$3.overlay.height * this.overlay.scale.y; switch (this.type) { case 'ground_1': position.add(new THREE.Vector3(0, (bracketModels[this.type].height + height / 2) * reverse, 0).applyQuaternion(this.overlay.quaternion)); break; case 'ground_2': quaternion.multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1, 0, 0), -Math.PI / 6 * reverse)); position.add(new THREE.Vector3(0, bracketModels[this.type].height * reverse, 0).applyQuaternion(reverse == 1 ? this.quaternion : quaternion)); break; case 'wall_0': case 'wall_1': case 'wall_2': case 'wall_3': position.add(new THREE.Vector3(0, (height / 2 + this.getFrameModelData().border) * reverse, 0).applyQuaternion(this.quaternion)); // 边框上移 break; } this.setFrameThickness(this.overlay.depth); return { position, quaternion }; } // 创建支架 }, { key: "createBracket", value: function createBracket() { var _this2 = this; var hideMaterial = new THREE.MeshPhongMaterial({ color: 0x000000 }); hideMaterial.visible = false; if (this.type == 'ground_1') { this.parts.body = new THREE.Group(); // 背面 var plane = new THREE.Mesh(new THREE.PlaneGeometry(settings$3.overlay.width, settings$3.overlay.height), hideMaterial); plane.scale.z = -1; this.parts.body.backFace = plane; var base = new THREE.Group(); this.parts.body.bottom = base; this.parts.body.add(base, plane); this.add(this.parts.body); this.initBracketMeshData(function (object) { base.add(object); // 背面替换为底座相同材质 var material = object.children[1].material; plane.material = material; _this2.dispatchEvent({ type: 'createDone' }); }); } else { // 可移动支架 this.parts.body = new THREE.Group(); this.parts.body.rotateX(-Math.PI / 6); this.add(this.parts.body); // 竖杆 var cube = new THREE.Mesh(new THREE.BoxGeometry(0.02, settings$3.overlay.height, 0.02), hideMaterial); cube.position.z -= 0.01; // 上横杆 var cube1 = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.01, 0.04), hideMaterial); cube1.position.y += settings$3.overlay.height / 2 + 0.005; // 下横杆 var cube2 = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.01, 0.04), hideMaterial); cube2.position.y -= settings$3.overlay.height / 2 + 0.005; // 背面 var _plane = new THREE.Mesh(new THREE.PlaneGeometry(settings$3.overlay.width, settings$3.overlay.height), hideMaterial); _plane.scale.z = -1; this.parts.body.middle = cube; this.parts.body.top = cube1; this.parts.body.bottom = cube2; this.parts.body.backFace = _plane; this.parts.body.add(cube, cube1, cube2, _plane); // 底座支架 this.parts.foot = new THREE.Group(); this.parts.foot.position.z -= 0.02; this.add(this.parts.foot); this.initBracketMeshData(function (object) { _this2.parts.foot.add(object); // 可移动支架替换为底座相同材质 var material = object.children[0].material; cube.material = cube1.material = cube2.material = _plane.material = material; _this2.dispatchEvent({ type: 'createDone' }); }); // bracketModels需要先init this.parts.body.position.y += bracketModels[this.type].height; } } // 创建边框 }, { key: "createFrame", value: function createFrame() { var body = new THREE.Mesh(); this.parts.body = body; var _this$getFrameModelDa = this.getFrameModelData(), vertices = _this$getFrameModelDa.vertices, indexs = _this$getFrameModelDa.indexs, uvs = _this$getFrameModelDa.uvs, normals = _this$getFrameModelDa.normals; body.geometry = new THREE.BufferGeometry(); body.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3)); body.geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2)); body.geometry.setIndex(new THREE.BufferAttribute(new Uint16Array(indexs), 1)); if (normals) body.geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3));else body.geometry.computeVertexNormals(); if (this.type == 'wall_0') { // let frameFace = new THREE.Mesh(frameGeo, new THREE.MeshBasicMaterial({ map: texture.load(texture.getImageURL('images/zzz.jpg')) })) body.material = new THREE.MeshPhongMaterial({ color: '#eeeeee' }); this.parts.line = new THREE.LineSegments(new THREE.EdgesGeometry(body.geometry), new THREE.LineBasicMaterial({ color: 0x000000 })); this.add(this.parts.line); } else if (this.type == 'wall_3') { body.material = new THREE.MeshStandardMaterial({ color: '#222222' }); } else if (this.type == 'wall_2' || this.type == 'wall_1') { body.material = new THREE.MeshLambertMaterial({ color: '#cccccc' }); // this.parts.line = new THREE.LineSegments(new THREE.EdgesGeometry(body.geometry), new THREE.LineBasicMaterial({ color: 0xcccccc, transparent: true, opacity: 0.4})) // this.add(this.parts.line) } body.position.z -= 0.001; // 向后移1mm,防止和overlay以及边框重叠 this.add(body); this.dispatchEvent({ type: 'createDone' }); } /** * overlayFrame和overlay之间互相影响变换 * @param {*} data TransformControls变换数据 */ }, { key: "update", value: function update(data) { var width = Math.abs(settings$3.overlay.width * this.overlay.scale.x); var height = Math.abs(settings$3.overlay.height * this.overlay.scale.y); // ground: 更新overlay,随overlayFrame变换(因为ground_2模型需要如此) // wall: 更新overlayFrame,随overlay变换(需要根据长宽高更新transfromControl) if (!data || data.mode == 'translate') { switch (this.type) { case 'ground_1': this.overlay.position.copy(this.position).add(new THREE.Vector3(0, height / 2 + bracketModels[this.type].height, 0).applyQuaternion(this.quaternion)); break; case 'ground_2': this.overlay.position.copy(this.position).add(new THREE.Vector3(0, bracketModels[this.type].height, 0).applyQuaternion(this.quaternion)); break; case 'wall_0': case 'wall_1': case 'wall_2': case 'wall_3': this.position.copy(this.overlay.position).add(new THREE.Vector3(0, -height / 2 - this.getFrameModelData().border, 0).applyQuaternion(this.quaternion)); // 边框上移 break; default: this.overlay.position.copy(this.position); break; } } // 更新overlay,随overlayFrame变换(因为ground_2模型需要如此) if (!data || data.mode == 'rotate') { switch (this.type) { case 'ground_1': this.overlay.rotation.copy(this.rotation); this.overlay.position.set(0, bracketModels[this.type].height + height / 2, 0).applyQuaternion(this.quaternion).add(this.position); break; case 'ground_2': this.overlay.quaternion.setFromAxisAngle(new THREE.Vector3(1, 0, 0).applyQuaternion(this.overlay.quaternion), -Math.PI / 6).multiply(this.quaternion); this.parts.body.quaternion.copy(this.quaternion).invert().multiply(this.overlay.quaternion); // local quaternion this.overlay.position.copy(this.position).add(new THREE.Vector3(0, bracketModels[this.type].height, 0).applyQuaternion(this.quaternion)); break; case 'wall_0': case 'wall_1': case 'wall_2': case 'wall_3': this.overlay.rotation.copy(this.rotation); this.overlay.position.set(0, this.getFrameModelData().border + height / 2, 0).applyQuaternion(this.quaternion).add(this.position); // 边框上移 break; default: this.overlay.rotation.copy(this.rotation); break; } } // 更新overlayFrame,随overlay变换(因为ground_2模型需要如此) if (!data || data.mode == 'scale') { switch (this.type) { case 'ground_1': this.parts.body.bottom.scale.x = this.overlay.scale.x; this.parts.body.backFace.scale.set(this.overlay.scale.x, this.overlay.scale.y, -this.overlay.scale.z); this.parts.body.backFace.position.set(0, height / 2 + bracketModels[this.type].height, 0); this.overlay.position.copy(this.position).add(new THREE.Vector3(0, height / 2 + bracketModels[this.type].height, 0).applyQuaternion(this.quaternion)); break; case 'ground_2': this.parts.body.middle.scale.y = this.overlay.scale.y; this.parts.body.top.position.y = height / 2 + 0.005; this.parts.body.bottom.position.y = -height / 2 - 0.005; this.parts.body.backFace.scale.set(this.overlay.scale.x, this.overlay.scale.y, -this.overlay.scale.z); break; case 'wall_0': case 'wall_1': case 'wall_2': case 'wall_3': var _this$getFrameModelDa2 = this.getFrameModelData(width, height), vertices = _this$getFrameModelDa2.vertices, normals = _this$getFrameModelDa2.normals; this.parts.body.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3)); normals && this.parts.body.geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3)); this.position.set(0, -this.getFrameModelData().border - height / 2, 0).applyQuaternion(this.quaternion).add(this.overlay.position); // 边框上移 if (this.parts.line) { this.parts.line.geometry.dispose(); this.parts.line.geometry = new THREE.EdgesGeometry(this.parts.body.geometry); } break; } } } // 边框模型数据 }, { key: "getFrameModelData", value: function getFrameModelData(width, height) { var depth = this.overlay && !isNaN(this.overlay.depth) ? this.overlay.depth : settings$3.overlay.depth; !width && (width = settings$3.overlay.width); !height && (height = settings$3.overlay.height); var bufferAttributesJson = { wall_0: { border: 0.05, vertices: [width / 2, height / 2, depth, // 0 width / 2 + 0.01, height / 2 + 0.01, depth + 0.02, // 1 width / 2 + 0.05, height / 2 + 0.05, depth + 0.02, // 2 width / 2, -height / 2, depth, // 3 width / 2 + 0.01, -height / 2 - 0.01, depth + 0.02, // 4 width / 2 + 0.05, -height / 2 - 0.05, depth + 0.02, // 5 -width / 2, -height / 2, depth, // 6 -width / 2 - 0.01, -height / 2 - 0.01, depth + 0.02, // 7 -width / 2 - 0.05, -height / 2 - 0.05, depth + 0.02, // 8 -width / 2, height / 2, depth, // 9 -width / 2 - 0.01, height / 2 + 0.01, depth + 0.02, // 10 -width / 2 - 0.05, height / 2 + 0.05, depth + 0.02, // 11 width / 2 + 0.05, height / 2 + 0.05, 0, // 12 width / 2 + 0.05, -height / 2 - 0.05, 0, // 13 -width / 2 - 0.05, -height / 2 - 0.05, 0, // 14 -width / 2 - 0.05, height / 2 + 0.05, 0 // 15 ], indexs: [0, 3, 4, 0, 4, 1, 1, 4, 5, 1, 5, 2, 3, 6, 7, 3, 7, 4, 4, 7, 8, 4, 8, 5, 6, 9, 10, 6, 10, 7, 7, 10, 11, 7, 11, 8, 9, 0, 1, 9, 1, 10, 10, 1, 2, 10, 2, 11, 0, 6, 3, 0, 9, 6, 2, 13, 12, 2, 5, 13, 5, 14, 13, 5, 8, 4, 8, 15, 14, 8, 11, 15, 11, 12, 15, 11, 2, 12, 12, 13, 14, 12, 14, 15] }, wall_1: { border: 0, vertices: [width / 2, height / 2, depth, // 0 width / 2, height / 2, 0, // 1 width / 2, -height / 2, depth, // 2 width / 2, -height / 2, 0, // 3 -width / 2, -height / 2, depth, // 4 -width / 2, -height / 2, 0, // 5 -width / 2, height / 2, depth, // 6 -width / 2, height / 2, 0 // 7 ], normals: [1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1], indexs: [0, 2, 3, 0, 3, 1, 2, 4, 5, 2, 5, 3, 4, 6, 7, 4, 7, 5, 6, 0, 1, 6, 1, 7, 0, 4, 2, 0, 6, 4, 1, 3, 5, 1, 5, 7] }, wall_2: { border: 0.06, vertices: [width / 2 + 0.02, height / 2 + 0.02, depth, // 0 width / 2 + 0.02, height / 2 + 0.02, depth + 0.03, // 1 width / 2 + 0.06, height / 2 + 0.06, depth, // 2 width / 2 + 0.02, -height / 2 - 0.02, depth, // 3 width / 2 + 0.02, -height / 2 - 0.02, depth + 0.03, // 4 width / 2 + 0.06, -height / 2 - 0.06, depth, // 5 -width / 2 - 0.02, -height / 2 - 0.02, depth, // 6 -width / 2 - 0.02, -height / 2 - 0.02, depth + 0.03, // 7 -width / 2 - 0.06, -height / 2 - 0.06, depth, // 8 -width / 2 - 0.02, height / 2 + 0.02, depth, // 9 -width / 2 - 0.02, height / 2 + 0.02, depth + 0.03, // 10 -width / 2 - 0.06, height / 2 + 0.06, depth, // 11 width / 2 + 0.06, height / 2 + 0.06, 0, // 12 width / 2 + 0.06, -height / 2 - 0.06, 0, // 13 -width / 2 - 0.06, -height / 2 - 0.06, 0, // 14 -width / 2 - 0.06, height / 2 + 0.06, 0 // 15 ], normals: [-1, -1, 0, 1, 1, 1, -1, -0.5, -1, -1, -1, 0, 1, 1, 1, -1, -0.5, -1, -1, -1, 0, 1, 1, 1, -1, -0.5, -1, -1, -1, 0, 1, 1, 1, -1, -0.5, -1, -1, 0.1, -1, 1, 0.1, -1, -1, 0.1, -1, 1, 0.1, -1], indexs: [0, 3, 4, 0, 4, 1, 1, 4, 5, 1, 5, 2, 3, 6, 7, 3, 7, 4, 4, 7, 8, 4, 8, 5, 6, 9, 10, 6, 10, 7, 7, 10, 11, 7, 11, 8, 9, 0, 1, 9, 1, 10, 10, 1, 2, 10, 2, 11, 0, 6, 3, 0, 9, 6, 2, 13, 12, 2, 5, 13, 5, 14, 13, 5, 8, 14, 8, 15, 14, 8, 11, 15, 11, 12, 15, 11, 2, 12, 12, 13, 14, 12, 14, 15] }, wall_3: { border: 0.05, vertices: [width / 2, height / 2, depth, // 0 width / 2 + 0.05, height / 2 + 0.05, depth, // 1 width / 2, -height / 2, depth, // 2 width / 2 + 0.05, -height / 2 - 0.05, depth, // 3 -width / 2, -height / 2, depth, // 4 -width / 2 - 0.05, -height / 2 - 0.05, depth, // 5 -width / 2, height / 2, depth, // 6 -width / 2 - 0.05, height / 2 + 0.05, depth, // 7 width / 2 + 0.05, height / 2 + 0.05, 0, // 8 width / 2 + 0.05, -height / 2 - 0.05, 0, // 9 -width / 2 - 0.05, -height / 2 - 0.05, 0, // 10 -width / 2 - 0.05, height / 2 + 0.05, 0 // 11 ], normals: [1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1], indexs: [0, 2, 3, 0, 3, 1, 2, 4, 5, 2, 5, 3, 4, 6, 7, 4, 7, 5, 6, 0, 1, 6, 1, 7, 0, 4, 2, 0, 6, 4, 1, 9, 8, 1, 3, 9, 3, 10, 9, 3, 5, 10, 5, 11, 10, 5, 7, 11, 7, 8, 11, 7, 1, 8, 8, 9, 10, 8, 10, 11] } }; var attrs = bufferAttributesJson[this.type]; // 边框上移 for (var i = 1; i < attrs.vertices.length; i += 3) { attrs.vertices[i] += height / 2 + attrs.border; } attrs.uvs = []; for (var _i = 0; _i < attrs.vertices.length * (2 / 3) / 8; _i++) { attrs.uvs.push(0, 1, 1, 1, 1, 0, 0, 0); } return attrs; } /** * 加载支架模型 * @param {*} func * @returns */ }, { key: "initBracketMeshData", value: function initBracketMeshData(func) { var _this3 = this; // 使用已有模型数据,注意需要clone if (bracketModels[this.type] && bracketModels[this.type].loaded) { func && func(bracketModels[this.type].object.clone()); return; } if (this.type == 'ground_1') { // 长度2.44m,高度0.58m var scaleYZ = 0.2; bracketModels[this.type] = { object: null, height: 0.58 * scaleYZ, loaded: false }; loaders.gltf(texture.getImageURL('images/brackets/bracket_1.glb'), function (model) { var object = model.scene; object.position.y *= scaleYZ; object.rotateY(Math.PI / 2); object.scale.set(scaleYZ, scaleYZ, 1 / 2.44); object.children.forEach(function (mesh) { if (mesh.name !== 'Plane') mesh.material.color.setRGB(0.3, 0.3, 0.3); }); bracketModels[_this3.type].object = object; bracketModels[_this3.type].loaded = true; func && func(object); }); return bracketModels[this.type]; } if (this.type == 'ground_2') { // 高度1.56m var scaleXYZ = 0.5; bracketModels[this.type] = { object: null, height: 1.59 * scaleXYZ, loaded: false }; loaders.gltf(texture.getImageURL('images/brackets/bracket_2.glb'), function (model) { var object = model.scene; object.children.forEach(function (mesh) { if (mesh.name == 'dizuo001') mesh.material.opacity = 0.6;else mesh.material.color.setRGB(0.3, 0.3, 0.3); }); object.scale.set(scaleXYZ, scaleXYZ, scaleXYZ); object.position.y += 0.01; bracketModels[_this3.type].object = object; bracketModels[_this3.type].loaded = true; func && func(object); }); } } }, { key: "switchTranformControls", value: function switchTranformControls(controls) { // switch (this.type) { // case 'ground_1': // // 只允许沿y轴旋转 // controls.filterRotateAxis(['y']) // break // default: // controls.filterRotateAxis() // break // } // switch (this.type) { // case 'ground_2': // // 沿着水平面平移 // controls.space = controls.mode == 'translate' ? 'world' : 'local' // break // default: // controls.space = 'local' // break // } // switch (this.type) { // case 'ground_2': // // y轴旋转整个支架,沿世界坐标系旋转;x轴z轴只旋转parts.body,沿本地坐标系旋转 // controls.spaceForRotate = { x: 'local', y: 'world', z: 'local' } // break // default: // controls.spaceForRotate = null // break // } // 变换TranformControls对象 if (controls.mode == 'scale' || controls.mode == 'translate' && this.type.indexOf('wall') > -1) { // 缩放、边框位移:以overlay为对象 controls.attach(this.overlay); } else { // 旋转、支架位移:以overlayFrame为对象 controls.attach(this); } } // 移除 }, { key: "remove", value: function remove(isFromInfo) { this.removeFromParent(); if (!isFromInfo) { // 数据回退时,坐标已变为数据库数据,无需重新计算 // 重新计算overlay坐标 var _this$computeOverlayT3 = this.computeOverlayTransform({ reverse: true }), position = _this$computeOverlayT3.position, quaternion = _this$computeOverlayT3.quaternion; this.overlay.position.copy(position); this.overlay.quaternion.copy(quaternion); } } // 销毁 }, { key: "dispose", value: function dispose(isFromInfo) { this.remove(isFromInfo); this.traverse(function (obj) { if (obj.isMesh) { obj.geometry.dispose(); obj.material.dispose(); } }); } }]); return OverlayFrame; }(THREE.Object3D); function _createSuper$1g(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1g(); 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 _isNativeReflectConstruct$1g() { 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; } } /* 目前只有box视频一种。分为带厚度和不带厚度两种。不带厚度时只有一个plane,带厚度时要加上一个五个面的box,这样刚好组成完整的box(变换中心调整至box背部)。 */ var isEdit$1; var Overlay = /*#__PURE__*/function (_THREE$Object3D) { _inherits(Overlay, _THREE$Object3D); var _super = _createSuper$1g(Overlay); function Overlay(player, info, videoPlayer) { var _this; _classCallCheck(this, Overlay); _this = _super.call(this); isEdit$1 = !player.$app.config.view; _this.player = player; _this._planeGeometry = new THREE.PlaneGeometry(settings$3.overlay.width, settings$3.overlay.height, 1, 1); _this._boxGeometry = new THREE.BoxBufferGeometry(settings$3.overlay.width, settings$3.overlay.height, settings$3.overlay.depth); //ie的mesh 加了polygonOffset也是会重叠。所以去掉前面的face: (但是突然ie又播放不了videoTexture) var newIndex = _toConsumableArray(_this._boxGeometry.index.array); newIndex.splice(4 * 6, 6); _this._boxGeometry.setIndex(new THREE.BufferAttribute(new Uint16Array(newIndex), 1)); _this._boxMat = new THREE.MeshBasicMaterial({ //MeshStandardMaterial color: '#eeeeee', transparent: !0, opacity: 0.8 }); _this.videoPlayer = videoPlayer; _this.isHidden = false; // 用于标识是否设置可视 info.reverse == void 0 && (info.reverse = false); info.limitToOnlyPano == void 0 && (info.limitToOnlyPano = false); //仅在当前点显示 _this.cornerPoints = []; _this.info = info; _this.sid = info.sid; _this.build(info); _this.name = 'overlay_' + _this.sid; _this.floor = _this.player.model.floors.get(info.floorIndex) || _this.raycastToFindFloor(); _this.updateVisibleOnFloor(); _this.addEventListener('isVisible', function (e) { if (_this.player.EditOverlay.editPlane != _assertThisInitialized(_this)) return; _this.player.EditOverlay.controlSelectOverlay(e.visible ? _assertThisInitialized(_this) : null); }); return _this; } _createClass(Overlay, [{ key: "show", value: function show() { var reason = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; //console.error('show', reason) common.updateVisible(this, reason, true); this.frame && this.frame.show(); if (reason == 'forceHide') { this.isHidden = false; } } }, { key: "hide", value: function hide() { var reason = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; //console.error('hide', reason) common.updateVisible(this, reason, false); this.frame && this.frame.hide(); if (reason == 'forceHide') { this.isHidden = true; } } }, { key: "raycastToFindFloor", value: function raycastToFindFloor() { //add this.floor = convertTool.raycastToFindFloor(this.player, this.plane.getWorldPosition(new THREE.Vector3())); if (!this.floor) { console.error('Overlay raycastToFindFloor cannot find floor?'); this.floor = this.player.model.floors.first(); } return this.floor; } }, { key: "updateVisibleOnFloor", value: function updateVisibleOnFloor(info) { //仅飞出后需要按楼层显示 if (this.player.model.currentFloor != this.floor && !this.player.model.allFloorsVisible && this.player.modeTran.split('-')[1] != 'panorama' // && (!this.player.EditOverlay || this.player.EditOverlay.editPlane != this)) || //this.info.hide ) { this.hide('visiOnFloor'); } else { this.show('visiOnFloor'); } } //注:楼层切换时的控制写在floor.show里 }, { key: "build", value: function build(info) { var _this2 = this; this.modified = info.modified; var plane = new THREE.Mesh(this._planeGeometry, new THREE.MeshBasicMaterial({ //MeshStandardMaterial color: '#00c8af', opacity: 0.4, transparent: !0, polygonOffset: true, //是否开启多边形偏移 //ie不开启时blank也不会闪烁 polygonOffsetFactor: -0.9, //多边形偏移因子 polygonOffsetUnits: -4.0 //多边形偏移单位 })); plane.renderOrder = RenderOrder.overlay; this.add(plane); this.plane = plane; this.player.OverlayManager.add(this); if (info.media) { // console.error(info) if (info.media.includes('video')) { info.type = 'video'; if (isEdit$1) { this.loadVideo(); } else { //展示页面延迟加载,且监控,可见才播放(如果支持多个视频,这段要去掉,改为overlayManager里addSliceListen的那段) this.player.on('view.changed', function () { var time = _this2.info.media instanceof HTMLVideoElement ? 1000 : 200; //加载需要时间,所以未加载时缩短判断间隔 common.intervalTool.isWaiting('overlayInsight_' + _this2.player.model.sid, function () { //延时update,防止崩溃 , 未到时间就拦截(第一次直接执行) if (!_this2.player.flying) { //飞行时不判断 if (_this2.visible && _this2.inSight()) { _this2.videoControl(true); } else { _this2.videoControl(false); } } }, time); }); } } else if (info.media.includes('photo')) { var img = new Image(); img.crossOrigin = 'anonymous'; if (this.info.isBillboard) { img.src = this.getMapSrc(); } else { img.src = this.player.$app.resource.getUserResourceURL(info.poster); } img.onload = function () { _this2.dispatchEvent({ type: 'mapLoaded' }); }; info.media = img; info.type = 'photo'; } plane.material.color = new THREE.Color(1, 1, 1); } if (info.width == void 0) info.width = settings$3.overlay.width; if (info.height == void 0) info.height = settings$3.overlay.height; this.setFromInfo(info); } }, { key: "loadVideo", value: function loadVideo() { if (this.info.media instanceof HTMLVideoElement) return this.info.media; //已加载 this.info.media = this.videoPlayer.getVideo(this.info.sid); //注:部分视频手机播放不了 this.info.media.addEventListener('ended', function () { info.media.play(); if (info.media.paused) ; }); this.setFromInfo(this.info); this.plane.material.needsUpdate = true; //console.log('loadVideo成功') return this.info.media; } }, { key: "setFromInfo", value: function setFromInfo(info) { var _this3 = this; //1 恢复到编辑之前 2 初始加载 var plane = this.plane; info.width && (this.scale.setX(info.width / settings$3.overlay.width), this.width = info.width); info.height && (this.scale.setY(info.height / settings$3.overlay.height), this.height = info.height); !isNaN(info.depth) && (this.depth = info.depth); info.pos instanceof Array && (info.pos = new THREE.Vector3().fromArray(info.pos)); info.qua instanceof Array && (info.qua = new THREE.Quaternion().fromArray(info.qua)); info.pos && this.position.copy(info.pos); info.qua && this.quaternion.copy(info.qua); info.reverse && (this.scale.x *= -1); this.isHidden = info.hide; common.updateVisible(this, 'forceHide', !this.isHidden); if (info.type) { if (!plane.material.map) { if (info.type == 'video') { if (!(this.info.media instanceof HTMLVideoElement)) return; var map = new THREE.VideoTexture(info.media); plane.material.map = map; if (!isEdit$1) { var needsUpdate_ = map.needsUpdate; Object.defineProperty(map, 'needsUpdate', { get: function get() { return needsUpdate_; }, set: function set(value) { needsUpdate_ = !_this3.info.media.paused && value; //增加判断:是否在播放,不在播放就不更新贴图 if (needsUpdate_) { //old set needsUpdate map.version++; map.source.needsUpdate = true; } } }); } } else { plane.material.map = new THREE.Texture(info.media); plane.material.map.needsUpdate = true; } plane.material.map.wrapS = plane.material.map.wrapT = THREE.ClampToEdgeWrapping; plane.material.map.minFilter = THREE.LinearFilter; //LinearMipMapLinearFilter 会被缩放到power of 2 plane.material.map.magFilter = THREE.LinearFilter; plane.material.map.anisotropy = 4; plane.material.map.generateMipmaps = false; plane.material.opacity = 1; } else { plane.material.map.image = info.media; plane.material.map.needsUpdate = true; } this.file = info.file; } this.overlayType = info.type; if (!info.frameType && !this.info.isBillboard) info.frameType = 'wall_1'; // 兼容旧数据 this.info.isBillboard || this.addFrame(info.frameType, this.modified !== 'new'); // 需要区分新增数据还是数据库数据 this.limitToOnlyPano = info.limitToOnlyPano ? this.player.model.panos.index[info.limitToOnlyPano] : false; this.limitToOnlyPano && this.limitToOnlyPano != this.player.currentPano && this.hide('limitToOnlyPano'); this.visiblePanos = convertTool.getVisiblePano(this.position, this.player.model); } }, { key: "addFrame", value: function addFrame(frameType, isFromInfo) { // 没有边框直接添加,有不同的边框先删旧的再添加 if (!this.frame || this.frame.type !== frameType || isFromInfo) { if (this.frame) { this.frame.dispose(isFromInfo); this.frame = null; } if (frameType) { // 其他边框替换为wall_1时要重新赋值厚度,初始化或回退的时候不用管 if (!isFromInfo && frameType == 'wall_1') { // depth是实际厚度,depthTemp用于暂存wall_1的厚度 this.depth = this.depthTemp; } var frame = new OverlayFrame(frameType); frame.setOverlay(this, isFromInfo); this.player.OverlayManager.frameGroup.add(frame); } } else { // 相同边框 根据overlay重新计算frame var _this$frame$computeOv = this.frame.computeOverlayTransform({ reverse: true }), position = _this$frame$computeOv.position, quaternion = _this$frame$computeOv.quaternion; this.frame.position.copy(position); this.frame.quaternion.copy(quaternion); } } }, { key: "dispose", value: function dispose() { this.plane.material.dispose(); this.plane.material.map = null; this.parent.remove(this); } }, { key: "inSight", value: function inSight() { if (isEdit$1) return true; // 太容易move了 if (this.player.mode == 'panorama' && this.player.currentPano) { if (this.visiblePanos && !this.visiblePanos.includes(this.player.currentPano)) return false; //最好保存下visiblePanos if (!this.player.camera) return; var cornerPointInfo = this.getCornerPoint(); var cornerPoint; var min = new THREE.Vector2(2, 2); var scaleRatio = 1 / this.player.zoomLevel; //根据media原始大小来调整阈值: media的原始大小能代表期望显示的大小,如果显示大小的远小于期望大小,就不显示(此时能感受到贴图锯齿严重,清晰度被浪费)。比如如果gif是一个很小的按钮,即使diffLon很小也要显示。缺点:需要用户根据所需上传合适清晰度的图。 var size = this.getMediaSize(); if (size.x > 0) { scaleRatio *= Math.sqrt(size.x * size.y) / 1000; } min.multiplyScalar(scaleRatio); if (cornerPointInfo.diffLon < min.x || cornerPointInfo.diffLat < min.y) { //console.log('two far and small') return false; } if (cornerPointInfo.diffLon < 15 && cornerPointInfo.diffLat < 15) { //当很小的时候,只判断中心点即可 cornerPoint = [cornerPointInfo.cornerPoint[0]]; } else { cornerPoint = cornerPointInfo.cornerPoint; } for (var i = 0, j = cornerPoint.length; i < j; i++) { //只要有一点可见就算看见 var pos2d = convertTool.getPos2d(cornerPoint[i], this.player); if (pos2d.trueSide && pos2d.inSight) return true; } } else { //飞出 只判断在不在画面内 var frustumMatrix = new THREE.Matrix4(); frustumMatrix.multiplyMatrices(this.player.camera.projectionMatrix, this.player.camera.matrixWorldInverse); var frustum = new THREE.Frustum(); frustum.setFromProjectionMatrix(frustumMatrix); if (!this.plane.geometry.boundingBox) { this.plane.geometry.computeBoundingBox(); } var bounding = this.plane.geometry.boundingBox.clone().applyMatrix4(this.matrixWorld); return frustum.intersectsBox(bounding); } } }, { key: "getMediaSize", value: function getMediaSize() { var size = new THREE.Vector2(); if (this.info.media instanceof Image) { size.x = this.info.media.width; size.y = this.info.media.height; } else if (this.info.media instanceof HTMLVideoElement) { size.x = this.info.media.videoWidth || 1000; size.y = this.info.media.videoHeight || 1000; } else { size.x = 1000; size.y = 1000; } return size; } }, { key: "getCornerPoint", value: function getCornerPoint() { var _this4 = this; //获取在每个漫游点上的视觉边界点 可以打开boxHelper和addBall来观测是否准确 if (this.cornerPoints[this.player.currentPano.id]) { return this.cornerPoints[this.player.currentPano.id]; } else { var boundPoint, cornerPoint; var center; //中心点 if (this.plane) { center = this.plane.getWorldPosition(new THREE.Vector3()); boundPoint = [new THREE.Vector3(-0.5, 0.5, 0), new THREE.Vector3(0.5, 0.5, 0), new THREE.Vector3(0.5, -0.5, 0), new THREE.Vector3(-0.5, -0.5, 0)]; } var maxLon = -Infinity; var minLon = +Infinity; var maxLat = -Infinity; var minLat = +Infinity; var pos1 = this.player.currentPano.position.clone(); center = this.position.clone(); //模型bound的中心点已经位移到了hot中心点。 注意不能用getWorldPosition,得到的会是偏移的 var dir = center.clone().sub(pos1).normalize(); var centerDirInfo = {}; this.player.cameraControls.controls.panorama.lookAt.call(centerDirInfo, null, dir); boundPoint.forEach(function (e) { //lon左右 var point = e.applyMatrix4(_this4.plane.matrixWorld); var dir = point.clone().sub(pos1).normalize(); var dirInfo = {}; _this4.player.cameraControls.controls.panorama.lookAt.call(dirInfo, null, dir); var diffLon = (dirInfo.lon - centerDirInfo.lon) % 360; if (Math.abs(diffLon) > 180) { //因为有时需要根据符号判断是在中心的左边还是右边,所以限制在180内 diffLon += diffLon > 0 ? -360 : 360; } var diffLat = dirInfo.lat - centerDirInfo.lat; maxLon = Math.max(diffLon, maxLon); minLon = Math.min(diffLon, minLon); maxLat = Math.max(diffLat, maxLat); minLat = Math.min(diffLat, minLat); }); var diffLon = maxLon - minLon; var diffLat = maxLat - minLat; if (diffLat > 180) { //可能是到了反面。不好算,直接返回所有boundPoint cornerPoint = boundPoint; } else { //读取lon lat的最大最小值,勾勒出一个没有倾斜的矩形 。它比boundPoint看起来范围更大些 maxLon = maxLon + centerDirInfo.lon; maxLat = maxLat + centerDirInfo.lat; minLon = minLon + centerDirInfo.lon; minLat = minLat + centerDirInfo.lat; var dirs = [math$1.getDirByLonLat(maxLon, maxLat), math$1.getDirByLonLat(minLon, minLat), math$1.getDirByLonLat(maxLon, minLat), math$1.getDirByLonLat(minLon, maxLat)]; cornerPoint = dirs.map(function (a) { return a.negate().add(pos1); }); cornerPoint = [center].concat(_toConsumableArray(cornerPoint)); //最后增加一个中心点 } /* if(this.objObject){ cornerPoint = [pos2, ...cornerPoint] } */ //addPoints(cornerPoint) this.cornerPoints[this.player.currentPano.id] = { cornerPoint, diffLon, diffLat }; return this.cornerPoints[this.player.currentPano.id]; } } }, { key: "videoControl", value: function videoControl(state) { var video = this.info.media; this.shouldPlay = state; if (!state || state == 'stop') { if (video instanceof HTMLVideoElement && !video.paused) { video.pause(); //console.log('paused ') } /* if(state == 'stop'){ video.currentTime = 0; } */ } else if (state) { if (video.paused || !(video instanceof HTMLVideoElement)) { //console.log('videoControl play ') video = this.loadVideo(); video.play(); //if (common.isVideoPlayed(video)) console.log('played ') } } } }]); return Overlay; }(THREE.Object3D); var CursorDeal = { priorityEvent: [//在前面的优先级高 //grab move crosshair not-allowed { polygonMark_move: 'move' }, { polygonMark_hover: 'pointer' }, { polygonMark_subPen: 'url(' + texture.getImageURL('images/polygon_mark/pic_pen_sub.png') + '),auto' }, { polygonMark_addPen: 'url(' + texture.getImageURL('images/polygon_mark/pic_pen_add.png') + '),auto' }, { polygonMark_pen: 'url(' + texture.getImageURL('images/polygon_mark/pic_pen.png') + '),auto' }, { dragOverlay: 'move' }, { hoverOverlay: 'pointer' }, { hoverMonitor: 'pointer' }, { addOverlay: 'url(https://4dkk.4dage.com/v3-test/img/box_video.png),auto' }, { addOverlay: 'url(https://4dkk.4dage.com/v3-test/img/box_video.png),auto' }, { hoverFootMarker: 'pointer' }, { hoverView: 'pointer' }, { dragView: 'move' }, { viewChoosePos: 'pointer' }], list: [], //当前存在的cursor状态 currentCursorIndex: null, init: function init(player) { /* app.Scene.on('loaded', () => { player = this.app.core.get('Player') this.domElements = [player.domeElement]; }) */ this.domElements = [player.domElement]; }, add: function add(name) { var priorityItem = this.priorityEvent.find(function (e) { return e[name]; }); if (!priorityItem) { console.error('CursorDeal 未定义优先级 name:' + name); return; } if (!this.list.includes(name)) { this.judge({ addItem: priorityItem, name }); this.list.push(name); } }, remove: function remove(name) { var index = this.list.indexOf(name); if (index > -1) { this.list.splice(index, 1); this.judge(); } }, judge: function judge() { var _this = this; var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; //console.log(o,this.list) if (o.addItem) { var addIndex = this.priorityEvent.indexOf(o.addItem); if (addIndex < this.currentCursorIndex || this.currentCursorIndex == void 0) { this.domElements.forEach(function (e) { return e.style.cursor = o.addItem[o.name]; }); this.currentCursorIndex = addIndex; } } else { var levelMax = { index: Infinity, cursor: null }; this.list.forEach(function (name) { var priorityItem = _this.priorityEvent.find(function (e) { return e[name]; }); var index = _this.priorityEvent.indexOf(priorityItem); if (index < levelMax.index) { levelMax.index = index; levelMax.cursor = priorityItem[name]; } }); this.currentCursorIndex = levelMax.index; this.domElements.forEach(function (e) { return e.style.cursor = levelMax.cursor || ''; }); } } }; function _createSuper$1f(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1f(); 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 _isNativeReflectConstruct$1f() { 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 exitFullScreen() { if (document.fullscreenElement && document.fullscreenElement.tagName === 'VIDEO' && document.fullscreenElement.getAttribute('unfullscreen')) { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.oRequestFullscreen) { document.oCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } else if (document.webkitCancelFullScreen) { document.webkitCancelFullScreen(); } setTimeout(function () { exitFullScreen(); }, 250); } } if (browser$1.detectAndroidMobile()) { //针对Android横屏时video会自动全屏播放的bug #39505 #43421 window.addEventListener('resize', function () { //resize时如果全屏元素为video, 退出全屏 setTimeout(function () { exitFullScreen(); }, 500); //太快可能检测不到document.fullscreenElement }); window.addEventListener('orientationchange', function (e) { // 空间视频横屏时会触发自动全屏 if (window.orientation == 0 || window.orientation == 180) { //竖屏 var videos = document.querySelectorAll('video[box]'); //只针对有box属性的video标签(空间视频) videos.forEach(function (item) { item.remove(); }); setTimeout(function () { videos.forEach(function (i) { document.body.appendChild(i); i.play(); }); }, 500); } else { // 横屏 var _videos = document.querySelectorAll('video[box]'); _videos.forEach(function (item) { item.remove(); }); setTimeout(function () { _videos.forEach(function (i) { document.body.appendChild(i); i.play(); }); }, 500); } }); } var FlvVideoPlayerBase = /*#__PURE__*/function (_EventEmitter) { _inherits(FlvVideoPlayerBase, _EventEmitter); var _super = _createSuper$1f(FlvVideoPlayerBase); function FlvVideoPlayerBase(player) { var _this; _classCallCheck(this, FlvVideoPlayerBase); _this = _super.call(this); _this.player = player; _this.instances = new Map(); _this.video = null; return _this; } //overlay info -- [metadata.overlay] _createClass(FlvVideoPlayerBase, [{ key: "addVideo", value: function addVideo(sid) { var instance = this._createVideo(this._getVideoPath(sid)); this.instances.set(sid, instance); instance.videoElement.masters = []; //一个video可以对应多个主体,因为它们链接一样 return instance; } }, { key: "getVideo", value: function getVideo(sid, master) { var instance = this.instances.get(sid); if (!instance) { instance = this.addVideo(sid); } master && instance.videoElement.masters.push(master); return instance.videoElement; } }, { key: "_getVideoPath", value: function _getVideoPath(sid) {//在子类中扩展 } }, { key: "_createVideo", value: function _createVideo(url) { var _this2 = this; var video = document.createElement('video'); video.setAttribute('crossOrigin', 'anonymous'); video.setAttribute('playsinline', 'true'); video.setAttribute('webkit-playsinline', 'true'); video.setAttribute('controls', 'true'); video.setAttribute('unfullscreen', 'true'); video.autoplay = false; video.muted = true; video.loop = true; video.style.position = 'fixed'; video.style.left = '0'; video.style.top = '0'; video.style.zIndex = '0'; video.style.width = '1px'; // video.style.display = 'none' //video.isFirstPlay = true; video.style.opacity = '0'; document.body.appendChild(video); video.player = this; var player = flvjs.createPlayer({ type: 'flv', url: url }); player.videoElement = video; player.attachMediaElement(video); player.on(flvjs.Events.ERROR, function () { _this2._onPlayerError(); console.log('尝试使用mp4链接进行播放'); video.src = url.replace('.flv', '.mp4'); }); player.load(); return player; } }, { key: "_onPlayerError", value: function _onPlayerError() { console.warn('视频加载失败'); } }]); return FlvVideoPlayerBase; }(EventEmitter); function _createSuper$1e(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1e(); 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 _isNativeReflectConstruct$1e() { 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; } } var FlvVideoPlayer$2 = /*#__PURE__*/function (_FlvVideoPlayerBase) { _inherits(FlvVideoPlayer, _FlvVideoPlayerBase); var _super = _createSuper$1e(FlvVideoPlayer); function FlvVideoPlayer(player) { _classCallCheck(this, FlvVideoPlayer); return _super.call(this, player); } _createClass(FlvVideoPlayer, [{ key: "_createVideo", value: function _createVideo(url) { var video = document.createElement('video'); video.setAttribute('crossOrigin', 'anonymous'); video.setAttribute('playsinline', 'true'); video.setAttribute('webkit-playsinline', 'true'); video.setAttribute('controls', 'true'); video.setAttribute('box', 'true'); video.setAttribute('unfullscreen', 'true'); video.autoplay = false; video.muted = true; video.loop = true; video.style.position = 'fixed'; video.style.left = '0'; video.style.top = '0'; video.style.zIndex = '0'; video.style.width = '1px'; // video.style.display = 'none' //video.isFirstPlay = true; video.style.opacity = '0'; document.body.appendChild(video); video.player = this; var player = flvjs.createPlayer({ type: 'flv', url: url }); player.videoElement = video; player.attachMediaElement(video); player.on(flvjs.Events.ERROR, this._onPlayerError.bind(this)); player.load(); return player; } }, { key: "_getVideoPath", value: function _getVideoPath(sid) { // return config.getResourceImageURL(`overlay` + sid + '.flv?m=' + config.version) return this.player.$app.resource.getUserResourceURL(sid + '.flv'); } }]); return FlvVideoPlayer; }(FlvVideoPlayerBase); function _createSuper$1d(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1d(); 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 _isNativeReflectConstruct$1d() { 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; } } var H5VideoPlayerBase = /*#__PURE__*/function (_EventEmitter) { _inherits(H5VideoPlayerBase, _EventEmitter); var _super = _createSuper$1d(H5VideoPlayerBase); function H5VideoPlayerBase(player) { var _this; _classCallCheck(this, H5VideoPlayerBase); _this = _super.call(this); _this.player = player; _this.video = null; _this.videos = new Map(); return _this; } //overlay info -- [metadata.overlay] _createClass(H5VideoPlayerBase, [{ key: "addVideo", value: function addVideo(sid) { var video = this._createVideoElement(this._getVideoPath(sid)); this.videos.set(sid, video); video.masters = []; return video; } }, { key: "getVideo", value: function getVideo(sid, master) { var video = this.videos.get(sid); if (!video) { video = this.addVideo(sid); } master && video.masters.push(master); return video; } }, { key: "_getVideoPath", value: function _getVideoPath(sid) { // return config.getResourceImageURL(window.kankan.config.num + `/overlay` + sid + '.mp4?m=' + config.version) return this.player.$app.resource.getUserResourceURL(sid + '.mp4'); } }, { key: "_createVideoElement", value: function _createVideoElement(src) { var video = document.createElement('video'); video.setAttribute('crossOrigin', 'anonymous'); video.setAttribute('playsinline', 'true'); video.setAttribute('x5-playsinline', 'true'); video.setAttribute('webkit-playsinline', 'true'); video.setAttribute('x5-video-player-type', 'h5'); video.setAttribute('controls', 'true'); video.setAttribute('x-webkit-airplay', 'allow'); video.autoplay = true; video.muted = true; video.loop = true; video.src = src; video.style.position = 'fixed'; video.style.left = '0'; video.style.top = '0'; video.style.zIndex = '1000'; video.style.width = '300px'; video.style.height = '300px'; //video.style.display = browser.urlHasValue('debug') ? 'block' : 'none' //document.body.appendChild(video) return video; } }]); return H5VideoPlayerBase; }(EventEmitter); function _createSuper$1c(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1c(); 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 _isNativeReflectConstruct$1c() { 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; } } var H5VideoPlayer$2 = /*#__PURE__*/function (_H5VideoPlayerBase) { _inherits(H5VideoPlayer, _H5VideoPlayerBase); var _super = _createSuper$1c(H5VideoPlayer); function H5VideoPlayer(player) { _classCallCheck(this, H5VideoPlayer); return _super.call(this, player); } _createClass(H5VideoPlayer, [{ key: "_getVideoPath", value: function _getVideoPath(sid) { // return config.getResourceImageURL(window.kankan.config.num + `/overlay` + sid + '.mp4?m=' + config.version) return this.player.$app.resource.getUserResourceURL(sid + '.mp4'); } }]); return H5VideoPlayer; }(H5VideoPlayerBase); var app$1; var store; function intStore() { store = { version: 1, upPath: '', // videoPath: 'https://4dkk.4dage.com/video/videot-FSVqkqQ0Bi/', //config.getPublicResource("video/video#m#/"), ${this.$app.config.num} // videoPath: config.getResourceURL('video/video' + window.kankan.config.num + '/'), videoPath: app$1.resource.getViewResourceURL('video/'), // scene_view_data/t-RGjyzx4/videos/ config.getResourceURL('video/video/'), videoInfos: new Map(), parameters: { inputWidth: 0, inputHeight: 0, outputWidth: 0, outputHeight: 0, focal: 0, pixel: 0, centerX: 0, centerY: 0, translateX: 0, translateY: 0, translateZ: 0, lenOffsetX: 0, lenOffsetY: 0, videoWidth: 0, videoHeight: 0, mapping: 0, //0-只对x轴做了clip 1-对中央固定区域做clip 2-动态clip cameraType: 0, blend_fov: 5 } }; } function handle(sceneMeta, sdk) { app$1 = sdk; if (!store) intStore(); var imagesVersion = ''; if (typeof sceneMeta.version != 'undefined') { imagesVersion = '?imagesVersion=' + sceneMeta.version; } if (!sceneMeta.videos) { sceneMeta.videos = { version: store.version, videos: store.videoInfos, parameters: store.parameters }; mergeNewPanoVideo(store, sceneMeta['videosUser'], imagesVersion); return; } else { try { var checkvideos = sceneMeta.videos; if (!checkvideos.data || !checkvideos.data.length) { sceneMeta.videos = { version: store.version, videos: store.videoInfos, parameters: store.parameters }; mergeNewPanoVideo(store, sceneMeta['videosUser'], imagesVersion); return; } } catch (err) { console.error(err); } } var sceneFrom = sceneMeta.sceneFrom || 'pro'; if (sceneFrom == 'pro') { //8目 var videosInfo = sceneMeta.videos; var version = videosInfo.version || 0; store.version = version; store.parameters.cameraType = 8; if (version == 1) { videosInfo.data.forEach(function (item) { store.videoInfos.set(item.id, { mp4: { url: store.videoPath + item.id + '.mp4' + imagesVersion }, mpeg: { url: store.videoPath + item.id + '.ts', size: item.tsSize + imagesVersion }, flv: { url: store.videoPath + item.id + '.flv' + imagesVersion }, //Test, exposure: Number(item.value) || 1, mapping: 0, cameraType: 8, blend_fov: item.blend_fov || 5 }); }); } else if (version > 1) { videosInfo.data.forEach(function (item) { store.videoInfos.set(item.id, { mp4: { url: store.videoPath + item.id + '.mp4' + imagesVersion }, mpeg: { url: store.videoPath + item.id + '.ts' + imagesVersion, size: item.tsSize }, flv: { url: store.videoPath + item.id + '.flv' + imagesVersion }, exposure: Number(item.value) || 1, mapping: 1, cameraType: 8, blend_fov: item.blend_fov || 5 }); }); } return loadParameterFor8Cameras(videosInfo.upPath).then(function (store) { if (version <= 2) { store.parameters.inputWidth = 2304; store.parameters.inputHeight = 1728; store.parameters.outputWidth = 2048; store.parameters.outputHeight = 1024; } else if (version > 2) { store.parameters.inputWidth = 4608; store.parameters.inputHeight = 3456; store.parameters.outputWidth = 8192; store.parameters.outputHeight = 4096; store.parameters.lenOffsetX = 1235; store.parameters.lenOffsetY = 954; store.parameters.videoWidth = 2112; store.parameters.videoHeight = 1584; store.parameters.mapping = 1; } sceneMeta.videos = { version: store.version, videos: store.videoInfos, parameters: store.parameters }; // 将新的方案数据融合进来 mergeNewPanoVideo(store, sceneMeta['videosUser'], imagesVersion); return store; }).catch(function (error) { throw error; }); } else if (sceneFrom == 'lite') { //2目 var _videosInfo = sceneMeta.videos; var _version = _videosInfo.version || 0; store.version = _version; store.parameters.cameraType = 2; var _imagesVersion = ''; if (typeof sceneMeta.version != 'undefined') { _imagesVersion = '?imagesVersion=' + sceneMeta.version; } if (_version == 1) { _videosInfo.data.forEach(function (item) { store.videoInfos.set(item.id, { mp4: { url: store.videoPath + item.id + '.mp4' + _imagesVersion }, mpeg: { url: store.videoPath + item.id + '.ts', size: item.tsSize + _imagesVersion }, flv: { url: store.videoPath + item.id + '.flv' + _imagesVersion }, //Test, exposure: Number(item.value) || 1, mapping: 1, cameraType: 2, blend_fov: item.blend_fov || 5 }); }); } return loadParameterFor2Cameras(_videosInfo.upPath).then(function (store) { if (_version == 1) { store.parameters.inputWidth = 3000; store.parameters.inputHeight = 3000; store.parameters.outputWidth = 4096; store.parameters.outputHeight = 2048; store.parameters.pixel = 1.12; } sceneMeta.videos = { version: store.version, videos: store.videoInfos, parameters: store.parameters }; return store; }).catch(function (error) { throw error; }); } else if (sceneFrom == 'minion' || sceneFrom == 'laser') { //转台双目 var _videosInfo2 = sceneMeta.videos; var _version2 = _videosInfo2.version || 0; store.version = _version2; store.parameters.cameraType = 3; var _imagesVersion2 = ''; if (typeof sceneMeta.version != 'undefined') { _imagesVersion2 = '?imagesVersion=' + sceneMeta.version; } _videosInfo2.data.forEach(function (item) { store.videoInfos.set(item.id, { mp4: { url: store.videoPath + item.id + '.mp4' + _imagesVersion2 }, mpeg: { url: store.videoPath + item.id + '.ts', size: item.tsSize + _imagesVersion2 }, flv: { url: store.videoPath + item.id + '.flv' + _imagesVersion2 }, //Test, exposure: Number(item.value) || 1, mapping: 1, cameraType: 3, blend_fov: item.blend_fov || 5 }); }); return loadParameterForRotStereoCameras(_videosInfo2.upPath).then(function (store) { store.parameters.inputWidth = 5472; store.parameters.inputHeight = 3648; store.parameters.outputWidth = 4096; store.parameters.outputHeight = 2048; store.parameters.lenOffsetX = 920; store.parameters.lenOffsetY = 500; store.parameters.videoWidth = 3630; store.parameters.videoHeight = 2670; store.parameters.pixel = 1.12; sceneMeta.videos = { version: store.version, videos: store.videoInfos, parameters: store.parameters }; mergeNewPanoVideo(store, sceneMeta['videosUser'], _imagesVersion2); //add return store; }).catch(function (error) { throw error; }); } else { console.warn('有尚不支持的相机来源:', sceneFrom); } } /** * @type Promise */ var loadParameterPromise = null; function loadParameterFor8Cameras(url) { if (loadParameterPromise) return loadParameterPromise; loadParameterPromise = new Promise(function (resolve, reject) { if (!url) reject('找不到参数请求地址'); http.getText(url).then(function (text) { return resolve(text); }).catch(function (reson) { return reject(reson); }); }).then(function (text) { var formatted = text.split(/\n/).filter(function (item) { return item.trim() != ''; }) //空行分割取第一个 .map(function (item) { return item.split(':'); }); var focal = Number(formatted[0][1]); var pixel = Number(formatted[1][1]); var center = formatted[2][1].trim().split(/\s+/).map(function (item) { return Number(item); }); var translateX = formatted[7][0].trim().split(/\s+/).map(function (item) { return Number(item); })[3], translateY = formatted[8][0].trim().split(/\s+/).map(function (item) { return Number(item); })[3], translateZ = formatted[9][0].trim().split(/\s+/).map(function (item) { return Number(item); })[3]; store.parameters.focal = focal; store.parameters.pixel = pixel; store.parameters.centerX = center[0]; store.parameters.centerY = center[1]; store.parameters.translateX = translateX; store.parameters.translateY = translateY; store.parameters.translateZ = translateZ; return store; }).catch(function (error) { console.warn('球幕视频【八目】:参数文件加载失败', error); return store; }).finally(function () { return store; }); return loadParameterPromise; } function loadParameterFor2Cameras(url) { if (loadParameterPromise) return loadParameterPromise; loadParameterPromise = new Promise(function (resolve, reject) { if (!url) reject('找不到参数请求地址'); http.getText(url, null, function (text) { resolve(text); }, function (reson) { reject(reson); }); }).then(function (text) { var properties = {}; text.split('\n').map(function (line) { if (line.length > 0) { var keyValueParse = line.split(':'); var key = keyValueParse[0]; var values = keyValueParse[1].trim().split(' '); properties[key] = Number(values[0]); } }); store.parameters.focal = properties['focal']; store.parameters.centerX = properties['cx']; store.parameters.centerY = properties['cy']; store.parameters.translateX = properties['tx']; store.parameters.translateY = properties['ty']; store.parameters.translateZ = properties['tz']; return store; }).catch(function (error) { console.warn('球幕视频【双目】:参数文件加载失败'); return store; }).finally(function () { return store; }); return loadParameterPromise; } function loadParameterForRotStereoCameras(url) { // url = url.replace('Uptxt', 'Up.txt') if (loadParameterPromise) return loadParameterPromise; loadParameterPromise = new Promise(function (resolve, reject) { if (!url) reject('找不到参数请求地址'); resolve(http.getText(url)); }).then(function (text) { var properties = {}; text.split('\n').map(function (line) { if (line.length > 0) { var keyValueParse = line.split(':'); var key = keyValueParse[0]; var values = keyValueParse[1].trim().split(' '); properties[key] = Number(values[0]); } }); store.parameters.focal = properties['focal']; store.parameters.centerX = properties['cx']; store.parameters.centerY = properties['cy']; store.parameters.translateX = properties['rx']; store.parameters.translateY = properties['ry']; store.parameters.translateZ = properties['rz']; return store; }).catch(function (error) { console.warn('球幕视频【转台】:参数文件加载失败', error); return store; }).finally(function () { return store; }); return loadParameterPromise; } function mergeNewPanoVideo(store, newScheme, imagesVersion) { // if(config.isEdit){ // return // } if (!newScheme) return; var data = JSON.parse(newScheme); data.forEach(function (item) { store.videoInfos.set(item.panoId, { dir: new THREE.Vector3().copy(item.dir), hfov: parseFloat(item.hfov), vfov: parseFloat(item.vfov), mp4: { url: store.videoPath + item.panoId + '-user.mp4' + imagesVersion }, mpeg: { url: store.videoPath + item.panoId + '-user.ts', size: item.tsSize + imagesVersion }, flv: { url: store.videoPath + item.panoId + '-user.flv' + imagesVersion }, //Test, exposure: 1, clipRect: item.rect, mapping: 2 }); }); store.parameters.mapping = 2; //动态clip store.parameters.cameraType = 8; } function getEnvironment() { if (!store) intStore(); /** * @type 'PC'|'Android'|'Ios' */ var os = 'PC'; /** * @type 'H5'|'WeChat'|'WeChatMiniprogram' */ var environment = 'H5'; if (browser$1.detectAndroidMobile()) { os = 'Android'; } else if (browser$1.detectIOS()) { os = 'Ios'; } if (browser$1.detectWeixin()) { environment = 'WeChat'; if (navigator.userAgent.match('miniProgram')) { environment = 'WeChatMiniprogram'; } } return { os, environment }; } var VersionControl = { handle: handle, getEnvironment: getEnvironment }; function _createSuper$1b(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1b(); 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 _isNativeReflectConstruct$1b() { 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; } } var OverlayManager = /*#__PURE__*/function (_EventEmitter) { _inherits(OverlayManager, _EventEmitter); var _super = _createSuper$1b(OverlayManager); function OverlayManager(player) { var _this; _classCallCheck(this, OverlayManager); _this = _super.call(this); _this.player = player; _this.group = new THREE.Object3D(); _this.group.name = 'OverlayGroup'; _this.frameGroup = new THREE.Object3D(); _this.frameGroup.name = 'OverlayFrameGroup'; player.OverlayManager = _assertThisInitialized(_this); _this.withBox = true; _this.lineMat = LineDraw.createFatLineMat({ depthTest: false, lineWidth: 2, color: '#4fffff', opacity: 0.3 }); _this.model = _this.player.model; _this.model.add(_this.group); _this.model.add(_this.frameGroup); _this.player.$app.core.get('SceneRenderer').addComponent(_assertThisInitialized(_this)); _this.VideoManager = _this.player.$app.VideoManager; var metadata = _this.player.$app.store.getValue('metadata'); if (metadata.boxVideos && metadata.boxVideos.length) { var info = metadata.boxVideos[0]; // let nonsupportH5Video = browser.detectAndroidMobile() //|| browser.detectWeixin() && !browser.detectWeixinMiniProgram() //iphoneX微信不能用flv, vivo var _VersionControl$getEn = VersionControl.getEnvironment(), os = _VersionControl$getEn.os, environment = _VersionControl$getEn.environment; if (window.MediaSource && (os == 'Android' || environment == 'WeChat')) { // 小米自带浏览器、安卓微信只能用FlvVideoPlayer _this.overlayVideoPlayer = new FlvVideoPlayer$2(_this.player); // console.log('use FlvVideoPlayer') } else { // console.log('use H5VideoPlayer') _this.overlayVideoPlayer = new H5VideoPlayer$2(_this.player); } //if (nonsupportH5Video) console.error('nonsupportH5Video') // this.overlayVideoPlayer = nonsupportH5Video ? new FlvVideoPlayer(this.player) : new H5VideoPlayer(this.player) _this.add(new Overlay(_this.player, info, _this.overlayVideoPlayer)); } if (metadata.boxPhotos && metadata.boxPhotos.length) { metadata.boxPhotos.forEach(function (info) { _this.add(new Overlay(_this.player, info)); }); } // let videoEdit = this.VideoManager.BoxVideo.edit // this.player.model.on('floor.changed', (toFloor, mode) => { // this.group.children.forEach(overlay => { // overlay.floor == toFloor ? videoEdit.setVisible(overlay.sid, true) : videoEdit.setVisible(overlay.sid, false) // }) // }) player.on('collectIntersectMesh', function (meshes) { //推送要intersect的mesh meshes.push.apply(meshes, _toConsumableArray(_this.group.children.filter(function (e) { return e.visible; }).map(function (overlay) { return overlay.plane; }))); }); player.on('judgeIntersect', function (intersect, e) { //判断是否intersect了overlay if ( /* e.getConsumed() || */ intersect && (intersect.object.overlayType || intersect.object.parent.overlayType)) { _this.hoverOverlay(intersect.object); e.consume(); } else { _this.hoverOverlay(null); } }); player.on('pointerStart', function () { /* this.intersect = player.getMouseIntersect(null, this.group.children.concat(player.model.colliders)) if (this.intersect && (this.intersect.object.overlayType || this.intersect.object.parent.overlayType)) { this.OverlayManager.hoverOverlay(this.intersect.object) } else this.OverlayManager.hoverOverlay(null) */ //for自动播放 _this.autoPlay(); }); player.on(PlayerEvents.FlyingStarted, function (_ref) { var panoId = _ref.panoId; //if (!this.player.EditOverlay.editPlane) { // 当overlay仅限某一点位显示时,其它点位或飞出则需要隐藏. _this.group.children.forEach(function (e) { if (e.limitToOnlyPano) { if (e.limitToOnlyPano.id != panoId) { e.hide('limitToOnlyPano'); _this.player.EditOverlay.editPlane == e && _this.VideoManager.emit('videos/panel/updatePanoVisi', false); } else { e.show('limitToOnlyPano'); _this.player.EditOverlay.editPlane == e && _this.VideoManager.emit('videos/panel/updatePanoVisi', true); } } }); //} }); if (player.$app.config.view) { //展示页面。 不要遮住漫游点视频 player.on(PlayerEvents.FlyingEnded, function (_ref2) { var currentPano = _ref2.currentPano; var panoVideoFilter; if (player.mode == 'panorama') { panoVideoFilter = currentPano.getVideoFilter(); } _this.group.children.forEach(function (e) { if (panoVideoFilter && panoVideoFilter(e.position)) { e.hide('coveredPanoVideo'); } else { e.show('coveredPanoVideo'); } }); }); //展示页面延迟加载,且监控,可见才播放 _this.group.children.filter(function (e) { return e.info.type == 'video'; }); //如果多个视频就这么写: /* common.batchHandling.addSliceListen({ getList: () => { return videos }, minCount: 0, maxCount: 1, durBound1: 3, durBound2: 13, maxHistory: 3, player: this.player, callback: overlay => { if (overlay.visible && overlay.inSight()) { overlay.videoControl(true) } else { overlay.videoControl(false) } }, }) */ } return _this; } _createClass(OverlayManager, [{ key: "add", value: function add(overlay) { this.group.add(overlay); } }, { key: "show", value: function show(floorIndex, keepHidden) { // this.group.visible = true this.group.children.forEach(function (overlay) { if (keepHidden && overlay.info.hide) return; if (floorIndex == 'all' || overlay.floor.floorIndex == floorIndex) overlay.show('visiOnFloor'); }); } }, { key: "hide", value: function hide(floorIndex) { // this.group.visible = false this.group.children.forEach(function (overlay) { if (floorIndex == 'all' || overlay.floor.floorIndex == floorIndex) overlay.hide('visiOnFloor'); }); } }, { key: "setGroupVisible", value: function setGroupVisible(visi) { this.group.visible = !!visi; this.frameGroup.visible = !!visi; } }, { key: "setSize", value: function setSize(x, y) { // this.lineMat.resolution.set( x,y ); if (this.openOverlay) { this.resizeOverlay(); } } /* hover到overlay时 创建四条fatLine 并渐变opacity由0至1;反之由1至0,最后删除 */ }, { key: "hoverOverlay", value: function hoverOverlay(plane, type) { //这个plane可能是box if (!this.group.visible) return; var overlay; if (this.withBox && plane) { overlay = plane.parent; plane = overlay.plane; } else { overlay = plane; } if (overlay && overlay.info.isBillboard && overlay.targetPano == void 0 && config$4.view) { //无跳转点不响应 return; } if (!this.model.player.billboardManager.editPlane) { //需要一直高亮所编辑的billboard this.highlight(overlay, type); } if (!plane) { if (this.hoveringPlane) { if (this.hoveringPlane.info.isBillboard) { this.model.player.billboardManager.emit('hoverBillboard', { sid: this.hoveringPlane.info.sid, state: false }); } this.hoveringPlane = null; } CursorDeal.remove('hoverOverlay'); CursorDeal.remove('dragOverlay'); return; } if (overlay.isEditing && overlay.info.isBillboard) { CursorDeal.add('dragOverlay'); } else { CursorDeal.add('hoverOverlay'); } this.hoveringPlane = overlay; if (overlay.info.isBillboard) { this.model.player.billboardManager.emit('hoverBillboard', { sid: overlay.info.sid, state: true }); } } }, { key: "highlight", value: function highlight(overlay, type) { var _this2 = this; if (this.player.$app.config.view) return; //4.12.0 新增 查看页不显示高亮边框 //同时只能有一个高亮 var changeTime = 200; if (!overlay) { if (this.highlightPlane) { //console.log('cancel highlight') var cancelFuc = function cancelFuc() { fadePlane.border.children.forEach(function (line) { line.geometry.dispose(); }); fadePlane.remove(fadePlane.border); }; var fadePlane = this.withBox ? this.highlightPlane.plane : this.highlightPlane; transitions$1.cancelById(settings$3.freeze.wallLineShine); if (type == 'soon') { this.lineMat.opacity = 0; cancelFuc(); } else { transitions$1.start(function (progress) { this.lineMat.opacity = 1 - progress; }.bind(this), changeTime, cancelFuc, 0, easing[settings$3.transition.blendEasing], 'wallLineShine', settings$3.freeze.wallLineShine, cancelFuc); } } this.highlightPlane = null; return; } if (!overlay.visible) return; if (overlay == this.highlightPlane) return; // 非编辑状态并且指示牌没有跳转点位,设置不高亮 //if (overlay.info.isBillboard && !overlay.isEditing && !overlay.info.targetPano) return if (this.highlightPlane) { this.highlight(null); } //console.log('highlight') this.highlightPlane = overlay; var points = overlay.plane.geometry.getAttribute('position').array; var borders = new THREE.Object3D(); var indeces = [0, 1, 3, 2]; for (var j = 0; j < 4; j++) { var p = [{ x: points[indeces[j] * 3], y: points[indeces[j] * 3 + 1], z: points[indeces[j] * 3 + 2] }, { x: points[indeces[(j + 1) % 4] * 3], y: points[indeces[(j + 1) % 4] * 3 + 1], z: points[indeces[(j + 1) % 4] * 3 + 2] }]; borders.add(LineDraw.createFatLine(p, { material: this.lineMat })); } // 显示边框前再清除一次所有边框,确保始终只有一个线框显示 this.group.children.forEach(function (overlay) { var fadePlane = _this2.withBox ? overlay.plane : overlay; if (fadePlane.border) { fadePlane.border.children.forEach(function (line) { return line.geometry.dispose(); }); fadePlane.remove(fadePlane.border); } }); this.lineMat.opacity = 0; transitions$1.cancelById(settings$3.freeze.wallLineShine, true); //加true是执行消失时的cancelFun,删除border transitions$1.start(function (opa) { this.lineMat.opacity = opa; }.bind(this), changeTime, null, 0, easing[settings$3.transition.blendEasing], 'wallLineShine', settings$3.freeze.wallLineShine); overlay.plane.border = borders; overlay.plane.add(borders); } }, { key: "getMatFromCss", value: function getMatFromCss(tran) { if (tran.includes('matrix3d')) { var arr = tran.slice(9, -1).split(','); } else { var arr = tran.slice(7, -1).split(','); } arr.forEach(function (v, i) { arr[i] = parseFloat(v); }); if (arr.length == 16) var matrix = new THREE.Matrix4().fromArray(arr);else if (arr.length == 6) var matrix = new THREE.Matrix4().fromArray([arr[0], arr[1], 0, 0, arr[2], arr[3], 0, 0, 0, 0, 1, 0, arr[4], arr[5], 0, 1]); return matrix; } }, { key: "getCssFromMatrix", value: function getCssFromMatrix(matrix) { return 'matrix3d(' + matrix.elements + ')'; } }, { key: "getOverlayOpenPos", value: function getOverlayOpenPos(overlay) { //除了初次获取,在player resize后也要重新获取 ,如果相机还旋转了,也要重新获取 var paddingRatio = 0.9; var ratioW = overlay.width / ($('#player').width() * paddingRatio); var ratioH = overlay.height / ($('#player').height() * paddingRatio); var ratio = 1 / Math.max(ratioW, ratioH); //缩放比例 var x = -overlay.width * ratio / $('#player').width(); var camera = player.cameraControls.activeControl ? player.cameraControls.activeControl.camera : player.camera; var pos3dLeft = new THREE.Vector3(x, 0, -1).unproject(camera); // player.camera的projectMatrix延迟了 var camToLeft = pos3dLeft.clone().sub(player.camera.position); var cameraDir = player.getDirection(); //same as control.lookVector var angle = cameraDir.angleTo(camToLeft); var camDisToPlane = overlay.width / 2 / Math.tan(angle); //plane应该离相机的距离 if (this.withBox) { var boxDepth = overlay.plane.position.length(); camDisToPlane += boxDepth; } var planePos = player.camera.position.clone().add(cameraDir.clone().multiplyScalar(camDisToPlane)); if (!this.useCssRender) this.updatePlaneElemStyle(ratio); return planePos; } }, { key: "updatePlaneElemStyle", value: function updatePlaneElemStyle(ratio) { this.openOverlay.elem.css({ width: this.openOverlay.width * ratio + 'px', height: this.openOverlay.height * ratio + 'px' }); } }, { key: "getPlanePos", value: function getPlanePos(overlay) { if (this.withBox) { return new THREE.Vector3().setFromMatrixPosition(overlay.plane.matrixWorld); } else return overlay.position.clone(); } /* 点击overlay时 box视频只需要飞到最佳观影点即可,根据屏幕宽度和fov,算出刚好屏幕宽度容纳下视频宽度的距离goodDistance */ }, { key: "clickOverlay", value: function clickOverlay(overlay) { var _this3 = this; var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, dontEmit = _ref3.dontEmit, forceFlyToPlane = _ref3.forceFlyToPlane, afterFly = _ref3.afterFly; //如果在outside点击了,要禁止飞入,否则涉及旋转 if (overlay.info.isBillboard) { dontEmit || this.model.player.billboardManager.emit('clickBillboard', { //通知编辑,更新面板 sid: overlay.info.sid //modified: overlay.info.modified, }); var firstViewPano = this.model.player.$app.core.get('Scene').firstView.pano; if (!forceFlyToPlane) { var pano = this.model.player.model.panos.index[overlay.targetPano]; if (pano != void 0 && (pano == firstViewPano || pano.hasNeighbor())) { this.model.player.flyToPano({ pano /* lookAtPoint: overlay.position, //看向的方向最好有个指定 checkAlone: true, */ }); } return; //没有跳转点就不响应 } if (overlay.homePanoId != void 0) { var _pano = this.model.player.model.panos.index[overlay.homePanoId]; if (_pano != void 0 && (_pano == firstViewPano || _pano.hasNeighbor())) { this.model.player.flyToPano({ pano: _pano, lookAtPoint: overlay.position, checkAlone: true }); return; //如果能回到绑定点的话 } } } if (this.openOverlay && !overlay || this.model.player.GLTFEditor.selecting) return; CursorDeal.remove('hoverOverlay'); var plane = this.withBox && overlay ? overlay.plane : overlay; if (overlay.overlayType == 'video') { plane.material.map.image.play(); } //适应屏幕的最佳距离 var tanW = this.player.cameraControls.cameras.panorama.aspect * Math.tan(THREE.MathUtils.degToRad(this.model.player.zoomFov / 2)); var tanH = Math.tan(THREE.MathUtils.degToRad(this.model.player.zoomFov / 2)); var goodDistanceW = overlay.width / 2 / tanW; var goodDistanceH = overlay.height / 2 / tanH; var goodDistance = Math.max(goodDistanceW, goodDistanceH); goodDistance *= goodDistance; console.log('goodDistance ' + goodDistance); if (overlay.limitToOnlyPano) { this.player.flyToPano({ pano: overlay.limitToOnlyPano, lookAtPoint: overlay.position }); } else { // var visiblePanos = convertTool.getVisiblePano(overlay.plane.getWorldPosition(),{model: this.model.player.mainDesign &&this.model.player.mainDesign.editing ? this.model.player.mainDesign.getMeshes(["wallMeshes","objWallMeshes","groundMeshes"]) : null}); var visiblePanos = overlay.visiblePanos; //convertTool.getVisiblePano(overlay.plane.getWorldPosition(new THREE.Vector3()), this.model) if (visiblePanos.length == 0) console.warn('clickOverlay 找不到visiblePanos'); var coss = {}; this.player.$app.Camera.flyToPoint(overlay.position.clone(), { rank: [function (pano) { //寻找正对着overlay的pano var overlayDir = new THREE.Vector3(0, 0, 1).applyQuaternion(overlay.quaternion); var v1 = overlayDir; //.setY(0); 朝上的话set0会得到0,0,0 无法求angle var v2 = pano.position.clone().sub(overlay.position); //.setY(0) //var angle = v1.angleTo(v2) var cos = v1.dot(v2.normalize()); coss[pano.id] = cos; return cos * 200; }, function (pano) { var dis = pano.position.clone().distanceToSquared(overlay.position); var goodDistance2 = goodDistance * Math.abs(coss[pano.id]); //考虑了倾斜角度后的最佳距离 var result = -1 * Math.abs(dis - goodDistance2) / goodDistance2; //dis和goodDistance2差距越大分数越低 //console.log(pano.id, dis, goodDistance2) return result; }, function (i) { var n = i.position.clone().sub(overlay.position).normalize(); return n.dot(_this3.player.getDirection()) * -500; }], require: [function (pano) { //不要被模型遮挡 return visiblePanos.includes(pano); //return pano.floorIndex == overlay.floor.floorIndex && pano.neighbourUUIDs.length > 0 }], dealDistance: 5, //超过这个距离才换pano done: afterFly }); } var isEditing = !dontEmit && this.player.EditOverlay && this.player.EditOverlay.editing; if (!isEditing) return; // 如果已有media在编辑,禁止选中其他media if (this.player.EditOverlay.editPlane && this.player.EditOverlay.editPlane.uuid != overlay.uuid) return; // 当正在添加media plane, 但鼠标并没有停在可用位置时,禁止添加plane if (this.player.EditOverlay.isAdding && this.player.domElement.style.cursor.indexOf('box_video.png') < 0) return; //if (this.player.EditOverlay.isAdding && this.player.OverlayManager.hoveringPlane ) return if (isEditing && this.player.EditOverlay.editPlane != overlay) { //console.log('videos/panel/display面板出现') setTimeout(function () { var infoCopy = JSON.parse(JSON.stringify(overlay.info)); infoCopy.sid = overlay.sid; infoCopy.type = overlay.overlayType; _this3.VideoManager.emit('videos/panel/display', infoCopy); _this3.player.EditOverlay.updateOverlayPanel(overlay); overlay.updateVisibleOnFloor(); //overlay.isHidden ? overlay.hide('forceHide') : overlay.show('forceHide') }, 10); //延迟是为了等待添加overlay的这个页面 created 完,监听才加好 return; } } }, { key: "autoPlay", value: function autoPlay(player) { //有的设备需要和设备交互才能自动播放,如移动端。不这么写video不会播放 . (2022.11.29: 可为何加了Hot.updateHots之后又会自动播了?https有关? this.group.children.forEach(function (overlay) { /* if(overlay.overlayType == 'video' && overlay.shouldPlay){ console.log(1) } */ if (!overlay.clickToPlayInited && overlay.info.media instanceof HTMLVideoElement && !common.isVideoPlayed(overlay.info.media) && overlay.shouldPlay) { console.log('try mobileAutoPlay '); overlay.videoControl(true); if (common.isVideoPlayed(overlay.info.media)) { console.log('clickToPlayInited '); overlay.clickToPlayInited = true; } } }); } }]); return OverlayManager; }(EventEmitter); function _createSuper$1a(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$1a(); 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 _isNativeReflectConstruct$1a() { 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; } } /** * 用于3d video的编辑 */ var EditOverlay = /*#__PURE__*/function (_EventEmitter) { _inherits(EditOverlay, _EventEmitter); var _super = _createSuper$1a(EditOverlay); function EditOverlay(player) { var _this; _classCallCheck(this, EditOverlay); _this = _super.call(this); _this.editing = false; _this.overlayMaxCount = 1; _this.meshGroup = new THREE.Object3D(); _this.player = player; // this.init() return _this; } _createClass(EditOverlay, [{ key: "checkIfCanInit", value: function checkIfCanInit() { return this.player.model && this.player.model.chunks.length && this.player.currentPano && this.player.model.transformControls; } }, { key: "waitToInit", value: function waitToInit() { var _this2 = this; console.log('waitToInit'); var timer = setInterval(function () { if (_this2.checkIfCanInit()) { _this2.init(); clearInterval(timer); } }, 50); } }, { key: "init", value: function init() { var _this3 = this; if (!this.checkIfCanInit()) { this.waitToInit(); return; } this.VideoManager = this.player.$app.VideoManager; this.transformControls = this.player.model.transformControls; this.transformControls.addEventListener('mousing', function (data) { if (data.state == 'overlay') { _this3.VideoManager.emit('VideoManager.BoxVideo.transform', data.mode); _this3.editPlane.frame.update(data); // 拖拽轴向时实时更新overlayFrame } }); this.meshGroup.name = 'overlay-group'; this.player.model.add(this.meshGroup); this.meshGroup.visible = false; this.player.OverlayManager.group.children.forEach(function (overlay) { //获取信息 _this3.updateOverlayInfo(overlay); }); window.addEventListener('keydown', function (e) { //用键盘来切换变换 var mode; if (_this3.editing) return; switch (e.which) { case 87: //w or W mode = 'translate'; break; /* case 69://e or E mode = "rotate"; break; */ case 82: //r or R mode = 'scale'; break; } mode && _this3.VideoManager.emit('videos/panel/switchTclMode', mode); e.stopPropagation(); }); // this.VideoManager.on('videos/panel/useImgRatio', this.useImgRatio.bind(this)) this.enter(); } }, { key: "enter", value: function enter() { if (this.editing) return; this.editing = true; this.meshGroup.visible = true; //this.transformControls.switchEditState('overlay') this.player.cameraControls.controls.dollhouse.resetRanges(3); this.player.cameraControls.controls.panorama.insideLookLimitDown = config$4.isMobile ? -55 : -50; // player.model.wallManager.updateRulersVisi(false); // player.model.cadFloorPlane.changeCadVisible(false) // player.model.cadFloorPlane.updateEntryVisi({visi:false}) // if (this.player.OverlayManager.group.children.length >= this.overlayMaxCount) { // //当前只能加一个视频,所以进入即自动开始添加或编辑 // var overlay = this.player.OverlayManager.group.children[0] // this.player.OverlayManager.clickOverlay(overlay) // } // else { // this.beginToAddPlane() // } } }, { key: "leave", value: function leave() { if (!this.editing) return; this.editing = false; this.endAddPlane(); this.meshGroup.visible = false; this.transformControls.switchEditState(null); this.player.cameraControls.controls.dollhouse.resetRanges(); this.player.cameraControls.controls.panorama.insideLookLimitDown = null; // this.player.model.wallManager.updateRulersVisi() // this.player.model.cadFloorPlane.changeCadVisible(null, { autoJudge: true }) // this.player.model.cadFloorPlane.updateEntryVisi({ autoJudge: true }) // bus.emit("videos/panel/exit") } }, { key: "beginToAddPlane", value: function beginToAddPlane() { //开始添加 this.player.viewLinkManager.exitView(); this.player.reticule.visible = false; // setTimeout(() => { //因为莫名会被其他页面的设置覆盖,所以延迟 //this.player.domElement.style.cursor = `url(https://4dkk.4dage.com/v3-test/img/box_video.png),auto` // playerDiv.style.cursor = `url(${config.getResourceImageURL('img')}/box_video.png),auto` // }, 10) this.isAdding = true; CursorDeal.add('addOverlay'); } }, { key: "endAddPlane", value: function endAddPlane() { //结束添加状态 this.isAdding = false; //this.player.domElement.style.cursor = '' CursorDeal.remove('addOverlay'); this.player.reticule.visible = true; } }, { key: "addOverlay", value: function addOverlay(o) { //调整旋转值,使贴合墙壁,且不重叠。 var normal = o.intersect.face.normal.clone(); var intersectType = Vectors$1.UP.angleTo(normal) > Math.PI / 4 ? 'wall' : 'ground'; if (this.player.getMouseDirection().angleTo(o.intersect.face.normal) < Math.PI / 2) { normal.negate(); } { // v4.6.0 + 使和地面垂直 console.log('normal', normal); if (normal.y > 0.85) { //如果原本平行于地面的话,就使之面对相机的方向 normal = this.player.getMouseDirection().negate(); //this.player.getDirection().negate() } // if(intersectType == "wall") { normal.y = 0; // } else { // normal.x = 0 // normal.z = 0 // } normal.normalize(); } var quaternion = new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().lookAt(normal, Vectors$1.ZERO, Vectors$1.UP)); var position = o.intersect.point.add(normal.multiplyScalar(0.01)); //添加 var overlay = new Overlay(this.player, { sid: common.getRandomSid(), floorIndex: this.player.model.currentFloor.floorIndex, pos: position, qua: quaternion, modified: 'new', frameType: intersectType + '_1' }); overlay.updateMatrixWorld(); this.player.OverlayManager.clickOverlay(overlay); //自动点击 this.VideoManager.emit('videos/panel/switchTclMode', 'translate'); this.endAddPlane(); //自动结束添加 } }, { key: "updateOverlayInfo", value: function updateOverlayInfo(overlay) { if (overlay.info.isBillboard) return; //获取当前overlay的信息, 用于取消时恢复 overlay.info = { width: overlay.width, height: overlay.height, depth: overlay.depth, pos: overlay.position.clone(), qua: overlay.quaternion.clone(), reverse: overlay.scale.x < 0, media: overlay.plane.material.map.image, file: overlay.file, type: overlay.overlayType, hide: overlay.isHidden, frameType: overlay.frame && overlay.frame.type, limitToOnlyPano: overlay.limitToOnlyPano && overlay.limitToOnlyPano.id }; } }, { key: "undoEdit", value: function undoEdit() { // 恢复 if (!this.editPlane) return; var overlay = this.editPlane; if (overlay.modified == 'new') { // 未保存过的video直接删除 this.disposeOverlay(overlay); } else { overlay.setFromInfo(overlay.info); // 如果是已删除的,则恢复 if (overlay.modified == 'delete') this.player.OverlayManager.add(overlay); } } }, { key: "updateOverlayScaleDisplay", value: function updateOverlayScaleDisplay() { //更新视频尺寸的数字 var overlay = this.editPlane; var maxWidth = 190, maxHeight = maxWidth; //maxWidth/2; var ratioW = Math.abs(overlay.width) / maxWidth; var ratioH = Math.abs(overlay.height) / maxHeight; var ratio = 1 / Math.max(ratioW, ratioH); //缩放比例 var w = Math.round(Math.abs(overlay.width) * ratio); var h = Math.round(Math.abs(overlay.height) * ratio); //console.log(overlay.width, overlay.height, overlay.depth) this.VideoManager.emit('videos/panel/changeSize', { wText: overlay.width.toFixed(2), hText: overlay.height.toFixed(2), width: w, height: h, depth: isNaN(overlay.depth) ? settings$3.overlay.depth : overlay.depth }); } }, { key: "updateOverlayPanel", value: function updateOverlayPanel(overlay) { this.editPlane = overlay; var plane = overlay.plane; var video = plane.material.map && plane.material.map.image; this.VideoManager.emit('videos/panel/updatePoster', video); this.updateOverlayScaleDisplay(); this.transformControls.switchEditState('overlay'); if (overlay.frame) { this.VideoManager.emit('videos/panel/changeDepth', overlay.depth * 100); } else { this.VideoManager.emit('videos/panel/changeDepth', 0); } this.player.emit('beginEditOverlay'); } }, { key: "controlSelectOverlay", value: function controlSelectOverlay(overlay) { //控制器的选择 if (overlay && overlay.visible) { //this.transformControls.switchEditState('overlay') overlay.frame ? overlay.frame.switchTranformControls(this.transformControls) : this.transformControls.attach(overlay); } else { this.transformControls.detach(); } } }, { key: "useImgRatio", value: function useImgRatio(o) { //使用素材自身尺寸比例 var plane = this.editPlane.plane; if (!plane.material.map) return; var img = plane.material.map.image; var mintranRatio = 200; //default is 200 , 防止图片太小时在墙上依旧很大 var width = this.editPlane.overlayType == 'video' ? img.videoWidth : img.width; var height = this.editPlane.overlayType == 'video' ? img.videoHeight : img.height; if (o == 'suitSize') { var boundWidth = Math.min(Math.max(width, height) / mintranRatio, 1); if (width > height) { var w = boundWidth; var h = boundWidth * height / width; } else { var h = boundWidth; var w = boundWidth * width / height; } } else { //假设不变总面积 var k = Math.sqrt(Math.abs(this.editPlane.width * this.editPlane.height) / (width * height)); var w = k * width * (this.editPlane.width < 0 ? -1 : 1); var h = k * height * (this.editPlane.height < 0 ? -1 : 1); } this.editPlane.scale.setX(w / settings$3.overlay.width); this.editPlane.scale.setY(h / settings$3.overlay.height); this.editPlane.width = w; this.editPlane.height = h; this.updateOverlayScaleDisplay(); } }, { key: "overlayUploaded", value: function overlayUploaded(file, media) { //video上传成功后,调整overlay var plane = this.editPlane.plane; media.style.width = '100%'; media.style.height = '100%'; if (media instanceof HTMLVideoElement) { plane.material.map = new THREE.VideoTexture(media); plane.material.map.image.play(); this.editPlane.overlayType = 'video'; media.autoplay = true; media.loop = true; media.volume = 0; media.muted = true; } else { plane.material.map = new THREE.Texture(media); plane.material.map.needsUpdate = true; this.editPlane.overlayType = 'photo'; } plane.material.map.minFilter = THREE.LinearFilter; this.useImgRatio(); //自适应比例 this.editPlane.file = file; plane.material.opacity = 1; plane.material.color = new THREE.Color(1, 1, 1); plane.material.needsUpdate = true; // this.updateOverlayInfo(this.editPlane) this.VideoManager.emit('videos/panel/updatePoster', media); this.editPlane.frame && this.editPlane.frame.update({ mode: 'scale' }); } }, { key: "getOverlaySavingInfo", value: function getOverlaySavingInfo() { //获取overlay保存信息 var overlay = this.editPlane; if (!overlay.file && (!overlay.plane.material.map || !overlay.plane.material.map.image)) return; // 当设置limitToOnlyPano时,仅保存时的点位可视 //if (overlay.limitToOnlyPano == true) overlay.limitToOnlyPano = this.player.currentPano var info = { width: math$1.toPrecision(overlay.width, 4), height: math$1.toPrecision(overlay.height, 4), depth: math$1.toPrecision(overlay.depth, 4), pos: math$1.toPrecision(overlay.position.toArray(), 4), qua: math$1.toPrecision(overlay.quaternion.toArray(), 4), reverse: overlay.scale.x < 0, sid: overlay.sid, media: [overlay.overlayType], hide: overlay.isHidden, floorIndex: overlay.floor.floorIndex, frameType: overlay.frame && overlay.frame.type, limitToOnlyPano: overlay.limitToOnlyPano && overlay.limitToOnlyPano.id }; var _self = this; return { data: info, type: overlay.modified == 'new' ? 1 : 0, needSaveMedia: !overlay.info || overlay.file != overlay.info.file, done: function done() { try { // if (overlay.modified == "delete") this.editPlane = null overlay.modified = false; overlay.visiblePanos = convertTool.getVisiblePano(overlay.position, _self.player.model); _self.updateOverlayInfo(overlay); } catch (e) { console.error(e); } } }; } }, { key: "disposeOverlay", value: function disposeOverlay(overlay) { //应用删除 if (overlay == this.player.OverlayManager.hoveringPlane) { this.player.OverlayManager.hoverOverlay(null, 'soon'); } if (overlay.plane.material.map) { //清空video var video = overlay.plane.material.map.image; if (video && video.load) { video.src = ''; video.load(); } } overlay.dispose(); overlay.modified = 'delete'; overlay.frame && overlay.frame.dispose(); } }, { key: "DeleteOverlay", value: function DeleteOverlay(overlay, delFun) { var _this4 = this; //删除 delFun(overlay.sid, function () { //删除成功后: _this4.disposeOverlay(overlay); _this4.controlSelectOverlay(null); }); } }]); return EditOverlay; }(EventEmitter); function _createSuper$19(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$19(); 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 _isNativeReflectConstruct$19() { 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; } } /** * 数据存储对象 */ defineComponent('store', function () { return /*#__PURE__*/function (_Emiter) { _inherits(Store, _Emiter); var _super = _createSuper$19(Store); function Store() { var _this; _classCallCheck(this, Store); _this = _super.call(this); _this.__store = {}; return _this; } /** * 获取指定key的数据 * @param {String} key 名称 * @param {Boolean} reload 是否强制重新加载 */ _createClass(Store, [{ key: "get", value: function () { var _get = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(key, reload) { var data; return regenerator.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (reload) { this.$app.resource.reload = true; } if (!(this.__store[key] && !reload)) { _context.next = 3; break; } return _context.abrupt("return", this.__store[key]); case 3: data = null; if (!(typeof this.$app.resource[key] === 'function')) { _context.next = 8; break; } _context.next = 7; return this.$app.resource[key](); case 7: data = _context.sent; case 8: this.$app.resource.reload = false; return _context.abrupt("return", data || this.__store[key]); case 10: case "end": return _context.stop(); } } }, _callee, this); })); function get(_x, _x2) { return _get.apply(this, arguments); } return get; }() }, { key: "getAppImage", value: function () { var _getAppImage = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2(path) { return regenerator.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: if (!this.__store[path]) { _context2.next = 2; break; } return _context2.abrupt("return", this.__store[path]); case 2: _context2.next = 4; return this.$app.resource.getAppImage(path); case 4: return _context2.abrupt("return", this.__store[path]); case 5: case "end": return _context2.stop(); } } }, _callee2, this); })); function getAppImage(_x3) { return _getAppImage.apply(this, arguments); } return getAppImage; }() }, { key: "getUserImage", value: function () { var _getUserImage = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3(path, reload) { return regenerator.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: if (!(this.__store[path] && !reload)) { _context3.next = 2; break; } return _context3.abrupt("return", this.__store[path]); case 2: _context3.next = 4; return this.$app.resource.getUserImage(path); case 4: return _context3.abrupt("return", this.__store[path]); case 5: case "end": return _context3.stop(); } } }, _callee3, this); })); function getUserImage(_x4, _x5) { return _getUserImage.apply(this, arguments); } return getUserImage; }() /** * 获取指定key的值 * @param {String} key * @returns any */ }, { key: "getValue", value: function getValue(key) { return this.__store[key]; } /** * 设置指定key的值并触发事件 * @param {String} key * @returns any */ }, { key: "setValue", value: function setValue(key, prop, value) { if (typeof key === 'undefined' || typeof prop === 'undefined') { return this; } var target = this.__store[key]; if (target) { target[prop] = value; this.emit(key, target, prop); } return this; } /** * 设置指定key的数据 * @param {String} key 名称 * @param {Object} value 新数据 * @param {Boolean} isCache 是否缓存 */ }, { key: "set", value: function set(key, value) { var isCache = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; if (typeof key === 'undefined') { return this; } if (isCache) { this.__store[key] = value; } this.emit(key, value); } }]); return Store; }(tinyEmitter); }); var DialogList3D = { WalkManger: { enter: "\u5355\u51FB\u8BBE\u7F6E\u9009\u4E2D\u70B9\u4F4D\u6F2B\u6E38\u53EF\u884C\u3002"), firstPointLimit: '初始点位无法隐藏。', link: '漫游到选中点位时,操作点位可以行走。', unLink: '漫游到选中点位时,操作点位不可行走。', show: '该点位已显示', hide: '已隐藏该点位,漫游时将不再显示', deactive: "\u5355\u51FB\u8BBE\u7F6E\u70B9\u4F4D\u6F2B\u6E38\u53EF\u884C\u3002"), activeHidePoint: "\u8BE5\u70B9\u4F4D\u5DF2\u9690\u85CF\uFF0C\u70B9\u51FB\u53EF\u663E\u793A\u3002") }, TagManger: { unLink: '在该点位漫游时不再显示选中热点。' } }; function _createSuper$18(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$18(); 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 _isNativeReflectConstruct$18() { 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; } } /* 漫游可行 和 热点可视 都是利用连线来表示连接性。 借助线的name来判断是否是新增线或者删除的线。每次更换中心点或热点时保存临时信息,然后重新创建线(刷新状态)。 复杂的点是要经常更新连接的footIcon的材质。不可见的pano就是没有neibourPanos的pano,所以漫游可行需要判断修改连接的两个pano的可见性的修改。 */ var panos, panoIndexes; var Link = /*#__PURE__*/function () { function Link(player) { _classCallCheck(this, Link); this.player = player; this.setPanoVisible = false; this.setMultiFloorPanoVisible = false; this.setTagVisible = false; this.footIcons; this.actionIcons; //漫游可见性 this.activePano; //正在设置的漫游中心点 this.panoVLines = {}; //线条 this.panoVTemp; //修改后还没保存的临时数据 //热点可见性 this.tagVsetting; //正在设置的热点中心点 this.tagsVLines = {}; //线条 this.tagVTemp; //修改后还没保存的临时数据 this.linkToFloorPano; //设置楼层连接点时选择的另一层的连接点 panos = player.model.panos.list.filter(function (e) { return e.isAligned(); }); panoIndexes = player.model.panos.index; } _createClass(Link, [{ key: "init", value: function init() { var _this = this; if (this.inited) return; this.footTex1 = texture.load(texture.getImageURL('images/End_256.png')); this.footTex2 = texture.load(texture.getImageURL('images/End_unable_256.png')); this.footTex1_v = texture.load(this.player.$app.resource.getAppURL('images/video_256.png')); /* texture.getImageURL('images/video_256.png') */ this.footTex2_v = texture.load(this.player.$app.resource.getAppURL('images/video_unable_256.png')); // this.footTex3 = texture.load(texture.getImageURL('images/mutil_connect_normal256.png')), // this.footTex4 = texture.load(texture.getImageURL('images/mutil_connect_unable256.png')), this.footTex5 = texture.load(texture.getImageURL('images/mutil_connect_upper.png')); this.footTex6 = texture.load(texture.getImageURL('images/mutil_connect_lower.png')); this.actionVisiTex0 = texture.load(texture.getImageURL('images/roam/roam_invisible.png')); this.actionVisiTex1 = texture.load(texture.getImageURL('images/roam/roam_visible.png')); this.actionLinkTex0 = texture.load(texture.getImageURL('images/roam/roam_uncheck.png')); this.actionLinkTex1 = texture.load(texture.getImageURL('images/roam/roam_checked.png')); this.ifAllPanoNoNeighbor(); this.meshGroup = new THREE.Object3D(); this.meshGroup.name = 'setVisible-group'; this.player.model.add(this.meshGroup); this.player.model.on('floor.changed', function (toFloor, mode) { if (_this.setTagVisible || _this.setPanoVisible) { //正在设置可视 _this.gotoFloor(toFloor.floorIndex); } }); this.player.on('collectIntersectMesh', function (meshes) { //推送要intersect的mesh if (_this.footIcons && (_this.setPanoVisible || _this.setTagVisible)) { meshes.push.apply(meshes, _toConsumableArray(_this.footIcons)); } }); this.player.on('judgeIntersect', function (intersect, e) { //判断是否intersect了 footIcon if (e.getConsumed() || _this.setPanoVisible || _this.setTagVisible) { if (intersect && intersect.object.type == 'FootIcon' /* && this.intersect.object.visible */ ) { CursorDeal.add('hoverFootMarker'); } else { CursorDeal.remove('hoverFootMarker'); } e.consume(); } }); this.inited = true; } }, { key: "enterSet", value: function enterSet(type) { var _this2 = this; this.init(); // toast: `单击设置选中点位漫游可行。` this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.enter', content: DialogList3D.WalkManger.enter, showClose: true }); if (type == 'panoVisible') { if (!this.player.modeTran) { //一开始就在这个页面 this.player.afterCModeFuc = function () { _this2.enterSet(type); }; return; } this.setPanoVisible = true; this.player.flyoutType = 'beginSetPanoVisible'; // if (this.player.modeTran.split('-')[1] != 'floorplan') { // setTimeout(this.beginSetPanoVisible.bind(this), 300) // } else { this.beginSetPanoVisible(); // } setTimeout(function () { //刚开始的页面就是设置漫游可行时飞出来角度很奇怪,但是延迟一下就不会,原因未知 _this2.player.flyToMode('floorplan', function () { _this2.updateFootIconSize(); _this2.focusFloor(); }); }, 10); } else { this.beginSetTagVisible(); this.player.flyToMode('floorplan', function () { _this2.focusFloor(); }); } } /** * 用于选中和取消“全部漫游可行” * @param {undefined | "all"} show * @returns */ }, { key: "toggle", value: function toggle(show) { var _this3 = this; //console.log('walk/Set ' + show) var activePano = this.activePano; if (!show) { // 当前点位是初始点位时,禁止隐藏 var firstView = this.player.$app.core.get('Scene').firstView; /* let p = this.getCurNeighbors(firstView.pano)-----被驳回,所以先注释 let firstViewWillHide = p.length == 1 && p.includes(activePano.id) */ if (firstView.pano == this.activePano /* && this.checkHasNeighbor(firstView.pano, 'beforeCreateLine') */ ) { // toast: `初始点位无法隐藏。` this.player.$app.WalkManager.emit(this.checkLinkStatus()); this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.firstPointLimit', content: DialogList3D.WalkManger.firstPointLimit, showClose: true }); return false; } // 全部取消连接 for (var _i in this.panoVLines) { //隐藏相当于点击所有连线的footIcon /* if (firstViewWillHide && i == firstView.pano.id) { -----被驳回,所以先注释 this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.firstPointLimit', content: DialogList3D.WalkManger.firstPointLimit, showClose: true }) continue } */ this.panoVLines[_i].visible && this.dealPanoVisible(_i); } } else { var list = common.sortByScore(panos, [function (e) { return e.isAligned(); }], [function (pano) { return -pano.position.distanceTo(activePano.position); }]); if (list.length == 1) { console.log('仅有一个漫游点'); return; } var okList = []; var s = Math.max(-list[1].score * 2, 4); //i==1的一定显示 if (show == 'all') { // 全部连接 okList = list.filter(function (data) { return data.score != 0 && data.item.footIcon.visible; } /* || this.panoVLines[data.item.id] */ ); /* //包括原先连接的另一个楼 */ okList.forEach(function (e) { return _this3.panoVLines[e.item.id] && _this3.panoVLines[e.item.id].visible || _this3.dealPanoVisible(e.item.id); }); } else { //连接周围一定距离内、到该点没有遮挡的pano var ifBlock = function ifBlock(panoA, panoB) { var A = panoA.position.clone(); var B = panoB.position.clone(); return convertTool.ifIntersectChunks(A, B, {}); }; for (var i = 1; i < list.length; i++) { if (-list[i].score < s) { if (ifBlock(activePano, list[i].item)) { list[i].block = true; //有阻挡 } list[i].good = true; } else { okList || (okList = list.filter(function (e) { return e.good && !e.block; })); //绝对可以使用的 if (okList.length < 2) { if (!ifBlock(activePano, list[i].item)) { if (okList.length == 0) { okList.push(list[i]); } else { //1 var lastPos = okList[0].item.position.clone().sub(activePano.position).setY(0); var thisPos = list[i].item.position.clone().sub(activePano.position).setY(0); if (lastPos.angleTo(thisPos) > Math.PI / 2) { console.log('再加一个 角度' + THREE.MathUtils.radToDeg(lastPos.angleTo(thisPos))); break; } } } } else { break; } } } if (okList.length == 0) { //如果length为0,至少加一个pano, 虽然是遮挡的 okList.push(list[0]); } okList.forEach(function (e) { return _this3.dealPanoVisible(e.pano.id); }); } //console.log(okList) } this.checkFloorLinkStatus(); return true; } //共同的 }, { key: "setDisplay", value: function setDisplay(state) { //在设置时一直显示视频漫游点,即使它被隐藏了 //panos.forEach(pano => pano.updateMarkerVisible(true, this.player)) this.player.path.currentPanoMarker.mesh.visible = !state; this.player.OverlayManager && this.player.OverlayManager.setGroupVisible(!state); this.player.reticule.visible = !state; this.player.emit('linkEditorSetVisible', state); if (!state && this.footIcons) { for (var i = 0; i < this.footIcons.length; i++) { var s = this.footIcons[i].pano.label._oriScale; if (s == void 0) break; this.footIcons[i].pano.marker.add(this.footIcons[i].pano.label); //放回 this.footIcons[i].pano.label.scale.set(s, s, s); delete this.footIcons[i].pano.label._oriScale; this.footIcons[i].pano.label.sprite.material.color.set('#fff'); this.footIcons[i].pano.label.sprite.material.opacity = 1; } } } //----------------漫游可见性--------------------------------- }, { key: "beginSetPanoVisible", value: function beginSetPanoVisible() { this.panoVTemp = {}; if (this.player.currentPano.floor != this.player.model.currentFloor) { //总是切到当前漫游点的楼层 this.player.gotoFloor(this.player.currentPano.floor.floorIndex); } this.SetOnePanoVisible(this.player.currentPano); this.setDisplay(true); // UI根据是否emit过LinkStatus来判断是否编辑过,初次进入默认activePano时需要标明还未编辑 this.player.$app.WalkManager.emit(this.checkLinkStatus(), 'enter'); } }, { key: "SetOnePanoVisible", value: function SetOnePanoVisible(pano) { //点击某个pano后就对该pano点进行设置 if (this.activePano == pano) return; this.activePano = pano; //记录正在修改的 this.delVisibleLines(); //删除线 this.showFootIcons(pano, true); this.createPanoVisiLines(pano); //创线 } }, { key: "checkPanoVisiChange", value: function checkPanoVisiChange() { if (Object.keys(this.panoVTemp).length) return true; for (var r in this.panoVLines) { var line = this.panoVLines[r]; if (line.name.indexOf('new') > -1 && line.visible) { //新设置为visible且没有取消 return true; } else if (line.name.indexOf('new') == -1 && !line.visible) { //旧的且已经取消 return true; } } return false; } }, { key: "saveLastPanoVi", value: function saveLastPanoVi(pano) { pano = pano || this.activePano; //xzw add on 2023.6.1 if (!pano) return; //保存刚设置过的pano var change = []; for (var r in this.panoVLines) { //所有修改信息都藏在线里~ var line = this.panoVLines[r]; if (line.name.indexOf('new') > -1 && line.visible) { //新设置为visible且没有取消 change.push({ type: 'add', id: r }); } else if (line.name.indexOf('new') == -1 && !line.visible) { //旧的且已经取消 change.push({ type: 'sub', id: r }); } } if (change.length) { var panoId = pano.id; //(pano && pano.id) || this.activePano.id this.savePanoVisiChange(panoId, change); } } }, { key: "savePanoVisiChange", value: function savePanoVisiChange(panoId, change) { //添加双向的neighbour: 将修改写入panoVTemp数据 var self = this.searchNeib(panoId); var seeMarkers_self = self.seeMarkers; var neighbourUUIDs_self = self.neighbourUUIDs; var neighbourPanos_self = self.neighbourPanos; for (var i = 0; i < change.length; i++) { var other = this.searchNeib(change[i].id); var seeMarkers = other.seeMarkers; var neighbourUUIDs = other.neighbourUUIDs; var neighbourPanos = other.neighbourPanos; if (change[i].type == 'add') { seeMarkers.push(panoId); neighbourUUIDs.push(panoId); neighbourPanos[panoId] = true; seeMarkers_self.push(change[i].id); neighbourUUIDs_self.push(change[i].id); neighbourPanos_self[change[i].id] = true; } else { var index = seeMarkers.indexOf(panoId); index > -1 && seeMarkers.splice(index, 1); var index = neighbourUUIDs.indexOf(panoId); index > -1 && neighbourUUIDs.splice(index, 1); neighbourPanos[panoId] = false; var index = seeMarkers_self.indexOf(change[i].id); index > -1 && seeMarkers_self.splice(index, 1); var index = neighbourUUIDs_self.indexOf(change[i].id); index > -1 && neighbourUUIDs_self.splice(index, 1); neighbourPanos_self[change[i].id] = false; } this.panoVTemp[change[i].id] = { //后面两个是作为保存到后台的数据存储,临时需要用到的是第一个 neighbourPanos: neighbourPanos, seeMarkers: seeMarkers, neighbourUUIDs: neighbourUUIDs }; } this.panoVTemp[panoId] = { //加上自己 neighbourPanos: neighbourPanos_self, seeMarkers: seeMarkers_self, neighbourUUIDs: neighbourUUIDs_self }; } }, { key: "pauseSetPanoVisible", value: function pauseSetPanoVisible(type, currentFloor) { var _this4 = this; //暂停 因为点击了保存设置 但没有退出设置 if (!this.setPanoVisible) return; if (type == 'unsaved') { //中途点击pano从而停止一个热点的设置 this.saveLastPanoVi(); } else { this.panoVTemp = {}; //清空数据 this.startEditPano = null; } this.delVisibleLines(); this.activePano = null; this.showFootIcons(null, true, currentFloor); //清空选择 //这句要放在this.activePano = null后。 根据可见性更改透明度 panos.forEach(function (pano) { return _this4.changeIconVisiState(pano.footIcon, _this4.checkHasNeighbor(pano)); }); } //按理说改变了neighbourPano,tag的初始visible也要改。但是这样还要考虑已经改过的tag。。很麻烦 }, { key: "finishSetPanoVisible", value: function finishSetPanoVisible() { //结束 退出这个设置 if (!this.setPanoVisible) return; //否则会加多个侦听 this.setPanoVisible = false; this.hideFootIcons(); this.delVisibleLines(); this.recoverAllState2(); this.activePano = null; this.startEditPano = null; this.panoVTemp = {}; this.player.flyoutType = null; this.setDisplay(false); CursorDeal.remove('hoverFootMarker'); } //最佳推荐操作顺序: 先设置pano可见性 再创建热点 这样热点的visible正确些,否则之后再设置热点可见性会改更多 }, { key: "savePanoVisibles", value: function savePanoVisibles(fuc) { //保存 if (this.activePano) this.saveLastPanoVi(this.activePano); //获取最后设置的那个热点的改动 var PanoData = []; for (var i in this.panoVTemp) { PanoData.push({ //希望算法部不会更改index排序,或者更改后能将visible信息一并更改 panoID: i, visibles: this.turnToPanoIndex(this.panoVTemp[i].seeMarkers), visibles3: this.turnToPanoIndex(this.panoVTemp[i].neighbourUUIDs) }); } if (PanoData.length == 0) { //没改变 console.warn('PanoLink没有改变'); return; } return PanoData; } }, { key: "afterSavePanoVisibles", value: function afterSavePanoVisibles() { var _this5 = this; //实施: for (var i in this.panoVTemp) { var pano = panoIndexes[i]; pano.seeMarkers = this.panoVTemp[i].seeMarkers; pano.neighbourUUIDs = this.panoVTemp[i].neighbourUUIDs; pano.neighbourPanos = this.panoVTemp[i].neighbourPanos; } var self = this; if (!this.checkHasNeighbor(this.player.currentPano)) { //currentPano变为孤立点 就要换一个防止飞入 var list = common.sortByScore(panos, [function (pano) { return _this5.checkHasNeighbor(pano); }], [function (pano) { return -pano.position.distanceTo(self.player.currentPano.position); }]); if (list && list.length) { this.player.currentPano = list[0].item; //找最近的一非孤立点 this.noPanoHasNeighbor = false; //更新状态 } else { this.noPanoHasNeighbor = true; //更新状态 } } else { this.noPanoHasNeighbor = false; //更新状态 } this.pauseSetPanoVisible(); this.player.$app.WalkManager.emit('walkManager.deactive'); this.updateFootIconSize(); //更新一下center大小 写在最后 } }, { key: "searchNeib", value: function searchNeib(panoId) { //寻找某pano的相关neighbour 可能是修改过的 var o = {}; if (this.panoVTemp[panoId]) { o.seeMarkers = this.panoVTemp[panoId].seeMarkers; o.neighbourUUIDs = this.panoVTemp[panoId].neighbourUUIDs; o.neighbourPanos = this.panoVTemp[panoId].neighbourPanos; } else { o.seeMarkers = panoIndexes[panoId].seeMarkers.slice(0); o.neighbourUUIDs = panoIndexes[panoId].neighbourUUIDs.slice(0); o.neighbourPanos = common.CloneObject(panoIndexes[panoId].neighbourPanos); } return o; } }, { key: "turnToPanoIndex", value: function turnToPanoIndex(panoArr) { var array = []; for (var i = 0; i < panoArr.length; i++) { var pano = panoIndexes[panoArr[i]]; var index = panos.indexOf(pano); array.push(index); } return array; } //========热点可见性============== }, { key: "beginSetTagVisible", value: function beginSetTagVisible() { if (this.setTagVisible) return; this.setTagVisible = true; this.tagVTemp = {}; //临时存储改动的tag的visible this.setDisplay(true); } }, { key: "SetOneTagVisible", value: function SetOneTagVisible(tag) { //点击某个热点后就对该热点进行设置,或者在热点修改时对其进行设置 if (this.tagVsetting == tag) return; if (this.tagVsetting) { this.saveLastTagVi(this.tagVsetting); } this.tagVsetting = tag; //记录正在修改的 this.delVisibleLines(); //删除线 this.showFootIcons(); this.createTagVisiLines(tag); //创线 this.updateFootIconSize(); //更新一下大小,尤其是上次换了中心点然后退出又进入但是镜头没有变化的话 this.player.$app.TagManager.emit(this.checkTagLinkStatus()); } }, { key: "checkTagVisiChange", value: function checkTagVisiChange() { if (Object.keys(this.tagVTemp).length) return true; for (var r in this.tagsVLines) { var line = this.tagsVLines[r]; if (line.name.indexOf('new') > -1 && line.visible) { //新设置为visible且没有取消 return true; } else if (line.name.indexOf('new') == -1 && !line.visible) { //旧的且已经取消 return true; } } return false; } }, { key: "checkTagLinkStatus", value: function checkTagLinkStatus() { var visibleLines = Object.values(this.tagsVLines).filter(function (line) { return line.visible; }); var visibleIcon = this.footIcons.filter(function (icon) { return icon.visible; }); //是连接还是不连接 if (visibleIcon.length == visibleLines.length) { // 全部连接 return 'tagManager.linkAll'; } else if (visibleLines.length == 0) { // 没有连接 return 'tagManager.linkNone'; } else { // 部分连接 return 'tagManager.linkSome'; } } }, { key: "saveLastTagVi", value: function saveLastTagVi() { //保存刚设置过的tag var change = false; var newVPs = this.tagVTemp[this.tagVsetting.sid] || this.tagVsetting.visiblePanos.slice(0); for (var r in this.tagsVLines) { var line = this.tagsVLines[r]; if (line.name.indexOf('new') > -1 && line.visible) { //新设置为visible且没有取消 newVPs.push(panoIndexes[r]); change = true; //console.log("add: "+r) } else if (line.name.indexOf('new') == -1 && !line.visible) { //旧的且已经取消 var i = newVPs.map(function (pano) { return pano.id; }).indexOf(r); if (i == -1) { console.log('visiblePanos删除error'); continue; } newVPs.splice(i, 1); change = true; //console.log("sub: "+r) } } if (change) { this.tagVTemp[this.tagVsetting.sid] = newVPs; } } }, { key: "pauseSetTagVisible", value: function pauseSetTagVisible(type) { //pc保存后删除连线 但还在继续设置 点选热点即开始 if (!this.setTagVisible || !this.tagVsetting) return; if (type == 'unsaved') { //中途点击pano从而停止一个热点的设置 this.saveLastTagVi(this.tagVsetting); } else { this.tagVTemp = {}; //清空数据 } this.delVisibleLines(); this.hideFootIcons(); this.tagVsetting = null; } }, { key: "finishSetTagVisible", value: function finishSetTagVisible() { if (!this.setTagVisible) return; this.pauseSetTagVisible(); this.setTagVisible = false; this.setDisplay(false); } }, { key: "saveTagVisibles", value: function saveTagVisibles() { //保存到服务器 if (this.tagVsetting) this.saveLastTagVi(this.tagVsetting); //获取最后设置的那个热点的改动 //可能出现数据没变但保存的情况。比如先改变了然后切换别的热点但切换回来时又改回来。 var tags = []; for (var i in this.tagVTemp) { tags.push({ sid: i, value: this.tagVTemp[i].filter(function (pano) { return !!pano; }).map(function (pano) { return pano.id; }) //turnToPanoIndex(this.tagVTemp[i]) }); } return tags; } }, { key: "afterSaveTagVisibles", value: function afterSaveTagVisibles() { this.finishSetTagVisible(); //还是保存完直接结束吧,因为现在热点可视不放在单独的设置页面了 } //------------visibles--------tag-------------------------------- }, { key: "createTagVisiLines", value: function createTagVisiLines(tag) { var _this6 = this; // 热点可见性线条 var visibleList = this.tagVTemp[tag.sid] || tag.visiblePanos; visibleList.forEach(function (pano) { /* if (pano && pano.floor.floorIndex == this.player.model.currentFloor.floorIndex) */ _this6.createTagSingleLine(pano, 'old', tag); }); } }, { key: "createTagSingleLine", value: function createTagSingleLine(pano, type, tag) { var line = LineDraw.createLine([pano.floorPosition.clone(), tag.position.clone()], { color: Colors.green }); this.meshGroup.add(line); line.name = 'tagVL-' + type + '-' + pano.id; this.tagsVLines[pano.id] = line; line.material.opacity = pano.floor.floorIndex == this.player.model.currentFloor.floorIndex ? 1 : 0.4; this.changeIconLinkState(panoIndexes[pano.id].footIcon, 'linked'); } }, { key: "dealTagVisible", value: function dealTagVisible(tag, panoName) { //外部调用 if (this.tagsVLines[panoName]) { this.tagsVLines[panoName].visible = !this.tagsVLines[panoName].visible; this.changeIconLinkState(panoIndexes[panoName].footIcon, this.tagsVLines[panoName].visible ? 'linked' : false); if (!this.tagsVLines[panoName].visible) this.player.$app.gui.toast({ event: 'DialogList3D.TagManger.unLink', content: DialogList3D.TagManger.unLink, showClose: true }); } else { this.createTagSingleLine(panoIndexes[panoName], 'new', tag); } this.player.$app.TagManager.emit(this.checkTagLinkStatus()); } }, { key: "setTagHideAll", value: function setTagHideAll(tag) { var _this7 = this; //外部调用 Object.keys(this.tagsVLines).forEach(function (panoName) { _this7.tagsVLines[panoName].visible = false; _this7.changeIconLinkState(panoIndexes[panoName].footIcon, false); }); } }, { key: "setTagShowAll", value: function setTagShowAll(tag) { var _this8 = this; //外部调用 this.footIcons.filter(function (icon) { return icon.visible; }).forEach(function (icon) { var panoName = icon.pano.id; if (_this8.tagsVLines[panoName]) { _this8.tagsVLines[panoName].visible = true; _this8.changeIconLinkState(panoIndexes[panoName].footIcon, 'linked'); } else { _this8.createTagSingleLine(panoIndexes[panoName], 'new', tag); } }); } }, { key: "delVisibleLines", value: function delVisibleLines() { //xzw add 所有线都删除 for (var i in this.tagsVLines) { this.tagsVLines[i].geometry.dispose(); this.tagsVLines[i].material.dispose(); this.meshGroup.remove(this.tagsVLines[i]); delete this.tagsVLines[i]; } for (var i in this.panoVLines) { this.panoVLines[i].geometry.dispose(); this.panoVLines[i].material.dispose(); this.meshGroup.remove(this.panoVLines[i]); delete this.panoVLines[i]; } } //--------panoVisible }, { key: "createPanoVisiLines", value: function createPanoVisiLines(pano, isAllFloor) { // pano可见性线条 var neighbours = this.panoVTemp[pano.id] && this.panoVTemp[pano.id].neighbourPanos || pano.neighbourPanos; for (var r in neighbours) { if (neighbours[r] && r != pano.id && !r.includes('view360_')) { // if (panoIndexes[r].floorIndex != pano.floorIndex && !isAllFloor) continue // 多楼层连接点不显示虚线 this.createPanoSingleLine(pano, 'old', r); } } } }, { key: "createPanoSingleLine", value: function createPanoSingleLine(pano, type, id) { //pano是中心 var pano2 = panoIndexes[id]; if (pano2.panoType) return; // 过滤掉场景关联pano var p2 = pano2.floorPosition.clone(); /* .sub(objects.player.model.position) */ var line = LineDraw.createLine([pano.floorPosition.clone() /* .sub(this.position) */ , p2], { color: Colors.green, deshed: pano2.floorIndex != pano.floorIndex }); this.meshGroup.add(line); line.name = 'PanoVL-' + type + '-' + id; pano2.floorIndex != pano.floorIndex && (line.material.opacity = 0.5); //连接到另一楼层的pano this.panoVLines[id] = line; if (this.activePano) { if (pano2.floorIndex != pano.floorIndex) this.changeIconLinkState(panoIndexes[id].footIcon, 'otherFloorLink');else this.changeIconLinkState(panoIndexes[id].footIcon, 'linked'); } } }, { key: "dealPanoVisible", value: function dealPanoVisible(panoId, icon) { var _this9 = this; //外部调用 if (this.setMultiFloorPanoVisible) { // 设置多楼层连接点时(点击的icon都是要添加的,无法取消) if (this.linkToFloorPano) { //取消旧的 var lastIcon = this.linkToFloorPano.footIcon; this.changeIconLinkState(lastIcon, false); var isLinkingFloor = this.changeFloorIconState(lastIcon); if (!isLinkingFloor) { lastIcon.status = 'visible'; lastIcon.material.uniforms.map.value = this.linkToFloorPano.hasVideo ? this.footTex1_v : this.footTex1; } } else { this.player.$app.WalkManager.emit('walkManager.multiFloorLinking', true); //解锁确定按钮 } this.linkToFloorPano = icon.pano; this.changeIconLinkState(icon, 'center'); if (this.setMultiFloorPanoVisible == 'upper') { // 下楼点 icon.status = 'floor'; icon.material.uniforms.map.value = this.footTex6; } else { icon.status = 'floor'; icon.material.uniforms.map.value = this.footTex5; } } else if (icon && icon.type == 'FootIcon') { //切换activePano if (this.activePano) { if (panoId == this.activePano.id) { if (!this.startEditPano) this.startEditPano = this.activePano; // 用于撤销时激活修改之前的pano(deactive,link,unlink) // 关闭当前pano设置 this.player.$app.WalkManager.emit('walkManager.deactive'); this.pauseSetPanoVisible('unsaved'); // 将actionIcon切换到是否可视(眼睛模式) this.actionIcons.forEach(function (i) { return i.material.map = i.footIcon.status == 'invisible' ? _this9.actionVisiTex0 : _this9.actionVisiTex1; }); // toast: `单击设置点位漫游可行。` this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.deactive', content: DialogList3D.WalkManger.deactive }); } else { this.lastFloorActivePano = null; this.pauseSetPanoVisible('unsaved'); this.SetOnePanoVisible(panoIndexes[panoId]); this.player.$app.WalkManager.emit('walkManager.active', this.checkLinkStatus()); } } else { // 激活当前pano设置 this.lastFloorActivePano = null; this.SetOnePanoVisible(panoIndexes[panoId]); this.player.$app.WalkManager.emit('walkManager.active', this.checkLinkStatus()); } } else if (!icon || icon.type == 'ActionIcon') { if (this.activePano) { // 连接 或 取消连接 var link; if (this.panoVLines[panoId]) { this.panoVLines[panoId].visible = !this.panoVLines[panoId].visible; link = this.panoVLines[panoId].visible; this.changeIconLinkState(panoIndexes[panoId].footIcon, panoIndexes[panoId].footIcon.visible ? this.panoVLines[panoId].visible ? 'linked' : false : 'otherFloorLink'); } else { this.createPanoSingleLine(this.activePano, 'new', panoId); link = true; } if (!this.startEditPano) this.startEditPano = this.activePano; // 用于撤销时激活修改之前的pano(deactive,link,unlink) if (link) { // 如果进行连接,直接判断该点是可见的(有附近点),(不能通过checkHasNeighbor来判断,因为新增的线条可能不在它的neighbour中 this.changeIconVisiState(panoIndexes[panoId].footIcon, true); this.changeIconVisiState(this.activePano.footIcon, true); // 只当点击ActionIcon时才toast if (icon && icon.type == 'ActionIcon') { this.player.$app.WalkManager.emit(this.checkLinkStatus()); } } else { // 如果取消连接,则需要checkHasNeighbor var firstViewPano = this.player.$app.core.get('Scene').firstView.pano; if (panoIndexes[panoId].floorIndex != this.activePano.floorIndex) { //取消楼层连接点 xzw panoIndexes[panoId].footIcon.visible = false; } else { var pickPanoCheck = this.checkHasNeighbor(panoIndexes[panoId]); this.changeIconVisiState(panoIndexes[panoId].footIcon, pickPanoCheck); } var activePanoCheck = this.checkHasNeighbor(this.activePano); //let activePanoCheck2 = this.checkHasNeighbor(panoIndexes[panoId]) -----被驳回,所以先注释 this.changeIconVisiState(this.activePano.footIcon, activePanoCheck); if (icon && icon.type == 'ActionIcon') { this.player.$app.WalkManager.emit(this.checkLinkStatus()); if (!activePanoCheck && this.activePano == firstViewPano /* || (!activePanoCheck2 && panoIndexes[panoId] == firstViewPano)-----被驳回,所以先注释 */ ) { // toast: `初始点位无法隐藏。` this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.firstPointLimit', content: DialogList3D.WalkManger.firstPointLimit }); this.dealPanoVisible(panoId, icon); //还原 return; } if (!activePanoCheck) { this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.hide', content: DialogList3D.WalkManger.hide }); } } } } else { // 显示 或 隐藏 // // var neighbours = (this.panoVTemp[panoIndexes[panoId].id] && this.panoVTemp[panoIndexes[panoId].id].neighbourPanos) || panoIndexes[panoId].neighbourPanos // // let neigbIds = Object.keys(neighbours) if (icon.footIcon.status == 'invisible') { //变为可见点 if (this.panoVTemp[panoId]) { // 未保存 还原保存前的neighbourPanos var neighbourIds = Object.keys(this.panoVTemp[panoId].neighbourPanos).filter(function (id) { return !id.includes('view360_') && id != panoId; }); var a = neighbourIds.filter(function (id) { return _this9.checkHasNeighbor(panoIndexes[id]); }); //尽量不选择已经隐藏了的,否则手动隐藏了又会被显示 bugID=36883# if (a.length) neighbourIds = a;else neighbourIds = neighbourIds.slice(0, 1); var change = []; neighbourIds.forEach(function (nId) { change.push({ type: 'add', id: nId }); }); this.savePanoVisiChange(panoId, change); } else { // 已保存,自动计算neighbourPanos(有可能变为楼层连接点) var _neighbourIds = convertTool.getVisiblePano(panoIndexes[panoId].position, this.player.model).map(function (pano) { return pano.id; }).filter(function (id) { return id != panoId; }); if (_neighbourIds.length == 0) { //随便选一个近的点吧(没有验证过) var list = common.sortByScore(panos, [function (e) { return e.isAligned(); }], [function (pano) { return -pano.position.distanceTo(panoIndexes[panoId].position); }]); var pano0 = list.map(function (e) { return e.item; }).find(function (pano) { return _this9.checkHasNeighbor(pano); }); //尽量不选择已经隐藏了的 if (pano0) _neighbourIds = [pano0.id];else _neighbourIds = [list[0].item.id]; } else { var _a = _neighbourIds.filter(function (id) { return _this9.checkHasNeighbor(panoIndexes[id]); }); //尽量不选择已经隐藏了的,否则手动隐藏了又会被显示 bugID=36883# if (_a.length) _neighbourIds = _a;else _neighbourIds = _neighbourIds.slice(0, 1); } var _change = []; _neighbourIds.forEach(function (nId) { return _change.push({ type: 'add', id: nId }); }); this.savePanoVisiChange(panoId, _change); } // toast: '该点位已显示' this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.show', content: DialogList3D.WalkManger.show }); } else { //变为不可见点 var firstView = this.player.$app.core.get('Scene').firstView; var isHideFirstView = firstView.pano.footIcon == icon.footIcon; if (isHideFirstView) { // toast: `初始点位无法隐藏。` this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.firstPointLimit', content: DialogList3D.WalkManger.firstPointLimit }); return false; } /* let p = this.getCurNeighbors(firstView.pano) -----被驳回,所以先注释 let firstViewWillHide = p.length == 1 && p.includes(panoId) */ this.createPanoVisiLines(panoIndexes[panoId], true); Object.values(this.panoVLines).forEach(function (line) { /* if (firstViewWillHide && line.name.split('-')[2] == firstView.pano.id) {-----被驳回,所以先注释 this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.firstPointLimit', content: DialogList3D.WalkManger.firstPointLimit }) return } */ line.visible = false; }); // toast: '已隐藏该点位,漫游时将不再显示' /* firstViewWillHide || */ this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.hide', content: DialogList3D.WalkManger.hide }); this.saveLastPanoVi(panoIndexes[panoId]); // this.pauseSetPanoVisible('unsaved') this.delVisibleLines(); } panos.forEach(function (pano) { return _this9.changeIconVisiState(pano.footIcon, _this9.checkHasNeighbor(pano)); }); } } this.updateFootIconSize(); } }, { key: "showFootIcons", value: function showFootIcons(centerPano, isPanovisible, currentFloor) { var _this10 = this; if (!this.footIcons) { this.footIcons = []; this.actionIcons = []; var scale = 0.4; scale *= 40 / Math.sqrt(Math.min(this.player.domElement.clientWidth, this.player.domElement.clientHeight)); //屏幕越小,放得越大 scale = THREE.MathUtils.clamp(scale, 0.3, 0.7); // console.error("scale"+scale) var geo = new THREE.PlaneGeometry(scale, scale, 1, 1); var actionGeo = geo.clone(); actionGeo.scale(0.5, 0.5, 0.5); panos.forEach(function (pano) { var foot = new FootIcon(geo, pano); foot.material.uniforms.map.value = pano.hasVideo ? _this10.footTex1_v : _this10.footTex1; foot.visible = false; pano.footIcon = foot; var actionIcon = new ActionIcon(foot, actionGeo, pano); actionIcon.material.map = _this10.actionLinkTex0; foot.actionIcon = actionIcon; _this10.meshGroup.add(foot); foot.add(actionIcon); _this10.footIcons.push(foot); _this10.actionIcons.push(actionIcon); }); } currentFloor = currentFloor || this.player.model.currentFloor; panos.forEach(function (pano) { if (pano.label.parent != pano.footIcon) { pano.label._oriScale = pano.label.scale.x; var numS = 1.65 * pano.label.scale.x; pano.label.scale.set(numS, numS, numS); pano.footIcon.add(pano.label); pano.footIcon.label = pano.label; } if (pano.floor == currentFloor) { pano.footIcon.visible = true; _this10.changeIconLinkState(pano.footIcon, false); if (isPanovisible) { _this10.changeIconVisiState(pano.footIcon, _this10.checkHasNeighbor(panoIndexes[pano.id], 'beforeCreateLine')); } if (centerPano && pano == centerPano) { //pano为中心 或者 currentPano 所以放大一点 pano.footIcon.oriScale = new THREE.Vector3(1.5, 1.5, 1.5); if (isPanovisible) { //currentPano特殊些: _this10.changeIconLinkState(pano.footIcon, 'center'); } } else { pano.footIcon.oriScale = new THREE.Vector3(1, 1, 1); pano.footIcon.actionIcon.visible = true; } } else { var neighbourUUIDs = _this10.panoVTemp && _this10.panoVTemp[pano.id] ? _this10.panoVTemp[pano.id].neighbourUUIDs : pano.neighbourUUIDs; var linkToActivePano = neighbourUUIDs.filter(function (id) { return centerPano && id == centerPano.id; }); pano.footIcon.oriScale = new THREE.Vector3(1, 1, 1); if (linkToActivePano.length > 0) { if (isPanovisible) { _this10.changeFloorIconState(pano.footIcon); } _this10.changeIconLinkState(pano.footIcon, 'otherFloorLink'); } else { pano.footIcon.visible = false; } } }); } }, { key: "checkHasNeighbor", value: function checkHasNeighbor(pano, state) { //检查当前状态pano点是否有可通行点 var neighbours = this.panoVTemp && this.panoVTemp[pano.id] ? this.panoVTemp[pano.id].neighbourPanos : pano.neighbourPanos; if (state != 'beforeCreateLine' && pano == this.activePano) { //是中心点的话。state == "beforeCreateLine"代表是showFootIcon时, 这时候线还没创建,无法用线判断中心点有几个相邻点,直接用neighbourPanos for (var i in this.panoVLines) { if (this.panoVLines[i].visible) { return true; //有一条线即可 } } return; } for (var i in neighbours) { if (i == pano.id || isNaN(parseInt(i))) continue; if (neighbours[i]) { if (this.activePano && this.activePano.id == i && this.panoVLines[pano.id] && !this.panoVLines[pano.id].visible) continue;else if (this.activePano == pano && this.panoVLines[i] && !this.panoVLines[i].visible) continue; return true; } } return false; } }, { key: "getCurNeighbors", value: function getCurNeighbors(pano) { //检查当前状态pano点是否有可通行点 var neighbours = this.panoVTemp && this.panoVTemp[pano.id] ? this.panoVTemp[pano.id].neighbourPanos : pano.neighbourPanos; var neighbourIds = []; for (var i in neighbours) { if (i == pano.id || isNaN(parseInt(i))) continue; if (neighbours[i]) { if (this.activePano && this.activePano.id == i && this.panoVLines[pano.id] && !this.panoVLines[pano.id].visible) continue;else if (this.activePano == pano && this.panoVLines[i] && !this.panoVLines[i].visible) continue;else neighbourIds.push(i); } } return neighbourIds; } }, { key: "ifAllPanoNoNeighbor", value: function ifAllPanoNoNeighbor() { //检查是否全是孤立点 for (var i in panoIndexes) { if (!panoIndexes[i].isAligned()) continue; if (this.checkHasNeighbor(panoIndexes[i])) { return false; } } this.noPanoHasNeighbor = true; return true; //是全部没有neighbour } }, { key: "changeIconLinkState", value: function changeIconLinkState(footIcon, state) { if (!footIcon) return; var color; footIcon.otherFloorLink = false; if (state == 'linked') { color = Colors.green; footIcon.actionIcon.material.map = this.actionLinkTex1; } if (state == 'otherFloorLink') { color = Colors.yellow; footIcon.actionIcon.visible = false; footIcon.material.uniforms.opacity.value = 0.5; footIcon.label.sprite.material.opacity = 0.5; footIcon.visible = true; //xzw add footIcon.otherFloorLink = true; } if (state == 'center') { color = Colors.yellow; footIcon.actionIcon.visible = false; } if (state == false) { color = '#fff'; footIcon.actionIcon.material.map = this.actionLinkTex0; } // footIcon.status = state try { footIcon.material.uniforms.color.value.set(color); footIcon.label.sprite.material.color.set(color); } catch (e) { console.log(e); } } }, { key: "checkLinkStatus", value: function checkLinkStatus() { this.checkFloorLinkStatus(); var visibleLines = Object.values(this.panoVLines).filter(function (line) { return line.visible; }); var visibleIcon = this.footIcons.filter(function (icon) { return icon.visible; }); //是连接还是不连接 if (visibleIcon.length == visibleLines.length + 1) { // 全部连接 return 'walkManager.linkAll'; } else if (visibleLines.length == 0) { // 没有连接 return 'walkManager.linkNone'; } else { // 部分连接 return 'walkManager.linkSome'; } } }, { key: "changeIconVisiState", value: function changeIconVisiState(footIcon, state) { if (!footIcon) return; // 初始点位永远可见 if (footIcon.pano == this.player.$app.core.get('Scene').firstView.pano) state = true; //是可见点还是不可见点 if (state) { footIcon.status = 'visible'; footIcon.material.uniforms.map.value = footIcon.pano.hasVideo ? this.footTex1_v : this.footTex1; // 眼睛变亮 if (!this.activePano) footIcon.actionIcon.material.map = this.actionVisiTex1; footIcon.otherFloorLink || (footIcon.material.uniforms.opacity.value = 1, footIcon.label.sprite.material.opacity = 1); this.changeFloorIconState(footIcon); } else { //不可见 footIcon.status = 'invisible'; var footIconMap = footIcon.material.uniforms.map; footIconMap.value = footIcon.pano.hasVideo ? this.footTex2_v : this.footTex2; // 眼睛变暗 if (!this.activePano) footIcon.actionIcon.material.map = this.actionVisiTex0; if (!this.activePano || this.activePano.id != footIcon.name) { //非中心点时 footIcon.material.uniforms.opacity.value = 0.5; footIcon.label.sprite.material.opacity = 0.5; } else { //变为中心点时 footIcon.material.uniforms.opacity.value = 1; footIcon.label.sprite.material.opacity = 1; // toast: `该点位已隐藏,点击可显示。` this.player.$app.gui.toast({ event: 'DialogList3D.WalkManger.activeHidePoint', content: DialogList3D.WalkManger.activeHidePoint }); } } } }, { key: "changeFloorIconState", value: function changeFloorIconState(footIcon) { var _this11 = this; if (!footIcon) return; //是否为楼层连接点 var pano = panoIndexes[footIcon.name]; var neighbourUUIDs = this.panoVTemp && this.panoVTemp[pano.id] ? this.panoVTemp[pano.id].neighbourUUIDs : pano.neighbourUUIDs; var linkToOtherFloor = neighbourUUIDs.filter(function (id) { return panoIndexes[id].floorIndex != pano.floorIndex && (!_this11.activePano || !_this11.panoVLines[id] || _this11.panoVLines[id].visible); }).map(function (id) { return panoIndexes[id].floor; }); if (linkToOtherFloor.length) { // 因为负楼层的问题,不能使用floorIndex if (this.getFloorOrder(linkToOtherFloor[0]) > this.getFloorOrder(pano.floor)) { //(linkToOtherFloor[0].center.y > pano.floor.center.y) { // 上楼点 footIcon.status = 'floor'; footIcon.material.uniforms.map.value = this.footTex5; } else if (this.getFloorOrder(linkToOtherFloor[0]) < this.getFloorOrder(pano.floor)) { // 下楼点 footIcon.status = 'floor'; footIcon.material.uniforms.map.value = this.footTex6; } return true; } else { // 不是楼层连接点 return false; } } // 获取离指定pano最近的上一层或下一层的pano(dir: "up"|"down") }, { key: "getClosestOtherFloorPano", value: function getClosestOtherFloorPano(pano, dir) { return this.player.model.panos.closestPanoTowardPoint({ point: pano.position, getAll: true }).map(function (p) { return p.pano; }).filter(function (p) { return dir == 'up' ? p.floorIndex > pano.floorIndex : p.floorIndex < pano.floorIndex; })[0]; } //xzw改 2023.6.7和ui一致,根据floorplan.json 中的id来定楼顺序------- }, { key: "checkFloorLinkStatus", value: function checkFloorLinkStatus() { var _this12 = this; var linkFloorStatus = 'walkManager.unlinkFloor'; var neighbours = this.panoVTemp[this.activePano.id] && this.panoVTemp[this.activePano.id].neighbourUUIDs || panoIndexes[this.activePano.id].neighbourUUIDs; var otherFloorPano = neighbours.map(function (pId) { return panoIndexes[pId]; }).filter(function (pano) { return pano.floorIndex != _this12.activePano.floorIndex && (!_this12.activePano || !_this12.panoVLines[pano.id] || _this12.panoVLines[pano.id].visible); })[0]; // 目前只检测单对单连接 if (otherFloorPano && this.getFloorOrder(otherFloorPano.floor) > this.getFloorOrder(this.activePano.floor)) linkFloorStatus = 'walkManager.linkUpperFloor'; if (otherFloorPano && this.getFloorOrder(otherFloorPano.floor) < this.getFloorOrder(this.activePano.floor)) linkFloorStatus = 'walkManager.linkLowerFloor'; //暂时不考虑两种都存在的情况 this.player.$app.WalkManager.emit(linkFloorStatus); } }, { key: "getFloorOrder", value: function getFloorOrder(floor) { var floorsData = this.player.$app.store.getValue('flooruser').floors; var curInfo = floorsData.find(function (e) { return e.subgroup == floor.floorIndex; }); return curInfo.id; } }, { key: "getFloor", value: function getFloor(floorIndex, type) { //获取上一层或下一层 var floors = this.player.model.floors; floors.index[floorIndex]; var floorsData = this.player.$app.store.getValue('flooruser').floors; var curInfo = floorsData.find(function (e) { return e.subgroup == floorIndex; }); var id = type == 'upper' ? curInfo.id + 1 : curInfo.id - 1; var upperInfo = floorsData.find(function (e) { return e.id == id; }); //id代表楼层 console.log('getFloor', type, floorIndex, upperInfo.subgroup); return upperInfo.subgroup; //subgroup就是floorIndex } //-------------------------------------------- /* getUpperFloor(floorIndex) { let floors = this.player.model.floors let currentFloor = floors.index[floorIndex] let upperFloor = { index: floorIndex, height: 9999, } floors.list.forEach(floor => { if ( floor.center.y > currentFloor.center.y && // 上面的楼层 Math.abs(floor.center.y - currentFloor.center.y) < Math.abs(upperFloor.height - currentFloor.center.y) // 最近 ) { upperFloor.index = floor.floorIndex upperFloor.height = floor.center.y } }) return upperFloor.index } getLowerFloor(floorIndex) { let floors = this.player.model.floors let currentFloor = floors.index[floorIndex] let upperFloor = { index: floorIndex, height: 9999, } floors.list.forEach(floor => { if ( floor.center.y < currentFloor.center.y && // 下面的楼层 Math.abs(floor.center.y - currentFloor.center.y) < Math.abs(upperFloor.height - currentFloor.center.y) // 最近 ) { upperFloor.index = floor.floorIndex upperFloor.height = floor.center.y } }) return upperFloor.index } checkFloorLinkStatus() { let linkFloorStatus = 'walkManager.unlinkFloor' let neighbours = (this.panoVTemp[this.activePano.id] && this.panoVTemp[this.activePano.id].neighbourUUIDs) || panoIndexes[this.activePano.id].neighbourUUIDs let othe rFloorPano = neighbours .map(pId => panoIndexes[pId]) .filter(pano => pano.floorIndex != this.activePano.floorIndex && (!this.activePano || !this.panoVLines[pano.id] || this.panoVLines[pano.id].visible))[0] // 目前只检测单对单连接 if (otherFloorPano && otherFloorPano.floor.center.y > this.activePano.floor.center.y) linkFloorStatus = 'walkManager.linkUpperFloor' if (otherFloorPano && otherFloorPano.floor.center.y < this.activePano.floor.center.y) linkFloorStatus = 'walkManager.linkLowerFloor' this.player.$app.WalkManager.emit(linkFloorStatus) } */ }, { key: "recoverAllState2", value: function recoverAllState2() { //为了热点可视恢复成pano全部可见 for (var i = 0; i < this.footIcons.length; i++) { this.footIcons[i].material.uniforms.opacity.value = 1; this.footIcons[i].label.sprite.material.opacity = 1; this.footIcons[i].material.uniforms.map.value = this.footIcons[i].pano.hasVideo ? this.footTex1_v : this.footTex1; } } }, { key: "hideFootIcons", value: function hideFootIcons() { if (!this.footIcons) return; for (var i = 0; i < this.footIcons.length; i++) { this.footIcons[i].visible = false; this.footIcons[i].actionIcon.visible = true; } } }, { key: "updateFootIconSize", value: function updateFootIconSize() { if (!this.footIcons) return; var s = math$1.getScaleForConstantSize({ width2d: 240, position: new THREE.Vector3(), camera: this.player.camera, dom: this.player.$app.dom }); //无论任何设备大小,呈现的icon大小一致 var player = this.player; s = THREE.MathUtils.clamp(s, 0.6, 2.5); // 最大值不可太大,否则场景缩小后容易重叠 this.footIcons.forEach(function (f) { f.visible && f.scale.copy(f.oriScale).multiplyScalar(s); // 使footIcons随相机逆旋转,保证其角度不变 f.quaternion.copy(player.quaternion); }); } }, { key: "resetTagVisiByModel", value: function resetTagVisiByModel() { //自动计算所有热点的可视 当模型修改后所有的热点可视都会重新自动计算(用户的设置将被覆盖) var visiTags = []; for (var i in objects.tagManager.tags) { var tag = objects.tagManager.tags[i]; if (tag.state == 'videoPanoFlag') continue; var visiblePanos = tag.getVisiblePanos(); visiTags.push({ sid: tag.sid, value: visiblePanos }); } return visiTags; } }, { key: "afterResetTagVisibles", value: function afterResetTagVisibles(visiTags) { visiTags.forEach(function (info) { objects.tagManager.tags[info.sid].setVisiblePanos(info.value); }); if (objects.player.mode == 'panorama') objects.tagManager.updateVisible('panorama'); } }, { key: "resetVisiblesByModel", value: function resetVisiblesByModel() { //自动计算所有热点和漫游点的可视 this.resetTagVisiByModel(); } }, { key: "gotoFloor", value: function gotoFloor(index) { var _this13 = this; if (this.player.model.currentFloor.floorIndex != index) return; var floor = this.player.model.floors.index[index]; // 记录跳转楼层前的activePano,用于跳回时再激活 // 跳转其他floor后没有新activepano,则在跳转回该floor时激活lastFloorActivePano // 跳转其他floor后有新activepano,则lastFloorActivePano赋值为null if (this.activePano) this.lastFloorActivePano = this.activePano; if (this.setTagVisible) { //this.pauseSetTagVisible('unsaved', floor) if (this.tagVsetting) { this.hideFootIcons(); this.showFootIcons(); for (var id in this.tagsVLines) { if (panoIndexes[id].floor.floorIndex == this.player.model.currentFloor.floorIndex && this.tagsVLines[id].visible) { this.tagsVLines[id].material.opacity = 1; this.changeIconLinkState(panoIndexes[id].footIcon, 'linked'); } else { this.tagsVLines[id].material.opacity = 0.4; } } } } else if (this.setPanoVisible) { this.pauseSetPanoVisible('unsaved', floor); setTimeout(function () { if (_this13.lastFloorActivePano && _this13.lastFloorActivePano.floorIndex == index) { _this13.SetOnePanoVisible(_this13.lastFloorActivePano); _this13.player.$app.WalkManager.emit('walkManager.active', _this13.checkLinkStatus()); } else { _this13.player.$app.WalkManager.emit('walkManager.deactive'); } }, 1); } //var size = this.getFitBoundSize(floor) this.focusFloor(floor); } }, { key: "focusFloor", value: function focusFloor(floor) { floor = floor || this.player.model.currentFloor; var bound = floor.boundingBox.clone(); if (this.setTagVisible) { this.player.$app.TagManager.tags.forEach(function (tag) { if (tag.floorIndex == floor.floorIndex) { bound.expandByPoint(tag.position); } }); } var center = bound.getCenter(new THREE.Vector3()); var size = bound.getSize(new THREE.Vector3()); this.player.focusPoint({ modelSize: size, aim: center }); } /* getFitBoundSize(floor, size_) { if (!size_) { size_ = floor.size } var MinWidth = (this.player.domElement.clientWidth + this.player.domElement.clientHeight) / 160 //size的x和z不小于MinWidth是为了防止当bound很小时放太大 根据屏幕大小,如果屏幕小会被缩小所以放大些 var w = size_.x var h = size_.y var size = new THREE.Vector3( w < MinWidth ? (MinWidth + floor.size.x) / 2 : Math.min(w + floor.size.x * 0.3, floor.size.x), 1, h < MinWidth ? (MinWidth + floor.size.z) / 2 : Math.min(h + floor.size.z * 0.3, floor.size.z) ) return size } */ }]); return Link; }(); var FootIcon = /*#__PURE__*/function (_THREE$Mesh) { _inherits(FootIcon, _THREE$Mesh); var _super = _createSuper$18(FootIcon); function FootIcon(geo, pano) { var _this14; _classCallCheck(this, FootIcon); _this14 = _super.call(this); _this14.geometry = geo; _this14.material = new THREE.RawShaderMaterial({ vertexShader: shaders.waypoint.vertexShader, fragmentShader: shaders.waypoint.fragmentShader, uniforms: THREE.UniformsUtils.clone(shaders.waypoint.uniforms), // side: THREE.DoubleSide, transparent: !0, depthWrite: !1, depthTest: false, name: 'footIcon' }); _this14.material.uniforms.color.value.set('#ffffff'); _this14.renderOrder = RenderOrder.footIcon; _this14.type = 'FootIcon'; _this14.name = pano.id; _this14.pano = pano; _this14.status = ''; _this14.position.copy(pano.floorPosition.clone()); _this14.position.y /= 100; //使之集体小于action的高度 _this14.lookAt(_this14.position.clone().add(new THREE.Vector3(0, 1, 0))); return _this14; } return FootIcon; }(THREE.Mesh); /** * 勾图标 */ var ActionIcon = /*#__PURE__*/function (_THREE$Mesh2) { _inherits(ActionIcon, _THREE$Mesh2); var _super2 = _createSuper$18(ActionIcon); function ActionIcon(footIcon, geo, pano) { var _this15; _classCallCheck(this, ActionIcon); _this15 = _super2.call(this); _this15.geometry = geo; _this15.material = new THREE.MeshPhongMaterial({ // side: THREE.DoubleSide, transparent: !0, depthTest: false, name: 'footIcon' }); _this15.footIcon = footIcon; _this15.renderOrder = RenderOrder.footIcon + 1; _this15.type = 'ActionIcon'; _this15.name = pano.id; _this15.pano = pano; _this15.position.set(0.2, 0.2, 1); //z是高度,抬高是为了点击时优先于footIcon被选中. 为了遮住所有高低不等的footicon,z需要设置高一些 return _this15; } return ActionIcon; }(THREE.Mesh); function _createSuper$17(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$17(); 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 _isNativeReflectConstruct$17() { 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; } } var DollLabel = /*#__PURE__*/function (_THREE$EventDispatche) { _inherits(DollLabel, _THREE$EventDispatche); var _super = _createSuper$17(DollLabel); function DollLabel(player, o) { var _this; _classCallCheck(this, DollLabel); _this = _super.call(this); _this.player = player; _this.position = o.pos; _this.sid = o.sid; _this.text = o.text || ''; _this.toPano = o.toPano; _this.clickFun = o.clickFun; _this.noLine = o.noLine; _this.driftDir = o.driftDir; _this.floorIndex = o.floorIndex; _this.elem = document.createElement('div'); _this.elem.className = 'room-label'; _this.elem.style.display = 'none'; _this.elem.innerHTML = "

".concat(_this.text, "

"); o.container ? o.container.append(_this.elem) : document.querySelector('.widgets-doll-labels').append(_this.elem); _this.player.dollLabels.push(_assertThisInitialized(_this)); _this.elem.addEventListener('click', _this.clickFuc.bind(_assertThisInitialized(_this))); _this.enable = true; _this.type = 'doll'; _this.pos2d = new THREE.Vector3(); if (_this.noLine) _this.elem.className += ' noLine'; //去掉线的话 _this.visible = true; //2023.6新增 用于控制多原因隐藏 player.on('beginShowMonitor', function () { common.updateVisible(_assertThisInitialized(_this), 'showMonitor', false); }); player.on('leavedShowMonitor', function () { common.updateVisible(_assertThisInitialized(_this), 'showMonitor', true); }); return _this; } _createClass(DollLabel, [{ key: "changeText", value: function changeText(t) { this.elem.querySelector('span').innerHTML = this.text = t; } }, { key: "update", value: function update() { //enable只和是否有cad图相关 if (this.player.mode !== 'dollhouse' || !this.enable || !this.visible || !this.text || this.player.model.currentFloor.floorIndex != this.floorIndex && !this.player.model.allFloorsVisible || this.player.EditOverlay && this.player.EditOverlay.editing || this.player.linkEditor && (this.player.linkEditor.setPanoVisible || this.player.linkEditor.setTagVisible) // )) ) { this.elem.style.display = 'none'; return; } var p = convertTool.getPos2d(this.position, this.player); if (!p.trueSide) { this.elem.style.display = 'none'; return; } //判断label是否被模型遮挡,遮挡则消失 if (convertTool.ifShelter(this.position, this.player, { x: p.vector.x, y: p.vector.y }, null, this.player.model.allFloorsVisible ? null : this.floorIndex)) { this.elem.style.display = 'none'; return; } this.elem.style.display = ''; //先显示,driftDir才能计算位置 if (this.driftDir) { //针对入户门标识。 label位置相对position向外偏移一段(driftDir为箭头方向),保证label的外沿相对position距离spaceDis个像素,这样看上去就会贴近箭头且距离稳定。 var driftPoint = convertTool.getPos2d(this.position.clone().add(this.driftDir), this.player); //先将label置于position的位置,然后求从箭头开始到position的这条射线在label的rect中的二维交点(向外的那个交点) var rect = this.elem.children[0].getBoundingClientRect(); var crossPos2d = math$1.getCrossPointAtRect(driftPoint.pos, p.pos, rect.width, rect.height, p.pos.x - rect.width / 2, p.pos.y - rect.height / 2); var driftVec = crossPos2d.sub(p.pos.clone()); //得到二维偏移方向 var dis = this.position.distanceTo(this.player.camera.position); var spaceDis = 100 / dis; //边距(距离position) 为了防止离远时看起来似乎较远,除以一下相机距离 //将label的二维位置向外偏移 长度为label的中心到label边缘(crossPos2d)的距离 外加一小段spaceDis var result = p.pos.clone().add(driftVec.multiplyScalar((spaceDis + driftVec.length()) / driftVec.length())); this.elem.style.left = result.x + 'px'; this.elem.style.top = result.y + 'px'; } else { this.elem.style.left = p.pos.x + 'px'; this.elem.style.top = p.pos.y + 'px'; } this.pos2d = p.vector; } }, { key: "clickFuc", value: function clickFuc() { if (this.toPano) this.player.flyToPano({ pano: this.toPano });else if (this.clickFun) this.clickFun(); } }, { key: "remove", value: function remove() { var parentElem = this.elem.parentElement; // document.querySelector('.widgets-doll-labels') parentElem && parentElem.removeChild(this.elem); var a = this.player.dollLabels.indexOf(this); if (a > -1) this.player.dollLabels.splice(a, 1); } }]); return DollLabel; }(THREE.EventDispatcher); function _createSuper$16(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$16(); 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 _isNativeReflectConstruct$16() { 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; } } var arrowHeight = 0.4; var arrowLength = 1.6; var arrowSpace = 1.8; var _scale$1 = 0.2; var oriVec = new THREE.Vector3(0, 0, -1); //箭头初始朝向 var matDefault = new THREE.MeshStandardMaterial({ //默认材质 transparent: true, color: new THREE.Color(1, 1, 1), opacity: 0.45, metalness: 1, //太低没有光照效果, 需要比emissive高一丢丢 emissive: new THREE.Color(0.85, 0.85, 0.85) }); var matHighLight = matDefault.clone(); //高亮材质 matHighLight.opacity = 0.9; var arrowGeo; //入户门的箭头动画 var EntryArrow = /*#__PURE__*/function (_THREE$Object3D) { _inherits(EntryArrow, _THREE$Object3D); var _super = _createSuper$16(EntryArrow); function EntryArrow(player, entryInfo) { var _this; _classCallCheck(this, EntryArrow); _this = _super.call(this); _this.player = player; var count = 4; var arrow = _this.createArrow(); _this.add(arrow); arrow.oriPosition = arrow.position.clone(); for (var i = 1; i < count; i++) { var arrow_ = arrow.clone(); arrow_.position.setZ(i * arrowSpace); arrow_.oriPosition = arrow_.position.clone(); _this.add(arrow_); } _this.name = 'entryArrow'; player.model.add(_assertThisInitialized(_this)); _this.scale.set(_scale$1, _scale$1, _scale$1); //this.scale.set(0.25,0.25,0.18) _this.setPosition(entryInfo); _this.currentHighLight = 0; //当前高亮的index _this.traverse(function (e) { e.renderOrder = RenderOrder.entryArrow; }); console.log('create entryArrow'); return _this; } _createClass(EntryArrow, [{ key: "createArrow", value: function createArrow() { if (!arrowGeo) { var points = [{ x: 0, y: 0 }, { x: 1, y: arrowLength / 2 }, { x: 1, y: arrowLength }, { x: 0, y: arrowLength / 2 }, { x: -1, y: arrowLength }, { x: -1, y: arrowLength / 2 }]; var arrowShape = new THREE.Shape(); //先画一个二维的箭头顶视图 arrowShape.moveTo(points[0].x, points[0].y); for (var i = 1, len = points.length; i < len; i++) { arrowShape.lineTo(points[i].x, points[i].y); } arrowShape.lineTo(points[0].x, points[0].y); arrowGeo = new THREE.ExtrudeBufferGeometry(arrowShape, { depth: arrowHeight, bevelEnabled: false }); //挤出成模型 } var arrow = new THREE.Mesh(arrowGeo, matDefault); arrow.rotation.x = Math.PI / 2; //水平放置 return arrow; } }, { key: "setPosition", value: function setPosition(entryInfo) { //设置入户门方位 //if(!metadata.cadInfo || (typeof metadata.cadInfo == "string" ? metadata.cadInfo.includes('"bound"') : metadata.cadInfo.bound))return;//代表是新版,cad图里的文字直接被planLabel取代,因此不用该函数 var left = new THREE.Vector3(entryInfo.points2d[0].x, entryInfo.bottom + arrowHeight * _scale$1, -entryInfo.points2d[0].y); var right = new THREE.Vector3(entryInfo.points2d[1].x, entryInfo.bottom + arrowHeight * _scale$1, -entryInfo.points2d[1].y); var entryPos = left.clone().add(right).multiplyScalar(0.5); //箭头就设定在门底部中央 var doorTangent = left.clone().sub(right).normalize(); var leftMat4 = new THREE.Matrix4(); leftMat4.set(0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1); doorTangent.applyMatrix4(leftMat4); var dir = entryInfo.openSide == 'LEFT' ? doorTangent.multiplyScalar(-1) : doorTangent; if (entryInfo.enter == 'reverse') { //翻转 entryPos.add(dir.clone().multiplyScalar(left.distanceTo(right))); dir.multiplyScalar(-1); } this.enterDir = dir; this.position.copy(entryPos); var qua = math$1.getQuaBetween2Vector(oriVec, dir, new THREE.Vector3(0, 1, 0)); this.quaternion.copy(qua); this.addLabel(entryPos, dir, entryInfo.floorIndex); this.entryPos = entryPos; } }, { key: "addLabel", value: function addLabel(entryPos, dir, floorIndex) { //创建入户门标识 var closetPano = this.player.model.panos.closestPanoTowardPoint({ point: entryPos }); if (!closetPano) { console.error('what!!! no closetPano'); } //pos为箭头末端位置, driftDir偏移反方向 var arrowWholeLen = (arrowSpace * 3 + arrowLength) * _scale$1; //总长度 this.dollLabelOriPos = entryPos.clone().sub(dir.clone().multiplyScalar(arrowWholeLen)); // TODO text 多语言 var dollLabel = new DollLabel(this.player, { sid: 'entry', pos: this.dollLabelOriPos, driftDir: dir, noLine: true, text: config$4.i18n('model.enter'), toPano: closetPano, floorIndex }); this.player.defaultRoomLabels.push(dollLabel); this.dollLabel = dollLabel; } }, { key: "moveCloseToWall", value: function moveCloseToWall(shift) { //移动到户型图墙壁边缘 和cadFloorPlane有关 this.children.forEach(function (mesh) { mesh.position.z = mesh.oriPosition.z + shift; }); this.dollLabel.position = this.dollLabelOriPos.clone().sub(this.enterDir.clone().multiplyScalar(shift * _scale$1)); } }, { key: "reSetHeight", value: function reSetHeight(y) { this.position.setY(y); this.dollLabel.position.y = y; this.dollLabelOriPos.y = y; } //----暂时是private------ }, { key: "animate", value: function animate() { var _this2 = this; this.children.forEach(function (mesh, index) { if (index == _this2.currentHighLight) { mesh.material = matHighLight; } else { mesh.material = matDefault; } }); this.currentHighLight = (this.currentHighLight - 1 + this.children.length) % this.children.length; this.stopAnimation(); //防止重复启动animate this.animation = setTimeout(this.animate.bind(this), 200); } }, { key: "stopAnimation", value: function stopAnimation() { clearTimeout(this.animation); this.animation = null; } //----------------------- }, { key: "dispose", value: function dispose() { this.parent.remove(this); this.stopAnimation(); } }, { key: "show", value: function show() { this.visible = true; this.animate(); } }, { key: "hide", value: function hide() { this.visible = false; this.stopAnimation(); } }], [{ key: "switchDepthTest", value: function switchDepthTest(state) { matDefault.depthTest = state; matHighLight.depthTest = state; } }]); return EntryArrow; }(THREE.Object3D); var axis = { forward: new THREE.Vector3(0, 0, -1), back: new THREE.Vector3(0, 0, 1), left: new THREE.Vector3(-1, 0, 0), right: new THREE.Vector3(1, 0, 0) }; var DoorLabel = /*#__PURE__*/function () { function DoorLabel(player, o) { _classCallCheck(this, DoorLabel); this.player = player; this.position = o.pos; //大约在门的位置 this.text = o.text || ''; this.aim = o.aim; //tagging的位置 this.toPano = o.toPano; this.door = o.door; this.visiblePanos = o.visiblePanos; this.sameRoomPanos = o.sameRoomPanos; this.doorDir = o.doorDir; this.floorIndex = o.floorIndex; this.enable = o.enable == void 0 ? true : o.enable; this.elem = document.createElement('div'); this.elem.className = 'door show-arrow'; this.elem.style.display = 'none'; this.elem.innerHTML = "".concat(this.text, ""); o.container ? o.container.append(this.elem) : document.querySelector('.widgets-doors').append(this.elem); this.player.doorLabels.push(this); this.elem.addEventListener('pointerup', this.clickFuc.bind(this)); this.type = 'door'; this.pos2d = new THREE.Vector3(); this.getDirection(); //初始化朝向 this.updateVisible(); } _createClass(DoorLabel, [{ key: "updateVisible", value: function updateVisible(toPano) { if (toPano) { //飞之前,判断目的地是否是该房间内的,若不是,就直接隐藏;否则等到飞到之后再判断 if (this.sameRoomPanos.includes(toPano)) ; else { this.enable = false; } } else { if (this.visiblePanos.includes(this.player.currentPano)) { this.enable = true; } else { this.enable = false; } } } }, { key: "update", value: function update() { if (this.player.mode !== 'panorama' || !this.enable || !this.text || settings$3.vrEnabled && settings$3.vrSplitScreen || this.player.linkEditor && (this.player.linkEditor.setPanoVisible || this.player.linkEditor.setTagVisible) // || // store.getters.page == 'cad' || // store.getters.page == 'data' // )) ) { this.elem.style.display = 'none'; return; } var p = convertTool.getPos2d(this.position, this.player); if (!p.trueSide) { this.elem.style.display = 'none'; return; } /* if(convertTool.ifShelter(this.position, {x:p.vector.x, y: p.vector.y} )){ this.elem.css('display','none'); return; } */ this.elem.style.left = p.pos.x + 'px'; this.elem.style.top = p.pos.y + 'px'; if (settings$3.vrEnabled) { this.elem.style.transform = 'rotate(' + window.screenFaceOrient + 'deg)'; } else { this.elem.style.transform = ''; } this.elem.style.display = ''; this.pos2d = p.vector; } }, { key: "getDirection", value: function getDirection() { //初始化doorLabel箭头朝向。决定了每个label的className (箭头朝向门内,不朝向tagging,因为tagging的位置会在房间任意地方,导致可能箭头指向门外) var toward = DoorLabel.getToward(this.doorDir); this.elem.className += ' ' + toward; } }, { key: "clickFuc", value: function clickFuc(e) { if (this.toPano) { //看向tagging e.stopPropagation(); this.player.flyToPano({ pano: this.toPano, lookAtPoint: this.aim.clone().setY(this.toPano.position.y), duration: 1800 }); } else { console.error('doorlabel没有toPano'); } } }, { key: "remove", value: function remove() { var parentElem = this.elem.parentElement; parentElem.removeChild(this.elem); var a = this.player.doorLabels.indexOf(this); if (a > -1) this.player.doorLabels.splice(a, 1); } }], [{ key: "getToward", value: function getToward(dir) { //传入方向后,归类四种朝向 for (var u in axis) { var a = axis[u].clone().dot(dir.setY(0).normalize()); var angle = Math.acos(a); if (angle < Math.PI / 4) { return u; } } console.warn('没有找到朝向..'); } }, { key: "updateCameraDir", value: function updateCameraDir(player) { if (player.mode != 'panorama' || player.doorLabels.length == 0) return; var dir = player.getDirection(); var toward = DoorLabel.getToward(dir); document.querySelector('.widgets-doors').setAttribute('data-camera-toward', toward); } }]); return DoorLabel; }(); var css$2 = "#compass {\n display: none;\n position: absolute;\n width: 90px;\n height: 90px;\n pointer-events: none;\n}\n\n#compass .north {\n color: #02a0e9;\n top: 0;\n}\n#compass .south {\n color: #ff1414;\n bottom: 0;\n}\n\n#compass .dirText {\n text-align: center;\n font-size: 10px;\n position: absolute;\n line-height: 25px;\n\n color: rgb(255, 255, 255);\n top: 50%;\n left: 50%;\n width: 45%;\n height: 0px;\n transform-origin: left center;\n}\n\n#compass #dirTextX {\n color: rgb(255, 0, 0);\n}\n\n#compass #dirTextY {\n color: rgb(0, 255, 0);\n}\n\n#compass #dirTextZ {\n color: rgb(0, 0, 255);\n}\n\n#compass .dirText span {\n display: block;\n position: absolute;\n right: 5px;\n top: 0;\n width: 20px;\n height: 20px;\n line-height: 20px;\n margin-top: -10px;\n}\n\n#compass .center {\n width: 50px;\n height: 50px;\n background-size: contain;\n background-position: center;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n position: absolute;\n}\n#compass .center canvas{\n position: relative;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n display: block;\n background-color: transparent;\n}\n\n.widgets-doll-labels a, .widgets-plan-labels a, .widgets-doors a {\n color: #fff;\n font-size: 14px;\n line-height: normal;\n font-family: OpenSans,sans-serif;\n user-select: none;\n}\n\n.widgets-doll-labels .room-label {\n position: absolute;\n width: 0;\n height: 0;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n -webkit-animation: room-label 0.3s ease 0.1s;\n animation: room-label 0.3s ease 0.1s;\n -webkit-animation-fill-mode: both;\n animation-fill-mode: both;\n cursor: pointer;\n}\n\n.widgets-doll-labels .room-label:not(.noLine):after {\n content: \"\";\n display: block;\n position: absolute;\n width: 4px;\n height: 68px;\n background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABQCAYAAADYxx/bAAAASElEQVQYlY2QwQoAIAhDR///x6Z2CCaGSpfHNoegcHdfAGwBCKVUMdAMK7IKm2Wh2oSOdkaUhVbG3u++x7aqPbX9lWVEdn9/AGvVUp4wTpLmAAAAAElFTkSuQmCC\");\n background-size: contain;\n background-repeat: no-repeat;\n bottom: 0;\n left: 50%;\n -webkit-transform: translate(-50%);\n transform: translate(-50%);\n}\n.widgets-doll-labels .room-label a {\n display: block;\n position: absolute;\n line-height: 22px;\n top: -66px;\n transform: translate(-50%, -100%);\n text-align: center;\n white-space: nowrap;\n font-size: 12px;\n font-style: normal;\n pointer-events: auto;\n \n background-repeat: no-repeat;\n background-size: 100% 100%;\n background: rgba(210, 210, 210, 0.7);\n border: 1px solid rgba(255, 255, 255, 0.4);\n border-radius: 3px; \n text-shadow: 0px 1px 3px rgb(0,0, 0, 0.5);\n}\n .widgets-doll-labels .room-label a::before {\n content: \"\";\n position: absolute;\n left: -1px;\n top: -1px;\n width: 10px;\n height: 10px;\n background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNnB4IiBoZWlnaHQ9IjZweCIgdmlld0JveD0iMCAwIDYgNiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KICAgIDx0aXRsZT5tYXBfY29ybmVyICA8L3RpdGxlPgogICAgPGcgaWQ9Iumhtemdoi0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i5bGV56S655WM6Z2iLeS4iee7tCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU2LjAwMDAwMCwgLTI3MC4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIiBmaWxsLXJ1bGU9Im5vbnplcm8iPgogICAgICAgICAgICA8ZyBpZD0i57yW57uELTE1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMS4wMDAwMDAsIDI3MC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSLlvaLnirbnu5PlkIgtKy3lvaLnirbnu5PlkIgt6JKZ54mIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNS4wMDAwMDAsIDAuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYsNiBMNSw2IEw1LDIuNzA1IEwzLjMwMSwxIEwwLDEgTDAsMCBMMy43MTUyMjY0MSwwIEw2LDIuMjkzNDQ3OTUgTDYsNiBaIiBpZD0ibWFwX2Nvcm5lci0tIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzLjAwMDAwMCwgMy4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTMuMDAwMDAwLCAtMy4wMDAwMDApICI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=);\n background-repeat: no-repeat;\n background-position: top left;\n }\n .widgets-doll-labels .room-label a::after {\n content: \"\";\n position: absolute;\n left: -1px;\n bottom: -1px;\n width: 10px;\n height: 10px;\n background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNnB4IiBoZWlnaHQ9IjZweCIgdmlld0JveD0iMCAwIDYgNiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KICAgIDx0aXRsZT5tYXBfY29ybmVyICA8L3RpdGxlPgogICAgPGcgaWQ9Iumhtemdoi0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i5bGV56S655WM6Z2iLeS4iee7tCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU2LjAwMDAwMCwgLTI3MC4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIiBmaWxsLXJ1bGU9Im5vbnplcm8iPgogICAgICAgICAgICA8ZyBpZD0i57yW57uELTE1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMS4wMDAwMDAsIDI3MC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSLlvaLnirbnu5PlkIgtKy3lvaLnirbnu5PlkIgt6JKZ54mIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNS4wMDAwMDAsIDAuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYsNiBMNSw2IEw1LDIuNzA1IEwzLjMwMSwxIEwwLDEgTDAsMCBMMy43MTUyMjY0MSwwIEw2LDIuMjkzNDQ3OTUgTDYsNiBaIiBpZD0ibWFwX2Nvcm5lci0tIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzLjAwMDAwMCwgMy4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTMuMDAwMDAwLCAtMy4wMDAwMDApICI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=);\n background-repeat: no-repeat;\n background-position: top left;\n transform: rotate(270deg);\n }\n .widgets-doll-labels .room-label a > p {\n margin: 0;\n padding: 2px 10px;\n height: 100%;\n line-height: 1.5;\n }\n .widgets-doll-labels .room-label a > p::before {\n content: \"\";\n position: absolute;\n right: -1px;\n top: -1px;\n width: 10px;\n height: 10px;\n background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNnB4IiBoZWlnaHQ9IjZweCIgdmlld0JveD0iMCAwIDYgNiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KICAgIDx0aXRsZT5tYXBfY29ybmVyICA8L3RpdGxlPgogICAgPGcgaWQ9Iumhtemdoi0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i5bGV56S655WM6Z2iLeS4iee7tCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU2LjAwMDAwMCwgLTI3MC4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIiBmaWxsLXJ1bGU9Im5vbnplcm8iPgogICAgICAgICAgICA8ZyBpZD0i57yW57uELTE1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMS4wMDAwMDAsIDI3MC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSLlvaLnirbnu5PlkIgtKy3lvaLnirbnu5PlkIgt6JKZ54mIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNS4wMDAwMDAsIDAuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYsNiBMNSw2IEw1LDIuNzA1IEwzLjMwMSwxIEwwLDEgTDAsMCBMMy43MTUyMjY0MSwwIEw2LDIuMjkzNDQ3OTUgTDYsNiBaIiBpZD0ibWFwX2Nvcm5lci0tIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzLjAwMDAwMCwgMy4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTMuMDAwMDAwLCAtMy4wMDAwMDApICI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=);\n background-repeat: no-repeat;\n background-position: top left;\n transform: rotate(90deg);\n }\n .widgets-doll-labels .room-label a > p::after {\n content: \"\";\n position: absolute;\n right: -1px;\n bottom: -1px;\n width: 10px;\n height: 10px;\n background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNnB4IiBoZWlnaHQ9IjZweCIgdmlld0JveD0iMCAwIDYgNiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KICAgIDx0aXRsZT5tYXBfY29ybmVyICA8L3RpdGxlPgogICAgPGcgaWQ9Iumhtemdoi0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i5bGV56S655WM6Z2iLeS4iee7tCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTU2LjAwMDAwMCwgLTI3MC4wMDAwMDApIiBmaWxsPSIjRkZGRkZGIiBmaWxsLXJ1bGU9Im5vbnplcm8iPgogICAgICAgICAgICA8ZyBpZD0i57yW57uELTE1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzMS4wMDAwMDAsIDI3MC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSLlvaLnirbnu5PlkIgtKy3lvaLnirbnu5PlkIgt6JKZ54mIIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNS4wMDAwMDAsIDAuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYsNiBMNSw2IEw1LDIuNzA1IEwzLjMwMSwxIEwwLDEgTDAsMCBMMy43MTUyMjY0MSwwIEw2LDIuMjkzNDQ3OTUgTDYsNiBaIiBpZD0ibWFwX2Nvcm5lci0tIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzLjAwMDAwMCwgMy4wMDAwMDApIHNjYWxlKC0xLCAxKSB0cmFuc2xhdGUoLTMuMDAwMDAwLCAtMy4wMDAwMDApICI+PC9wYXRoPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=);\n background-repeat: no-repeat;\n background-position: top left;\n transform: rotate(180deg);\n }\n\n.widgets-doll-labels .room-label.noLine a {\n top: 16px;\n}\n\n.widgets-doll-labels .room-label a span {\n white-space: nowrap;\n user-select: none;\n}\n\n.widgets-doll-labels .room-label.with-entrance:after {\n display: none;\n}\n\n.widgets-doll-labels .room-label.with-entrance a {\n top: 50%;\n width: 38.5px;\n height: 15.75px;\n background-size: 38.5px 15.75px;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n}\n\n.widgets-doll-labels .room-label.with-entrance a span {\n margin-left: -0.875px;\n margin-top: -0.875px;\n}\n\n.widgets-plan-labels .room-label {\n position: absolute;\n -webkit-animation: room-label 0.3s ease 0.1s;\n animation: room-label 0.3s ease 0.1s;\n -webkit-animation-fill-mode: both;\n animation-fill-mode: both;\n}\n\n.widgets-plan-labels .room-label a {\n display: block;\n position: absolute;\n line-height: 24px;\n -webkit-transform: translate(-50%);\n transform: translate(-50%, -50%);\n text-align: center;\n white-space: nowrap;\n font-size: 14px;\n font-style: normal;\n}\n\n.widgets-doors {\n position: absolute;\n pointer-events: none;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n}\n\n.widgets-doors[data-camera-toward=right] .door.show-arrow.right a:before,\n.widgets-doors[data-camera-toward=forward] .door.show-arrow.right a:before {\n margin-right: 3.5px;\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.widgets-doors[data-camera-toward=right] .door.show-arrow.right a:before,\n.widgets-doors[data-camera-toward=forward] .door.show-arrow.forward a:before,\n.widgets-doors[data-camera-toward=forward] .door.show-arrow.left a:after,\n.widgets-doors[data-camera-toward=forward] .door.show-arrow.right a:before {\n content: \"\";\n position: relative;\n display: inline-block;\n width: 10.5px;\n height: 10.5px;\n background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMCIgdmlld0JveD0iMCAwIDE0IDEwIj4KICA8ZyBpZD0iaW1nX2Fycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzIxIC01OTMpIj4KICAgIDxwYXRoIGlkPSLot6/lvoRfMTQ0NSIgZGF0YS1uYW1lPSLot6/lvoQgMTQ0NSIgZD0iTTUyNS41OCw1MTAuNzczbC00LjczOC00LjU4OGEuNjIyLjYyMiwwLDAsMC0uNDM0LS4xNzNINTE3LjdhLjYyNS42MjUsMCwwLDEsLjQzNS4xNzNsNC43MzgsNC41ODhhLjM3LjM3LDAsMCwxLDAsLjU0bC00LjczOSw0LjUzMmEuNjIxLjYyMSwwLDAsMS0uNDMyLjE2N2gyLjcxMWEuNjIxLjYyMSwwLDAsMCwuNDMxLS4xNjdsNC43MzktNC41MzJBLjM3LjM3LDAsMCwwLDUyNS41OCw1MTAuNzczWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA5LjMwMyA4Ni45ODkpIiBmaWxsPSIjZmZmIi8+CiAgICA8cGF0aCBpZD0i6Lev5b6EXzE0NDYiIGRhdGEtbmFtZT0i6Lev5b6EIDE0NDYiIGQ9Ik01MjUuNTgsNTEwLjc3M2wtNC43MzgtNC41ODhhLjYyMi42MjIsMCwwLDAtLjQzNC0uMTczSDUxNy43YS42MjUuNjI1LDAsMCwxLC40MzUuMTczbDQuNzM4LDQuNTg4YS4zNy4zNywwLDAsMSwwLC41NGwtNC43MzksNC41MzJhLjYyMS42MjEsMCwwLDEtLjQzMi4xNjdoMi43MTFhLjYyMS42MjEsMCwwLDAsLjQzMS0uMTY3bDQuNzM5LTQuNTMyQS4zNy4zNywwLDAsMCw1MjUuNTgsNTEwLjc3M1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwMy4zMDMgODYuOTg5KSIgZmlsbD0iI2ZmZiIgb3BhY2l0eT0iMC41Ii8+CiAgPC9nPgo8L3N2Zz4K) no-repeat 50%;\n background-size: 100% 100%;\n vertical-align: middle;\n}\n\n.widgets-doors[data-camera-toward=\"forward\"] .door.show-arrow.left a:after {\n margin-left: 4px;\n}\n\n.widgets-doors[data-camera-toward=\"forward\"] .door.show-arrow.back a:after,\n.widgets-doors[data-camera-toward=\"right\"] .door.show-arrow.left a:after {\n content: \"\";\n display: inline-block;\n vertical-align: middle;\n width: 10.5px;\n height: 10.5px;\n background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMCIgdmlld0JveD0iMCAwIDE0IDEwIj4KICA8ZyBpZD0iaW1nX2Fycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzIxIC01OTMpIj4KICAgIDxwYXRoIGlkPSLot6/lvoRfMTQ0NSIgZGF0YS1uYW1lPSLot6/lvoQgMTQ0NSIgZD0iTTUyNS41OCw1MTAuNzczbC00LjczOC00LjU4OGEuNjIyLjYyMiwwLDAsMC0uNDM0LS4xNzNINTE3LjdhLjYyNS42MjUsMCwwLDEsLjQzNS4xNzNsNC43MzgsNC41ODhhLjM3LjM3LDAsMCwxLDAsLjU0bC00LjczOSw0LjUzMmEuNjIxLjYyMSwwLDAsMS0uNDMyLjE2N2gyLjcxMWEuNjIxLjYyMSwwLDAsMCwuNDMxLS4xNjdsNC43MzktNC41MzJBLjM3LjM3LDAsMCwwLDUyNS41OCw1MTAuNzczWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA5LjMwMyA4Ni45ODkpIiBmaWxsPSIjZmZmIi8+CiAgICA8cGF0aCBpZD0i6Lev5b6EXzE0NDYiIGRhdGEtbmFtZT0i6Lev5b6EIDE0NDYiIGQ9Ik01MjUuNTgsNTEwLjc3M2wtNC43MzgtNC41ODhhLjYyMi42MjIsMCwwLDAtLjQzNC0uMTczSDUxNy43YS42MjUuNjI1LDAsMCwxLC40MzUuMTczbDQuNzM4LDQuNTg4YS4zNy4zNywwLDAsMSwwLC41NGwtNC43MzksNC41MzJhLjYyMS42MjEsMCwwLDEtLjQzMi4xNjdoMi43MTFhLjYyMS42MjEsMCwwLDAsLjQzMS0uMTY3bDQuNzM5LTQuNTMyQS4zNy4zNywwLDAsMCw1MjUuNTgsNTEwLjc3M1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwMy4zMDMgODYuOTg5KSIgZmlsbD0iI2ZmZiIgb3BhY2l0eT0iMC41Ii8+CiAgPC9nPgo8L3N2Zz4K) no-repeat 50%;\n background-size: 100% 100%;\n margin-left: 4px;\n -webkit-transform: rotate(-90deg);\n transform: rotate(-90deg);\n}\n\n.widgets-doors[data-camera-toward=forward] .door.show-arrow.forward a:before ,\n.widgets-doors[data-camera-toward=right] .door.show-arrow.back a:before {\n margin-right: 3.5px;\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.widgets-doors[data-camera-toward=\"right\"] .door.show-arrow.back a:before,\n.widgets-doors[data-camera-toward=\"right\"] .door.show-arrow.forward a:after {\n content: \"\";\n position: relative;\n display: inline-block;\n width: 10.5px;\n height: 10.5px;\n background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMCIgdmlld0JveD0iMCAwIDE0IDEwIj4KICA8ZyBpZD0iaW1nX2Fycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzIxIC01OTMpIj4KICAgIDxwYXRoIGlkPSLot6/lvoRfMTQ0NSIgZGF0YS1uYW1lPSLot6/lvoQgMTQ0NSIgZD0iTTUyNS41OCw1MTAuNzczbC00LjczOC00LjU4OGEuNjIyLjYyMiwwLDAsMC0uNDM0LS4xNzNINTE3LjdhLjYyNS42MjUsMCwwLDEsLjQzNS4xNzNsNC43MzgsNC41ODhhLjM3LjM3LDAsMCwxLDAsLjU0bC00LjczOSw0LjUzMmEuNjIxLjYyMSwwLDAsMS0uNDMyLjE2N2gyLjcxMWEuNjIxLjYyMSwwLDAsMCwuNDMxLS4xNjdsNC43MzktNC41MzJBLjM3LjM3LDAsMCwwLDUyNS41OCw1MTAuNzczWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA5LjMwMyA4Ni45ODkpIiBmaWxsPSIjZmZmIi8+CiAgICA8cGF0aCBpZD0i6Lev5b6EXzE0NDYiIGRhdGEtbmFtZT0i6Lev5b6EIDE0NDYiIGQ9Ik01MjUuNTgsNTEwLjc3M2wtNC43MzgtNC41ODhhLjYyMi42MjIsMCwwLDAtLjQzNC0uMTczSDUxNy43YS42MjUuNjI1LDAsMCwxLC40MzUuMTczbDQuNzM4LDQuNTg4YS4zNy4zNywwLDAsMSwwLC41NGwtNC43MzksNC41MzJhLjYyMS42MjEsMCwwLDEtLjQzMi4xNjdoMi43MTFhLjYyMS42MjEsMCwwLDAsLjQzMS0uMTY3bDQuNzM5LTQuNTMyQS4zNy4zNywwLDAsMCw1MjUuNTgsNTEwLjc3M1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwMy4zMDMgODYuOTg5KSIgZmlsbD0iI2ZmZiIgb3BhY2l0eT0iMC41Ii8+CiAgPC9nPgo8L3N2Zz4K) no-repeat 50%;\n background-size: 100% 100%;\n vertical-align: middle;\n}\n\n.widgets-doors[data-camera-toward=\"right\"] .door.show-arrow.forward a:after {\n margin-left: 4px;\n}\n\n.widgets-doors[data-camera-toward=\"left\"] .door.show-arrow.right a:after {\n -webkit-transform: rotate(-90deg);\n transform: rotate(-90deg);\n}\n\n.widgets-doors[data-camera-toward=back] .door.show-arrow.back a:after,\n.widgets-doors[data-camera-toward=left] .door.show-arrow.left a:after,\n.widgets-doors[data-camera-toward=left] .door.show-arrow.back a:after,\n.widgets-doors[data-camera-toward=left] .door.show-arrow.right a:after {\n content: \"\";\n display: inline-block;\n vertical-align: middle;\n width: 10.5px;\n height: 10.5px;\n background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMCIgdmlld0JveD0iMCAwIDE0IDEwIj4KICA8ZyBpZD0iaW1nX2Fycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzIxIC01OTMpIj4KICAgIDxwYXRoIGlkPSLot6/lvoRfMTQ0NSIgZGF0YS1uYW1lPSLot6/lvoQgMTQ0NSIgZD0iTTUyNS41OCw1MTAuNzczbC00LjczOC00LjU4OGEuNjIyLjYyMiwwLDAsMC0uNDM0LS4xNzNINTE3LjdhLjYyNS42MjUsMCwwLDEsLjQzNS4xNzNsNC43MzgsNC41ODhhLjM3LjM3LDAsMCwxLDAsLjU0bC00LjczOSw0LjUzMmEuNjIxLjYyMSwwLDAsMS0uNDMyLjE2N2gyLjcxMWEuNjIxLjYyMSwwLDAsMCwuNDMxLS4xNjdsNC43MzktNC41MzJBLjM3LjM3LDAsMCwwLDUyNS41OCw1MTAuNzczWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA5LjMwMyA4Ni45ODkpIiBmaWxsPSIjZmZmIi8+CiAgICA8cGF0aCBpZD0i6Lev5b6EXzE0NDYiIGRhdGEtbmFtZT0i6Lev5b6EIDE0NDYiIGQ9Ik01MjUuNTgsNTEwLjc3M2wtNC43MzgtNC41ODhhLjYyMi42MjIsMCwwLDAtLjQzNC0uMTczSDUxNy43YS42MjUuNjI1LDAsMCwxLC40MzUuMTczbDQuNzM4LDQuNTg4YS4zNy4zNywwLDAsMSwwLC41NGwtNC43MzksNC41MzJhLjYyMS42MjEsMCwwLDEtLjQzMi4xNjdoMi43MTFhLjYyMS42MjEsMCwwLDAsLjQzMS0uMTY3bDQuNzM5LTQuNTMyQS4zNy4zNywwLDAsMCw1MjUuNTgsNTEwLjc3M1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwMy4zMDMgODYuOTg5KSIgZmlsbD0iI2ZmZiIgb3BhY2l0eT0iMC41Ii8+CiAgPC9nPgo8L3N2Zz4K) no-repeat 50%;\n background-size: 100% 100%;\n margin-left: 4px;\n}\n\n.widgets-doors[data-camera-toward=\"left\"] .door.show-arrow.back a:after {\n position: relative;\n}\n\n.widgets-doors[data-camera-toward=\"left\"] .door.show-arrow.forward a:before {\n position: relative;\n margin-right: 3.5px;\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.widgets-doors[data-camera-toward=\"back\"] .door.show-arrow.forward a:after,\n.widgets-doors[data-camera-toward=\"left\"] .door.show-arrow.forward a:before {\n content: \"\";\n display: inline-block;\n width: 10.5px;\n height: 10.5px;\n background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMCIgdmlld0JveD0iMCAwIDE0IDEwIj4KICA8ZyBpZD0iaW1nX2Fycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzIxIC01OTMpIj4KICAgIDxwYXRoIGlkPSLot6/lvoRfMTQ0NSIgZGF0YS1uYW1lPSLot6/lvoQgMTQ0NSIgZD0iTTUyNS41OCw1MTAuNzczbC00LjczOC00LjU4OGEuNjIyLjYyMiwwLDAsMC0uNDM0LS4xNzNINTE3LjdhLjYyNS42MjUsMCwwLDEsLjQzNS4xNzNsNC43MzgsNC41ODhhLjM3LjM3LDAsMCwxLDAsLjU0bC00LjczOSw0LjUzMmEuNjIxLjYyMSwwLDAsMS0uNDMyLjE2N2gyLjcxMWEuNjIxLjYyMSwwLDAsMCwuNDMxLS4xNjdsNC43MzktNC41MzJBLjM3LjM3LDAsMCwwLDUyNS41OCw1MTAuNzczWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA5LjMwMyA4Ni45ODkpIiBmaWxsPSIjZmZmIi8+CiAgICA8cGF0aCBpZD0i6Lev5b6EXzE0NDYiIGRhdGEtbmFtZT0i6Lev5b6EIDE0NDYiIGQ9Ik01MjUuNTgsNTEwLjc3M2wtNC43MzgtNC41ODhhLjYyMi42MjIsMCwwLDAtLjQzNC0uMTczSDUxNy43YS42MjUuNjI1LDAsMCwxLC40MzUuMTczbDQuNzM4LDQuNTg4YS4zNy4zNywwLDAsMSwwLC41NGwtNC43MzksNC41MzJhLjYyMS42MjEsMCwwLDEtLjQzMi4xNjdoMi43MTFhLjYyMS42MjEsMCwwLDAsLjQzMS0uMTY3bDQuNzM5LTQuNTMyQS4zNy4zNywwLDAsMCw1MjUuNTgsNTEwLjc3M1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwMy4zMDMgODYuOTg5KSIgZmlsbD0iI2ZmZiIgb3BhY2l0eT0iMC41Ii8+CiAgPC9nPgo8L3N2Zz4K) no-repeat 50%;\n background-size: 100% 100%;\n vertical-align: middle;\n}\n\n.widgets-doors[data-camera-toward=\"back\"] .door.show-arrow.forward a:after {\n margin-left: 4px;\n -webkit-transform: rotate(-90deg);\n transform: rotate(-90deg);\n}\n\n.widgets-doors[data-camera-toward=\"back\"] .door.show-arrow.right a:after {\n margin-left: 4px;\n}\n\n.widgets-doors[data-camera-toward=\"back\"] .door.show-arrow.left a:before,\n.widgets-doors[data-camera-toward=\"back\"] .door.show-arrow.right a:after {\n content: \"\";\n position: relative;\n display: inline-block;\n width: 10.5px;\n height: 10.5px;\n background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxMCIgdmlld0JveD0iMCAwIDE0IDEwIj4KICA8ZyBpZD0iaW1nX2Fycm93IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzIxIC01OTMpIj4KICAgIDxwYXRoIGlkPSLot6/lvoRfMTQ0NSIgZGF0YS1uYW1lPSLot6/lvoQgMTQ0NSIgZD0iTTUyNS41OCw1MTAuNzczbC00LjczOC00LjU4OGEuNjIyLjYyMiwwLDAsMC0uNDM0LS4xNzNINTE3LjdhLjYyNS42MjUsMCwwLDEsLjQzNS4xNzNsNC43MzgsNC41ODhhLjM3LjM3LDAsMCwxLDAsLjU0bC00LjczOSw0LjUzMmEuNjIxLjYyMSwwLDAsMS0uNDMyLjE2N2gyLjcxMWEuNjIxLjYyMSwwLDAsMCwuNDMxLS4xNjdsNC43MzktNC41MzJBLjM3LjM3LDAsMCwwLDUyNS41OCw1MTAuNzczWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA5LjMwMyA4Ni45ODkpIiBmaWxsPSIjZmZmIi8+CiAgICA8cGF0aCBpZD0i6Lev5b6EXzE0NDYiIGRhdGEtbmFtZT0i6Lev5b6EIDE0NDYiIGQ9Ik01MjUuNTgsNTEwLjc3M2wtNC43MzgtNC41ODhhLjYyMi42MjIsMCwwLDAtLjQzNC0uMTczSDUxNy43YS42MjUuNjI1LDAsMCwxLC40MzUuMTczbDQuNzM4LDQuNTg4YS4zNy4zNywwLDAsMSwwLC41NGwtNC43MzksNC41MzJhLjYyMS42MjEsMCwwLDEtLjQzMi4xNjdoMi43MTFhLjYyMS42MjEsMCwwLDAsLjQzMS0uMTY3bDQuNzM5LTQuNTMyQS4zNy4zNywwLDAsMCw1MjUuNTgsNTEwLjc3M1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwMy4zMDMgODYuOTg5KSIgZmlsbD0iI2ZmZiIgb3BhY2l0eT0iMC41Ii8+CiAgPC9nPgo8L3N2Zz4K) no-repeat 50%;\n background-size: 100% 100%;\n vertical-align: middle;\n}\n\n.widgets-doors[data-camera-toward=\"back\"] .door.show-arrow.left a:before {\n margin-right: 3.5px;\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.widgets-doors .door {\n position: absolute;\n width: 0;\n height: 0;\n /* display: none; */\n -webkit-animation: viewport-door-label 0.3s ease 1s;\n animation: viewport-door-label 0.3s ease 1s;\n -webkit-animation-fill-mode: both;\n animation-fill-mode: both;\n -webkit-transform: translateZ(0);\n transform: translateZ(0);\n cursor: pointer;\n}\n\n.widgets-doors .door a {\n display: block;\n position: absolute;\n top: 50%;\n left: 50%;\n -webkit-transform: translate(-50%, -50%);\n transform: translate(-50%, -50%);\n border-radius: 1.75px;\n background: rgba(0, 0, 0, 0.5);\n line-height: 14px;\n padding: 8px 8px;\n border-radius: 4px;\n white-space: nowrap;\n font-size: 14px;\n font-style: normal;\n pointer-events: auto;\n -webkit-transition: background 0.3s ease, color 0.3s ease, -webkit-transform 1s ease;\n transition: background 0.3s ease, color 0.3s ease, -webkit-transform 1s ease;\n transition: transform 1s ease, background 0.3s ease, color 0.3s ease;\n transition: transform 1s ease, background 0.3s ease, color 0.3s ease, -webkit-transform 1s ease;\n}\n\n.widgets-doors .door a:after {\n -webkit-transition: opacity 0.3s ease;\n transition: opacity 0.3s ease;\n}\n\n.widgets-doors .door a:active {\n background: rgba(0, 0, 0, 0.5);\n color: hsla(0, 0%, 100%, 0.5);\n}\n\n.widgets-doors .door a:active:after {\n opacity: 0.5;\n}\n\n\n.polygonMark-label {\n position: absolute;\n max-width: 340px;\n max-height: 125px;\n min-width: 45px;\n\n -webkit-animation: mark-label 0.3s ease 0.1s;\n animation: mark-label 0.3s ease 0.1s;\n -webkit-animation-fill-mode: both;\n animation-fill-mode: both;\n}\n.polygonMark-label .line{\n width: 100%;\n height: 0px;\n background-color: rgba(255, 255, 255, 0.75);\n box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.5);\n border: 1px solid rgba(255, 255, 255, 0.75);\n\n}\n.polygonMark-label .point{\n position: relative;\n top: -4px;\n left: -8px;\n opacity: 1;\n\n width: 8px;\n height: 8px;\n background-color: #ffffff; \n box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.5);\n border-radius: 100%;\n}\n.polygonMark-label .name {\n margin: 0;\n padding: 0;\n max-width: 320px;\n max-height: 63px;\n min-width: auto;\n\n margin-left: 20px;\n padding-bottom: 2.5px;\n word-break:normal;\n word-break: break-all;\n\n font-family: Microsoft YaHei;\n font-weight: bold;\n font-size: 16px;\n color: #FFFFFF;\n line-height: 19px;\n text-shadow: 0px 0px 4px rgba(0,0,0,0.8);\n text-align: left;\n font-style: normal;\n}\n.polygonMark-label .type{\n margin: 0;\n padding: 0;\n max-width: 320px;\n max-height: 63px;\n min-width: auto;\n\n margin-left: 20px;\n padding-top: 2.5px;\n word-break:normal;\n word-break: break-all;\n\n\n font-family: Microsoft YaHei;\n font-weight: 400;\n font-size: 14px;\n color: #FFFFFF;\n line-height: 16px;\n text-shadow: 0px 0px 4px rgba(0,0,0,0.8);\n text-align: left;\n font-style: normal;\n\n}\n\n@-webkit-keyframes mark-label {\n 0% {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n@keyframes mark-label {\n 0% {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n\n@-webkit-keyframes room-label {\n 0% {\n opacity: 0;\n margin-top: 8.75px;\n }\n\n to {\n opacity: 1;\n margin-top: 0;\n }\n}\n\n@keyframes room-label {\n 0% {\n opacity: 0;\n margin-top: 8.75px;\n }\n\n to {\n opacity: 1;\n margin-top: 0;\n }\n}\n\n@-webkit-keyframes door-label {\n 0% {\n opacity: 0;\n margin-top: 8.75px;\n }\n\n to {\n opacity: 1;\n margin-top: 0;\n }\n}\n\n@keyframes door-label {\n 0% {\n opacity: 0;\n margin-top: 8.75px;\n }\n\n to {\n opacity: 1;\n margin-top: 0;\n }\n}"; n$4(css$2,{}); function _createSuper$15(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$15(); 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 _isNativeReflectConstruct$15() { 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; } } /*#__PURE__*/(function (_THREE$EventDispatche) { _inherits(PlanLabel, _THREE$EventDispatche); var _super = _createSuper$15(PlanLabel); function PlanLabel(player, o) { var _this; _classCallCheck(this, PlanLabel); _this = _super.call(this); console.log(PlanLabel); _this.player = player; _this.position = o.pos; _this.sid = o.sid; _this.text = o.text || ''; _this.toPano = o.toPano; _this.enable = o.enable == void 0 ? true : o.enable; _this.elem = document.createElement('div'); _this.elem.className = 'room-label'; _this.elem.style.display = 'none'; _this.elem.innerHTML = "".concat(_this.text, ""); o.container ? o.container.append(_this.elem) : document.querySelector('.widgets-plan-labels').append(_this.elem); player.planLabels.push(_assertThisInitialized(_this)); _this.type = 'plan'; _this.floorIndex = o.floorIndex; return _this; } _createClass(PlanLabel, [{ key: "changeText", value: function changeText(t) { this.elem.querySelector('a').innerHTML = this.text = t; } }, { key: "update", value: function update() { //enable只和是否有cad图相关 if (this.player.mode !== 'floorplan' || !this.enable || !this.text || this.player.model.currentFloor.floorIndex != this.floorIndex && !this.player.model.allFloorsVisible || this.player.linkEditor && (this.player.linkEditor.setPanoVisible || this.player.linkEditor.setTagVisible) // || // store.getters.page == 'cad' || // store.getters.page == 'data' // )) ) { this.elem.style.display = 'none'; return; } var p = convertTool.getPos2d(this.position, this.player); if (!p.trueSide) { this.elem.style.display = 'none'; return; } //使之随着模型缩放,就像贴图一样。缺陷1:当不显示户型图时,ImgRatio为null;缺陷2:当模型很大时,每个房间看起来很小,可能字会超出边缘。 // var s = ( document.getElementsByClassName('player')[0].clientWidth * (this.player.model.cadFloorPlane.ImgRatio || 1 / 50) ) var s = this.player.domElement.clientWidth * (1 / 50) / Math.abs(this.player.cameraControls.activeControl.camera.left); //乘上app.model.floorplanCadImg.ImgRatio是为了让字相对于图片的像素不变。(否则就是根据模型尺寸) 防止图片覆盖的模型范围大的字也跟着被缩小。 s = THREE.MathUtils.clamp(s, 0.4, 3); //限定范围,主要是防止字太大,也可去除 this.elem.style.left = p.pos.x + 'px'; this.elem.style.top = p.pos.y + 'px'; this.elem.style.transform = 'scale(' + s + ')'; this.elem.style.display = ''; } }, { key: "remove", value: function remove() { var parentElem = this.elem.parentElement; parentElem.removeChild(this.elem); var a = this.player.planLabels.indexOf(this); if (a > -1) this.player.planLabels.splice(a, 1); } }]); return PlanLabel; })(THREE.EventDispatcher); /* 判断遮挡方式:当户型和模型相差较大时的问题(尽力使户型贴准模型) 1 用模型: 会有被遮挡然后看不见的情况,尤其是从斜侧面看,门容易被其他墙挡住。因为此外还有门没打洞的情况,加上该功能基于户型,所以不使用此方案。 2 用数据: 会有看上去被墙遮挡但却还看得见的情况。 */ var LabelManager = /*#__PURE__*/function () { function LabelManager(player) { _classCallCheck(this, LabelManager); this.player = player; var dollElem = document.createElement('div'); dollElem.className = 'widgets-doll-labels'; player.domElement.append(dollElem); var planElem = document.createElement('div'); planElem.className = 'widgets-plan-labels'; player.domElement.append(planElem); var doorElem = document.createElement('div'); doorElem.className = 'widgets-doors'; player.domElement.append(doorElem); // let isAllFloor = false // 因为单楼层和全部楼层都会触发floor.changed, 以此来做区分 // this.player.model.on('floor.changed', (toFloor, mode) => { // if (!isAllFloor) { // this.gotoFloor(toFloor.floorIndex) // } else { // isAllFloor = false // } // }) // this.player.model.on('allfloors.toggled', (floors, currentFloor) => { // if (floors) { // this.gotoFloor() // isAllFloor = true // } // }) if (this.player.$app.store.getValue('flooruser')) { this.init(); } this.player.$app.store.on('flooruser', this.init.bind(this)); } _createClass(LabelManager, [{ key: "init", value: function init() { var _this = this; //开户门箭头 // if (this.initedLabel) return var floorJson = this.player.$app.store.getValue('flooruser'); // floorJson = common.compatiblev2(floorJson) // 导入平面图后传入的就是空数据,且需要清空原先数据,所以不能这样判断 // var voidValue = true //可能还没得到数据,都是空的 // for (let i = 0; i < floorJson.floors.length; i++) { // for (let j in floorJson.floors[i]) { // if (floorJson.floors[i][j] instanceof Array && floorJson.floors[i][j].length > 0) { // voidValue = false // break // } // } // } // if (voidValue) return //空的 // // console.error(floorJson) common.timeMeasuring.addTimeMark('initLabels', 'start'); this.player.defaultRoomLabels.forEach(function (label) { return label.remove(); }); this.player.defaultRoomLabels = []; floorJson.floors.forEach(function (floorData0, index) { // const index = this.player.model.floors.list.length > 1 ? (floorData.subgroup != void 0 ? floorData.subgroup : floorData.id) : this.player.model.floors.list[0].floorIndex //旧版单层model的id和json不对应,使用model的 index = _this.player.model.floors.list.length > 1 ? floorData0.subgroup != void 0 ? floorData0.subgroup : floorData0.id : index; //旧版单层model的id和json不对应,使用model的 var floor = _this.player.model.floors.index[index]; if (!floor) { logger$1.warn("floor[".concat(index, "] is empty")); return; } floor.entryArrow = []; var bottom = floor.boundingBox.min.y; // 变换floorJson里的所有坐标 var floorData = JSON.parse(JSON.stringify(floorData0)); var modelCenter = JSON.parse(JSON.stringify(_this.player.model.center)); modelCenter.z = -1 * modelCenter.z; //let modelCenter = floorData.boundingBox && new THREE.Vector3((floorData.boundingBox.minX + floorData.boundingBox.maxX) / 2, 0, -(floorData.boundingBox.minY + floorData.boundingBox.maxY) / 2) floorData.symbols && Object.keys(floorData.symbols).forEach(function (key) { var symbol = floorData.symbols[key]; symbol.endPoint = getPointForRevRotate(symbol.endPoint, floorJson.angle, modelCenter); symbol.startPoint = getPointForRevRotate(symbol.startPoint, floorJson.angle, modelCenter); symbol.points2d = (symbol.points2d || []).map(function (point) { return getPointForRevRotate(point, floorJson.angle, modelCenter); }); }); floorData.tags && Object.keys(floorData.tags).forEach(function (key) { var tag = floorData.tags[key]; tag.center = getPointForRevRotate(tag.center, floorJson.angle, modelCenter); tag.points2d = tag.points2d.map(function (point) { return getPointForRevRotate(point, floorJson.angle, modelCenter); }); }); floorData.rooms && Object.keys(floorData.rooms).forEach(function (key) { var room = floorData.rooms[key]; room.center = getPointForRevRotate(room.center, floorJson.angle, modelCenter); }); floorData.points && Object.keys(floorData.points).forEach(function (key) { var point = floorData.points[key]; var pointpos = getPointForRevRotate({ x: point.x, y: point.y }, floorJson.angle, modelCenter); point.x = pointpos.x; point.y = pointpos.y; }); if (floorData.symbols) { var entry; var symbolKeys = Object.keys(floorData.symbols); for (var i = 0; i < symbolKeys.length; i++) { if (floorData.symbols[symbolKeys[i]].enter) { entry = JSON.parse(JSON.stringify(floorData.symbols[symbolKeys[i]])); entry.bottom = bottom + 0.1; //根据模型 entry.floorIndex = index; // entry.endPoint = getPointForRevRotate(entry.endPoint, floorJson.angle, this.player.model.center) // entry.startPoint = getPointForRevRotate(entry.startPoint, floorJson.angle, this.player.model.center) // entry.points2d = entry.points2d.map(point => getPointForRevRotate(point, floorJson.angle, this.player.model.center)) floor.entryArrow.push(new EntryArrow(_this.player, entry)); if (_this.player.model.currentFloor.floorIndex == index) _this.updateEntryVisi(true, index);else _this.updateEntryVisi(false, index); } } _this.moveEntryArrow(index); } //添加label 房间名 floorData.tags = floorData.tags || {}; _this.hasPlaneLabels = floorData.tags.length > 0; var labelHeight = floor.center.y; //.panoHeightAve Object.keys(floorData.tags).forEach(function (index_) { var info = floorData.tags[index_]; var des = info.des && parseFloat(info.des).toFixed(2); var title = info.title; var area = des + info.unit + '2'; var content = info.des ? '约' + area : ''; if (!title && !content) return; var text = title && content ? title + '
' + area // 如果name是空或只有空格,视若showArea == false; trim:去除字符串的头尾空格 : title ? title : content; // y方向有差异 var rayDir = _this.player.modeTran.split('-')[1] == 'floorplan' ? new THREE.Vector3(0, -1, 0) : new THREE.Vector3(0, 1, 0); // let center = getPointForRevRotate(info.center, floorJson.angle, this.player.model.center) var center = info.center; var pos = new THREE.Vector3(center.x, -999 * rayDir.y, -center.y); // 检测当前pos在模型底部的映射坐标,确认标签高度 var ray = new THREE.Raycaster(pos, rayDir, 0.001, 9999); var rayInfo = ray.intersectObject(floor.children[0]); if (rayInfo[0]) { pos = rayInfo[0].point; pos.y += 0.5; } else { pos.y = labelHeight; } var closetPano = _this.player.model.panos.closestPanoTowardPoint({ point: pos, floor }); if (!closetPano) { console.error('what!!! no closetPano'); } var dollLabel = new DollLabel(_this.player, { sid: index_, pos: pos.clone(), text: text, toPano: closetPano, floorIndex: index }); _this.player.defaultRoomLabels.push(dollLabel); // var planLabel = new PlanLabel(this.player, { sid: 'pl_' + index_, pos: pos.clone(), text: text, floorIndex: index }) // this.player.defaultRoomLabels.push(planLabel) _this.player.defaultRoomLabels.forEach(function (label) { label.update(); }); }); _this.initDoorLabels(index, JSON.parse(JSON.stringify(floorData))); }); this.initedLabel = true; //-------initedLabel之后------ this.setPlanLabelVisi(); common.timeMeasuring.addTimeMark('initLabels', 'end', true); } }, { key: "initDoorLabels", value: function initDoorLabels(floorIndex, floorJson) { var _this2 = this; var doors = []; if (!floorJson.rooms || !floorJson.rooms[0] || !floorJson.rooms[0].wallPointIDs) { console.log('没有room or 数据不标准 得不到doorlabels'); return; } var floor = this.player.model.floors.index[floorIndex]; var bottom = floor.boundingBox.min.y; Object.keys(floorJson.tags).forEach(function (tagKey) { var tag = floorJson.tags[tagKey]; tag.__panos = []; //for taggingTables if (!tag.title) delete floorJson.tags[tagKey]; }); var doorJson = {}; Object.keys(floorJson.symbols).forEach(function (symKey) { var symbol = floorJson.symbols[symKey]; if (symbol.geoType == 'SingleDoor' || symbol.geoType == 'SlideDoor' || symbol.geoType == 'DoubleDoor') doorJson[symKey] = symbol; }); floorJson.rooms.forEach(function (room, index) { room.name = ''; room.doors = Object.values(doorJson).filter(function (door) { return room.wallIds.indexOf(door.parent) > -1; }) || []; room.taggings = []; room.panos = []; }); Object.keys(doorJson).forEach(function (doorKey) { var door = doorJson[doorKey]; door.doorLabels = []; doors.push(door); door.center = { x: (door.points2d[0].x + door.points2d[1].x) / 2, y: (door.points2d[0].y + door.points2d[1].y) / 2 }; //中心位置 //正常一个门对应两个atRooms,但数据却可能多个,冗余的都是没有tagging的room,但没有tagging不代表是冗余的房间 door.atRooms = []; floorJson.rooms.forEach(function (room) { var door_ = room.doors.find(function (door_) { return door_.vectorId == door.vectorId; }); if (door_) { //room.doors.push(door) door.atRooms.push(room); } }); }); //保险起见,统一删除rooms里没对应上的门 floorJson.rooms.forEach(function (room) { room.doors = room.doors.filter(function (door) { return door.atRooms; }); }); //找完了所有门和房间的对应关系 floor.panos.forEach(function (pano) { pano._atRoom = null; }); //查找房间中的tagging和pano floorJson.rooms.forEach(function (room) { room.points = room.wallPointIDs.map(function (pointId) { return floorJson.points[pointId]; }); if (room.closetParent == void 0) { //只从非内环找起,内环在searchTagRoom找 floor.panos.forEach(function (pano) { if (pano._atRoom || !pano.isAligned()) return; _this2.searchAtRoom(floorJson, room, pano, { x: pano.position.x, y: -pano.position.z }, function (atRoom) { pano._atRoom = atRoom; atRoom.panos.push(pano); }); }); Object.keys(floorJson.tags).forEach(function (tagKey) { var tagging = floorJson.tags[tagKey]; if (tagging._atRoom) return; _this2.searchAtRoom(floorJson, room, tagging, { x: tagging.center.x, y: tagging.center.y }, function (atRoom) { tagging._atRoom = atRoom; atRoom.taggings.push(tagging); atRoom.name += tagging.title + ' '; //将tagging收集到name中 }); }); } room.taggings.length && room.panos.forEach(function (pano) { //可能有pano不属于任何一个房间或tagging、也可能有tagging没有一个pano var score = common.sortByScore(room.taggings, [], [function (tagging) { //取距离最近的tagging作为pano的tagging var panoPos = new THREE.Vector2(pano.position.x, pano.position.z); var labelPos = new THREE.Vector2(tagging.center.x, -tagging.center.y); return -panoPos.distanceTo(labelPos); }]); if (score && score.length) { var noShelter = score.slice(0, 3).find(function (e) { //当前点位看向tagging的视线不能被墙挡住 var tagging = e.item; var panoPos = new THREE.Vector2(pano.position.x, pano.position.z); var labelPos = new THREE.Vector2(tagging.center.x, -tagging.center.y); return !_this2.isShelter(floorJson, labelPos, panoPos); }); var tagging = (noShelter || score[0]).item; tagging.__panos.push(pano); } }); }); Object.keys(floorJson.tags).forEach(function (tagKey) { var tagging = floorJson.tags[tagKey]; var panos = tagging.__panos.filter(function (pano) { return pano.neighbourUUIDs.length > 0; }); //排除孤立的pano (是否要排除在当前楼层无其他连接的pano,这样的话最好漫游可行中也更改相关设置,及checkHasNeighbor if (!panos.length) return; tagging.clickToPano = common.sortByScore(panos, [], [function (pano) { var panoPos = new THREE.Vector2(pano.position.x, pano.position.z); var labelPos = new THREE.Vector2(tagging.center.x, -tagging.center.y); return -panoPos.distanceTo(labelPos); }])[0].item; }); floor.taggingTables = Object.values(floorJson.tags).filter(function (tagging) { return tagging.clickToPano; }); //去掉没有pano的 //---------------end--------------------------------- var log = "floor".concat(floorIndex, "(").concat(floorJson.name || 'no name', ") \u5171\u6709").concat(floorJson.rooms.length, "\u4E2A\u623F\u95F4\uFF0C\u5206\u522B\u662F "); floorJson.rooms.forEach(function (room) { log += "\n\u623F\u95F4".concat(room.roomId, " : ").concat(room.name, " "); }); //如果从0开始 说明没有外墙 //建立doorLabel floorJson.rooms.forEach(function (room) { if (room.taggings.length == 0) return; var isClockWise = math$1.getArea(room.points) > 0; //是否顺时针 room.doors.forEach(function (door) { //if (door.atRooms.length < 2) return //忽略atRooms只有一个的门,因为它在墙边上,不通两个房间,比如入户门//2023.7.20发现有时候外围区域没闭合就算不了房间,这样客厅就看不到其他房间了,所以单向门还是要加上 //获取门朝向(朝房间内的那个法线) var points = []; if (room.closetChilds) { //可能在子环 var atRoom = door.atRooms.find(function (e) { return door.startPoint && door.endPoint; }); isClockWise = math$1.getArea(atRoom.points) > 0; //是否顺时针 atRoom != room && (isClockWise = !isClockWise); //如果在子环上,判断方向相反 points = atRoom.points; } else { points = room.points; } //var normal = math.getNormal({ points: [door.startPoint, door.endPoint] }) var atWall = floorJson.walls[door.parent]; var point1 = floorJson.points[atWall.start]; //this.searchItemById(atWall.start, Object.values(floorJson.points)) var point2 = floorJson.points[atWall.end]; //this.searchItemById(atWall.end, Object.values(floorJson.points)) var pointOrder = _this2.order(point1, point2, points); //p1是否在p2前 var normal = math$1.getNormal({ points: [point1, point2] }); var doorDir = new THREE.Vector3(normal.x, 0, -normal.y); //门朝向为:垂直于线条、朝房间内 if (pointOrder == isClockWise) doorDir.negate(); var roomOutside = false; var panos = room.panos.filter(function (pano) { return pano.neighbourUUIDs.length > 0; }); //排除孤立的pano if (panos.length == 0) { //如果该房间没有,选择门外侧一点,范围不可过大 roomOutside = true; panos = floor.panos.filter(function (pano) { if (pano.neighbourUUIDs.length == 0) return; var pos1 = new THREE.Vector2(door.center.x, -door.center.y); var pos2 = new THREE.Vector2(pano.position.x, pano.position.z); if (pos1.distanceTo(pos2) > 5) return; var panoDir = pano.position.clone().sub(new THREE.Vector3(door.center.x, 0, -door.center.y)); if (doorDir.angleTo(panoDir) < Math.PI / 2) return true; //在门外这一侧,否则可能到隔壁房间 }); } var toPano = common.sortByScore(panos, [], [function (pano) { var score0 = 0; if (roomOutside) { //在房间外 var panoDir = pano.position.clone().sub(new THREE.Vector3(door.center.x, 0, -door.center.y)); score0 = -doorDir.angleTo(panoDir) * 2; //尽量垂直于门 } var pos1 = new THREE.Vector2(door.center.x, -door.center.y); var pos2 = new THREE.Vector2(pano.position.x, pano.position.z); return -pos1.distanceTo(pos2) + score0; }]); //寻找离该门最近的pano toPano = toPano.length ? toPano[0].item : null; var forTag = common.sortByScore(room.taggings, [], [function (tagging) { var pos1 = toPano ? new THREE.Vector2(toPano.position.x, toPano.position.z) : new THREE.Vector2(door.center.x, door.center.y); var pos2 = new THREE.Vector2(tagging.center.x, -tagging.center.y); return -pos1.distanceTo(pos2); }])[0].item; //如果当前房间有多个tagging,寻找离toPano最近的tagging, 或离该门最近的tagging,作为该门的标签 var labelPos = new THREE.Vector3(door.center.x, bottom + 0.3, -door.center.y); var anotherRoom = door.atRooms.find(function (r) { return r != room && r.name; }); //先排除没有tagging的,因为可能是冗余room if (!anotherRoom) anotherRoom = door.atRooms.find(function (r) { return r != room; }); //如果没找到,说明对面的房间就是没有tagging var minDis1 = 1.5, minDis2 = 4, maxDis = 15, minAngle = Math.PI / 6; //"前方"的判定角度 var visiPanos1 = anotherRoom ? anotherRoom.panos : _this2.player.model.panos.list.filter(function (e) { return !e._atRoom; }); var visiPanos = visiPanos1.filter(function (pano) { var distance = pano.position.clone().setY(0).distanceTo(labelPos.clone().setY(0)); if (distance < minDis1 || distance > maxDis) return; //必要条件 if (distance > minDis2) return !_this2.isShelter(floorJson, labelPos, pano.position, door.parent); //充分条件 //门没有打洞的话就会被挡住 没有pano了 //如果在此pano前方有别的pano,也可见 var frontPano = visiPanos1.find(function (anotherPano) { return Panorama.filters.isInFanAngle(labelPos, pano.position.clone().sub(labelPos).setY(0), minAngle)(anotherPano.position); }); if (frontPano) return !_this2.isShelter(floorJson, labelPos, pano.position, door.parent); //convertTool.ifIntersectChunks(labelPos, pano.position); }); if (visiPanos.length) { var doorLabel = new DoorLabel(_this2.player, { doorDir, text: forTag.title, pos: labelPos, visiblePanos: visiPanos, sameRoomPanos: visiPanos1, toPano, aim: new THREE.Vector3(forTag.center.x, 0, -forTag.center.y), floorIndex }); doorLabel.door = door; doorLabel.forRoom = room; doorLabel.forTag = forTag; door.doorLabels.push(doorLabel); _this2.player.defaultRoomLabels.push(doorLabel); } else { console.log("\u56E0\u65E0visiblePanos\u53D6\u6D88\u521B\u5EFAdoorlabel\u7684\u95E8\uFF1A ".concat(anotherRoom ? anotherRoom.name : '(未闭合区域) ', "\u901A\u5F80 ").concat(forTag.title, " ")); } }); }); //doors = doors.filter(door => door.atRooms.length > 1) log += "\n\u95E8\u5171\u6709".concat(doors.length, "\u6247\uFF1A \n"); //其中仍包括一些无效门,连通的是冗余房间 doors.forEach(function (door, index) { log += "\u95E8".concat(door.vectorId, "\u5728 "); door.atRooms.forEach(function (room) { log += "\u623F\u95F4".concat(room.roomId, "(").concat(room.name, ")\u3001 "); }); log += "\u7684\u8FB9\u4E0A \n"; }); //门一定要真的放在当前线上(因为门可以游走,所以很难判断是否真的是当前的线) console.log("%c".concat(log), 'color:#13f'); this.player.doorLabels.forEach(function (label) { label.update(); }); this.player.updateLabelZIndex(['doorLabels']); DoorLabel.updateCameraDir(this.player); } }, { key: "setPlanLabelVisi", value: function setPlanLabelVisi(show, floorIndex) { var metadata = this.player.$app.store.getValue('metadata') || {}; if (metadata.floorPlanAngle != void 0) return; //代表是新版,cad图里的文字直接被planLabel取代,因此不用该函数 if (!this.initedLabel) return; if (show == void 0) { show = this.player.model.floorplanCadImg.getVisible(); } var planLabels = this.player.planLabels; if (floorIndex != void 0) { planLabels = planLabels.filter(function (label) { return label.floorIndex == floorIndex; }); } planLabels.forEach(function (label) { label.enable = show; label.update(); }); //dontShow完全和cad是否该显示有关 而labelEnable则还要额外考虑其他 } }, { key: "setDoorLabelVisi", value: function setDoorLabelVisi(show, floorIndex) { var metadata = this.player.$app.store.getValue('metadata') || {}; if (metadata.floorPlanAngle != void 0) return; if (!this.initedLabel) return; var doorLabels = this.player.doorLabels; if (floorIndex != void 0) { doorLabels = doorLabels.filter(function (label) { return label.floorIndex == floorIndex; }); } doorLabels.forEach(function (label) { label.enable = show; label.update(); }); } }, { key: "setDollLabelVisi", value: function setDollLabelVisi(show, floorIndex) { var metadata = this.player.$app.store.getValue('metadata') || {}; if (metadata.floorPlanAngle != void 0) return; if (!this.initedLabel) return; var dollLabels = this.player.dollLabels; if (floorIndex != void 0) { dollLabels = dollLabels.filter(function (label) { return label.floorIndex == floorIndex; }); } dollLabels.forEach(function (label) { label.enable = show; label.update(); }); } }, { key: "updateEntryVisi", value: function updateEntryVisi(show, floorIndex) { var _this3 = this; // 更改楼层的entryArrow显示 // “平面图”和“漫游可行”不显示entryArrow var visi = !(this.player.model.floorplanCadImg && this.player.model.floorplanCadImg.isEdit) && !(this.player.linkEditor && this.player.linkEditor.setPanoVisible); // console.log('updateEntryVisi', show) var floors = this.player.model.floors; if (floorIndex != void 0) { floors = floors.filter(function (floor) { return floor.floorIndex == floorIndex; }); } floors.forEach(function (floor) { if (!floor.entryArrow.length) return; if (visi) { if (show == false) visi = false; /*if (show == true)*/ else { //需要额外判断一下 var mode = _this3.player.modeTran.split('-')[1]; if (mode == 'floorplan') visi = true; //visi = floor.plane && floor.plane.visible else if (mode == 'panorama') visi = false;else if (mode == 'dollhouse') visi = true;else visi = false; // if(visi && this.player.model.currentFloor.floorIndex != floor.floorIndex) visi = false } } floor.entryArrow.forEach(function (arrow) { return visi ? arrow.show() : arrow.hide(); }); }); } }, { key: "moveEntryArrow", value: function moveEntryArrow(index) { var floor = this.player.model.floors.index[index]; if (floor.entryArrow.length && floor.cadImgRatio) { var wallDepth = 24; // 墙壁厚度恒定24px (2880*1620图时测得) var shiftY = wallDepth * this.player.model.floors.index[index].cadImgRatio; //得到墙壁真实厚度 按理说应该除以2的,但是不除以2却刚好 floor.entryArrow.forEach(function (arrow) { return arrow.moveCloseToWall(shiftY); }); } } //广度搜索 }, { key: "searchAtRoom", value: function searchAtRoom(floorJson, room, object, pos, callback) { var _this4 = this; var inside = math$1.isPointInArea(room.points, pos); if (inside) { if (room.closetChilds) { var finded = room.closetChilds.find(function (roomId) { return _this4.searchAtRoom(floorJson, floorJson.rooms.find(function (e) { return e.roomId == roomId; }), object, pos, callback); }); if (!finded) { callback(room); } } else { callback(room); } return true; } } }, { key: "order", value: function order(p1, p2, points) { //wall的p1 p2在ground中是否p1在前一个 /* var p1 = points.find(point => point.vectorId == p1ID) var p2 = points.find(point => point.vectorId == p2ID) */ var index1 = points.indexOf(p1); var index2 = points.indexOf(p2); return (index2 - index1 + points.length) % points.length === 1; } }, { key: "isShelter", value: function isShelter(floorJson, labelPos, panoPos, atWall) { //performance.mark('isShelter-start') var line1 = [new THREE.Vector2(labelPos.x, -labelPos.z), new THREE.Vector2(panoPos.x, -panoPos.z)]; var isIntersect = Object.values(floorJson.walls).find(function (wall) { if (atWall != void 0 && wall.vectorId != void 0 && wall.vectorId === atWall) return; var point1 = floorJson.points[wall.start]; //this.searchItemById(wall.start, Object.values(floorJson.points)) var point2 = floorJson.points[wall.end]; //this.searchItemById(wall.end, Object.values(floorJson.points)) var line2 = [point1, point2]; return math$1.isLineIntersect(line1, line2); }); /* performance.mark('isShelter-end') let measure = performance.measure('isShelter', "isShelter-start", "isShelter-end"); console.log('isShelter', measure.duration.toFixed(3)) */ return isIntersect; } /* searchItemById(id, arr) { for (let i = 0, len = arr.length; i < len; i++) { if (arr[i].vectorId == id) { return arr[i] } } } */ /* sortByScore = function(list, request, rank) { var i = common.filterAll(list, request) return 0 === i.length ? null : (i = i .map(function(e) { return { item: e, score: rank.reduce(function(t, i) { return t + i(e) }, 0) } }) .sort(function(e, t) { return t.score - e.score })) } */ }, { key: "show", value: function show(floorIndex) { this.updateEntryVisi(true, floorIndex); this.setPlanLabelVisi(true, floorIndex); this.setDoorLabelVisi(true, floorIndex); this.setDollLabelVisi(true, floorIndex); } }, { key: "hide", value: function hide(floorIndex) { this.updateEntryVisi(false, floorIndex); this.setPlanLabelVisi(false, floorIndex); this.setDoorLabelVisi(false, floorIndex); this.setDollLabelVisi(false, floorIndex); } }, { key: "reset", value: function reset() { this.player.defaultRoomLabels.forEach(function (label) { return label.remove(); }); this.player.model.floors.forEach(function (floor) { floor.entryArrow.forEach(function (arrow) { return arrow.dispose(); }); }); } }, { key: "gotoFloor", value: function gotoFloor(index) { this.hide(); this.show(index); } }]); return LabelManager; }(); function getPointForRevRotate(vec2, angle, modelCenter) { // let modelCenter = new THREE.Vector3(0, 0, 0) var point = new THREE.Vector2(vec2.x, vec2.y); if (Math.abs(angle) < 0.01 || Math.abs(angle - 2 * Math.PI) < 0.01) { return point; } else { var x = (point.x - modelCenter.x) * Math.cos(angle) - (point.y - modelCenter.z) * Math.sin(angle) + modelCenter.x; var y = (point.y - modelCenter.z) * Math.cos(angle) + (point.x - modelCenter.x) * Math.sin(angle) + modelCenter.z; point.x = x; point.y = y; return point; } } var ModelSide = { side: null //空为自动,有值锁定side }; ModelSide.setSide = function (side) { if (side === THREE.FrontSide || side === THREE.BackSide || side === THREE.DoubleSide) { this.side = side; } else { this.side = null; } }; var ModelSideManager = function ModelSideManager(player) { var _this = this; _classCallCheck(this, ModelSideManager); this.tempAuto = function () { _this.recoverSide = ModelSide.side; ModelSide.setSide(null); _this.updateSide(); }; this.recover = function () { ModelSide.setSide(_this.recoverSide); _this.recoverSide = null; _this.updateSide(); }; this.updateSide = function () { if (_this.player.mode === Viewmode$1.FLOORPLAN) { _this.player.model.setMode('floorplan'); } else if (_this.player.mode === Viewmode$1.DOLLHOUSE) { _this.player.model.setMode('dollhouse'); } }; this.player = player; this.recoveSide = null; }; var initDir = new THREE.Vector3(0, 0, -1); //指南针模型的北方向 /** * 指南针 * 相关css在 ./label/static/label.css */ var Compass = /*#__PURE__*/function () { function Compass(player) { _classCallCheck(this, Compass); this.angle = 0; this.quar = new THREE.Quaternion(); this.player = player; this.config = player.$app.config; this.init(); this.show = false; this.force = false; this.switch('direction'); } _createClass(Compass, [{ key: "switch", value: function _switch(type) { this.type = type; if (type == 'direction') { this.dirTextNDiv.style.display = 'block'; this.dirTextXDiv.style.display = 'none'; this.dirTextYDiv.style.display = 'none'; this.dirTextZDiv.style.display = 'none'; this.lines.visible = false; this.cones.visible = true; } if (type == 'axis') { this.dirTextNDiv.style.display = 'none'; this.dirTextXDiv.style.display = 'block'; this.dirTextYDiv.style.display = 'block'; this.dirTextZDiv.style.display = 'block'; this.lines.visible = true; this.cones.visible = false; } this.autoJudgeDisplay(); } }, { key: "init", value: function init() { var _this = this; var width = 50, height = 50; this.dom = document.createElement('div'); this.dom.id = 'compass'; this.dom.innerHTML = "\n
N
\n\n
X
\n
Y
\n
Z
\n
\n "; this.player.domElement.append(this.dom); this.dirTextNDiv = this.dom.querySelector('.north'); this.dirTextXDiv = this.dom.querySelector('#dirTextX'); this.dirTextYDiv = this.dom.querySelector('#dirTextY'); this.dirTextZDiv = this.dom.querySelector('#dirTextZ'); this.centerDiv = this.dom.querySelector('.center'); if (this.config.view) { this.dom.style.right = this.config.mobile ? '1%' : '2%'; this.dom.style.top = this.config.mobile ? '10%' : '4%'; } else { this.dom.style.right = this.config.mobile ? '1%' : '277px'; this.dom.style.top = this.config.mobile ? '10%' : '55px'; } this.centerDiv.style.width = width + 'px'; this.centerDiv.style.height = height + 'px'; if (this.config.mobile) { var _this$player$getSize = this.player.getSize(), clientWidth = _this$player$getSize.clientWidth, clientHeight = _this$player$getSize.clientHeight; var minWidth = Math.min(clientWidth, clientHeight); if (minWidth < 450) { var initScale = Math.round(minWidth / 450 * 1000) / 1000; this.dom.transform = " scale(".concat(initScale, ")"); } } try { ; this.renderer = new THREE.WebGLRenderer({ antialias: this.config.antialias, alpha: true }), this.renderer.autoClear = !0, this.renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1), this.renderer.domElement.setAttribute('name', 'compass'); this.renderer.setClearAlpha(0.0); this.renderer.setSize(width, height, false, window.devicePixelRatio ? window.devicePixelRatio : 1); } catch (e) { throw new RendererCreationException('Unable to create a WebGL rendering context'); } this.centerDiv.appendChild(this.renderer.domElement); this.camera = new THREE.PerspectiveCamera(); this.camera.fov = 70; this.scene = new THREE.Scene(), this.scene.add(this.camera); this.createCompass(); /* this.player.on('scene/LoadHouseFloor', () => { this.setNorth() }) this.player.on('changeDir', () => { this.setNorth() }) //点击旋转户型图按钮 */ var floorUserData = this.player.$app.store.getValue('flooruser'); this.angle = (floorUserData.compass - THREE.MathUtils.radToDeg(floorUserData.angle) + 360) % 360 || 0; this.player.$app.store.on('flooruser', function (data) { //在cad页面 点击保存后,更新cad和指南针的旋转 _this.angle = (data.compass - THREE.MathUtils.radToDeg(data.angle) + 360) % 360 || 0; }); } /* setNorth() { //设置北方向,这决定了自身的朝向。 const floors = this.player.$app.store.getValue('flooruser').floors if (!floors || !floors.length) { return } const floor = floors[0] const metadata = this.player.$app.store.getValue('metadata') || {} this.angle = ((floor && floor.dire) || 0) + THREE.MathUtils.radToDeg(parseFloat(metadata.floorPlanAngle || 0)) //基础朝向 this.cones.rotation.y = Math.PI / 2 - THREE.MathUtils.degToRad(this.angle) console.log('dir:' + floor.dire + ', floorPlanAngle:' + metadata.floorPlanAngle) this.update() this.player.model.floorLogos.setDir(this.angle) } */ }, { key: "createCompass", value: function createCompass() { //ConeBufferGeometry(radius : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float) var height = 2; var geometry1 = new THREE.ConeBufferGeometry(0.7, height, 4, true); var geometry2 = new THREE.ConeBufferGeometry(0.7, height, 4, true); var material = new THREE.MeshBasicMaterial({ vertexColors: true }); //指南针由两个四棱锥拼成,为了渐变颜色,采用指定vertexColor的方式。 var setColor = function setColor(geometry, color1, color2) { var colors = []; for (var i = 0, n = geometry.attributes.position.count; i < n; ++i) { colors.push(1, 1, 1); } var set = function set(index, color) { //设置第index个点的颜色 colors[index * 3 + 0] = color[0]; colors[index * 3 + 1] = color[1]; colors[index * 3 + 2] = color[2]; }; var mid = [(color1[0] + color2[0]) / 2, (color1[1] + color2[1]) / 2, (color1[2] + color2[2]) / 2]; set(1, color1); set(5, color1); set(6, color1); set(2, mid); set(3, mid); set(7, mid); set(4, color2); set(8, color2); set(9, color2); geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3)); }; var blue1 = [1 / 255, 238 / 255, 245 / 255]; //逐渐变深 var blue2 = [20 / 255, 146 / 255, 170 / 255]; var blue3 = [40 / 255, 60 / 255, 103 / 255]; setColor(geometry1, blue1, blue2); setColor(geometry2, blue2, blue3); /* 朝箭头方向看点构成如下 虽然geometry.attributes.position.count = 19 只有1-9设置的颜色是有效的 另外为什么7决定了上下两边的颜色呢…… 5、9可将其分成上下两个颜色 6 /|\ / | \ 7 /_2|1_\ 5 \ 3|4 / 9 \ | / \|/ 8 */ var cone = new THREE.Mesh(geometry1, material); cone.position.setY(height / 2); geometry1.computeVertexNormals(); //computeFaceNormals geometry2.computeVertexNormals(); var cones = new THREE.Object3D(); cones.add(cone); var cone2 = new THREE.Mesh(geometry2, material); cone2.rotation.x = Math.PI; cone2.position.setY(-height / 2); cones.add(cone2); cones.rotation.z = Math.PI / 2; cones.rotation.y = Math.PI / 2; //转向initDir的方向 cones.scale.set(0.7, 0.7, 0.7); this.scene.add(cones); this.cones = cones; var lines = new THREE.Object3D(); var lineX = new THREE.Line(new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, 10)]), new THREE.LineBasicMaterial({ color: 0x0000ff })); lines.add(lineX); var lineY = new THREE.Line(new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 10, 0)]), new THREE.LineBasicMaterial({ color: 0x00ff00 })); lines.add(lineY); var lineZ = new THREE.Line(new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(10, 0, 0)]), new THREE.LineBasicMaterial({ color: 0xff0000 })); lines.add(lineZ); this.lines = lines; this.scene.add(lines); } }, { key: "update", value: function update(quaternion) { if (!this.show) return; if (!quaternion) quaternion = this.player.camera.quaternion.clone(); this.cones.rotation.y = Math.PI / 2 - this.angle / 180 * Math.PI; // 指南针基础方向 this.updateCamera(quaternion); this.updateLabel(quaternion); this.render(); } }, { key: "updateLabel", value: function updateLabel(quaternion) { //更新北标签 var dir = this.player.getDirection(); var oriDir = initDir.clone(); //指南针最初始时的北方向 var extraQua; if (this.player.mode == 'transitioning') { //当transitioning时,相机的quaternion不是用control的lookAt算出来,而是直接由一个quaternion过渡到另一个,这样相机将会是歪的,投影面也就不会是原先的水平面。 var tempCamera = new THREE.Camera(); //借用camera的lookAt算出如果正视同样的target, quaternion会是什么值。 将它乘以当前相机quaternion,得到的就是相机歪的旋转值。 tempCamera.position.copy(this.camera.position); tempCamera.lookAt(tempCamera.position.clone().add(dir)); var q = tempCamera.quaternion.invert(); extraQua = q.premultiply(quaternion); //歪掉的额外旋转值 } //北标签的方向为指南针轮盘方向,也就是要将camera的方向投影到水平面上。 但是如果相机歪了,看到的世界都会歪一定角度,投影面也要歪一定角度。 var up = new THREE.Vector3(0, 1, 0); //投影水平面的法线,也是相机的摆正的up方向 extraQua && up.applyQuaternion(extraQua); dir.projectOnPlane(up); //将方向投影到水平面上; 如果相机不是正视(extraQua不为0001),就要将水平面也转动 oriDir.projectOnPlane(up); //为什么initDir投影了和没有投影angle结果一样 var angle = dir.angleTo(oriDir); if (dir.cross(oriDir).y > 0) angle = -angle; var deg = this.angle - 90 + THREE.MathUtils.radToDeg(angle); //因为css写的样式初始是指向右方,和initDir差了90°,所以减去。 if (this.type == 'axis') { this.dirTextXDiv.style.transform = 'rotate(' + (deg + 90 - this.angle) + 'deg)'; this.dirTextXDiv.querySelector('span').style.transform = 'rotate(' + -(deg + 90 - this.angle) + 'deg)'; this.dirTextYDiv.style.transform = 'rotate(' + -90 + 'deg)'; this.dirTextYDiv.querySelector('span').style.transform = 'rotate(' + 90 + 'deg)'; this.dirTextZDiv.style.transform = 'rotate(' + (deg + 90 + 90 - this.angle) + 'deg)'; this.dirTextZDiv.querySelector('span').style.transform = 'rotate(' + -(deg + 90 + 90 - this.angle) + 'deg)'; } else { this.dirTextNDiv.style.transform = 'rotate(' + deg + 'deg)'; this.dirTextNDiv.querySelector('span').style.transform = 'rotate(' + -deg + 'deg)'; } } }, { key: "updateCamera", value: function updateCamera(quaternion) { //更新canvas中的指南针表现,也就是更新相机,和场景中的相机朝向一致。 var radius = 5; //相机距离 this.camera.quaternion.copy(quaternion); var dir = this.player.getDirection(); //相机朝向 this.camera.position.copy(dir.multiplyScalar(radius).negate()); //相机绕着指南针中心(000)转动 } }, { key: "render", value: function render() { this.renderer.render(this.scene, this.camera); } }, { key: "setDisplay", value: function setDisplay(state, force) { if (this.force && force == void 0) { return; } if (force != void 0) { this.force = force; } this.show = !!state; if (this.show) { this.update(); // this.dom.fadeIn(100) this.dom.style.display = 'block'; } else { // this.dom.fadeOut(100) this.dom.style.display = 'none'; } } }, { key: "autoJudgeDisplay", value: function autoJudgeDisplay() { // if(this.player.modeTran.split("-")[1] != "panorama" && store.getters.page != 'cad' && store.getters.page != 'data') { if (this.player.modeTran.split('-')[1] != 'panorama' || this.type == 'axis') { this.setDisplay(true); } else { this.setDisplay(false); } } }, { key: "setDomLeft", value: function setDomLeft() { this.dom.css({ right: 'none', left: this.config.mobile ? '1%' : '2%' }); } }]); return Compass; }(); function _createSuper$14(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$14(); 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 _isNativeReflectConstruct$14() { 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; } } var player$8, sceneRenderer$2, app; var planeGeo1, planeGeo2, balloonMap, balloonMap2, defaultCircleMap, defaultExitMap, camera, scene, mesh, isEdit; var viewLinkEdit = {}; var fishEyeRadius = 10; //使用鱼眼尽量提高清晰度。即渲染出相机在接近球边缘的地方看向球心的画面,球上是全景图。 /* 将全景图渲染成某个漫游视角的贴图 renderTarget的作用是直接将渲染结果作为贴图 */ var render = function render(renderTarget, unDealTex, enterQuaternion) { mesh.material.uniforms.tDiffuse.value = unDealTex; var rot90 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2); camera.quaternion.copy(new THREE.Quaternion().multiplyQuaternions(rot90, enterQuaternion)); //改 为球目全景照片而改 var target = new THREE.Vector3(0, 0, -fishEyeRadius * 0.8).applyQuaternion(camera.quaternion); camera.position.copy(target.clone().negate()); var V = sceneRenderer$2.renderer.autoClear; sceneRenderer$2.renderer.autoClear = !1; // sceneRenderer.renderer.render(scene, camera, renderTarget, !1) sceneRenderer$2.renderer.setRenderTarget(renderTarget); // sceneRenderer.renderer.clear() sceneRenderer$2.renderer.render(scene, camera); sceneRenderer$2.renderer.setRenderTarget(null); sceneRenderer$2.renderer.autoClear = V; }; var dealURL = function dealURL(url) { console.log(url); if (url && /* url.slice(0, 5) != 'blob:' && url.slice(0, 4) != 'http') || */ !url.includes('/')) { var src = app.resource.getUserResourceURL(url); return src; } else return url; }; var ViewLinkManager = /*#__PURE__*/function (_THREE$EventDispatche) { _inherits(ViewLinkManager, _THREE$EventDispatche); var _super = _createSuper$14(ViewLinkManager); function ViewLinkManager(app_, player_) { var _this; _classCallCheck(this, ViewLinkManager); _this = _super.call(this); app = app_; isEdit = !app.config.view; player$8 = player_; sceneRenderer$2 = app.core.get('SceneRenderer'); _this.loaded = false; _this.enabled = true; _this.views = {}; _this.ViewLinkCircles = new THREE.Object3D(); _this.ViewLinkCircles.name = 'ViewLinkCircles'; _this.ViewLinkBalloons = new THREE.Object3D(); _this.ViewLinkBalloons.name = 'ViewLinkBalloons'; _this.ViewLinkExits = new THREE.Object3D(); _this.ViewLinkExits.name = 'ViewLinkExits'; _this.ViewTitles = new THREE.Object3D(); _this.ViewTitles.name = 'ViewTitles'; _this.addEventListener('getViewLinkEdit', function (e) { viewLinkEdit = e.v; }); app.Scene.on('loadeddata', function () { var data = app.store.getValue('links'); if (!data) { _this.init(); return; } if (!player$8.model.builded) { //floor需要 return player$8.model.addEventListener('builded', _this.init.bind(_assertThisInitialized(_this), data)); } _this.init(data); }); return _this; } _createClass(ViewLinkManager, [{ key: "init", value: function init(data) { var _this2 = this; ViewLink.init(); this.createViews(data); player$8.model.add(this.ViewLinkCircles); player$8.model.add(this.ViewLinkBalloons); player$8.model.add(this.ViewLinkExits); player$8.model.add(this.ViewTitles); this.inited = true; //if(isEdit)viewLinkEdit.init(); if (player$8.currentPano && player$8.currentPano.hasVideo) { //初始画面是有视频点的地方,延迟出现。因为circle容易闪烁,可能是被视频遮盖。 this.ViewLinkCircles.visible = false; this.ViewLinkBalloons.visible = false; this.ViewLinkExits.visible = false; setTimeout(function () { if (_this2.enabled) { _this2.ViewLinkCircles.visible = true; _this2.ViewLinkBalloons.visible = true; _this2.ViewLinkExits.visible = true; } }, 1000); } var intersectMesh, viewMeshes = []; player$8.on('collectIntersectMesh', function (meshes, e) { //推送要intersect的mesh if (!_this2.inited || !_this2.enabled /* || (isEdit && store.getters.page == 'videos') */ ) return; var detectChunk = true; if (player$8.isOutsideMode()) { if (viewLinkEdit.markView) { viewMeshes = [viewLinkEdit.markView.balloon.mesh]; } else { viewMeshes = _this2.ViewLinkBalloons.children; } } else if (player$8.is360View(player$8.mode, player$8.currentPano)) { if (viewLinkEdit.settingEntry) viewMeshes = []; //设置进入画面 else if (viewLinkEdit.settingVisibles) { viewMeshes = _this2.ViewLinkCircles.children; } else { viewMeshes = _this2.ViewLinkExits.children.concat(_this2.ViewLinkCircles.children); } detectChunk = false; } else { if (viewLinkEdit.markView) { //可以拖拽 viewMeshes = [viewLinkEdit.markView.circle.mesh]; detectChunk = false; } else { viewMeshes = _this2.ViewLinkCircles.children; } } if (detectChunk) { meshes.push.apply(meshes, _toConsumableArray(viewMeshes)); } else { //非detectChunk状态下intersect到的话,直接dealwithIntersect, 将不会执行下面judgeIntersect的 var intersect = convertTool.getMouseIntersect(player$8.camera, viewMeshes, player$8.mouse); if (intersect && viewMeshes.includes(intersect.object)) { intersectMesh = intersect; _this2.dealwithIntersect(intersect); e.consume(); } } }); player$8.on('judgeIntersect', function (intersect, e) { //判断是否intersect了overlay if (e.getConsumed()) return; if (intersect && viewMeshes.includes(intersect.object)) { intersectMesh = intersect; e.consume(); } else { intersectMesh = null; } _this2.dealwithIntersect(intersectMesh); }); player$8.on('click', function (e) { //判断是否intersect了overlay if (e.getConsumed()) return; if (_this2.dealWithClick()) { e.consume(); } }); player$8.on('update', function (e) { if (e.hasChanged.cameraChanged) { _this2.update(); } }); player$8.on('mode.changing', function (fromMode, toMode, pano, dur) { //转换前 if (fromMode == 'panorama') { setTimeout(function () { for (var i in _this2.views) { _this2.views[i].balloon.showOrHide(true, dur / 2, 'auto'); _this2.views[i].circle.setVisible(false); } viewLinkEdit.markView && viewLinkEdit.markView.circle.setVisible(true); }, dur || 500); } else if (fromMode == 'floorplan') { for (var i in _this2.views) { _this2.views[i].balloon.mesh.material.depthTest = true; //防止其他楼层遮挡 } } if (toMode == 'floorplan') { setTimeout(function () { for (var _i in _this2.views) { _this2.views[_i].balloon.mesh.material.depthTest = false; //防止其他楼层遮挡 } }, dur); } if (toMode == 'panorama') { for (var _i2 in _this2.views) { _this2.views[_i2].balloon.showOrHide(false); _this2.views[_i2].circle.setVisible(true); } viewLinkEdit.cancelPos && viewLinkEdit.cancelPos(); } }); //let floorsVisi = {} player$8.model.on('floor.changed', function (currentFloor, toMode, oldFloor) { if (player$8.mode == 'panorama' && toMode != 'panorama') return; //使用mode.changing var isAll = player$8.model.allFloorsVisible; player$8.model.floors.forEach(function (floor) { if (floor == currentFloor || isAll) { //floorsVisi[floor.floorIndex] = true if (toMode == 'floorplan' || toMode == 'dollhouse') { floor.views.forEach(function (view) { view.balloon.showOrHide(true, 500); }); } } else { floor.views.forEach(function (view) { viewLinkEdit.markView != view && view.balloon.showOrHide(false, 500); }); } }); }); if (player$8.$app.config.view) { //展示页面。 不要遮住漫游点视频 player$8.on(PlayerEvents.FlyingEnded, function (_ref) { var currentPano = _ref.currentPano; var panoVideoFilter; if (player$8.mode == 'panorama') { panoVideoFilter = currentPano.getVideoFilter(); } _this2.ViewLinkCircles.children.forEach(function (e) { if (currentPano == _this2.views[e.name.split('circle_')[1]].nearestPano) { return common.updateVisible(e, 'coveredPanoVideo', true); //如果是其最近点就不隐藏。否则点击列表跳转过来后又找不到图标 } if (panoVideoFilter && panoVideoFilter(e.position)) { common.updateVisible(e, 'coveredPanoVideo', false); } else { common.updateVisible(e, 'coveredPanoVideo', true); } }); }); } if (!app.store.getValue('metadata').controls.showLinkTitle) { this.changeTitlesShow(false); } } }, { key: "createViews", value: function createViews(data) { if (!data) return; // 无 var views = common.CloneJson(data.tags || data); views.forEach(function (item) { if (this.views[item.sid]) { console.log('有重复的view sid' + item.sid); return; } var view = new ViewLink(item); this.addView(view); }.bind(this)); if (player$8.getToMode() != 'panorama') { for (var i in this.views) { this.views[i].balloon.showOrHide(true, 0); } } this.dispatchEvent({ type: 'loaded' }); this.loaded = true; } /* 判断鼠标移动到哪个view mesh上 */ /* getIntersectView() { var viewMeshes if (!this.inited || !this.enabled || (isEdit && store.getters.page == 'videos')) return var detectChunk = true, meshes if (player.isOutsideMode()) { viewMeshes = this.ViewLinkBalloons.children } else if (player.is360View(player.mode, player.currentPano)) { if (viewLinkEdit.settingEntry) viewMeshes = [] else if (viewLinkEdit.settingVisibles) { viewMeshes = this.ViewLinkCircles.children } else { viewMeshes = this.ViewLinkExits.children.concat(this.ViewLinkCircles.children) } detectChunk = false } else { if (viewLinkEdit.markView) { //可以拖拽 viewMeshes = [viewLinkEdit.markView.circle.mesh] detectChunk = false } else { viewMeshes = this.ViewLinkCircles.children } } if (detectChunk) { meshes = this.model.floors.reduce(function (e, t) { return t.hidden ? e : e.concat(t.collider.children) }, viewMeshes) } else meshes = viewMeshes var origin = new THREE.Vector3(player.mouse.x, player.mouse.y, -1).unproject(player.camera) player.raycaster.set(origin, player.getMouseDirection(player.mouse)) var results = player.raycaster.intersectObjects(meshes) if (results && results.length && viewMeshes.includes(results[0].object)) { return results[0] } } */ /* 根据上面那个函数得到的mesh来判断是哪个view被pick到了,并且记下来,且触发setSelect、 更改鼠标cursor */ }, { key: "dealwithIntersect", value: function dealwithIntersect(intersect) { if (!this.enabled) return; var mesh = intersect && intersect.object; if (this.hoverCircle && this.hoverCircle.mesh != mesh && (!viewLinkEdit.markView || viewLinkEdit.markView.circle != this.hoverCircle)) { this.dispatchEvent({ type: 'changeIntersect', hovered: null }); this.hoverCircle.setSelect(false); } if (this.hoverBalloon && this.hoverBalloon.mesh != mesh && (!viewLinkEdit.markView || viewLinkEdit.markView.balloon != this.hoverBalloon)) { this.dispatchEvent({ type: 'changeIntersect', hovered: null }); this.hoverBalloon.setSelect(false); } if (this.hoverExit && this.hoverExit.mesh != mesh /* && (!viewLinkEdit.markView || viewLinkEdit.markView.exitDoor != this.hoverExit) */ ) { //bus.emit('link/tag/active', null) this.hoverExit.setSelect(false); } this.clickEnable = false; this.hoverBalloon = null; this.hoverCircle = null; this.hoverExit = null; if (!intersect) { //$('#player').css('cursor', '') CursorDeal.remove('hoverView'); CursorDeal.remove('dragView'); return true; } var view; if (mesh.name.includes('balloon')) { view = this.views[mesh.name.split('balloon_')[1]]; view.balloon.setSelect(true); this.hoverBalloon = view.balloon; this.dispatchEvent({ type: 'changeIntersect', hovered: view.sid }); } else if (mesh.name.includes('exit')) { view = this.views[mesh.name.split('circle_exitDoor')[1]]; view.exitDoor.setSelect(true); this.hoverExit = view.exitDoor; } else { view = this.views[mesh.name.split('circle_')[1]]; if (!view) { return console.error('找不到view?', mesh.name); } this.hoverCircle = view.circle; view.circle.setSelect(true); this.dispatchEvent({ type: 'changeIntersect', hovered: view.sid }); } if (viewLinkEdit.markView == view && (player$8.currentPano != view.pano || viewLinkEdit.settingExit || viewLinkEdit.settingVisibles)) { CursorDeal.add('dragView'); } else { CursorDeal.add('hoverView'); this.clickEnable = true; } /* if (viewLinkEdit.markView) { if (viewLinkEdit.markView == view || viewLinkEdit.settingVisibles) { CursorDeal.add('dragView') } } else { CursorDeal.add('hoverView') } */ } /* and如果点击了鼠标,就触发相应的点击的事件 */ }, { key: "dealWithClick", value: function dealWithClick() { if (this.clickEnable) { var hovered = this.hoverCircle || this.hoverBalloon || this.hoverExit; var view = this.views[hovered.sid]; if (hovered == this.hoverExit) { /* if(viewLinkEdit.settingExit){ }else */ view.backToPanorama(); return true; } else { if (view.linkType == 'url') { /* if (browser.urlHasValue('scene-link')) { //?? bus.emit('link/tag/click', view.url) } else { */ if (app.config.link && typeof app.config.link === 'object') { var url = view.url; if (typeof app.config.link.onAction === 'function') { url = app.config.link.onAction(url); } if (url) { if (app.config.link.target == 'blank') { window.open(url); } else { window.location.href = url; } } } else if (view.url) { window.location.href = view.url; } //} } else if (view.linkType == 'pano' && view.pano) { view.enter360Pano(); } return true; } } } }, { key: "addView", value: function addView(view) { this.views[view.sid] = view; this.ViewLinkCircles.add(view.circle.mesh); this.ViewLinkBalloons.add(view.balloon.mesh); view.exitDoor && this.ViewLinkExits.add(view.exitDoor.mesh); this.ViewTitles.add(view.titleLabel); } }, { key: "removeView", value: function removeView(view) { this.ViewLinkCircles.remove(view.circle.mesh); this.ViewLinkBalloons.remove(view.balloon.mesh); this.ViewLinkExits.remove(view.exitDoor.mesh); delete this.views[view.sid]; } }, { key: "update", value: function update(camera) { for (var r in this.views) { this.views[r].update(); } } }, { key: "showAllViews", value: function showAllViews() { if (this.enabled) return; //直接更改parent的visible this.ViewLinkCircles.visible = true; this.ViewLinkBalloons.visible = true; this.ViewLinkExits.visible = true; this.changeTitlesShow(true, 'showAll'); this.enabled = true; } }, { key: "hideAllViews", value: function hideAllViews() { if (!this.enabled) return; if (player$8.is360View(player$8.mode, player$8.currentPano)) { //先退出全景 player$8.currentPano.view.backToPanorama(); } else if (player$8.enteringView) { /* player.waitFlytoItemFuc = ()=>{ player.currentPano.view.backToPanorama() } */ player$8.once(PlayerEvents.FlyingEnded, function () { player$8.currentPano.view.backToPanorama(); }); } //直接更改parent的visible this.ViewLinkCircles.visible = false; this.ViewLinkBalloons.visible = false; this.ViewLinkExits.visible = false; this.changeTitlesShow(false, 'showAll'); this.dealwithIntersect(null); //清除所有hover this.enabled = false; } }, { key: "changeTitlesShow", value: function changeTitlesShow(state) { var cause = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'onShow'; common.updateVisible(this.ViewTitles, cause, !!state); if (state) { this.ViewTitles.children.forEach(function (e) { return e.updatePos(); }); } } }, { key: "setViewsVisible", value: function setViewsVisible(type, visi) { //根据类型显示隐藏 if (!this.enabled) return; for (var i in this.views) { if (this.views[i].linkType == type) { this.views[i].setVisible(visi); } } } /* 主要是在编辑状态下,focus on某个view,让用户知道自己正在编辑的view在画布中是哪个mesh。 如果是漫游模式就飞向其入口、 如果是ouside模式,就让相机移近气球,以气球为target。 */ }, { key: "focusOn", value: function focusOn(view) { var _this3 = this; if (player$8.flying) { return player$8.once(PlayerEvents.FlyingEnded, function () { _this3.focusOn(view); }); } if (player$8.mode == 'panorama') { player$8.flyToPano({ pano: view.nearestPano, lookAtPoint: view.circle.mesh.position, checkAlone: true }); } else player$8.focusPoint({ aim: view.balloon.mesh.position }); } }, { key: "updateCirclesWhenFade", value: function updateCirclesWhenFade(state, o) { if (state == 'enter') { for (var i in this.views) { //更新此view中的其他view的circle的表现 if (i in o.pano.view.visibleViews) { var info = {}; info.viewDir = new THREE.Vector3().fromArray(o.pano.view.visibleViews[i]); this.views[i].circle.updatePos('at360View', info); this.views[i].circle.setVisible(true); } else { this.views[i].circle.setVisible(false); } } } else { for (var _i3 in this.views) { if (this.views[_i3].circle.at360View) { this.views[_i3].circle.updatePos('normal'); } o.flyOut || this.views[_i3].circle.setVisible(true); } o.flyOut && viewLinkEdit.markView && viewLinkEdit.markView.circle.setVisible(true); } } }, { key: "exitView", value: function exitView() { var deferred = new Deferred$1(); if (player$8.is360View(player$8.mode, player$8.currentPano)) { player$8.currentPano.view.backToPanorama(); player$8.once(PlayerEvents.FlyingEnded, function () { deferred.resolve(); }); } else { deferred.resolve(); } return deferred.promise(); } }]); return ViewLinkManager; }(THREE.EventDispatcher); //----------------------------------------------------------------- //全景 or 超链接 var ViewLink = /*#__PURE__*/function (_THREE$EventDispatche2) { _inherits(ViewLink, _THREE$EventDispatche2); var _super2 = _createSuper$14(ViewLink); function ViewLink(data) { var _this4; _classCallCheck(this, ViewLink); _this4 = _super2.call(this); //console.log(data) _this4.sid = data.sid; _this4.pano = null; //对应的pano _this4.balloon = new ViewLinkBalloon(data, _assertThisInitialized(_this4)); _this4.circle = new ViewLinkCircle(data, _assertThisInitialized(_this4)); //this.quaternion = data.quaternion ? new THREE.Quaternion().fromArray(data.quaternion) : new THREE.Quaternion; //全景图的旋转 _this4.linkType = data.type; //'url' or 'pano' _this4.enterQuaternion = data.enterQuaternion ? new THREE.Quaternion().fromArray(data.enterQuaternion) : new THREE.Quaternion(); //进入时的朝向 _this4.exitDirection = data.exitDirection ? new THREE.Vector3().fromArray(data.exitDirection) : new THREE.Vector3(0, 0, settings$3.view360.circleDisToCenter); //出口的位置 _this4.url = data.url; if (isEdit || _this4.linkType == 'pano') _this4.exitDoor = new ViewLinkCircle(Object.assign({}, data, { circleType: 'exitDoor', exitDirection: _this4.exitDirection }), _assertThisInitialized(_this4)); { _this4.titleLabel = new viewTitle(data.title, _assertThisInitialized(_this4)); _this4.addEventListener('updatePose', function (e) { if (e.target.circleType == 'exitDoor') return; _this4.titleLabel.updatePos(); }); _this4.circle.addEventListener('move', function () { _this4.titleLabel.bindTo == 'circle' && _this4.titleLabel.updatePos(); }); } //处理图片缓存 version有bug,所以用scene.json里的 且scene.json和getinfo里的version还不太同步,getinfo要发布后才改变 //data.version = app.store.get('metadata').version if (data.thumb) { _this4.imgSid = data.thumb.split('.jpg')[0]; //data.thumb = `https://4dkankan.oss-cn-shenzhen.aliyuncs.com/${isEdit ? 'scene_edit_data' : 'scene_view_data'}/${player.model.sid}/images/panorama/${this.imgSid}/low/${data.thumb}` data.thumb = app.resource.getUserImagesURL("panorama/".concat(_this4.imgSid, "/low/").concat(data.thumb)); _this4.resolution = data.resolution; // '2k' or '4k' } _this4.nearestPano = data.nearestPano && player$8.model.panos.index[data.nearestPano]; if (_this4.nearestPano) { _this4.floor = _this4.nearestPano.floor; _this4.floor.addView(_assertThisInitialized(_this4)); } _this4.setPano(data); _this4.visibleViews = data.visibleViews || {}; _this4._data = data; return _this4; } _createClass(ViewLink, [{ key: "update", value: function update(force) { //this.mesh.quaternion.copy(camera.quaternion); this.balloon.update(force); this.circle.update(force); this.exitDoor && this.exitDoor.update(force); } }, { key: "dispose", value: function dispose() { var _this5 = this; this.balloon.dispose(); this.circle.dispose(); this.exitDoor.dispose(); this.deleteOldPano(); this.titleLabel.dispose(); if (player$8.currentPano == this.pano) this.backToPanorama();else if (this.entering) { player$8.once(PlayerEvents.FlyingEnded, function () { _this5.backToPanorama(); }); //player.waitFlytoItemFuc = ()=>{this.backToPanorama()} } this.floor && this.floor.removeView(this); } /* 删除旧的pano在tile贴图上留下的残留 (可能还有bug) */ }, { key: "deleteOldPano", value: function deleteOldPano() { var _this6 = this; if (!this.pano) return; this.pano.floor.removePano(this.pano); this.pano.exit(); delete this.pano.panoRenderer.activeRenderTargetDescriptors[this.sid]; delete this.pano.panoRenderer.panoDescriptors[this.sid]; if (this.pano.tiled) { delete this.pano.panoRenderer.tileTrees[this.sid]; delete this.pano.panoRenderer.tileDirectory[this.sid]; delete this.pano.tileDownloader.downloadDescriptors[this.sid]; this.pano.tileDownloader.priorityQueue = this.pano.tileDownloader.priorityQueue.filter(function (item) { return item.pano != _this6.pano; }); this.pano.tileDownloader.activeDownloads = this.pano.tileDownloader.activeDownloads.filter(function (item) { return item.pano != _this6.pano; }); } //cleanupActiveDownloads var M = this.pano.panoRenderer.M; for (var i = 0; i < M.length; i++) { if (M[i].pano == this.pano) { M.splice(i, 1); break; } } var u = player$8.model.panos.list.indexOf(this.pano); player$8.model.panos.list.splice(u, 1); } /* 绑定对应pano, 以及全景图 */ }, { key: "setPano", value: function setPano() { var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (this.linkType == 'pano') { if (o.thumb || o.thumbPanoTex) { //o.thumb是上传贴图后的src, o.thumbPanoTex是点击取消时恢复的;相同点是都换图了,要重新创建pano var rebuild = !!this.pano; if (this.pano) { this.deleteOldPano(); } var pano = new Panorama(player$8.$app, this.sid, { panoType: '360view', position: new THREE.Vector3(), quaternion: new THREE.Quaternion(), //this.enterQuaternion, puck: new THREE.Vector3(0, -1.6, 0), seeMarkers: [], subgroup: this.nearestPano.floor.floorIndex, tiled: !o.mapSrc }); pano.mapSrc = o.mapSrc; //编辑时临时的整张贴图src pano.attachToPanoRenderer(player$8.$app.core.get('PanoRenderer')); pano.qualityManager = player$8.$app.core.get('QualityManager'); if (pano.tiled) { pano.tileDownloader = player$8.$app.core.get('TileDownloader'); } pano.build1(); pano.view = this; player$8.model.panos.add(pano); //加载tiles需要 this.panoImgVersion = o.version; //防止缓存的后缀 /* if(rebuild){ if(player.model.projectedPano0 == this.pano)player.model.projectedPano0 = pano; if(player.model.projectedPano1 == this.pano)player.model.projectedPano1 = pano; } */ if (rebuild && player$8.currentPano == this.pano) { //重新加载贴图 var retryCallback = function retryCallback() { if (!player$8.checkAndWaitForPanoLoad(pano, 'high', 'low', player$8.basePanoSize, retryCallback)) { player$8.model.setProjectedPanos(pano, pano); pano.enter(); } }; player$8.currentPano = pano; retryCallback(); } this.pano = pano; if (o.thumbPanoTex) { this.thumbPanoTex = o.thumbPanoTex; } else { this.thumbPanoTex = this.renderToGetMap(o.thumb); } this.circle.setMapIn(this.thumbPanoTex); this.balloon.setMapIn(this.thumbPanoTex); } if (this.thumbPanoTex) { //没传图时changeMap仍为0 this.circle.mesh.material.uniforms.changeMap.value = 1; this.balloon.mesh.material.uniforms.changeMap.value = 1; } } else { this.circle.mesh.material.uniforms.changeMap.value = 0; this.balloon.mesh.material.uniforms.changeMap.value = 0; } } //将全景图渲染成某个漫游视角的贴图 }, { key: "renderToGetMap", value: function renderToGetMap(src) { var _this7 = this; var renderTarget = new THREE.WebGLRenderTarget(256, 256, { stencilBuffer: !1 }); /* if(!isEdit){ //咋写 src = config.getPublicResource(src) src = src.replace("results","pan") src = src.replace("scene/","") } */ var tex = texture.load(src, function () { isEdit && (_this7.unDealTex = tex); render(renderTarget, tex, _this7.enterQuaternion); }); tex.flipY = false; tex.minFilter = THREE.LinearFilter; this.renderTarget = renderTarget; return renderTarget.texture; } }, { key: "mapChangeRot", value: function mapChangeRot() { //修改初始视角后重新渲染贴图 render(this.renderTarget, this.unDealTex, this.enterQuaternion); } /* updateMap(fov){ camera.fov = fov; camera.updateProjectionMatrix() var V = sceneRenderer.renderer.autoClear; sceneRenderer.renderer.autoClear = !1 sceneRenderer.renderer.render(scene, camera, this.renderTarget, !1) sceneRenderer.renderer.autoClear = V //renderTarget.texture.needsUpdate = true; } */ }, { key: "enter360Pano", value: function enter360Pano(fun) { //进入全景 /* if (player.isOutsideMode()) { player.flyToNewMode({ mode: 'panorama', pano: this.pano, callback: fun }) } else { if (player.cameraControls.activeControl) { player.cameraControls.activeControl.insideLookLimitUp = 89.9 player.cameraControls.activeControl.insideLookLimitDown = -89.9 player.cameraControls.activeControl.limitAngleIsBound = false } player.flyToPano({ pano: this.pano }, () => { if (typeof fun === 'function') { fun() } player.model.floorLogos.changefloorLogoOpa({//隐藏 dur: 0, index: 0, opa: 0, }) }) } */ player$8.flyToPano({ pano: this.pano }, function () { if (typeof fun === 'function') { fun(); } }); } }, { key: "backToPanorama", value: function backToPanorama() { /* if (player.cameraControls.activeControl) { player.cameraControls.activeControl.insideLookLimitUp = null player.cameraControls.activeControl.insideLookLimitDown = null player.cameraControls.activeControl.limitAngleIsBound = true } */ //出来到漫游点 player$8.flyToPano({ pano: player$8.lastPano || this.nearestPano, lookAtPoint: this.circle.mesh.position }); } }, { key: "setVisible", value: function setVisible(v) { if (!v == this.disabled) return; if (v) { this.balloon.disabled = false; this.balloon.showOrHide(true, 0, 'auto'); } else { this.balloon.showOrHide(false, 0); this.balloon.disabled = true; if (player$8.currentPano == this.pano || player$8.enteringView == this) { //注:enteringView时其实不会退出,所以这句其实需要改为callback后,以后再改 this.backToPanorama(); } } this.disabled = !v; this.circle.disabled = !v; this.circle.setVisible(); } }, { key: "setSelect", value: function setSelect(state) { if (this.selected == state) return; this.selected = !!state; this.circle.setSelect(state); this.balloon.setSelect(state); } }]); return ViewLink; }(THREE.EventDispatcher); ViewLink.init = function () { if (ViewLink.inited) return; planeGeo1 = new THREE.PlaneBufferGeometry(0.4, 0.4); planeGeo2 = new THREE.PlaneBufferGeometry(1.5, 1.5); balloonMap = texture.load(texture.getImageURL('images/img_pamove.png') /* ,null,null,{antialias:true} */ ); balloonMap2 = texture.load(texture.getImageURL('images/img_pamove_normal.png')); //分区 defaultCircleMap = texture.load(texture.getImageURL('images/img_panorama_dot.png')); defaultExitMap = texture.load(texture.getImageURL('images/img_exit_dot.png')); balloonMap2.minFilter = THREE.LinearMipmapNearestFilter; //1007 //可能缩小锯齿更弱一些 balloonMap2.needsUpdate = true; /* defaultCircleMap.anisotropy = 4 defaultCircleMap.needsUpdate = true */ //用于渲染出贴图的一些工具: camera = new THREE.PerspectiveCamera(); camera.fov = 80; camera.aspect = 1; camera.updateProjectionMatrix(); scene = new THREE.Scene(); scene.add(camera); mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(fishEyeRadius, 25, 25), new THREE.RawShaderMaterial({ //new THREE.BoxBufferGeometry(1,1) uniforms: THREE.UniformsUtils.clone(sphereRenderToCube.uniforms), vertexShader: sphereRenderToCube.vertexShader, fragmentShader: sphereRenderToCube.fragmentShader, depthWrite: !1, depthTest: !1, side: THREE.DoubleSide })); scene.add(mesh); ViewLink.inited = true; }; /* 整体 360view 本质是全景pano 和 入口出口等mesh集合 默认对应的pano的位置都是Vector3(0,0,0) exitDoor: 全景图内exit图标 enterQuaternion: 进入全景图时的初始角度 exitDirection: 全景图内exit图标的方向。 linkType: 全景或者超链接 nearestPano: 最近的pano, 退出全景后到达的pano。 (因为是在编辑时确定的,所以干脆保存下来。) visibleViews:在该全景图中可以看到的 别的全景的circle集合, 每个全景包含了它在该全景内的位置信息 */ //---------------------------------------- var ViewLinkBase = /*#__PURE__*/function (_THREE$EventDispatche3) { _inherits(ViewLinkBase, _THREE$EventDispatche3); var _super3 = _createSuper$14(ViewLinkBase); function ViewLinkBase(data, view) { var _this8; _classCallCheck(this, ViewLinkBase); _this8 = _super3.call(this); _this8.view = view; _this8.sid = data.sid; //this.state = 'sprite' return _this8; } _createClass(ViewLinkBase, [{ key: "update", value: function update(force) { var changed = false; if (this.state == 'sprite' && this.mesh.visible && (force || (this.mesh.material.uniforms.opacity ? this.mesh.material.uniforms.opacity.value > 0 : true))) { this.mesh.quaternion.copy(player$8.camera.quaternion); changed = true; } if (this.strictScale) { //通过限定二维大小,防止看起来过小。 var _camera = player$8.mode == 'floorplan' ? player$8.cameraControls.activeControl.camera : player$8.camera; //floorplan 时要用到OrthographicCamera var s = math$1.getScaleForConstantSize({ dom: player$8.$app.dom, maxSize: 100, minSize: 40, nearBound: 2, farBound: 80, camera: _camera, position: this.mesh.position }); this.mesh.scale.set(s, s, s); changed = true; } changed && this.view.dispatchEvent({ type: 'updatePose' }); } }, { key: "setStrictScale", value: function setStrictScale(state) { //设定是否限定二维大小 this.strictScale = state; if (state) this.update();else this.mesh.scale.set(1, 1, 1); this.view.dispatchEvent({ type: 'updatePose' }); } }, { key: "setMapIn", value: function setMapIn(map) { this.mesh.material.uniforms.mapIn.value = map; } }, { key: "dispose", value: function dispose() {} }]); return ViewLinkBase; }(THREE.EventDispatcher); /* 在漫游模式下看到的圆圈部分: 分为入口和出口 入口分为两种状态:1 普通状态 2 在别的全景内时 出口和在别的全景内的入口都是billboardSprite状态 即其quaternion同相机quaternion,在画面上看就是标准的圆。只是大小会在屏幕边缘更大些。 */ var ViewLinkCircle = /*#__PURE__*/function (_ViewLinkBase) { _inherits(ViewLinkCircle, _ViewLinkBase); var _super4 = _createSuper$14(ViewLinkCircle); //飞入后 function ViewLinkCircle(data, view) { var _this9; _classCallCheck(this, ViewLinkCircle); _this9 = _super4.call(this, data, view); _this9.circleType = data.circleType; _this9.position = new THREE.Vector3(); //记录在普通状态下的位置 _this9.quaternion = new THREE.Quaternion(); //记录在普通状态下的旋转 _this9.build(data); return _this9; } _createClass(ViewLinkCircle, [{ key: "build", value: function build(data) { var uniforms = THREE.UniformsUtils.clone(linkSpotInside.uniforms); var mesh = new THREE.Mesh(planeGeo1, new THREE.RawShaderMaterial({ uniforms: uniforms, vertexShader: linkSpotInside.vertexShader, fragmentShader: linkSpotInside.fragmentShader, transparent: true, side: THREE.DoubleSide })); mesh.renderOrder = RenderOrder.view; mesh.name = 'circle_' + (this.circleType ? this.circleType : '') + this.sid; this.mesh = mesh; this.setMapOut(data); if (this.circleType == 'exitDoor') { this.mesh.visible = false; this.mesh.material.depthTest = false; data.exitDirection && this.mesh.position.copy(data.exitDirection); this.state = 'sprite'; } else { if (data.circle) { data.circle.pos && this.position.fromArray(data.circle.pos); data.circle.qua && this.quaternion.fromArray(data.circle.qua); var s = data.circle.scale / 100; data.circle.scale && this.mesh.scale.set(s, s, s); this.state = '3D'; this.updatePos(); } if (player$8.isOutsideMode()) this.setVisible(false); } } /* circle在全景之内需要转换位置 */ }, { key: "updatePos", value: function updatePos(type, o) { if (type == 'at360View') { //在别的view内显示时 //var dir = this.position.clone().sub(o.viewPos).normalize() new THREE.Vector3(); var dir = o.viewDir.clone().normalize(); this.mesh.position.copy(dir.multiplyScalar(settings$3.view360.circleDisToCenter)); //this.mesh.lookAt(center) this.at360View = true; this.state = 'sprite'; //console.log("changeTosprite :"+this.sid) } else { if (o) { o.position && this.position.copy(o.position); o.quaternion && this.quaternion.copy(o.quaternion); } this.mesh.position.copy(this.position); this.mesh.quaternion.copy(this.quaternion); this.at360View = false; this.state = '3D'; //console.log("changeTo3D :"+this.sid) this.judgeDepthTest(); this.dispatchEvent({ type: 'move' }); } } }, { key: "state", get: function get() { return this._state; }, set: function set(v) { this._state = v; //console.log('state', v, this.name) this.mesh && this.update(); } }, { key: "judgeDepthTest", value: function judgeDepthTest() { this.mesh.material.depthTest = !(this.state == 'sprite' || this.selected); } }, { key: "update", value: function update() { _get(_getPrototypeOf(ViewLinkCircle.prototype), "update", this).call(this); this.judgeDepthTest(); } /* 选中后材质渐变 */ }, { key: "setSelect", value: function setSelect(state) { if (state == this.selected) return; this.selected = state; var fadeTime = 500; this.judgeDepthTest(); transitions$1.cancelById('circlePro'); transitions$1.start(lerp.uniform(this.mesh, 'progress', state ? 1 : 0), fadeTime, function () {}, 0, easing[settings$3.transition.blendEasing], 'circlePro' /* , settings.freeze.FlyToPano */ ); } /* 使用用户设置的贴图或者默认 */ }, { key: "setMapOut", value: function setMapOut(data) { var map; if (this.circleType == 'exitDoor') { if (!data) map = defaultExitMap;else if (data instanceof THREE.Texture) map = data;else if (typeof data == 'string') { map = texture.load(data); } else { /* if (data.style && data.style.exit.url) map = texture.load(dealURL(data.style.exit.url)) else map = defaultExitMap //name:out, exit-style-${name}.jpg */ if (data.style) { var url; if (data.style.exit.name && data.style.exit.name != 'custom') { url = app.resource.getAppURL("images/link/exit-style-".concat(data.style.exit.name, ".png")); //console.log('circle 使用默认图片', data.style.exit.name, url) } else { if (data.style.exit.url) url = dealURL(data.style.exit.url); } map = texture.load(url); } else map = defaultExitMap; } } else { if (!data) map = defaultCircleMap;else if (data instanceof THREE.Texture) map = data;else if (typeof data == 'string') { map = texture.load(dealURL(data)); } else { if (data.style) { var _url; if (data.style.enter.name && data.style.enter.name != 'custom') { _url = app.resource.getAppURL("images/link/enter-style-".concat(data.style.enter.name, ".png")); //console.log('circle 使用默认图片', data.style.enter.name, url) } else { if (data.style.enter.url) _url = dealURL(data.style.enter.url); } map = texture.load(_url); } else map = defaultCircleMap; } } this.mesh.material.uniforms.mapOut.value = map; } }, { key: "setVisible", value: function setVisible(v) { if (v == void 0) { //使用历史值 v = this._visible; } common.updateVisible(this.mesh, 'setVisible', !this.disabled && v); //this.mesh.visible = !this.disabled && v this._visible = v; } }]); return ViewLinkCircle; }(ViewLinkBase); /* 在空中的气球部分 */ var ViewLinkBalloon = /*#__PURE__*/function (_ViewLinkBase2) { _inherits(ViewLinkBalloon, _ViewLinkBase2); var _super5 = _createSuper$14(ViewLinkBalloon); //飞出后 function ViewLinkBalloon(data, view) { var _this10; _classCallCheck(this, ViewLinkBalloon); _this10 = _super5.call(this, data, view); _this10.state = 'sprite'; _this10.build(data); return _this10; } _createClass(ViewLinkBalloon, [{ key: "build", value: function build(data) { var uniforms = THREE.UniformsUtils.clone(linkSpot.uniforms); uniforms.mapOut.value = balloonMap; uniforms.mapOut2.value = balloonMap2; uniforms.opacity.value = 0; var mesh = new THREE.Mesh(planeGeo2, new THREE.RawShaderMaterial({ uniforms: uniforms, vertexShader: linkSpot.vertexShader, fragmentShader: linkSpot.fragmentShader, transparent: true, side: THREE.DoubleSide, depthTest: false //飞出后再变为true })); mesh.renderOrder = RenderOrder.view; mesh.name = 'balloon_' + this.sid; this.mesh = mesh; if (data.balloon) { data.balloon.pos && this.mesh.position.fromArray(data.balloon.pos); } this.mesh.visible = false; //因为一开始在panorama模式 } /* 从外飞到漫游模式时气球会渐渐消失,反之渐渐出现 */ }, { key: "showOrHide", value: function showOrHide(state, fadeTime, type) { var _this11 = this; //console.log('showOrHide ', state , this.sid, type) if (this.disabled) return; if (type == 'auto') { //自动判断是否可见 飞出后,在别的楼层不可见 state = player$8.getToMode() != 'panorama' && (player$8.model.allFloorsVisible || !this.view.floor || this.view.floor == player$8.model.currentFloor); } var fadeTime = fadeTime != void 0 ? fadeTime : 500; var opa = state ? 1 : 0; transitions$1.cancelById('balloonOpa_' + this.sid); if (this.mesh.material.uniforms.opacity.value == opa) return; state && (this.mesh.visible = true); this.update(true); transitions$1.start(lerp.uniform(this.mesh, 'opacity', opa), fadeTime, function (e) { _this11.mesh.material.depthTest = player$8.modeTran.split('-')[1] != 'floorplan'; _this11.mesh.visible = !!state; //消失时防止遮住其他mesh 如circle _this11.view.titleLabel.switchBind(state ? 'balloon' : 'circle'); }, 0, easing[settings$3.transition.blendEasing], null, 'balloonOpa_' + this.sid); } /* hover and click */ }, { key: "setSelect", value: function setSelect(state) { //this.mesh.material.uniforms.isActive.value = state ? 1 : 0 if (state == this.selected) return; this.selected = state; var fadeTime = 300; transitions$1.cancelById('balloonPro'); transitions$1.start(lerp.uniform(this.mesh, 'activeProgress', state ? 1 : 0), fadeTime, function () {}, 0, easing[settings$3.transition.blendEasing], 'balloonPro' /* , settings.freeze.FlyToPano */ ); } }]); return ViewLinkBalloon; }(ViewLinkBase); var viewTitle = /*#__PURE__*/function (_TextSprite) { _inherits(viewTitle, _TextSprite); var _super6 = _createSuper$14(viewTitle); function viewTitle(text, view) { var _this12; _classCallCheck(this, viewTitle); _this12 = _super6.call(this, { text, backgroundColor: { r: 255, g: 255, b: 255, a: 0 }, textColor: { r: 255, g: 255, b: 255, a: 1 }, textshadowColor: '#888', borderRadius: 2, fontsize: 34, renderOrder: 5, margin: { x: 12, y: 10 }, player: player$8, fixOrient: true, sizeInfo: { scale: 0.4, nearBound: 3 } }); _this12.sprite.material.depthTest = _this12.sprite.material.depthWrite = true; _this12.view = view; _this12.visible = false; setTimeout(function () { _this12.visible = true; _this12.switchBind(view.balloon.mesh.visible ? 'balloon' : 'circle'); }, 1); /* const s = 0.3 this.scale.set(s, s, s) */ return _this12; } _createClass(viewTitle, [{ key: "switchBind", value: function switchBind(bindTo) { //console.error('bindTo', bindTo) this.bindTo = bindTo; if (bindTo == 'circle') { this.fixOrient = true; this.quaternion.copy(this.view.circle.mesh.quaternion); } else { this.fixOrient = false; this.view.balloon; } this.updatePos(); } }, { key: "updatePos", value: function updatePos() { if (!common.realVisible(this)) return; var mesh, margin, localPos = new THREE.Vector3(0, -1, 0); if (this.bindTo == 'circle') { mesh = this.view.circle.mesh; margin = 0.08; this.quaternion.copy(this.view.circle.mesh.quaternion); } else { mesh = this.view.balloon.mesh; mesh.scale.x * 0.8, margin = 0.2; } mesh.updateMatrix(); localPos.multiplyScalar(margin + Math.abs(mesh.geometry.attributes.position.array[0])); localPos.applyMatrix4(mesh.matrix); //this.scale.set(s, s, s) this.position.copy(localPos); this.updatePose(); //scale //console.log('updatepos') } }]); return viewTitle; }(TextSprite); function _createSuper$13(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$13(); 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 _isNativeReflectConstruct$13() { 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; } } /** * 马赛克效果 * 注:原本的马赛克效果产品经理不太满意,因此现在的马赛克其实是高斯模糊 */ var Paint$1 = /*#__PURE__*/function (_Emiter) { _inherits(Paint, _Emiter); var _super = _createSuper$13(Paint); function Paint(app, player) { var _this; _classCallCheck(this, Paint); _this = _super.call(this); _this.app = app; _this.player = player; // app.core.get('Player') _this.sceneRenderer = app.core.get('SceneRenderer'); _this.sceneNum = app.config.num; _this.painting = false; // 进入/结束涂抹 _this.pause = false; // 是否暂停涂抹 _this.mousePosition = new THREE.Vector4(); _this.currentPaintUrl = null; // 当前马赛克图片路径 var metadata = app.store.getValue('metadata'); if (!metadata) { app.store.on('metadata', function (data) { _this.paintData = data.mosaicList; // 涂抹贴图的大小 _this.width = 1024 * (data.sceneFrom == 'pro' ? 2 : 4); // window.innerWidth; _this.height = 1024 * (data.sceneFrom == 'pro' ? 1 : 2); // window.innerHeight }); } else { _this.paintData = metadata.mosaicList; _this.width = 1024 * (metadata.sceneFrom == 'pro' ? 2 : 4); _this.height = 1024 * (metadata.sceneFrom == 'pro' ? 1 : 2); } return _this; } _createClass(Paint, [{ key: "init", value: function init() { var _this2 = this; // 准备离屏渲染的render和shader var resolution = new THREE.Vector3(this.width, this.height, window.devicePixelRatio); this.bufferRenderer = new BufferRenderer(this.sceneRenderer.renderer, { width: this.width, height: this.height }); this.bufferShader = new BufferShader({ iResolution: { value: resolution }, iMouse: { value: this.mousePosition }, iChannel0: { value: null }, // 马赛克 iChannel1: { value: null }, // 全景图 iBrushType: { value: 1 }, iBrushSize: { value: 5 }, iAngle: { value: 0 }, iPitch: { value: 0 }, iIsBrush: { value: 0 } }); // 同时更新skybox和chunk的相关uniforms,因为还要在model.js里渲染笔刷 Object.assign(this.player.model.skybox.material.uniforms, this.bufferShader.uniforms); this.player.model.chunks.forEach(function (chunk) { return Object.assign(chunk.materialInside.uniforms, _this2.bufferShader.uniforms); }); } // 开始涂抹 }, { key: "start", value: function start(isPause) { var _this3 = this; this.player.reticule.visible = false; this.player.cameraControls.activeControl.enabled = false; this.mousePosition.setZ(0); // z用于标识是否mousedown // 计算相机角度-------------------------------- var lookAt = this.player.camera.getWorldDirection(new THREE.Vector3()); // 上下转角 var projectVec = lookAt.clone().projectOnPlane(new THREE.Vector3(0, 1, 0)); var pitch = lookAt.angleTo(projectVec) * Math.sign(-lookAt.y); // 左右转角 var lookAtXZ = lookAt.clone().setY(0); var skyRota = new THREE.Euler().setFromQuaternion(this.player.currentPano.quaternion); //this.player.currentPano.skyboxMesh.rotation var skyDir = new THREE.Vector3(1, 0, 0).applyEuler(skyRota).setY(0); var skyDirCross = new THREE.Vector3(0, 0, 1).applyEuler(skyRota).setY(0); var angle = lookAtXZ.angleTo(skyDir) * Math.sign(lookAtXZ.dot(skyDirCross)); this.bufferShader.uniforms['iAngle'].value = angle; this.bufferShader.uniforms['iPitch'].value = pitch; // ------------------------------------------- if (isPause) { // 恢复暂停 this.showBrush(true); this.pause = false; } else { // 将已有马赛克数据放入到离屏渲染 var startPaint = function startPaint(texture) { // 不重置readBuffer的话,保存一次后将不再能涂抹 _this3.bufferRenderer.readBuffer = new THREE.WebGLRenderTarget(_this3.width, _this3.height, _this3.bufferRenderer.bufferOptions); texture && (_this3.bufferRenderer.readBuffer.texture = texture); _this3.bufferRenderer.writeBuffer = new THREE.WebGLRenderTarget(_this3.width, _this3.height, _this3.bufferRenderer.bufferOptions); // 将全景图马赛克设置为离屏渲染texture,使涂抹实时更新 _this3.setPaintTexture('paint0Map', _this3.bufferRenderer.readBuffer.texture); _this3.setPaintTexture('paint1Map', _this3.bufferRenderer.readBuffer.texture); _this3.painting = true; if (_this3.pause) _this3.cancel(true); }; if (this.currentPaintUrl) { // 这里必须load一个新texture,否则会形成readbuffer和texture的反馈环 new THREE.TextureLoader().load(this.currentPaintUrl, function (texture) { texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.type = THREE.FloatType; // 和readbuffer一致 texture.needsUpdate = true; startPaint(texture); }); } else { startPaint(); } this.player.locked = true; this.hasEdit = false; // 标明start后有没有涂抹过 this.defineHasPaint(true); // 设置hasPaint为true,否则涂抹相关shader将被ifelse判断跳过 // 加载一张全景图作为涂抹的底图(高斯模糊必须用pan/high/,马赛克用pan/low/就可以) texture.load(this.app.resource.getViewImagesURL("pan/high/".concat(this.player.currentPano.id, ".jpg")), function (panoTexture) { _this3.bufferShader.uniforms['iChannel1'].value = panoTexture; // 给离屏shader设置底图 _this3.showBrush(true); // 显示笔刷 _this3.emit('start'); }); } } // 停止涂抹 }, { key: "cancel", value: function cancel(isPause) { this.player.reticule.visible = true; this.player.cameraControls.activeControl.enabled = true; this.showBrush(false); // 隐藏笔刷 if (isPause) { // 暂停,只停下来转视角 this.pause = true; } else { this.painting = false; this.hasEdit = false; this.player.locked = false; this.setPaintImage(this.currentPaintUrl, this.currentPaintUrl); // 更新马赛克图片到全景图,替换离屏渲染texture this.bufferRenderer.readBuffer.dispose(); this.bufferRenderer.writeBuffer.dispose(); } } // 保存涂抹数据 }, { key: "save", value: function save() { var self = this; var panoId = this.player.currentPano.id; return { panoId: panoId, data: this.bufferRenderer.save(), // base64 func: function func() { // 把base64当做链接存起来,就不用等后端返回png路径了 self.currentPaintUrl = self.bufferRenderer.base64; // 更新panoPaint if (!self.paintData) self.paintData = []; var panoPaint = self.paintData.find(function (data) { return data.panoId == panoId; }); if (panoPaint) { panoPaint.data = self.bufferRenderer.base64; } else { self.paintData.push({ panoId: panoId, data: self.bufferRenderer.base64 }); } } }; } }, { key: "update", value: function update() { // 涂抹实时更新 if (this.painting && !this.pause) { this.bufferShader.uniforms['iChannel0'].value = this.bufferRenderer.readBuffer.texture; // 每次渲染出马赛克都更新到bufferShader保存下来 this.bufferRenderer.render(this.bufferShader.scene, this.bufferShader.camera); // 渲染bufferShader场景,得到新马赛克 } } /** * 笔刷 */ // 笔刷显隐 }, { key: "showBrush", value: function showBrush(show) { this.sceneRenderer.renderer.domElement.style.cursor = show ? 'none' : 'default'; // 如果显示笔刷的话,就要隐藏鼠标 this.player.model.skybox && (this.player.model.skybox.material.uniforms['iShowBrush'].value = show ? 1 : 0); this.player.model.chunks.forEach(function (chunk) { return chunk.materialInside.uniforms['iShowBrush'].value = show ? 1 : 0; }); } // 笔刷切换 }, { key: "changeBrush", value: function changeBrush(type) { if (parseInt(type) == -1) { this.cancel(true); // 暂停涂抹 } else { this.pause && this.start(true); // 从暂停恢复 this.bufferShader.uniforms['iBrushType'].value = parseInt(type); } } // 调整笔刷大小 }, { key: "setBrushSize", value: function setBrushSize(size) { this.bufferShader.uniforms['iBrushSize'].value = parseFloat(size); } /** * 涂抹贴图更新 */ // 外部调用,用于pano跳转 }, { key: "updatePanoPaint", value: function updatePanoPaint(pano0Id, pano1Id) { if (!this.paintData) return; var pano0Paint = this.paintData.find(function (data) { return data.panoId == pano0Id; }); var path0 = pano0Paint && (pano0Paint.data || this.app.resource.getUserResourceURL(pano0Paint.fileName)); var pano1Paint = this.paintData.find(function (data) { return data.panoId == pano1Id; }); var path1 = pano1Paint && (pano1Paint.data || this.app.resource.getUserResourceURL(pano1Paint.fileName)); this.currentPaintUrl = pano1Id != null ? path1 : path0; this.setPaintImage(path0, path1); } // 用于非涂抹时更新贴图 }, { key: "setPaintImage", value: function setPaintImage(path0, path1) { var _this4 = this; this.defineHasPaint(!!path1 || !!path0); // 考虑到过渡效果,pano1和pano0都要判断 path0 ? texture.loadWithoutUpdate(path0, function (t) { return _this4.setPaintTexture('paint0Map', t); }, function () {} // 给个空函数catch error ) : this.setPaintTexture('paint0Map', null); path1 ? texture.loadWithoutUpdate(path1, function (t) { return _this4.setPaintTexture('paint1Map', t); }, function () {}) : this.setPaintTexture('paint1Map', null); } // 设置涂抹贴图 mapName: 'paint0Map' | 'paint1Map' }, { key: "setPaintTexture", value: function setPaintTexture(mapName, texture) { if (texture) { texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; } this.app.core.get('QuickstartManager').skybox.material.uniforms[mapName].value = texture; this.player.model.skybox && (this.player.model.skybox.material.uniforms[mapName].value = texture); this.player.model.chunks.forEach(function (chunk) { return chunk.materialInside.uniforms[mapName].value = texture; }); this.player.model.highMapCube && this.player.model.highMapCube.tiles.forEach(function (tile) { tile.material.uniforms[mapName].value = texture; }); } // 设置HasPaint,为true时才运行马赛克相关shader,减少显存占用 }, { key: "defineHasPaint", value: function defineHasPaint(isDefine) { var materials = []; materials.push(this.app.core.get('QuickstartManager').skybox.material); this.player.model.skybox && materials.push(this.player.model.skybox.material); this.player.model.chunks.forEach(function (chunk) { return materials.push(chunk.materialInside); }); this.player.model.highMapCube && materials.push.apply(materials, _toConsumableArray(this.player.model.highMapCube.tiles.map(function (e) { return e.material; }))); if (isDefine) { materials.forEach(function (mat) { return mat.defines['HasPaint'] = true, mat.needsUpdate = true; }); } else { materials.forEach(function (mat) { return delete mat.defines['HasPaint'], mat.needsUpdate = true; }); } } /** * 涂抹鼠标事件处理 */ }, { key: "dealPointerDown", value: function dealPointerDown() { if (this.player.locked) { this.hasEdit = true; this.mousePosition.setZ(1); } else { // 保证start完再mousedown,防止底图还未加载好 this.once('start', this.dealPointerDown.bind(this)); } } }, { key: "dealPointerMove", value: function dealPointerMove(mouse) { // 适应zoom和校准 mouse.x = (mouse.x - window.innerWidth / 2) / (this.player.zoomLevel + (this.player.zoomLevel - 1) * 0.2) + window.innerWidth / 2; mouse.y = (mouse.y - window.innerHeight / 2) / (this.player.zoomLevel + (this.player.zoomLevel - 1) * 0.2) + window.innerHeight / 2; this.mousePosition.setX(mouse.x / window.innerWidth * this.width); this.mousePosition.setY((1 - mouse.y / window.innerHeight) * this.height); } }, { key: "dealPointerUp", value: function dealPointerUp() { this.mousePosition.setZ(0); } }]); return Paint; }(tinyEmitter); // 离屏渲染场景 var BufferShader = function BufferShader() { var uniforms = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, BufferShader); this.uniforms = uniforms; // 涂抹材质 this.material = new THREE.RawShaderMaterial({ fragmentShader: shaders['model'].fragmentBufferShader, vertexShader: shaders['model'].vertexShader, uniforms: uniforms, side: THREE.DoubleSide }); this.scene = new THREE.Scene(); this.scene.add(new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), this.material)); // 涂抹Plane this.camera = new THREE.PerspectiveCamera(90, 1, 0.01, 1000); // Camera this.camera.position.set(0, 0, 1); }; // 离屏渲染renderer var BufferRenderer = /*#__PURE__*/function () { function BufferRenderer(renderer, size) { _classCallCheck(this, BufferRenderer); this.renderer = renderer; this.width = size.width; this.height = size.height; this.bufferOptions = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, type: THREE.FloatType, stencilBuffer: false }; // 在start()的时候初始化 this.readBuffer = null; // 一般用于从该buffer读取先前的渲染结果:this.readBuffer.texture this.writeBuffer = null; // 一般用于将渲染结果写入该buffer:render() } _createClass(BufferRenderer, [{ key: "render", value: function render(scene, camera) { var toScreen = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (toScreen) { this.renderer.render(scene, camera); } else { // 离屏渲染 var V = this.renderer.autoClear; this.renderer.autoClear = !1; // 暂时关闭autoClear this.renderer.setRenderTarget(this.writeBuffer); this.renderer.render(scene, camera); // 将BufferShader场景的渲染结果存储到writeBuffer里 this.renderer.setRenderTarget(null); this.renderer.autoClear = V; } // 每次render都要交换readBuffer/writeBuffer的值 var _ref = [this.writeBuffer, this.readBuffer]; this.readBuffer = _ref[0]; this.writeBuffer = _ref[1]; } // 将涂抹数据保存为base64,之后发给后端转成png格式并存入数据库 }, { key: "save", value: function save() { var bufferArray = new Float32Array(this.width * this.height * 4); // 宽像素 * 高像素 * rgba四个值 // 把readBuffer里的涂抹贴图按像素存入bufferArray this.renderer.readRenderTargetPixels(this.readBuffer, 0, 0, this.width, this.height, bufferArray); this.outputCanvas = document.createElement('canvas'); this.outputCanvas.width = this.width; this.outputCanvas.height = this.height; var ctx = this.outputCanvas.getContext('2d'); var rowBytes = this.width * 4; for (var row = 0; row < this.height; row++) { var srow = this.height - 1 - row; var imageData = ctx.createImageData(this.width, 1); var start = srow * this.width * 4; for (var i = 0; i < rowBytes; i++) { imageData.data[i] = bufferArray[start + i] * 255; } // 把bufferArray画到outputCanvas上 ctx.putImageData(imageData, 0, row); } // outputCanvas转存为base64 this.base64 = this.outputCanvas.toDataURL('image/png'); // let img = document.createElement("img") // img.src = this.base64 // document.querySelector("body").appendChild(img) // console.error(this.base64) return this.base64; } }]); return BufferRenderer; }(); function _createSuper$12(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$12(); 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 _isNativeReflectConstruct$12() { 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; } } /** * 空间模型 */ var GLTFDecoration = /*#__PURE__*/function (_THREE$Group) { _inherits(GLTFDecoration, _THREE$Group); var _super = _createSuper$12(GLTFDecoration); function GLTFDecoration(manager, info) { var _this; _classCallCheck(this, GLTFDecoration); _this = _super.call(this); _this.manager = manager; _this.version = 0; _this.axisAngle = { x: 0, y: 0, z: 0 }; if (!info) { // 新增 _this.sid = common.getRandomSid(); _this.panoId = _this.manager.player.currentPano.id; _this.isNew = true; _this.position.setY(1000); var BoxMaterial = new THREE.MeshBasicMaterial({ color: '#00c8af', opacity: 0.4, transparent: !0, polygonOffset: true, //是否开启多边形偏移 polygonOffsetFactor: -0.9, //多边形偏移因子 polygonOffsetUnits: -4.0 //多边形偏移单位 }); var BoxGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); BoxGeometry.translate(0, 0.25, 0); var box = new THREE.Mesh(BoxGeometry, BoxMaterial); _this.add(box); } else { // 数据库数据 _this.setFromInfo(info); _this.updateInfo(true); } return _this; } /** * 加载模型 * @param {*} url 模型名称 */ _createClass(GLTFDecoration, [{ key: "load", value: function load(url) { this.children.forEach(function (mesh) { mesh.geometry.dispose(); mesh.material.dispose(); }); this.children = []; if (url) { this.url = url; loaders.gltf("".concat(this.manager.player.$app.resource.getUserModelResourceURL(url), "&v=").concat(this.version), // `${url}?v=${this.manager.player.$app.store.getValue('metadata').version}_${this.version}`, function (gltf) { var _this2 = this; var meshes = []; gltf.scene.traverse(function (obj) { return obj.type == 'Mesh' && meshes.push(obj); }); meshes.forEach(function (mesh) { // mesh.material.color.setRGB(3, 3, 3) _this2.add(mesh); mesh.renderOrder = RenderOrder.overlay; //xzw add mesh.material.transparent = true; //xzw add 否则会被marker遮住 }); this.version++; this.dispatchEvent({ type: 'loaded' }); }.bind(this)); } } // 删除模型 }, { key: "remove", value: function remove() { this.removeFromParent(); this.children.forEach(function (mesh) { mesh.geometry.dispose(); mesh.material.dispose(); }); } // 通过info初始化或回退 }, { key: "setFromInfo", value: function setFromInfo(info) { this.sid = info.sid; this.panoId = info.panoId; this.url != info.url && this.load(info.url); this.zipName = info.zipName; this.visible = info.visible; this.setTransformFromInfo(info); } }, { key: "setTransformFromInfo", value: function setTransformFromInfo(info) { var position = info.position, rotation = info.rotation, scale = info.scale, quaternion = info.quaternion; this.position.set(parseFloat(position.x), parseFloat(position.y), parseFloat(position.z)); if (quaternion) { this.setRotationFromQuaternion(new THREE.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w)); } else { // this.rotation.set(THREE.MathUtils.degToRad(rotation.x), THREE.MathUtils.degToRad(rotation.y), THREE.MathUtils.degToRad(rotation.z)) this.setAxisAngle('x', THREE.MathUtils.degToRad(rotation.x)); this.setAxisAngle('y', THREE.MathUtils.degToRad(rotation.y)); this.setAxisAngle('z', THREE.MathUtils.degToRad(rotation.z)); } this.scale.set(parseFloat(scale.x), parseFloat(scale.y), parseFloat(scale.z)); } /** * 旋转 * @param {'x' | 'y' | 'z'} axisName 旋转轴 * @param {*} angle 旋转角 */ }, { key: "setAxisAngle", value: function setAxisAngle(axisName, angle) { var axis = axisName == 'x' ? Vectors$1.RIGHT : axisName == 'y' ? axis = Vectors$1.UP : Vectors$1.BACK; this.rotateOnAxis(axis, angle - this.axisAngle[axisName]); this.axisAngle[axisName] = angle; } /** * 返回空间模型数据 * @param {*} isSave 是否保存当前数据 * @returns */ }, { key: "updateInfo", value: function updateInfo(isSave) { var info = { sid: this.sid, panoId: this.panoId, url: this.url, zipName: this.zipName, position: { x: parseFloat(this.position.x.toFixed(2)), y: parseFloat(this.position.y.toFixed(2)), z: parseFloat(this.position.z.toFixed(2)) }, rotation: { x: parseInt(THREE.MathUtils.radToDeg(this.axisAngle.x)), y: parseInt(THREE.MathUtils.radToDeg(this.axisAngle.y)), z: parseInt(THREE.MathUtils.radToDeg(this.axisAngle.z)) }, scale: { x: parseFloat(this.scale.x.toFixed(1)), y: parseFloat(this.scale.y.toFixed(1)), z: parseFloat(this.scale.z.toFixed(1)) }, visible: this.visible }; if (isSave) this.info = info; return info; } }]); return GLTFDecoration; }(THREE.Group); var GLTFAddManager = /*#__PURE__*/function () { function GLTFAddManager(player) { _classCallCheck(this, GLTFAddManager); this.player = player; this.editing = false; this.adding = null; // 添加后确认位置前的状态 this.selecting = null; // 选中出现轴向时的状态 this.group = new THREE.Group(); this.group.name = 'GLTFDecorations'; player.model.add(this.group); this.bindEvents(); } _createClass(GLTFAddManager, [{ key: "show", value: function show(floorIndex, keepHidden) { var _this = this; this.group.children.forEach(function (gltf) { if (gltf === _this.adding || gltf === _this.selecting) return; // 忽略编辑中模型的显隐计算 if (keepHidden && !gltf.info.visible) return; if (floorIndex == 'all' || _this.player.model.panos.get(gltf.panoId).floorIndex == floorIndex) gltf.visible = true; }); } }, { key: "hide", value: function hide(floorIndex) { var _this2 = this; this.group.children.forEach(function (gltf) { if (gltf === _this2.adding || gltf === _this2.selecting) return; if (floorIndex == 'all' || _this2.player.model.panos.get(gltf.panoId).floorIndex == floorIndex) gltf.visible = false; }); } /** * 事件 */ }, { key: "bindEvents", value: function bindEvents() { var _this3 = this; this.player.on('pointerUp', this.onMouseUp.bind(this)); this.player.on('pointerMove', this.onMouseMove.bind(this)); var axisAngleTemp; this.player.model.transformControls.addEventListener('mouseDown', function () { if (_this3.selecting) { axisAngleTemp = JSON.parse(JSON.stringify(_this3.selecting.axisAngle)); } }); this.player.model.transformControls.addEventListener('mousing', function (e) { if (_this3.selecting) { // 移动模型轴向 if (e.mode == 'rotate') { var axis = e.axis.toLowerCase(); var angle = axisAngleTemp[axis] + e.angle; _this3.selecting.axisAngle[axis] = ((angle + Math.PI) % (Math.PI * 2) - Math.PI * 2) % (Math.PI * 2) + Math.PI; // 限制在-179到180 } _this3.player.$app.Scene.Decoration.emit('Decoration.GLTF.select', _this3.selecting.updateInfo()); } }); this.player.model.transformControls.addEventListener('mouseUp', function () { if (_this3.selecting) ; }); } }, { key: "onMouseUp", value: function onMouseUp(e) { if (this.player.EditOverlay.isAdding || this.player.EditOverlay.editPlane) return; if (this.selecting || !this.editing) return; if (this.adding) { e.consume(); // 确认位置 this.adding.updateInfo(true); this.select(this.adding); this.adding = null; } else if (this.player.mouseCouldBeClickToMove) { var intersect = this.player.getMouseIntersect(null, this.group.children.filter(function (d) { return d.visible; })); if (intersect) { // 点击选中 e.consume(); var decoration = intersect.object.parent; this.select(decoration); this.player.flyToPano({ pano: this.player.model.panos.get(decoration.panoId), lookAtPoint: decoration.position, checkAlone: true }); } } } }, { key: "onMouseMove", value: function onMouseMove() { if (this.adding) { var intersect = this.player.getMouseIntersect(null, this.player.model.colliders); if (intersect) { this.adding.position.copy(intersect.point); } } } /** * 选中 */ }, { key: "select", value: function select(decoration) { this.selecting = decoration; this.player.model.transformControls.switchEditState('decoration'); this.player.model.transformControls.attach(decoration); this.player.$app.Scene.Decoration.emit('Decoration.GLTF.select', decoration.updateInfo()); this.player.compass.switch('axis'); } }, { key: "unselect", value: function unselect() { this.selecting = null; this.player.model.transformControls.detach(); this.player.compass.switch('direction'); } /** * 增删 */ }, { key: "add", value: function add(info) { var decoration = new GLTFDecoration(this, info); this.group.add(decoration); if (!info) this.adding = decoration; return decoration; } }, { key: "delete", value: function _delete(decoration) { if (decoration == this.selecting) this.unselect(); decoration.remove(); } /** * 保存 */ }, { key: "save", value: function save(func) { // let data = this.group.children.map(decoration => decoration.updateInfo()) var data = this.selecting.updateInfo(); // let data = {} // this.group.children.forEach((decoration, index) => { // data[index] = decoration.updateInfo() // }) return { // data: JSON.stringify(data), data, successCallBack: function () { try { this.selecting.isNew = false; this.selecting.updateInfo(true); this.unselect(); // this.group.children.forEach(decoration => { // decoration.isNew = false // decoration.updateInfo(true) // }) func && func(); } catch (e) { console.error(e); } }.bind(this) }; } }]); return GLTFAddManager; }(); function _createSuper$11(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$11(); 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 _isNativeReflectConstruct$11() { 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; } } var log = function log() { }; /* const _camereChangeLazyTime = 80 */ defineComponent('Player', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(Player, _EventEmitter); var _super = _createSuper$11(Player); function Player() { var _this; _classCallCheck(this, Player); _this = _super.call(this); _this.setupCustomProperties = function (e) { var t = e || Viewmode$1.PANORAMA; Object.defineProperty(this, 'mode', { get: function get() { return t; }, set: function set(e) { var i = t; t = e, this.onModeUpdated(i, t); } }); }; _this.isOutsideMode = function (mode) { mode = mode || this.mode; return mode === Viewmode$1.DOLLHOUSE || mode === Viewmode$1.FLOORPLAN; }; _this.is360View = function (e, t) { return e === Viewmode$1.PANORAMA && t && t.panoType == '360view'; }; _this.setScene = function () { var scene = this.$app.core.get('SceneRenderer').scene; this.sceneIntersectionPlane = scene.plane; this.path.setScene(scene); this.moveReticuleToScene(scene); }; _this.moveReticuleToScene = function (e) { this.reticule.parent && this.reticule.parent.remove(this.reticule), e.add(this.reticule); }; _this.updateModel = function () { var _this2 = this; // function updateCamera(centerY) { // var camera = this.cameraControls.cameras[Viewmode.DOLLHOUSE] // , control = this.cameraControls.controls[Viewmode.DOLLHOUSE] // , positionY = camera.position.y + (centerY - control.target.y) // , duration = settings.showFloorDuration + settings.showFloorDelay; // transitions.start(lerp.property(control.target, "y", centerY), duration, null, settings.flydown.movementDelay, easing[settings.flydown.movementEasing], null, settings.freeze.FlyToViewFloor); // transitions.start(lerp.property(camera.position, "y", positionY), duration, null, settings.flydown.movementDelay, easing[settings.flydown.movementEasing], null, settings.freeze.FlyToViewFloor); // } this.model = this.modelManager.getActiveModel(); this.model.player = this; // this.model.on("floor.changed", function(newFloor, t, oldFloor) { // this.mode === Viewmode.DOLLHOUSE && newFloor !== oldFloor && updateCamera.call(this, newFloor.center.y) // } // .bind(this)); // this.model.on("allfloors.toggled", function(flag, floor) { // if (this.mode === Viewmode.DOLLHOUSE) { // var centerY = flag ? this.model.center.y : centerY = floor.center.y; // updateCamera.call(this, centerY) // } // } // .bind(this)); this.paintEditor.init(); this.on(PlayerEvents.PanoChosen, function (pano0, pano1, flag) { _this2.model.setProjectedPanos(pano0, pano1, flag); _this2.paintEditor && _this2.paintEditor.updatePanoPaint(pano0.id, pano1.id); _this2.$app.FilterManager && _this2.$app.FilterManager.updatePanoFilters(pano0, pano1); }); this.on(PlayerEvents.FlyingStarted, this.model.resetHighMap.bind(this.model)); }; _this.updateModelDependentData = function () { this.cameraControls.setModelForControls(this.model); this.getPanoMarkersFromModel(this.model); }; _this.getPanoMarkersFromModel = function (e) { this.panoMarkers = e.panos.list.reduce(function (e, t) { return t.marker ? e.concat(t.marker) : e; }, []); }; _this.handleControlMove = function (e) { this.emit(PlayerEvents.Move, e); if (this.mode === Viewmode$1.PANORAMA) { this.emit(PlayerEvents.Rotate, { quaternion: this.cameraControls.activeControl.camera.quaternion, mode: Viewmode$1.PANORAMA, currentPanoId: this.nextPano ? this.nextPano.id : this.currentPano ? this.currentPano.id : null, type: 'rotate' }); } }; _this.handleControlInputStart = function (e) { this.emit(PlayerEvents.InputStart, e); }; _this.onModeUpdated = function (fromMode, toMode) { this.cameraControls.activateControls(toMode); this.emit(PlayerEvents.ModeChanged, fromMode, toMode); //add: //beforechangeMode if (toMode == 'transitioning') { fromMode = this.modeTran.split('-')[0]; //按钮active改变 //this.store.commit('SetPlayerOptions',{mode:toMode == "panorama" ? "pano" : toMode == "dollhouse" ? "3d" : "2d",modeCanSwitch:false}) if (fromMode == Viewmode$1.PANORAMA) { this.flyingToTag = this.flyRotate = this.flyingWithRot = false; //有出现过如果还没校准好热点就飞出的话会是true /* this.model.chunks.forEach(chunk=>{//4.6.0 xzw 改写 common.updateVisible(chunk,'atPano',true) //恢复漫游点处隐藏的chunk }) */ } } else { //afterChangeMode toMode = this.modeTran.split('-')[1]; if (!(this.isOutsideMode(fromMode) && this.isOutsideMode(toMode))) this.model.fadePanoMarkers(null, 0); if (toMode == Viewmode$1.PANORAMA) ; } }; _this.isWarping = function () { //return this.path.warping return false; }; _this.isWaitingToWarp = function () { //return this.path.waitingToWarp return false; }; _this.bindEvents = function (e) { e !== document && e.setAttribute('tabindex', -1), e.addEventListener('mousedown', this.onMouseDown.bind(this)), e.addEventListener('mousemove', this.onMouseMove.bind(this)), e.addEventListener('mouseover', this.onMouseOver.bind(this)), e.addEventListener('mouseout', this.onMouseOut.bind(this)), e.addEventListener('mouseup', this.onMouseUp.bind(this)), //this.$app.core.get('ModelManager').on(ModelManagerEvents.ActiveModelChanged, this.onModelChanged.bind(this)), e.addEventListener('touchstart', this.onTouchStart.bind(this), { passive: false }), e.addEventListener('touchmove', this.onTouchMove.bind(this), { passive: false }), e.addEventListener('touchend', this.onTouchEnd.bind(this)), e.addEventListener('pointerdown', this.onPointerDown.bind(this)), e.addEventListener('pointermove', this.onPointerMove.bind(this)), e.addEventListener('pointerup', this.onPointerUp.bind(this)), e.addEventListener('pointerout', this.onPointerOut.bind(this)), e.addEventListener('pointercancel', this.onPointerCancel.bind(this)), document.addEventListener('keydown', this.onKeyDown.bind(this)), this.cameraControls.on(ControlEvents.Move, this.handleControlMove.bind(this)), this.cameraControls.on(ControlEvents.InputStart, this.handleControlInputStart.bind(this)), this.cameraControls.on(ControlEvents.Pinch, this.handleControlPinch.bind(this)), this.cameraControls.on(ControlEvents.Scroll, this.handleControlScroll.bind(this)); }; _this.onMouseDown = function (e) { e.currentTarget !== document && e.currentTarget.focus(), 0 === e.button && (this.handleInputStart.call(this, e.clientX, e.clientY, !1), this.updateIntersect()); //this.distanceToCamera(2) }; _this.onMouseMove = function (e) { (this.isTouchEvent = !1, this.containsMouse = !0), this.handleInputMove.call(this, e.clientX, e.clientY, !1); }; _this.onMouseOver = function (e) { this.containsMouse = !0, !this.mouseDown || 0 !== e.which && 0 !== e.buttons || (this.mouseDown = !1); }; _this.onMouseOut = function (e) { this.containsMouse = !1; }; _this.onMouseUp = function (e) { this.handleInputEnd.call(this, e.clientX, e.clientY, !1); this.emit(PlayerEvents.EndRotation, { rotationSpeed: this.cameraControls.activeControl ? this.cameraControls.activeControl.rotationSpeed : null, type: 'endRotation' }); }; _this.onTouchStart = function (e) { if (e.currentTarget !== document && e.currentTarget.focus(), !this.mouseDown) { this.couldBeLongTap = !0; var t = common.average(e.changedTouches, 'clientX'), i = common.average(e.changedTouches, 'clientY'); this.handleInputStart.call(this, t, i, !0), this.mouseDownTimer = setTimeout(function () { this.updateIntersect(), this.handleInputEnd.call(this, t, i, !0); }.bind(this), settings$3.input.longTapThreshold); } //ios safari 球幕视频无法自动播放,必须静音才能播放,播放后关闭静音会导致视频暂停 #43676 //需要用户交互才能播放带声音的视频 the request is not allowed by the user agent or the platform in thre current context, possibly because the user denied permission if (browser$1.detectIOS()) { var panoVideoRenderer = this.$app.core.get('PanoVideoRenderer'); panoVideoRenderer.setMuted(false); } }; _this.onTouchMove = function (e) { var t = common.average(e.changedTouches, 'clientX'), i = common.average(e.changedTouches, 'clientY'); this.handleInputMove.call(this, t, i, !0); }; _this.onTouchEnd = function (e) { if (clearTimeout(this.mouseDownTimer), this.mouseDown) { this.couldBeLongTap = !1, this.updateIntersect(); var t = common.average(e.changedTouches, 'clientX'), i = common.average(e.changedTouches, 'clientY'); this.handleInputEnd.call(this, t, i, !0); this.emit(PlayerEvents.EndRotation, { rotationSpeed: this.cameraControls.activeControl ? this.cameraControls.activeControl.rotationSpeed : null, type: 'endRotation' }); } }; _this.onPointerDown = function (e) { e.currentTarget !== document && e.currentTarget.focus(); if (this.mouseDown || 'mouse' === e.pointerType) { return this.onMouseDown(e); } else { this.couldBeLongTap = !0; this.handleInputStart.call(this, e.clientX, e.clientY, !0); return void (this.mouseDownTimer = setTimeout(function () { this.updateIntersect(), this.handleInputEnd.call(this, e.clientX, e.clientY, !0); }.bind(this), settings$3.input.longTapThreshold)); } }; _this.onPointerMove = function (e) { 'mouse' !== e.pointerType ? this.handleInputMove.call(this, e.clientX, e.clientY, !0) : this.onMouseMove(e); }; _this.onPointerUp = function (e) { if (this.mouseDown && 'mouse' !== e.pointerType) { if (this.mouseDownTimer) { clearTimeout(this.mouseDownTimer); } this.couldBeLongTap = !1; this.updateIntersect(); void this.handleInputEnd.call(this, e.clientX, e.clientY, !0); this.emit(PlayerEvents.EndRotation, { rotationSpeed: this.cameraControls.activeControl ? this.cameraControls.activeControl.rotationSpeed : null, type: 'endRotation' }); } else { this.onMouseUp(e); } }; _this.onPointerOut = function (e) { this.mouseDown = !1; }; _this.onPointerCancel = function (e) { this.mouseDown = !1; }; _this.onKeyDown = function (e) { if (!this.$app.config.useShortcutKeys) { return; } var t = function () { this.cameraControls.activeControl && this.cameraControls.activeControl.emit(ControlEvents.Move, 'key'); }.bind(this), i = e.which; switch (i) { case Keys.F: t(), this.changeFloor(-1); break; case Keys.R: t(), this.changeFloor(1); } if (this.mode === Viewmode$1.PANORAMA) switch (i) { case Keys.UPARROW: case Keys.W: this.flyLocalDirection(Vectors$1.FORWARD.clone()); break; case Keys.DOWNARROW: case Keys.S: this.flyLocalDirection(Vectors$1.BACK.clone()); break; case Keys.A: this.flyLocalDirection(Vectors$1.LEFT.clone()); break; case Keys.D: this.flyLocalDirection(Vectors$1.RIGHT.clone()); } if (this.started /* && ( !viewEditLink.markView && !editSpot.setSpotPos && (!this.linkEditor || !this.linkEditor.setPanoVisible && !this.linkEditor.setTagVisible)) */ ) { switch (i) { case Keys.ONE: //i.isInMode(_e.TRANSITIONING) || (t.changeMode(_e.PANORAMA)); this.insideMode(); break; case Keys.TWO: //this.model.outsideAllowed() && !this.isInMode(_e.FLOORPLAN, _e.TRANSITIONING) && (t.changeMode(_e.FLOORPLAN)); this.flyToNewMode({ mode: Viewmode$1.DOLLHOUSE }); break; case Keys.THREE: //this.model.outsideAllowed() && !this.isInMode(_e.DOLLHOUSE, _e.TRANSITIONING) && (t.changeMode(_e.DOLLHOUSE)); this.flyToNewMode({ mode: Viewmode$1.FLOORPLAN }); break; } } }; _this.handleScrollPinchZoom = function () { return function (e) { var t = e, i = this.zoomLevel; this.zoomBy(t), this.currentPano && this.zoomStats.addZoomAction(i, this.zoomLevel, this.currentPano.id); }; }(); _this.handleControlPinch = function (e) { if (settings$3.zoom.enabled) { this.handleScrollPinchZoom(1 - e); } else if (this.$app.config.useShortcutKeys) { this.flyLocalDirection(new THREE.Vector3(0, 0, e).normalize()); } }; _this.handleControlScroll = function (e) { if (settings$3.zoom.enabled) { if (e > 0) { e = 1 + this.scrollZoomSpeed; } else { e < 0 && (e = 1 - this.scrollZoomSpeed); } 0 !== e && this.handleScrollPinchZoom(e); this.emit(PlayerEvents.Zoom, { zoom: e, type: 'zoom', zoomLevel: this.zoomLevel }); } else if (this.$app.config.useShortcutKeys) { this.flyLocalDirection(new THREE.Vector3(0, 0, -e).normalize()); } }; _this.handleInputStart = function (e, t, i, ignorePad) { var mouse = { x: e, y: t }; if ( /* !config.mobile && */ !ignorePad) { mouse = math$1.handelPadding(e, t, this.domElement); } math$1.convertScreenPositionToNDC(mouse.x, mouse.y, this.mouse, this.domElement); math$1.convertScreenPositionToNDC(mouse.x, mouse.y, this.mouseAtMouseDown, this.domElement); this.mouseCouldBeClickToMove = !0; this.mouseDown = !0; this.updateIntersect(); //为了触屏版,在点击时立刻checkIntersect //add--------------------------------- var consumed; var consume = function consume() { consumed = true; }; var getConsumed = function getConsumed() { return consumed; }; //被使用 this.emit('pointerStart', { consume, getConsumed }); if (consumed) { return; } // 有被事件作用到,且需要阻止后续进行 //------------------------------------ if (this.EditPanoVideo && this.EditPanoVideo.editing) { this.EditPanoVideo.dealPointerDown(); } else if (this.EditPanoMosaic && this.EditPanoMosaic.editing) { this.EditPanoMosaic.dealPointerDown(); } else { this.model.transformControls && this.model.transformControls.handleDragStart(); } if (this.paintEditor && this.paintEditor.painting) { this.paintEditor.dealPointerDown(); } // this.setQuaternionTransition(null) this.aimQuaternion = null; }; _this.handleInputMove = function (e, t, i) { this.isTouchEvent = i; var mouse = math$1.handelPadding(e, t, this.domElement); math$1.convertScreenPositionToNDC(mouse.x, mouse.y, this.mouse, this.domElement); // 不能给0,三星手机在pointmove上非常敏感,需要一定容错才能触发click if (this.mouseAtMouseDown.distanceTo(this.mouse) > 0.01 /*settings.input.moveToleranceNDC*/ ) { this.mouseCouldBeClickToMove = !1; this.couldBeLongTap = !1; clearTimeout(this.mouseDownTimer); this.model.transformControls && this.model.transformControls.handleDragging(); } if (this.EditPanoMosaic && this.EditPanoMosaic.editing) { this.EditPanoMosaic.dealPointerMove(); } if (this.paintEditor && this.paintEditor.painting) { this.paintEditor.dealPointerMove(mouse); } //add--------------------------------- var consumed; var consume = function consume() { consumed = true; }; var getConsumed = function getConsumed() { return consumed; }; //被使用 this.emit('pointerMove', { consume, getConsumed }); if (consumed) { return; } // pointerDown 有被事件作用到,且需要阻止后续进行 //------------------------------------ this.mouseLastMoveTime = Date.now(); this.reticule.move(e, t, i); }; _this.handleInputEnd = function (e, t, i) { var _this3 = this; if (this.isTouchEvent = i, this.mouseDown = !1, this.cameraControls.controls[Viewmode$1.PANORAMA].emit('interaction.direct'), !i && this.couldBeLongTap) return !0; this.model.transformControls && this.model.transformControls.handleDragEnd(); this.EditPanoVideo && this.EditPanoVideo.dealPointerUp(); this.EditPanoMosaic && this.EditPanoMosaic.dealPointerUp(); if (this.paintEditor && this.paintEditor.painting) { this.paintEditor.dealPointerUp(); } //add--------------------------------- var consumed; var consume = function consume() { consumed = true; }; //被使用 var getConsumed = function getConsumed() { return consumed; }; this.emit('pointerUp', { consume, getConsumed }); if (consumed) { return; } // 有被事件作用到,且需要阻止后续进行 //------------------------------------ if (this.handleLongTap()) return !0; if (this.mouseCouldBeClickToMove) { if (this.flying) { //this.path.activeTransType === WarpStyle.WALK && this.emit(PlayerEvents.WarpInterruptedWithFlyTo, this.path.activeTransType); return this.flyToPanoClosestToMouse(); //!0; 改for panoTask } // if (this.checkMattertagClick()) // return !0; if (this.chosenMeasureRuler) { //取消“删除”显示 this.chosenMeasureRuler.showOptionLabel(false); } if (this.linkEditor && this.linkEditor.setPanoVisible) { //正在设置漫游可行 var currentFloorIcons = [].concat(_toConsumableArray(this.linkEditor.actionIcons), _toConsumableArray(this.linkEditor.footIcons)).filter(function (icon) { return icon.pano.floorIndex == _this3.model.currentFloor.floorIndex; }); this.intersect = this.getMouseIntersect(null, currentFloorIcons /* .concat(this.measureRulers.map(ruler => ruler.boldLine)) */ ); if (this.intersect && this.intersect.object.visible) { var icon = this.intersect.object; if (icon.type == 'ActionIcon' && !this.linkEditor.activePano && icon.footIcon.status == 'floor') { // 设置楼层连接点隐藏需要做二次确认提示 var self = this; this.$app.WalkManager.emit('walkManager.floorPointHide', function () { self.linkEditor.dealPanoVisible(self.intersect.object.name, self.intersect.object); }); } else { this.linkEditor.dealPanoVisible(this.intersect.object.name, this.intersect.object); } } return; } if (this.linkEditor && this.linkEditor.setTagVisible) { //正在设置热点可视 this.linkEditor.tagVsetting && this.intersect && this.intersect.object.visible && this.linkEditor.dealTagVisible(this.linkEditor.tagVsetting, this.intersect.object.name); return; } var measureIntersect = this.getMouseIntersect(null, this.measureRulers.filter(function (e) { return e.state == 'active'; }).map(function (ruler) { return ruler.boldLine; })); if (measureIntersect && measureIntersect.object.parentRuler) { //点击测距标尺 以删除 measureIntersect.object.parentRuler.showOptionLabel(true, measureIntersect.point); return; } if (this.EditOverlay && this.EditOverlay.isAdding) { this.intersect && this.EditOverlay.addOverlay({ intersect: this.intersect }); return; } if (this.OverlayManager.hoveringPlane) { this.OverlayManager.clickOverlay(this.OverlayManager.hoveringPlane); return; } if (this.intersect && this.billboardManager && this.billboardManager.isAdding) { return this.billboardManager.startInsertion({ intersect: this.intersect }); } //add--------------------------------- var _consumed; var _consume = function _consume() { _consumed = true; }; //被使用 var _getConsumed = function _getConsumed() { return _consumed; }; this.emit('click', { intersect: this.intersect, consume: _consume, getConsumed: _getConsumed, raycaster: this.raycaster }); if (_consumed) { return; } // 有被事件作用到,且需要阻止后续进行 //------------------------------------ if (this.currentPano && this.is360View(this.mode, this.currentPano)) return; this.cameraControls.activeControl && this.cameraControls.activeControl.emit(ControlEvents.Move, this.isTouchEvent ? 'touch' : 'mouse'); this.history.invalidate(); if (this.intersect) { return this.flyToPanoClosestToMouse(); } if (this.mode === Viewmode$1.PANORAMA) { var pano = this.closestPanoInDirection(this.getMouseDirection()); if (pano) { return this.flyToPano({ pano: pano }); } else { return this.bump(this.getMouseDirection()); } } } this.intersect && this.closestPano && this.closestPano.hoverOff(this.mode); }; _this.handleLongTap = function () { if (this.couldBeLongTap && (!this.isPanoHover || this.mode !== Viewmode$1.PANORAMA)) { this.cameraControls.activeControl && this.cameraControls.activeControl.emit(ControlEvents.LongTap, 'touch'); return !0; } }; _this.start = function (initialPanoInfo) { var _this4 = this; var mode = initialPanoInfo.mode, pano = initialPanoInfo.pano, position = initialPanoInfo.position, quaternion = initialPanoInfo.quaternion, tag = initialPanoInfo.tag, quickstart = initialPanoInfo.quickstart, deferred = Deferred$1(); this.updateModelDependentData(); this.updateFromControls(); //this.findDefaultViews(); var is360 = this.is360View(mode, pano); var done = function done(e) { _this4.emit(PlayerEvents.Ready, is360, e, tag); _this4.started = true; }; if (!this.model.outsideAllowed() || is360 || quickstart) { this.startInside(pano, position, quaternion, tag, deferred); } else { this.startOutside(initialPanoInfo, deferred); this.once(PlayerEvents.FlyingEnded, done); //add } this.compass = new Compass(this); this.linkEditor = new Link(this); this.labelManager = new LabelManager(this); return deferred; }; _this.startOutside = function (initialPanoInfo, deferred) { var mode = initialPanoInfo.mode, pano = initialPanoInfo.pano, position = initialPanoInfo.position, quaternion = initialPanoInfo.quaternion, zoom = initialPanoInfo.zoom, floorVisibility = initialPanoInfo.floorVisibility, tag = initialPanoInfo.tag; this.emit(PlayerEvents.StartOutside, settings$3[mode].transitionTime); if (this.isOutsideMode(mode)) { this.model.warpDestFloors(floorVisibility, !0); transitions$1.cancelById(settings$3.freeze.FlyToViewFloor); if (mode === Viewmode$1.FLOORPLAN) { this.floorplanMode(position, quaternion, zoom); } else { this.dollhouseMode(position, quaternion); } deferred.resolve(!1); } else { this.startInsideWithFlyin(pano, position, quaternion, tag, deferred); } this.beforeChangeMode(null, mode); }; _this.startInside = function (pano, position, quaternion, tag, deferred) { deferred = deferred || Deferred$1(); this.currentPano = pano; var o = pano && !pano.isAligned(); position = o ? pano.position : position || pano.position; quaternion = quaternion || pano.quaternion; if (pano) { //这里开始加载第一个点的全景图。如果未加载好,等加载好以后还会执行一遍此startInside函数。 var a = this.startInside.bind(this, pano, position, quaternion, tag, deferred); if (this.checkAndWaitForPanoLoad(pano, 'high', 'low', this.basePanoSize, a)) return; } //add:-------- this.modeTran = 'panorama-panorama'; //modeTran要比mode先设置,因mode修改会触发onModeUpdated,需要用到modeTran this.beforeChangeMode(null, Viewmode$1.PANORAMA, this.currentPano, 0); //xzw add this.afterChangeMode(null, Viewmode$1.PANORAMA); pano.enter(); //------------ this.mode = Viewmode$1.PANORAMA; pano.floor.enter(this.mode); this.emit(PlayerEvents.PanoChosen, this.currentPano, this.currentPano); this.switchCameraMode(this.mode, quaternion); this.emit(PlayerEvents.StartInside, o); // 初始点位球幕视频静音播放 var panoVideoRenderer = this.$app.core.get('PanoVideoRenderer'); panoVideoRenderer.setMuted(true); panoVideoRenderer.activatePanorama(this.currentPano); deferred.resolve(!0); return deferred; }; _this.startInsideWithFlyin = function (initPano, initPosition, initQuaternion, tag, deferred) { deferred = deferred || Deferred$1(); this.dollhouseMode(); if (!initPano) { logger$1.warn('Player.startInsideWithFlyin() -> targetPano is invalid.'); deferred.resolve(!1); return deferred; } initPosition = initPosition || initPano.position; var quaternion = initQuaternion || this.cameraControls.activeControl.camera.quaternion, position = initPano.position; //这个作用是加载完数据,模型第一次出现的位置 this.fitDollhouse(position, initPosition, quaternion); setTimeout(function (t) { this.cameraControls.activeControl && (this.cameraControls.activeControl.maxDistance = t); var newMode = { mode: Viewmode$1.PANORAMA, pano: initPano, quaternion: initQuaternion, callback: function () { this.emit(PlayerEvents.FlyinFinished); deferred.resolve(!0); }.bind(this) }; this.flyToNewMode(newMode); }.bind(this, this.cameraControls.activeControl.maxDistance), settings$3.startupFlyinDelay); return deferred; }; _this.checkAndWaitForPanoLoad = function () { var loadingPanos = {}, LoadedTimePanos = {}, loadedCallback = {}, //add maxTime = 5e3; /* var withinTime = function () {//5秒之内还在加载的话,直接返回仍在加载状态,否则重新判断 for (var panoId in loadingPanos) if (loadingPanos.hasOwnProperty(panoId) && loadingPanos[panoId]) {//还在加载 var differTime = performance.now() - LoadedTimePanos[panoId] if (differTime < maxTime) return !0 } return !1 } */ //xzw withinTime 改为只判断当前请求的点。原始代码的callback是针对任意pano的,所以遍历所有漫游点,只要有在加载的就返回,但已不满足需求。 var withinTime = function withinTime(pano) { //5秒之内还在加载的话,直接返回仍在加载状态,否则重新判断 if (loadingPanos.hasOwnProperty(pano.id) && loadingPanos[pano.id]) { //还在加载 var differTime = performance.now() - LoadedTimePanos[pano.id]; if (differTime < maxTime) return !0; } }; return function (pano, imgQuality1, imgQuality2, basePanoSize, successCallbackFunc1, successCallbackFunc2, progressCallback, iswait, isclear, p) { if (withinTime(pano)) { log('loadedCallback re add', pano.id); loadedCallback[pano.id] = successCallbackFunc1; //add 更新 因为有可能之前请求的没加successCallbackFunc1 return !0; //距离上次请求时间很近 } /* withinTime的原因: 多次重复飞向一个点,withinTime()为true 。如修改热点位置时 */ var callback1 = function (panoId, param1, param2) { common.delayOneFrame(function () { loadingPanos[panoId] = !1; //console.log('loadedCallback consume:', pano.id) loadedCallback[pano.id] && loadedCallback[pano.id](param1, param2); loadedCallback[pano.id] = null; }.bind(this)); }.bind(this, pano.id); var callback2 = function (panoId, param) { common.delayOneFrame(function () { this.clearPanosTaskList(); // 加载tile失败后清掉task loadingPanos[panoId] = !1; successCallbackFunc2 && successCallbackFunc2(param); }.bind(this)); }.bind(this, pano.id); try { ; null !== iswait && void 0 !== iswait || (iswait = !0); if (pano.tiled) { loadingPanos[pano.id] = this.checkAndWaitForTiledPanoLoad(pano, basePanoSize, callback1, callback2, progressCallback, iswait, isclear, p); } else { loadingPanos[pano.id] = this.checkAndWaitForWholePanoLoad(pano, imgQuality1, imgQuality2, callback1, iswait); } if (loadingPanos[pano.id]) { LoadedTimePanos[pano.id] = performance.now(); //console.log('loadedCallback add', pano.id) loadedCallback[pano.id] = successCallbackFunc1; //add 如果加载好就执行最新的successCallbackFunc1 } return loadingPanos[pano.id]; //false 代表加载好了 } catch (msg) { loadingPanos[pano.id] = !1; LoadedTimePanos[pano.id] = performance.now() - maxTime; throw msg; } }; }(); _this.checkAndWaitForWholePanoLoad = function (pano, imgQuality1, imgQuality2, callbackFunc, iswait) { if (!pano) { throw new BasicException('Player.checkAndWaitForWholePanoLoad() -> Cannot load texture for null pano.'); } if (iswait) { this.model.waitForLoad(pano, function () { return pano.isLoaded(imgQuality2); }); } if (!pano.isLoaded(imgQuality1)) { pano.loadCube(imgQuality1).done(callbackFunc); return true; } else { return false; } }; _this.checkAndWaitForTiledPanoLoad = function () { var vectorForward = new THREE.Vector3(); return function (pano, basePanoSize, callback1, callback2, progressCallback, iswait, isclear, l) { if (!pano) { throw new BasicException('Player.checkAndWaitForTiledPanoLoad() -> Cannot load texture for null pano.'); } vectorForward.copy(Vectors$1.FORWARD); this.getDirection(vectorForward); if (!pano.isLoaded(basePanoSize)) { iswait && this.model.waitForLoad(pano, function () { return pano.isLoaded(basePanoSize); }); pano.loadTiledPano(basePanoSize, vectorForward, null, isclear, l /* , undefined, quality */ ).done(function (e, t) { callback1 && callback1(e, t); }.bind(this)).fail(function (msg) { callback2 && callback2(msg); }.bind(this)).progress(function (e, t, i) { progressCallback && progressCallback(e, t, i); }.bind(this)); return !0; } }; }(); _this.switchCameraMode = function (mode, quaternion, target, position, currentScale) { var o = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; var control = this.cameraControls.controls[mode], camera = control.camera; if (mode == Viewmode$1.PANORAMA) { camera.position.copy(this.currentPano.position); var direction; if (quaternion) { direction = Vectors$1.FORWARD.clone().applyQuaternion(quaternion); } else { direction = this.getDirection().setY(0).normalize(); } control.lookAt(direction.add(camera.position)); } else { if (target) { control.target.copy(target); } if (position) { camera.position.copy(position); } if (mode == Viewmode$1.DOLLHOUSE) { ////////////////// if (!position && !target) { if (o.dontFitScreen && this.mode === Viewmode$1.PANORAMA) { //当前位置的抬升 position = this.position.clone(); if (this.mode === Viewmode$1.PANORAMA) { position.add(new THREE.Vector3(0, 6, 0)).add(this.getDirection().multiplyScalar(-10)); } else { position.add(Vectors$1.DOWN.clone().applyQuaternion(this.quaternion).multiplyScalar(6)).setY(6); } } else { //fitScreen 居中 . by xzw var vec; if (this.mode === Viewmode$1.PANORAMA) { control.target.copy(this.model.center).setY(this.model.boundingBox.min.y + 2); vec = this.getDirection().negate().setY(1).normalize(); //获得朝向 } else { control.target.copy(this.target.clone().setY(this.model.boundingBox.min.y + 2)); vec = Vectors$1.DOWN.clone().applyQuaternion(this.quaternion).setY(1).normalize(); } var distance = control.suitableDistance; vec.multiplyScalar(distance); position = control.target.clone().add(vec); } camera.position.copy(position); } } else if (mode == Viewmode$1.FLOORPLAN) { //////////////////// if (!target) { control.target.copy(this.model.center).setY(0); } if (!position) { var y = this.mode == 'panorama' ? this.cameraControls.controls.dollhouse.suitableDistance * 0.7 : THREE.MathUtils.clamp(this.camera.position.y, 1, settings$3.floorplan.cameraHeight); //尽量和dollhouse的高度一致,渐变才不突兀 y = Math.max(y, this.model.boundingBox.max.y + constants$4.orthoNear + constants$4.planeHeightShift + 1); camera.position.copy(this.model.center).setY(y); control.rotateToView(this.model.size, this.getDirection()); } if (currentScale) { control.currentScale = control.absoluteScale = currentScale; } else if (o.fitBoundSize) { control.zoomToContain(this.fitBoundSize); } else { control.zoomToContain(this.model.size); } } } control.update(0); }; _this.update = function () { var e = {}, maxDelayCount_ = 15, //最大延迟帧数 waitUpdateCount = 2, //先延迟两帧 needsDelayUpdate; return function (i) { this.updatePersistentZooming(i), this.updateFromControls(i); //this.getCurrentNodePanos(t); this.lastFrameChanged = false; if (this.hasChanged(e)) { //相机、鼠标等是否有变化 this.lastFrameChanged = e.cameraChanged3 ? 'level3' : e.cameraChanged2 ? 'level2' : e.cameraChanged ? 'level1' : false; this.lastChangeTime = Date.now(); !this.mouseDown && this.containsMouse && this.updateIntersect(); this.emit(PlayerEvents.ViewChanged, e); if (e.cameraChanged) { if (this.compass) this.compass.update(this.quaternion); this.model.floorLogos.updateFloorlogo(this.camera && this.camera.quaternion, this); if (this.linkEditor && (this.linkEditor.setTagVisible || this.linkEditor.setPanoVisible)) this.linkEditor.updateFootIconSize(); this.updateLabelZIndex(['dollLabels', 'doorLabels']); //更新"删除测量线"的标签所在位置 if (this.chosenMeasureRuler) { this.chosenMeasureRuler.updateOptionPos(); } needsDelayUpdate = true; } //----cameraChanged end if (e.cameraChanged || e.floorChanged || e.allFlVisiChanged) { this.dollLabels.concat(this.planLabels).concat(this.doorLabels).concat(this.measureRulers).concat(this.polygonmarkLabels).forEach(function (label) { label.update(); }); } } //----hasChanged end---------- if (needsDelayUpdate) { //延时update,防止崩溃 if (waitUpdateCount-- == 0) { //console.log('update1', waitUpdateCount) DoorLabel.updateCameraDir(this); this.setAnimateMakerPano(); waitUpdateCount = maxDelayCount_; needsDelayUpdate = false; } else if (waitUpdateCount % Math.round(maxDelayCount_ / 3) == 0) { //更频繁点的更新(和上一个错开 ) //console.log('update2', waitUpdateCount ) if (this.model.supportsTiles) { var upcomingPanos = this.panosTaskList.length > 1 ? this.panosTaskList.map(function (e) { return e.pano; }) : []; //add this.updateTileDownloader(upcomingPanos); //提前加载好512图,否则持续漫游会延迟1ms而卡顿 this.updatePanoRenderer(); this.updateZoomPano(); } } } if (this.paintEditor && this.paintEditor.painting) this.paintEditor.update(); this.reticule.update(); //this.path.update(); //this.spider.update(); this.cachedPanoCandidates && settings$3.navigation.panoScores && this.model.panos.showPanoScores(this.cachedPanoCandidates); this.updateControlLocks(); this.emit('update', { x: this.position.x, y: this.position.z, lon: this.cameraControls.controls.panorama.lon, hasChanged: e, mode: this.mode, lastFrameChanged: this.lastFrameChanged }); }; }(); _this.updateLabelZIndex = function (types) { var _this5 = this; //更新labels的z-index types.forEach(function (type) { if (type == 'dollLabels' && _this5.mode != 'dollhouse' || type == 'doorLabels' && _this5.mode != 'panorama') return; var labels = _this5[type].sort(function (a, b) { return b.pos2d.z - a.pos2d.z; }); labels.forEach(function (label, index) { label.elem.style.zIndex = index; }); }); }; _this.updatePersistentZooming = function (e) { if (1 === this.zooming) { this.zoomBy(1 + this.zoomSpeed * e); } else if (this.zooming === -1) { this.zoomBy(1 - this.zoomSpeed * e); } }; _this.updateControlLocks = function () { if (this.currentPano && this.model.supportsTiles) { var ctl = this.cameraControls.controls[Viewmode$1.PANORAMA]; ctl.locked = ctl.lockedForce || settings$3.vrEnabled || !this.currentPano.highestFullTileRenderOpCompleted && this.currentPano.lockUntilRenderingComplete; //xzw add lockedForce } }; _this.updatePanoRenderer = function () { var vectorForward = new THREE.Vector3(); return function (t) { var i = this.nextPano || this.currentPano; vectorForward.copy(Vectors$1.FORWARD); this.getDirection(vectorForward); if (this.$app.core.get('PanoRenderer').hasQueuedTiles() && i) { this.$app.core.get('PanoRenderer').updateDirection(vectorForward); } }; }(); _this.updatePreRendering = function () { var e = {}; return function (t) { if (1 === settings$3.tiling.preRenderTourPanos && this.preRenderingEnabled) { var i = this.nextPano || this.currentPano; if (i && t && t.length > 1) { var n = t.findIndex(function (e) { if (e.id === i.id) return !0; }); if (n >= 0 && n + 1 < t.length) { var r = t[n + 1]; r.isLoaded(this.basePanoSize) || e[r.id] || (window.setTimeout(function (t) { this.checkAndWaitForPanoLoad(t, 'high', 'low', this.basePanoSize, null, null, null, !1, !1, !1), window.setTimeout(function (t) { e[t.id] = !1; }.bind(this, t), settings$3.tiling.panoPreRenderRepeatDelay); }.bind(this, r), settings$3.tiling.panoPreRenderDelay), e[r.id] = !0); } } } }; }(); _this.enablePreRendering = function () { this.preRenderingEnabled = !0; }; _this.updateTileDownloader = function () { var e = new THREE.Vector3(); return function (upcomingPanos) { var i = this.nextPano || this.currentPano; if (i) { var loopTime = common.timeMeasuring.collection['loop'].median; /* let quality = 1024 let lowQuality = this.$app.config.mobile && (this.flying || Date.now() - this.lastFlyPanoDoneTime < camereChangeLazyTime - 1) //手机漫游时(尤其无缝漫游时)不要加载2048,停止后再加载 if (lowQuality) { if ((this.panosTaskList.length > 1 && (loopTime > 3 || this.model.texSizeBlock * loopTime > 80)) || loopTime > 6 || this.model.texSizeBlock * loopTime > 240) { quality = 512 } this.curTileQuality = quality } else this.curTileQuality = this.$app.core.get('QualityManager').getMaxNavPanoSize() //if(lowQuality)console.log('lowQuality2', quality, loopTime, this.model.texSizeBlock * loopTime) */ this.lowTile = this.$app.config.mobile && 'level1'; if (this.lowTile) { if (loopTime > 10 || this.model.texSizeBlock * loopTime > 500) { //尽量不要使用,非常模糊 this.lowTile = 'level2'; //this.flying && console.log('lowTile level2') } } e.copy(Vectors$1.FORWARD); this.getDirection(e); this.$app.core.get('TileDownloader').tilePrioritizer.updateCriteria(i, this.position, e, upcomingPanos.length > 0 ? upcomingPanos : null), this.$app.core.get('TileDownloader').processPriorityQueue = !0; } }; }(); _this.updateFromControls = function (e) { null !== e && void 0 !== e || (e = 0); var activeControl = this.cameraControls.activeControl; if (activeControl) { activeControl.update(e); this.quaternion.copy(activeControl.camera.quaternion); this.position.copy(activeControl.camera.position); this.target.copy(activeControl.target); activeControl.camera.updateProjectionMatrix(); this.camera.projectionMatrix.copy(activeControl.camera.projectionMatrix); this.camera.projectionMatrixInverse.copy(activeControl.camera.projectionMatrixInverse); this.emit('updateFromControls', this, e); //add } //activeControl.camera是不更新matrixWorld的 this.camera.position.copy(this.position); this.camera.quaternion.copy(this.quaternion); this.camera.updateMatrix(); this.camera.updateMatrixWorld(); }; _this.updateIntersect = function () { var _this6 = this; //console.log('updateIntersect') var e = this.flying, t = this.isOutsideMode() && this.cameraControls.controls[this.mode].isEngaged(), i = transitions$1.getById(settings$3.freeze.LookTransition); !(e || t || this.isTouchEvent || i.length && i[0].running); if (this.linkEditor && this.linkEditor.footIcons && (this.linkEditor.setPanoVisible || this.linkEditor.setTagVisible)) { this.intersect = this.getMouseIntersect(null, this.linkEditor.footIcons.filter(function (e) { return e.visible && !e.otherFloorLink; })); if (this.intersect) { CursorDeal.add('hoverFootMarker'); } else { CursorDeal.remove('hoverFootMarker'); } return; } if (this.$app.Camera.monitor.control.cameras.find(function (e) { return e.isWatching; })) { return; //观看监控中不能点击场景物体 } { //xzw var consumed; var consume = function consume() { consumed = true; }; //被使用 var getConsumed = function getConsumed() { return consumed; }; var meshes = []; this.emit('collectIntersectMesh', meshes, { consume, getConsumed }); //搜集要intersect的mesh if (consumed) { return; //有不加collider情况下获得了intersect且需要阻断的情况 } var markers = this.panoMarkers.filter(function (e) { return e.visible && Panorama.filters.isNeighbourPanoTo(_this6.currentPano)(e.pano); }); var videoTags = this.model.panos.list.filter(function (pano) { return pano.flagSpot && !pano.flagSpot.hidden; }).map(function (pano) { return pano.flagSpot.disc; }); this.intersect = this.getMouseIntersect(null, markers.concat(videoTags)); if (!this.intersect) { meshes.push.apply(meshes, _toConsumableArray(this.getColliders())); common.timeMeasuring.addTimeMark('getMouseIntersect', 'start'); this.intersect = this.getMouseIntersect(null, meshes); common.timeMeasuring.addTimeMark('getMouseIntersect', 'end', true); this.emit('judgeIntersect', this.intersect, { consume, getConsumed }); if (consumed) return; } /* if (!this.is360View(this.mode, this.currentPano)) { meshes = this.model.floors.reduce(function (e, t) { return t.hidden ? e : e.concat(t.collider.children) }, meshes) if (this.mode == 'panorama') meshes.push(this.model.skybox) } */ //this.intersect = this.getMouseIntersect(null, null) } this.intersect && this.updateClosestPano(this.intersect); if (this.intersectLabel && this.intersect) { var text = ['pos: ' + math$1.toPrecision(this.intersect.point.toArray(), 3), 'nor: ' + math$1.toPrecision(this.intersect.normal.toArray(), 2), 'dis: ' + math$1.toPrecision(this.intersect.distance, 2)]; this.intersectLabel.setText(text); this.intersectLabel.setPos(this.intersect.point); } if (this.closestPano || this.closestPanoInDirection(this.getMouseDirection()) || this.reticule.alwaysShow) { this.reticule.updatePosition(this.position, this.intersect); if (settings$3.navigation.panoScores && !settings$3.navigation.mouseDirection) { this.closestPanoInDirection(this.getDirection()); } } else { this.reticule.hide(); } }; _this.getMouseDirection = function (e) { e = e || this.mouse; var t = new THREE.Vector3(e.x, e.y, -1).unproject(this.camera), i = new THREE.Vector3(e.x, e.y, 1).unproject(this.camera); return i.sub(t).normalize(); }; _this.getColliders = function () { var colliders = []; if (!this.is360View(this.mode, this.currentPano)) { if (!this.$app.config.mobile || this.mode != Viewmode$1.PANORAMA) { //xzw:手机漫游时不intersect模型,因为有的模型很大,八千个mesh用时3ms。但可能导致问题:方向不准 colliders = this.model.floors.reduce(function (e, t) { return t.hidden ? e : e.concat(t.collider.children); }, [] //this.mode === Viewmode.PANORAMA ? this.panoMarkers : [] ); } if (this.mode === Viewmode$1.PANORAMA) colliders.push(this.model.skybox); } return colliders; }; _this.getMouseIntersect = function (mouse, colliders) { var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, _ref$recursive = _ref.recursive, recursive = _ref$recursive === void 0 ? false : _ref$recursive, type = _ref.type; mouse = mouse || this.mouse.clone(); if (!colliders) { colliders = this.getColliders(); } //performance.mark('intersect-start') var origin = new THREE.Vector3(mouse.x, mouse.y, -1).unproject(this.camera); this.raycaster.set(origin, this.getMouseDirection(mouse)); this.raycaster.camera = this.camera; var objects3d = this.raycaster.intersectObjects(colliders, recursive); //加了个true遍历子集 // console.log(this.raycaster) /* performance.mark('intersect-end') let measure = performance.measure('intersect','intersect-start','intersect-end'); colliders.length> 0 && console.log('getMouseIntersect',measure.duration.toFixed(4)) */ if (0 === objects3d.length) { return null; } if (type == 'getAll') return objects3d; var object3d = objects3d[0]; if (object3d.face) { object3d.normal = object3d.face.normal.applyQuaternion(object3d.object.quaternion); var point = this.position.clone().sub(object3d.point); if (point.dot(object3d.normal) < 0) { //x,y,z全部反向 object3d.normal.negate(); } if (this.currentPano) { object3d.onFloor = object3d.point.y < this.position.y - 0.5 * this.currentPano.height; } else { object3d.onFloor = object3d.point.y < this.position.y - 0.5; } object3d.horizontal = object3d.normal.y > 0.8; } return object3d; }; _this.updateClosestPano = function (intersect) { var _this7 = this; // 如果在fly过程中hover到marker时会使本该隐藏的marker显示出来 if (this.mode === Viewmode$1.TRANSITIONING) return; var filterFuncs = [Panorama.filters.isPanoAligned()]; var pano; if (!this.flying) { //为了避免飞的过程中还能hover到原先currentPano的邻居点,飞的时候禁止onHover if (intersect && (this.panoMarkers.includes(intersect.object) || //是marker . xzw add this.model.panos.list.find(function (pano) { return pano.flagSpot && pano.flagSpot.disc == intersect.object; })) // 是videoTag ) { pano = intersect.object.pano; //console.log('pano = intersect.object.pano', pano.id) } if (!pano) { if (this.mode === Viewmode$1.PANORAMA) { if (!this.currentPano) { return; } filterFuncs.push(Panorama.filters.not(this.currentPano)); filterFuncs.push(Panorama.filters.isNeighbourPanoTo(this.currentPano)); filterFuncs.push(Panorama.filters.inFloorDirection(this.currentPano.floorPosition, this.getDirection(), 0.25)); filterFuncs.push(Panorama.filters.isCloseEnoughTo(intersect.point, settings$3.panoFloorClickRadius)); //如果在地面下很远,由于先识别到地面,intersect就离floorPosition很远,识别不到。所以改为先单独识别marker。 filterFuncs.push(Panorama.filters.isNotBehindNormal(intersect.point, intersect.normal)); } else { // 避开孤立点,但初始点一定可进入 filterFuncs.push(function (pano) { return _this7.linkEditor.checkHasNeighbor(pano) || pano == _this7.$app.core.get('Scene').firstView.pano; }); filterFuncs.push(Panorama.filters.isOnVisibleFloor()); this.mode !== Viewmode$1.FLOORPLAN && filterFuncs.push(Panorama.filters.inDirection(this.position, this.getDirection(), 0.25)); } pano = this.model.panos.find(filterFuncs, [Panorama.sortFunctions.floorDistanceToPoint(intersect.point)]); } } if (pano !== this.closestPano) { pano && (this.isPanoHover = !0); //触发事件,导致地面的marker变清晰 this.emit(PlayerEvents.ClosestPanoChanging, this.closestPano, pano, this.mode); this.closestPano = pano; } else { this.isPanoHover = !1; } }; _this.dollhouseMode = function (position, quaternion) { this.modeTran = 'dollhouse-panorama'; this.emit(PlayerEvents.ModeChanging, this.mode, Viewmode$1.DOLLHOUSE); this.mode = Viewmode$1.DOLLHOUSE; this.cameraControls.controls[Viewmode$1.DOLLHOUSE].reset(); var center = new THREE.Vector3(this.model.center.x, 0, this.model.center.z), cameraPosition = new THREE.Vector3(15, 10, 15); if (position && quaternion) { var direction = Vectors$1.FORWARD.clone().applyQuaternion(quaternion), position = this.model.center.clone().sub(position), s = position.dot(direction); if (s > 0) { center = direction.clone().multiplyScalar(s).add(position); //cameraPosition.copy(position) } else { logger$1.warn("Tried to initiate dollhouse mode that wasn'quaternion looking at the model", position, quaternion); } } this.cameraControls.controls[Viewmode$1.DOLLHOUSE].resetRanges(0, !0); this.cameraControls.controls[Viewmode$1.DOLLHOUSE].target.copy(center); this.cameraControls.cameras[Viewmode$1.DOLLHOUSE].position.copy(cameraPosition); this.updateFromControls(); this.model.alpha = 1; this.model.skybox.material.uniforms.opacity.value = 0; }; _this.insideMode = function (pano, callback) { var deferred = Deferred$1(), callbackFunc = callback || null; if (this.mode !== Viewmode$1.PANORAMA && this.mode !== Viewmode$1.TRANSITIONING) { if (!pano) { if (!this.currentPano || this.model.currentFloor && this.currentPano.floor != this.model.currentFloor) { pano = this.getFloorPanoByScore(null, this.model.currentFloor); //到当前所在楼层 } if (!pano) { pano = this.currentPano; } } this.flyToNewMode({ mode: Viewmode$1.PANORAMA, pano: pano, callback: callbackFunc }).done(deferred.resolve.bind(deferred)).fail(deferred.reject.bind(deferred)); } else { var msg = 'Cannot change mode during mode transition'; if (this.mode === Viewmode$1.PANORAMA) { msg = 'Already in panorama mode'; } deferred.reject(msg); } return deferred.promise(); }; _this.fitDollhouse = function (initPosition1, initPosition2, initQuaternion) { var maxY = this.model.boundingBox.max.y; var n = Vectors$1.FORWARD.clone().applyQuaternion(initQuaternion); initQuaternion = n.clone().add(initPosition1); this.cameraControls.activeControl.target.copy(initQuaternion); this.cameraControls.activeControl.camera.position.set(0, maxY * 2.4, 0).add(initPosition1).add(n.multiplyScalar(-10)); /* var n = Vectors.FORWARD.clone().applyQuaternion(initQuaternion) this.cameraControls.activeControl.target.copy(n).add(initPosition1) var o = Vectors.RIGHT.clone().applyQuaternion(initQuaternion), a = Vectors.UP.clone(), s = o.clone().applyAxisAngle(a, Math.PI / 2), boundingBoxMax = this.model.boundingBox.max.clone(), boundingBoxMin = this.model.boundingBox.min.clone(), h = [ new THREE.Vector3(boundingBoxMax.x, 0, boundingBoxMax.z).sub(initPosition1), new THREE.Vector3(boundingBoxMax.x, 0, boundingBoxMin.z).sub(initPosition1), new THREE.Vector3(boundingBoxMin.x, 0, boundingBoxMax.z).sub(initPosition1), new THREE.Vector3(boundingBoxMin.x, 0, boundingBoxMin.z).sub(initPosition1) ], u = 0, p = 0, g = 0 h.forEach(function(e, t, i) { var n = Math.abs(e.dot(o)), r = e.dot(s) n > u && ((u = n), (p = r)), r > g && (g = r) }) var m = Math.max(Math.abs(new THREE.Vector3(0, boundingBoxMax.y, 0).sub(initPosition1).dot(a)), Math.abs(new THREE.Vector3(0, boundingBoxMin.y, 0).sub(initPosition1).dot(a))), v = s .clone() .multiplyScalar(p) .add(initPosition2), A = s .clone() .multiplyScalar(g) .add(initPosition2) ;(p = u / Math.tan((this.cameraControls.activeControl.camera.fov / 2) * this.cameraControls.activeControl.camera.aspect * (Math.PI / 180))), (g = m / Math.tan((this.cameraControls.activeControl.camera.fov / 2) * (Math.PI / 180))), (p = Math.max(p, 10)), (g = Math.max(g, 10)) var y = n .clone() .multiplyScalar(-p) .add(v) .sub(initPosition2) .length(), C = n .clone() .multiplyScalar(-g) .add(v) .sub(initPosition2) .length() this.cameraControls.activeControl.maxDistance = settings.skyboxRadius - 1 if (y >= C) { this.cameraControls.activeControl.camera.position .set(0, 6, 0) .add(v) .add(n.multiplyScalar(1.1 * -p)) } else { this.cameraControls.activeControl.camera.position .set(0, 6, 0) .add(A) .add(n.multiplyScalar(1.1 * -g)) } */ }; _this.floorplanMode = function (position, quaternion, zoom, ratio) { this.mode = Viewmode$1.FLOORPLAN; var control = this.cameraControls.controls[Viewmode$1.FLOORPLAN]; control.reset(); var cameraPosition = position ? position : this.model.center; control.target.copy(cameraPosition).setY(0); control.camera.position.copy(cameraPosition).setY(settings$3.floorplan.cameraHeight); if (zoom) { control.currentScale = zoom / (this.domElement.clientWidth / this.domElement.clientHeight); control.absoluteScale = control.currentScale; } else { control.zoomToContain(this.model.size, ratio); } if (quaternion) { var direction = Vectors$1.LEFT.clone().applyQuaternion(quaternion); control.rotateLeft(-Math.atan2(direction.x, direction.z)); } else { control.rotateToView(this.model.size, this.getDirection()); } control.update(0); }; _this.getAimToNextPano = function (pano, aim, aimQua) { //flyToPano 获取quaternion var hasVideo; if (!aim && !aimQua) { var askAim = { importance: 0, aim: null }; //发送请求看看是否需要强制focus的点(比如热点添加时) this.emit('ifFocusPoint', askAim); if (askAim.aim) { if (askAim.importance >= 3) { //importance判断权重 aim = askAim.aim; } } } if (!aim) { if (pano.panoVideo) { hasVideo = true; aim = pano.position.clone().add(pano.panoVideo.dir); } else { hasVideo = !aim && pano.hasVideo && this.$app.core.get('PanoVideoRenderer') && this.$app.core.get('PanoVideoRenderer').ifEnable(); if (hasVideo) { // if(!objects.mainDesign || !objects.mainDesign.editing){ if (pano.videoInfo.dir) { //同panoVideo 展示页 aim = pano.position.clone().add(pano.videoInfo.dir); } else { var qua = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(this.model.supportsTiles ? 90 : 180)); aim = Vectors$1.FORWARD.clone().applyQuaternion(qua.multiply(pano.quaternion)).add(pano.position); } // } } } } if (aim) aimQua = convertTool.getQuaByAim(aim, pano.position);else aimQua = aimQua; return { aimQua, hasVideo }; }; _this.flyToPano = function (toPano, callbackFunc) { var _this8 = this; /* toPano.callback = callbackFunc return this.fastToPano(toPano ) */ //-----测试瞬间过渡 if (this.locked) { return; } //if (this.unableChangePano) return if (typeof toPano == 'number' || typeof toPano == 'string') toPano = { pano: this.model.panos.index[toPano] }; var pano = toPano.pano, aim = toPano.lookAtPoint, //优先级比quaternion 高 aimQua = toPano.quaternion, duration = toPano.duration, aimDuration = toPano.aimDuration, rotSpeed = toPano.rotSpeed; //xzw toPano.maxDistanceOverride; toPano.skipWarpingCheck; //constantMoveSpeed = toPano.constantMoveSpeed, toPano.easeType; var //如果为'constant'代表一直保持某个速度,一般是导览,直到最后一个点减速 newPano = null, retryCallback = null, zoomLevel = toPano.zoomLevel || (settings$3.zoom.zoomToDefaultWhenToPano ? 1 : this.zoomLevel), //add cancelLookFun = toPano.cancelLookFun, checkAlone = toPano.checkAlone; callbackFunc = callbackFunc || toPano.callback; toPano.quaOri = this.quaternion.clone(); //记录一下 if (typeof pano == 'number') pano = toPano.pano = this.model.panos.index[pano]; if (this.EditPanoMosaic && this.EditPanoMosaic.editVideo && this.EditPanoMosaic.editVideo.pano != pano) { return; } // checkAlone 如果pano是孤立点,则根据aim跳转到最近的非孤立点 if (checkAlone && aim && pano.neighbourUUIDs.filter(function (id) { return id != pano.id; }).length == 0) { var notAlonePano = this.model.panos.closestPanoTowardPoint({ point: aim, require: [function (pano) { return pano.neighbourUUIDs.filter(function (id) { return id != pano.id; }).length > 0; }] }); if (notAlonePano) { pano = notAlonePano; toPano.pano = pano; } } if (!toPano.gotQua) { var _this$getAimToNextPan = this.getAimToNextPano(pano, aim, aimQua), aimQua = _this$getAimToNextPan.aimQua; _this$getAimToNextPan.hasVideo; toPano.quaternion = aimQua; toPano.gotQua = true; } //this.updateLastView(); //飞入 if (this.mode !== Viewmode$1.PANORAMA) { return void this.flyToNewMode({ mode: Viewmode$1.PANORAMA, pano: pano, duration: duration, quaternion: aimQua, callback: callbackFunc }); } /* toPano.callback = callbackFunc return this.fastToPano(toPano ) //-----测试瞬间过渡 */ //console.log('this.flying',this.flying, this.panosTaskList.length) var isFade360 = this.is360View(this.mode, pano) || this.is360View(this.mode, this.currentPano); if (!this.judgePanoTask(toPano, isFade360)) { //console.log('judgePanoTask return',this.panosTaskList ) callbackFunc && callbackFunc(false); return; } //处理panosTaskList //this.$app.core.get('PanoVideoRenderer').activatePanorama(pano) if (pano) { newPano = common.deepExtend(toPano); retryCallback = function () { common.delayOneFrame(function () { if (this.panosTaskList[0] != newPano) { //非最新任务 //checkAndWaitForPanoLoad可能有点问题,isLoaded和callback不同步?导致add了没及时 consume return log(); } newPano.retry = true; //add this.flyToPano(newPano, callbackFunc); }.bind(this)); }.bind(this); } if (config$4.mobile) { //手机端的终点出发时使用1024,直到到达终点(也就是高了要降, 低了不升) this.$app.core.get('PanoRenderer').switchPanoQuality(pano, { size: 1024 }); if (this.lowTile == 'level2') { if (!pano.tiledPanoRenderTarget) { //非快速漫游时降当前的漫游点 this.$app.core.get('PanoRenderer').switchPanoQuality(this.currentPano, { size: 1024 }); } } } else { if (!pano.tiledPanoRenderTarget) this.$app.core.get('PanoRenderer').switchPanoQuality(pano, { size: 2048 }); //pc在非无缝过渡的出发时, 终点要使用2048. 无缝时还保留之前半路加载的1024 } if (!pano || !this.checkAndWaitForPanoLoad(pano, 'high', 'low', this.basePanoSize, retryCallback)) { // logger.time(`[fly to pano] ${pano && pano.id}`) console.log("[flytopano]", pano && pano.id); var callback = toPano.finalCallback = function (flyDone) { //console.log('飞callback', this.currentPano.id ) this.nextPanoTask(toPano, flyDone); //继续执行panosTaskList的下一个pano callbackFunc && callbackFunc(flyDone); //xzw 2022.7.8移动到最后。 万一callbackFunc中包含要飞向下一个,就需要先执行 nextPanoTask。但是万一又需要这个先怎么办 }.bind(this); if (!this.currentPano) { this.currentPano = pano; } //this.adjustFlySpeed(this.currentPano, pano) var _duration = duration; if (typeof duration != 'number') { _duration = this.computeDuration(toPano); } // 加载3dtiles会拖长跳转时间,减去150ms比较合适 //无缝过渡不允许修改 //if (this.model._3dTilesRuntime) _duration = Math.max(_duration - 150, 1) toPano.duration = _duration; log('flytopano', toPano.pano.id, toPano, this.panosTaskList.map(function (e) { return e.pano.id; })); /* if( this.panosTaskList[0] != toPano ){ console.error('?') } */ if (this.zoomLevel !== zoomLevel) { switch (settings$3.zoom.transitionStyle) { case 1: this.smoothZoomLevelTo(zoomLevel, _duration / 2); break; case 2: newPano = common.deepExtend(toPano); retryCallback = this.flyToPano.bind(this, newPano, callbackFunc); return void this.smoothZoomLevelTo(zoomLevel, settings$3.zoom.restoreTime * (this.zoomLevel - zoomLevel), retryCallback); } } if (aimQua /* && !isFade360 */ ) { var quaNow = toPano.quaOri.clone(); var M = new THREE.Vector3(); transitions$1.cancelById(settings$3.freeze.LookTransition); //_duration *= settings.transition.aimSlowFactor if (pano === this.currentPano) { var R = Vectors$1.FORWARD.clone().applyQuaternion(toPano.quaOri), P = Vectors$1.FORWARD.clone().applyQuaternion(aimQua), O = R.angleTo(P); var callback2 = function callback2() { callback(true); _this8.emit('flytopano.rotateEnd', {}); }; this.flyRotate = true; //许钟文 add 在原地旋转,看向某一点 return void 0 != aimDuration || (aimDuration = 1 * Math.sqrt(O) / (rotSpeed ? rotSpeed : settings$3.tags.navigate.rotateSpeedFactor) * 1e3), void transitions$1.start(function (ee) { if (this.mode != Viewmode$1.PANORAMA) { //xzw transitions$1.cancelById(settings$3.freeze.LookTransition); callback2(); return; } quaNow.copy(toPano.quaOri); lerp.quaternion(quaNow, aimQua)(ee); M.copy(convertTool.getAimByQua(quaNow, this.cameraControls.activeControl.camera.position)); this.cameraControls.activeControl.lookAt(M); }.bind(this), aimDuration, callback2, 0, easing[settings$3.transition.movementEasing], null, settings$3.freeze.LookTransition, cancelLookFun); } } if (pano === this.currentPano || this.flying) { log('flytopano return ', pano === this.currentPano, this.flying); return void callback(); } this.flying = !0; this.position.clone(); var currentPano = this.currentPano; this.nextPano = pano; // logger.debug('Flying to pano ', pano.position) this.emit(PlayerEvents.PanoChosen, this.currentPano, pano); // this.emit(PlayerEvents.FlyingStarted, { // targetPosition: pano.position, // currentPosition: position, // targetPano: pano, // currentPano: currentPano, // type: 'flyToPano', // }) // currentPano必须加上,否则球幕视频挂起失效 this.emit(PlayerEvents.FlyingStarted, { panoId: pano.id, quaternion: aimQua, lastPanoId: currentPano.id, type: 'flyToPano', duration: toPano.duration, isTagFlying: toPano.isTagFlying // 飞向热点 }); this.model.currentFloor = pano.floor; this.doorLabels.forEach(function (label) { return label.updateVisible(pano); }); this.model.fadePanoMarkers(0, 0, { hideVideoFlag: true }); //过渡时先隐藏, 因marker可能飘 if (isFade360) { this.fade360View(this.cameraControls.activeControl.camera, { pano: pano, aim: aim, aimQua: aimQua }, function () { _this8.afterFlyToPano(toPano); }); return; } //地标变化 this.model.floorLogos.changefloorLogoOpa({ index: 0, opa: 0, dur: _duration, delay: 0.7 }); //this.model.floorLogoFade(0, _duration*0.5, 0.7); this.model.floorLogos.secondLogo.position.copy(pano.floorPosition.clone().sub(this.model.position)); //this.model.floorLogos.adjustfloorLogoHeight(); common.updateVisible(this.model.floorLogos.secondLogo, 'flyToPano', true); //第二个地标只在过渡时显示 this.model.floorLogos.changefloorLogoOpa({ index: 1, opa: 1, dur: 250 }); //this.model.floorLogoShow(1,250); //flyingWithRot边飞边旋转 (许钟文) if (aimQua && !isFade360) { this.flyingWithRot = true; toPano.aimQua = aimQua; } toPano.chunkProgress = this.judgeHideWall(pano); //穿墙判断 //console.log('执行过渡:' + _duration) this.startTransition(toPano); // // 虚拟人物导览对象 // const roleAnimation = this.$app.TourManager.roleAnimation // //离toPano 3米距离 // if (roleAnimation && roleAnimation.model && this.$app.TourManager.playing && aimQua) { // let newRolePosition = roleAnimation.getTarget2(toPano.pano.position.clone(), aimQua.clone(), 0, 3) // const roleStartPosition = roleAnimation.model.position.clone() // //人物到目的地的方向 // const direction = new THREE.Vector3().subVectors(newRolePosition, roleStartPosition) // if (toPano.duration != 0) { // //let speed = this.currentPano.position.distanceTo(toPano.pano.position) / toPano.duration // let speed = roleStartPosition.distanceTo(newRolePosition) / toPano.duration // roleAnimation.setModifyTimeScale(speed * 500) // //console.log('speed:' + speed) // } // transitions.start( // progress => { // if (progress != 0 && progress != 1 && roleAnimation.getVisible()) { // //累加并更新人物坐标 // let _newRolePosition = new THREE.Vector3().addVectors(roleStartPosition, new THREE.Vector3(direction.x * progress, 0, direction.z * progress)) // roleAnimation.setWalkingToTarget(_newRolePosition) // roleAnimation.model.position.set(_newRolePosition.x, this.model.currentFloor.boundingBox.min.y, _newRolePosition.z) // //console.log('RoleAnimation-setWalkingToTarget1:' + roleAnimation.model.rotation.y + '&&' + progress) // } // }, // toPano.duration, // null, // 0, // null, // null, // 'roleWalk' // ) // } } }; _this.startTransition = function (toPano) { var _this9 = this; //this.model.chunks.forEach(e => common.updateVisible(e, 'force', false)) if (!toPano.easeFun) toPano.easeFun = easing.linearTween; var startProgress = toPano.progress || 0; // 同屏时过渡transitionsId必须做区分 var transitionsId = this.$app.resource.num + settings$3.freeze.FlyToPano; transitions$1.cancelById(transitionsId); var dis = this.currentPano.position.distanceTo(toPano.pano.position); var loadNextProgress = THREE.MathUtils.clamp(1 - 2 / dis, 0, 0.9); var quaNow = toPano.quaOri.clone(); var M = new THREE.Vector3(); /* console.log( 'startTransition ', toPano.pano.id, toPano.easeFun == easing.easeOutSine ? '减速' : '匀速', (toPano.easeFun == easing.linearTween && toPano.flySpeed) ? '目标速度' + toPano.flySpeed.toFixed(5) : '', 'dur', toPano.duration.toFixed(2), 'pgs',toPano.progress.toFixed(3), toPano.easeFun == easing.linearTween ? 'loadNextP '+ loadNextProgress.toFixed(2):'' ) */ transitions$1.start(function (progress_, delta) { var item = transitions$1.getById(transitionsId)[0]; var progress = startProgress + progress_ * (1 - startProgress); var currentSpeed; if (progress_ != 1 && progress_ != 0) { // 1的时候不准,往往偏小, 0的时候速度为0,也不记录 currentSpeed = toPano.currentSpeed = (progress - toPano.progress) * dis / delta; //记录下当前速度,当变为匀速时可以过渡到flySpeed //console.log('currentSpeed',currentSpeed, progress_, progress) } else { currentSpeed = toPano.currentSpeed || 0; } //console.log('progress',progress, delta) toPano.progress = progress; if (progress_ > 0 && progress_ < 1 && delta) { var adjustSpeed = function adjustSpeed(ratio, cause) { var maxChange = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.08; //调速 var change = Math.abs(ratio - 1); if (change > maxChange) { if (ratio > 1) ratio = 1 + maxChange;else ratio = 1 - maxChange; } transitions$1.adjustSpeed(transitionsId, ratio); //改速 transitions$1.adjustSpeed(settings$3.freeze.LookTransition, ratio); //把旋转的也改速下 //console.log(cause, 'ratio', ratio.toFixed(4), 'speed', currentSpeed.toFixed(5), 'progress', progress.toFixed(4), 'dur',item.duration.toFixed(3)) }; if (toPano.easeFun == easing.linearTween && toPano.flySpeed) { //调整速度向期望速度靠近(匀速时的flySpeed是期望速度) if (currentSpeed > 0 && !math$1.closeTo(currentSpeed, toPano.flySpeed) && toPano.flySpeed) { var ratio = toPano.flySpeed / currentSpeed; var maxChange = toPano.easeType == 'constant' ? ratio - 1 : 0.01; //改变幅度小的话,有惰性,可以保持接近匀速但整体又能保持平均标准速度。 导览不限制最大变速 adjustSpeed(ratio, '渐变匀速', maxChange); } } if (progress > loadNextProgress && toPano.flyCount == 1 && toPano.easeFun == easing.linearTween /* && toPano.easeType != 'constant' */ && _this9.panosTaskList.length == 1) { //匀速行走超过一半时,若还是最后一个,就减速(之后若又按下,还会变为匀速) toPano.easeFun = easing.easeOutSine; var restDis = (1 - progress) * dis; toPano.duration = Math.PI / 2 * restDis / currentSpeed; /* settings.transition.flySpeed */ // 这样能保证初始速度为flySpeed toPano.duration = Math.max(toPano.duration, settings$3.transition.flyTime - item.duration * progress); //避免停止过于迅速 toPano.ignoreFirstFrame = false; _this9.startTransition(toPano); } if (progress > 0.2 && _this9.panosTaskList.length > 1 && !_this9.panosTaskList[1].pano.tiledPanoRenderTarget) { //无缝过渡中途 提前加载下一个, 防止停顿 _this9.$app.core.get('PanoRenderer').switchPanoQuality(_this9.panosTaskList[1].pano, { useIdel: true, size: _this9.lowTile == 'level2' ? 512 : 1024 }); //该质量将会一直持续到到达它 _this9.checkAndWaitForPanoLoad(_this9.panosTaskList[1].pano, 'low', 'low', _this9.basePanoSize, function () {}); //'low', 'low' } /* if(toPano.easeFun != easing.linearTween && progress > 0.1 && progress < 0.9 && currentSpeed > 0.001 && item.duration < settings.transition.flyTime){ let r = THREE.MathUtils.clamp(item.duration * 2.3 / settings.transition.flyTime, 0.9, 0.95) adjustSpeed(r, '降速') //防止停止的最后一段因太短而迅速停止 } */ } _this9.model.skybox.material.uniforms.progress.value = progress; _this9.emit('updataProgress', progress); //别的模块借用一下透明度 if (toPano.chunkProgress) { _this9.model.chunks.forEach(function (e) { return e.materialInside.uniforms.progress.value = progress; }); } if (isNaN(progress)) { console.error('progress isNaN', progress, progress_, startProgress, delta, toPano.duration, toPano); transitions$1.cancelById(transitionsId); } var position = _this9.currentPano.position.clone(); var endPos = toPano.pano.position.clone(); lerp.vector(position, endPos)(progress); _this9.cameraControls.cameras[Viewmode$1.PANORAMA].position.copy(position); //过渡的同时旋转镜头 if (toPano.aimQua) { quaNow.copy(toPano.quaOri); lerp.quaternion(quaNow, toPano.aimQua)(progress); M.copy(convertTool.getAimByQua(quaNow, _this9.cameraControls.activeControl.camera.position)); _this9.cameraControls.activeControl.lookAt(M); } }, toPano.duration, this.afterFlyToPano.bind(this, toPano), 0, toPano.easeFun, 'chunkFly', transitionsId, function () { //cancelById _this9.afterFlyToPano(toPano, true); }, toPano.ignoreFirstFrame); toPano.flyCount++; }; _this.nextPanoTask = function (lastToPano, dealTask) { if (lastToPano == this.panosTaskList[0]) this.panosTaskList.splice(0, 1); //this.off('makeConstantSpeed', startTransition) if (dealTask && this.panosTaskList.length) { //继续处理下一个任务 var next = this.panosTaskList[0]; next.dealingTask = true; //log('准备执行下一个任务', this.panosTaskList[0].pano.id) var dis = next.pano.position.distanceTo(lastToPano.pano.position); var currentSpeed = lastToPano.currentSpeed; var hopeDur = this.computeDuration(next); currentSpeed = Math.max(0.002, currentSpeed); next.duration = dis / currentSpeed; //初始速度,为了衔接。即将被使用 if (next.quaternion) { next.duration = hopeDur; //next.duration = Math.max(hopeDur/3, next.duration) //防止过小,导致后期追不上标准速度,尤其是有转向时 } next.flySpeed = dis / hopeDur; //期待速度, 是标准速度 //console.log('上一个的速度', currentSpeed, '期待速度', next.flySpeed) this.flyToPano(next); } }; _this.judgePanoTask = function (toPano, isFade360) { //处理panosTaskList toPano.progress = toPano.progress || 0; toPano.flyCount = 0; var length = this.panosTaskList.length; var last = this.panosTaskList[length - 1]; if (this.dontInterruptPanoTask) { return !!toPano.dealingTask; } if (!toPano.retry && !toPano.dealingTask) { var currentTask = this.panosTaskList[0]; /* if (currentTask && !currentTask.canConstantlyWalk) { return console.log('当前执行的是非canConstantlyWalk,不允许加入') } */ if (toPano.quaternion || isFade360) { //遇到特殊的toPano,在这之后不能继续添加 toPano.canConstantlyWalk = false; //是否可以一直点击一直走。(是否允许添加下一个) } // 如果上个点位tile加载有问题卡住,就直接清空panosTaskList if (last && last.pano.tileError) { this.clearPanosTaskList(); length = 0; last = undefined; } if (length == 0 || last.canConstantlyWalk || toPano.pano == this.currentPano) { if (length > 0) { if (this.panosTaskList.some(function (e) { var _e$lookAtPoint; return e.pano == toPano.pano && (!e.lookAtPoint && !toPano.lookAtPoint || ((_e$lookAtPoint = e.lookAtPoint) === null || _e$lookAtPoint === void 0 ? void 0 : _e$lookAtPoint.equals(toPano.lookAtPoint))); })) { //去除重复的 return; } /* let wholeDur = this.panosTaskList.reduce((w, c) => { return w + c.duration }, 0) if (length > 4 || (wholeDur > 2500 && length > 1)) { //console.log('过多',length, wholeDur) return } */ if (length > 1) return; if (currentTask.flyCount == 0 /* && currentTask.easeType != 'constant' */ ) { return; } } this.panosTaskList.push(toPano); //只要通过都加入列表,包括 == currentPano的 length++; log('panosTaskList加入', toPano.pano.id); } else { return log(); } if (length > 1) { //等待上一个任务完成 //log('增加任务', toPano.pano.id) /* let {k, easeFun } = easing.getEaseOut( 2 / dis + 1) toPano.easeFun = easeFun toPano.duration = k * dis / settings.transition.flySpeed */ //当前任务如果不是匀速,要变成匀速, 且重新执行: if (currentTask.easeFun != easing.linearTween) { var dis = this.currentPano.position.distanceTo(currentTask.pano.position); var restDis = (1 - currentTask.progress) * dis; //console.log('currentSpeed', currentTask.currentSpeed) var currentSpeed = Math.max(currentTask.currentSpeed, 0.002); //避免起步过慢 var newDur = restDis / currentSpeed; //初始速度和原先一致, 为了衔接。 if (isNaN(newDur)) { console.error('newDur isNaN', currentSpeed, currentTask.progress, currentTask); } currentTask.easeFun = easing.linearTween; currentTask.flySpeed = dis / this.computeDuration(currentTask); //渐变加速到标准速度 currentTask.duration = newDur; this.startTransition(currentTask); } return; } } return true; }; _this.judgeHideWall = function (pano) { var chunkProgress = true; /* if(objects.mainDesign && objects.mainDesign.editing){ chunkProgress = false; editModel = true; } */ //var metadata = this.store.getters['scene/metadata']; //if(metadata.sceneSource != 12){//123永远要显示模型 this.model.chunks.forEach(function (e) { return common.updateVisible(e, 'isBlock', true); }); //先显示 if (this.currentPano.noBlockPanos.includes(pano.id)) ; else { //4.6.0 xzw //console.log('judgeHideWall', pano.id) //在算法部将有门的地方更改为不隐藏模型之前,先这么写: 判断走过的路中是否真的穿墙。 if (this.currentPano.blocks[pano.id]) { this.hideWalls = this.currentPano.blocks[pano.id]; this.hideWalls.forEach(function (hideWall) { common.updateVisible(hideWall, 'isBlock', false); }); } else { var safeDepth = 0.1; //向前后延伸一些,为了防止刚好墙壁在眼前 var A = this.currentPano.origin.clone(); var B = pano.origin.clone(); var AB_ = B.clone().sub(A).normalize().multiplyScalar(safeDepth); var A_ = A.clone().sub(AB_); //延长A到A_ 延长长度为safeDepth var B_ = B.clone().add(AB_); //延长B到B_ 延长长度为safeDepth var intersects = convertTool.ifIntersectChunks(A_, B_, this.model, { throughWidth: 0.08, meshes: this.model.chunks }); if (intersects) { //throughWidth是为了防止刚好从缝隙中穿过,感觉和穿墙近似 this.hideWalls = intersects.map(function (intersect) { intersect.object.visible = false; return intersect.object; }); { //非编辑页面要记录下,下次不用判断 this.currentPano.blocks[pano.id] = this.hideWalls.slice(0); } } else { { //非编辑页面要记录下,下次不用判断 this.currentPano.noBlockPanos.push(pano.id); } } } } return chunkProgress; }; _this.afterFlyToPano = function (toPano, cancel) { this.currentPano.isAligned() && (this.lastPano = this.currentPano); //add if (this.currentPano !== toPano.pano) { this.currentPano.exit(); toPano.pano.enter(); this.currentPano = toPano.pano; this.nextPano = null; this.path.placeCpm(); if (this.mode == Viewmode$1.PANORAMA) { this.path.fadeOutCpm(settings$3.path.fadeOutTime); this.paintEditor && this.paintEditor.updatePanoPaint(this.currentPano.id, this.currentPano.id); } } if (!cancel) { if (this.mode == Viewmode$1.PANORAMA) { this.flying = !1; this.emit(PlayerEvents.FlyingEnded, { targetPosition: toPano.pano.position, currentPosition: toPano.pano.position, targetPano: toPano.pano, currentPano: this.currentPano }); this.model.floorLogos.firstLogo.position.copy(this.model.floorLogos.secondLogo.position); //this.model.floorLogos.adjustfloorLogoHeight() this.model.floorLogos.changefloorLogoOpa({ index: 0, opa: 1, dur: 0 }); //this.model.floorLogos[0].material.uniforms.opacity.value = 1; common.updateVisible(this.model.floorLogos.secondLogo, 'flyToPano', false); this.model.chunks.forEach(function (chunk) { chunk.materialInside.uniforms.progress.value = 1; //chunk.visible = true // 需要显示因穿墙而隐藏的模型 common.updateVisible(chunk, 'isBlock', true); //vr模式下似乎不能隐藏?settings.vrEnabled 因为改变chunks显示会让画面分离度改变,可能和眼睛看物体远近不同的夹角有关????? }); this.panosTaskList.length == 1 && this.$app.core.get('PanoRenderer').switchPanoQuality(this.currentPano, { size: 2048 }); //非无缝过渡时 升quality } this.model.fadePanoMarkers(); this.doorLabels.forEach(function (label) { return label.updateVisible(); }); this.lastFlyPanoDoneTime = Date.now(); //logger.timeEnd(`[fly to pano] ${this.currentPano.id}`) toPano.finalCallback && toPano.finalCallback(true); } }; _this.fastToPano = function () { var _this10 = this; var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; //瞬间过渡(支持同点过渡,支持角度) if (this.flying || this.isWarping()) return; var pano = o.pano || this.model.panos.index[o.panoId]; if (!pano) return console.error('fastToPano pano 无'); this.position.clone(); var oldPano = this.currentPano; var duration = o.duration || 1500; this.path.warpDestPano = pano; var retry = function retry() { _this10.waitingToWarp = !1, _this10.fastToPano(o); }; if (config$4.mobile) { //手机端的终点出发时使用1024,直到到达终点 this.$app.core.get('PanoRenderer').switchPanoQuality(pano, { size: 1024 }); } else { if (!pano.tiledPanoRenderTarget) this.$app.core.get('PanoRenderer').switchPanoQuality(pano, { size: 2048 }); //pc在非无缝过渡的出发时, 终点要使用2048. 无缝时还保留之前半路加载的1024 } if (this.checkAndWaitForPanoLoad(pano, 'high', 'low', this.basePanoSize, retry)) return void (this.waitingToWarp = !0); this.emit('pano.chosen', oldPano, pano); // 用于暂停oldPano的球幕视频播放 this.emit(PlayerEvents.FlyingStarted, { panoId: pano.id, lastPanoId: oldPano.id, type: 'flyToPano' }); this.flying = true; this.nextPano = pano; //提前加载高清图片 this.path.warpDestHeroLoc = { panoId: o.panoId, position: pano.position, quaternion: o.quaternion || this.quaternion.clone() }; //console.log('fastToPano', pano && pano.id ) logger$1.time("[fly to pano] ".concat(pano && pano.id)); this.path.warpTravel_BLACK(null, duration, 1, function () { /* pano != this.currentPano && this.currentPano.exit() pano.enter() this.currentPano = pano this.flying = false */ //this.emit("flying.ended", pano.position, oldPos, pano, oldPano) o.finalCallback = o.callback; _this10.afterFlyToPano(o); }); }; _this.fade360View = function (currentCamera, o, fuc) { var _this11 = this; //这个其实可以用fastToPano var transitionTime = o.transitionTime || 400; if (o.pano && o.pano.view) { if (!this.viewLinkManager.views[o.pano.view.sid]) { fuc && fuc(); return; } //已经删除 if (this.enteringView) { console.log('重复进入360'); fuc && fuc(); return; } if (o.pano == this.currentPano && !o.flyIn) { console.log('已经在此360漫游点'); fuc && fuc(); return; } o.pano.view.entering = true; this.enteringView = o.pano.view; //从开始直到doAfterFlying这段时间标记player的状态是正在fade360View } //热点直接利用updateVisible //this.model.wallManager.updateRulersVisi(false); this.domElement.style.opacity = 1; //init value transitions$1.start(lerp.property(this.domElement.style, 'opacity', 0), transitionTime, function () { !o.flyIn && config$4.mobile && _this11.$app.core.get('PanoRenderer').switchPanoQuality(_this11.currentPano, { size: 1024 }); //降旧的。其实也可以直接exit,但shader里要确保用不到tex o.pano && _this11.$app.core.get('PanoRenderer').switchPanoQuality(o.pano, { size: 2048 }); _this11.model.skybox.material.uniforms.opacity.value = o.skyboxOpacity != void 0 ? o.skyboxOpacity : 1; _this11.model.alpha = o.modelAlpha != void 0 ? o.modelAlpha : 0; o.pano && (currentCamera.position.copy(o.pano.position), currentCamera.quaternion.copy(o.pano.quaternion)); var enterView = !!(o.pano && o.pano.view), leaveView = !!(_this11.is360View(_this11.mode, _this11.currentPano) && !o.flyIn || o.flyOut); //console.log('fade360View : ', enterView, leaveView) if (enterView) { //进入360view o.pano.view.exitDoor.mesh.visible = true; //console.log("exitDoor.mesh.show "+o.pano.view.sid) //this.tagManager.hideShowTagsForBlackoutStyle(BlackoutStyle.END, transitionTime) _this11.viewLinkManager.updateCirclesWhenFade('enter', o); o.pano.view.balloon.showOrHide(false); o.pano.view.entering = false; var lookAtPoint = o.aim || new THREE.Vector3(0, 0, -1).applyQuaternion(o.pano.view.enterQuaternion || o.pano.quaternion).add(currentCamera.position); _this11.cameraControls.controls.panorama.lookAt(lookAtPoint); _this11.cameraControls.controls.panorama.update(0); _this11.OverlayManager.setGroupVisible(false); _this11.GLTFEditor.group.visible = false; // 隐藏空间模型 _this11.viewLinkManager.changeTitlesShow(false, 'enterView360'); _this11.$app.Camera.monitor.changeTitlesShow(false, 'enterView360'); //去除角度限制 _this11.cameraControls.controls.panorama.insideLookLimitUp = 89.9; _this11.cameraControls.controls.panorama.insideLookLimitDown = -89.9; _this11.cameraControls.controls.panorama.limitAngleIsBound = false; common.updateVisible(_this11.model.floorLogos.firstLogo, 'inView360', false); //隐藏 common.updateVisible(_this11.model.floorLogos.secondLogo, 'inView360', false); //隐藏 } if (leaveView) { //从360view出来 var view = _this11.currentPano.view; view.exitDoor.mesh.visible = false; //console.log("exitDoor.mesh.fade "+this.currentPano.view.sid) if (o.flyOut) { if (o.toMode == 'dollhouse') { //相机方向与着balloon到circle一致 var dir = new THREE.Vector3().subVectors(view.circle.mesh.position, view.balloon.mesh.position).setY(0).normalize(); _this11.cameraControls.controls.dollhouse.target.copy(view.circle.mesh.position); _this11.cameraControls.cameras.dollhouse.position.copy(view.balloon.mesh.position).add(new THREE.Vector3(0, 4, 0)).add(dir.multiplyScalar(-10)); _this11.cameraControls.controls.dollhouse.update(0); } view.balloon.visible = false; //因为在beforeChangeMode里 setTimeout(function () { view.balloon.visible = true; }, 500); //延迟出现 } if (!enterView) { _this11.viewLinkManager.updateCirclesWhenFade('leave', o); _this11.viewLinkManager.changeTitlesShow(true, 'enterView360'); _this11.$app.Camera.monitor.changeTitlesShow(true, 'enterView360'); //this.tagManager.hideShowTagsForBlackoutStyle(BlackoutStyle.FADEIN, transitionTime) //热点出现 } if (o.aim && !o.flyIn && !o.flyOut) { //出来是漫游模式 _this11.cameraControls.controls.panorama.lookAt(o.aim); _this11.cameraControls.controls.panorama.update(0); } _this11.OverlayManager.setGroupVisible(true); _this11.GLTFEditor.group.visible = true; // 显示空间模型 _this11.cameraControls.controls.panorama.insideLookLimitUp = null; _this11.cameraControls.controls.panorama.insideLookLimitDown = null; _this11.cameraControls.controls.panorama.limitAngleIsBound = true; common.updateVisible(_this11.model.floorLogos.firstLogo, 'inView360', true); common.updateVisible(_this11.model.floorLogos.secondLogo, 'inView360', true); } if (o.pano) { _this11.emit(PlayerEvents.PanoChosen, _this11.currentPano, o.pano); //触发 setProjectedPanos _this11.model.chunks.concat([_this11.model.skybox]).forEach(function (mesh) { mesh.material.uniforms.progress.value = 1; }); //地标变化(在这里不需要显示) _this11.model.floorLogos.changefloorLogoOpa({ index: 0, opa: 0, dur: 0, delay: 0 }); //this.model.floorLogoFade(0, _duration*0.5, 0.7); _this11.model.floorLogos.secondLogo.position.copy(o.pano.floorPosition.clone().sub(_this11.model.position)); enterView || common.updateVisible(_this11.model.floorLogos.secondLogo, 'flyToPano', true); enterView || _this11.model.floorLogos.changefloorLogoOpa({ index: 1, opa: 1, dur: 250 }); } transitions$1.start(lerp.property(_this11.domElement.style, 'opacity', 1), transitionTime, function () { _this11.enteringView = null; fuc && fuc(); //this.model.wallManager.updateRulersVisi(); _this11.reticule.hide(); //隐藏. 如果是离开 会自动updatePosition()后显示 if (enterView) { _this11.emit('enteredView'); } else _this11.emit('leavedView'); }, 0, null /* easing[settings.flydown.movementEasing] */ , null, 'fade360'); }, 0, null /* easing[settings.flydown.movementEasing] */ , null, 'fade360'); }; _this.flyToPanoClosestToMouse = function () { if (Date.now() - this.mouseLastMoveTime > 50) { /* this.intersect = this.getMouseIntersect() this.intersect && this.updateClosestPano(this.intersect) */ this.updateIntersect(); //这个才准确 } if (this.closestPano) { return this.flyToPano({ pano: this.closestPano, checkAlone: true }); } var direction = this.getMouseDirection(); if (!this.flyDirection(direction)) { this.flyToPano({ pano: this.currentPano }); } }; _this.flyLocalDirection = function (playerDirection) { if (this.panosTaskList.length > 1 || this.panosTaskList.length == 1 && this.panosTaskList[0].progress < 0.3) { //比0.5少一点,因0.5时会判断个数 //按键行走。在当前任务执行超过一定比率后才允许添加下一个任务 return; } var direction = this.getDirection(playerDirection), playerDirectionZ = 1 === playerDirection.z ? 0.4 : 0.75, playerDirectionX = 1 === Math.abs(playerDirection.x); return this.flyDirection(direction, playerDirectionZ, playerDirectionX, true); }; _this.flyDirection = function (direction, playerDirectionZ, playerDirectionX, byKey) { if (this.locked) return; var deferred = Deferred$1(); this.history.invalidate(); var panoSet = this.closestPanoInDirection(direction, playerDirectionZ, playerDirectionX); if (panoSet) { this.flyToPano({ pano: panoSet, canConstantlyWalk: this.canConstantlyWalk, // add byKey }, deferred.resolve.bind(deferred, !0)); } else if (this.panosTaskList.length == 0) { this.bump(direction); deferred.resolve(!1); } return deferred.promise(); }; _this.closestPanoInDirection = function (direction, playerDirectionZ, playerDirectionX) { return this.rankedPanoInDirection(0, direction, playerDirectionZ, playerDirectionX); }; _this.rankedPanoInDirection = function () { var panoSet = { pano: null, candidates: [] }; return function (t, direction, PlayerDirectionZ, PlayerDirectionX) { t || (t = 0); PlayerDirectionZ = void 0 !== PlayerDirectionZ ? PlayerDirectionZ : 0.75; var o = PlayerDirectionX ? 'angle' : 'direction'; //add 相对于即将达到的目标点 或当前点 var currentPano = this.panosTaskList.length ? this.panosTaskList[this.panosTaskList.length - 1].pano : this.currentPano; var request = [//必要条件 Panorama.filters.not(currentPano), Panorama.filters.isPanoAligned(), Panorama.filters.isNeighbourPanoTo(currentPano), Panorama.filters.inPanoDirection(currentPano.position, direction, PlayerDirectionZ)]; var list = [//决胜项目 Panorama.scoreFunctions.distanceSquared(currentPano), Panorama.scoreFunctions[o](currentPano.position, direction)]; /* if (editSpot.setSpotPos){ if(editSpot.editType == "tag" || editSpot.editType == "measure"){ request.push(function(pano){ return pano.assistPano != editSpot.spotPosInfo.panoB && pano != editSpot.spotPosInfo.panoB;//不允许走回到和右侧相同的位置 }) }else if(editSpot.editType == "designWall"){ request.push(function(pano){ return pano != editSpot.spotPosInfo.panoB//不允许走回到和右侧相同的位置 }) } } */ //performance.mark('rankedPano-start') this.model.panos.findRankedByScore(t, request, list, panoSet); /* performance.mark('rankedPano-end') let measure = performance.measure('rankedPano','rankedPano-start','rankedPano-end'); console.log('rankedPano', measure.duration.toFixed(4)) */ this.cachedPanoCandidates = panoSet.candidates; return panoSet.pano; }; }(); _this.bump = function (direction) { var _this12 = this; if (this.mode === Viewmode$1.PANORAMA && !this.flying && !this.isWarping()) { var t, i, n, r = settings$3.transition, o = (r.flytimeMaxDistanceThreshold * r.flytimeDistanceMultiplier + r.flyTime) / 10, a = this.camera.getWorldDirection(new THREE.Vector3()).dot(direction), s = Math.abs(a) > 0.5; if (s) t = function () { transitions$1.start(lerp.property(this.cameraControls.cameras[Viewmode$1.PANORAMA], 'zoom', a > 0 ? 1.04 : 0.96), o, i, 0, easing.easeInOutSine, 'bumpZStart'); }.bind(this), i = function () { transitions$1.start(lerp.property(this.cameraControls.cameras[Viewmode$1.PANORAMA], 'zoom', 1), 3 * o, n, 0, easing.easeInOutSine, 'bumpZRelax'); }.bind(this);else { var l = this.camera.position.clone(), c = direction.clone(); this.raycaster.set(l, c); var h = this.model.floors.reduce(function (e, t) { return e.concat(t.collider.children); }, []), d = this.raycaster.intersectObjects(h), p = d.length > 0 ? d[0].distance / 25 : 0.04, g = l.clone().add(c.multiplyScalar(p)); t = function () { transitions$1.start(lerp.vector(this.cameraControls.cameras[Viewmode$1.PANORAMA].position, g), o, i, 0, easing.easeInOutSine, 'bumpTStart'); }.bind(this), i = function () { transitions$1.start(lerp.vector(this.cameraControls.cameras[Viewmode$1.PANORAMA].position, l), 5 * o, n, 0, easing.easeInOutSine, 'bumpTRelax'); }.bind(this); } n = function n() { if (_this12.mode == 'panorama') { //add _this12.flying = !1; _this12.emit(PlayerEvents.FlyingEnded, { /* targetPosition: this.position, currentPosition: this.position, */ targetPano: _this12.currentPano, currentPano: _this12.currentPano }); //add } /* if (this.waitFlytoItemFuc) { //手动加的函数 var cf = this.waitFlytoItemFuc; this.waitFlytoItemFuc = null;//因为可能在执行afterCModeFuc时需要再添加afterCModeFuc所以要置空的话提前 cf(); } //直接使用 player.once('flying.ended',()=>{ }) */ }; this.flying = !0, t(); } }; _this.changeFloor = function (e) { if (!this.is360View(this.mode, this.currentPano)) { if (this.mode === Viewmode$1.PANORAMA) { var t = this.history.reversePano(e); if (t) { this.flyToPano({ pano: t }); } else { var pano = this.getFloorPanoByScore(e); if (pano) { this.cachedPanoCandidates = e.candidates; this.history.push(t, this.currentPano); this.flyToPano({ pano }); } } // t && t.isAligned() ? this.flyToPano({ // pano: t // }) : this.changeFloorByScore(e) } else { this.model.setFloor(this.model.nextFloor(e) || this.model.currentFloor); } } }; _this.getFloorPanoByScore = function () { var e = { pano: null, candidates: [] }; return function (t, floor) { var i = floor || this.model.nextFloor(t); return i ? (this.model.panos.lowestByScore([Panorama.filters.atFloor(i), Panorama.filters.isPanoAligned(), function (pano) { return pano.hasNeighbor(); }], [Panorama.scoreFunctions.distance(this.currentPano), Panorama.scoreFunctions.direction(this.position, new THREE.Vector3(0, t, 0)), Panorama.scoreFunctions.penalizeHeightDifferenceUnder(this.position, 0.5)], e), e.pano) : /* void (e.pano ? ((this.cachedPanoCandidates = e.candidates), this.history.push(t, this.currentPano), this.flyToPano({ pano: e.pano })) : logger.warn('No pano found on selected floor, not moving there.')))*/ void logger$1.debug('player.changeFloor(' + t + '): no such floor'); }; }(); _this.gotoFloor = function (e) { var t = e - this.model.currentFloor.floorIndex; this.changeFloor(t); }; _this.getDirection = function (e) { return e = e ? e : new THREE.Vector3().copy(Vectors$1.FORWARD), e.applyQuaternion(this.camera.quaternion); }; _this.flyToNewMode = function (newModeInfo, deferred) { var _this13 = this; newModeInfo = newModeInfo || {}; var mode = newModeInfo.mode, pano = newModeInfo.pano, duration = newModeInfo.duration; newModeInfo.warpDest; var callback = newModeInfo.callback; newModeInfo.force; var quaternion = newModeInfo.quaternion, target = newModeInfo.target, //add position = newModeInfo.position, //add currentScale = newModeInfo.currentScale, //add floor = newModeInfo.floor, //add fitBoundSize = newModeInfo.fitBoundSize; deferred = deferred || Deferred$1(); if (this.isWarping()) { logger$1.warn('Player.flyToNewMode() -> Cannot fly when warping'); callback && callback(!1); return deferred.reject('Cannot change mode during tour transition'); } if (this.mode === Viewmode$1.TRANSITIONING) { callback && callback(!1); return deferred.reject('Cannot change mode during mode transition'); } if (mode === this.mode) { //return callback && callback(!1), deferred.reject('Already in ' + mode + ' mode') callback && callback(!1); deferred.resolve(); return deferred; } // 进入PANORAMA, 要在下载panotiles前先清掉正在加载的3dtiles if (mode == Viewmode$1.PANORAMA && this.model._3dTilesRuntime) { this.model._3dTilesRuntime.pauseTilesetUpdate(true); this.model._3dTilesRuntime.clearLoadingTiles(); } logger$1.debug('Switching mode to ' + mode); var successCallbackFunc = function () { common.delayOneFrame(function () { this.flyToNewMode(newModeInfo, deferred); }.bind(this)); }.bind(this); if (pano && this.checkAndWaitForPanoLoad(pano, 'low', 'low', this.basePanoSize, successCallbackFunc)) { //'low', 'low' return deferred.promise(); } if (!this.model.mesh3dTilesLoaded && !this.model.meshTexturesLoaded && this.isOutsideMode(mode)) { logger$1.info('Waiting for model 3dTiles or damTextures to be loaded before going out to dollhouse'); this.model.waitForLoad(this.model, function () { return false; }.bind(this)); successCallbackFunc(); return deferred.promise(); } this.history.invalidate(); //this.updateLastView(); var currentMode = this.mode; var currentCamera = this.cameraControls.cameras[mode]; var switchingParams = common.deepExtend({}, settings$3[mode], settings$3[currentMode + '-' + mode]); //许钟文------------ this.modeTran = this.mode + '-' + mode; //------------------ var transitionTime = switchingParams.transitionTime; if (void 0 !== duration) { transitionTime = duration; } this.emit(PlayerEvents.ModeChanging, currentMode, mode, pano, transitionTime); pano && (this.currentPano = pano); transitions$1.cancelById(settings$3.freeze.LookTransition); transitions$1.cancelById(this.$app.resource.num + settings$3.freeze.FlyToPano); if (mode === Viewmode$1.PANORAMA) { this.$app.core.get('PanoRenderer').switchPanoQuality(pano, { size: 2048 }); this.emit(PlayerEvents.PanoChosen, pano, pano); setTimeout(function () { pano.floor.enter(mode); }.bind(this), transitionTime / 2); this.path.fadeOutCpm(settings$3.path.fadeOutTime); //当前站点logo消失 } else { this.path.placeCpm(); //设置当前站点logo位置 this.path.fadeInCpm(settings$3.path.fadeInTime); //当前站点logo出现 //console.log('floor',floor) if (floor != void 0) { if (floor == 'all' && mode != Viewmode$1.FLOORPLAN) this.model.toggleAllFloors(!0); //默认floorplan没有all的可能 else if (typeof floor == 'number') { floor = this.model.floors.list[floor]; floor.enter(mode); } } else if (mode === Viewmode$1.FLOORPLAN) { this.model.currentFloor.enter(mode); } else if (mode == Viewmode$1.DOLLHOUSE) { this.model.toggleAllFloors(!0); } } this.switchCameraMode(mode, quaternion, target, position, currentScale, { fitBoundSize }); var currentPosition = new THREE.Vector3().copy(this.position); var currentPano = this.currentPano, playerPosition = this.position.clone(); this.emit(PlayerEvents.FlyingStarted, { mode: newModeInfo.mode, duration: newModeInfo.duration, target: newModeInfo.target, position: newModeInfo.position, quaternion: newModeInfo.quaternion ? new THREE.Quaternion().set(newModeInfo.quaternion._x, newModeInfo.quaternion._y, newModeInfo.quaternion._z, newModeInfo.quaternion._w) : null, zoom: newModeInfo.zoom, panoId: newModeInfo.pano ? newModeInfo.pano.id : null, lastPanoId: currentPano && currentPano.id, type: 'flyToNewMode' }); this.flying = !0; var startChange = function startChange() { //360全景: if (_this13.isOutsideMode(mode) && _this13.is360View(currentMode, currentPano)) { //飞出 switchingParams.blackoutStyle = BlackoutStyle$1.FADEIN; transitionTime = settings$3.show360Views.transitionTime; switchingParams.transitionTime = transitionTime; switchingParams.skyboxOpacity = 0; switchingParams.modelAlpha = 1; switchingParams.flyOut = true; switchingParams.toMode = mode; _this13.fade360View(currentCamera, switchingParams); } else if (_this13.isOutsideMode(currentMode) && _this13.is360View(mode, pano)) { //飞入 _this13.mode = mode; switchingParams.pano = pano; //this.currentPano switchingParams.blackoutStyle = BlackoutStyle$1.END; transitionTime = settings$3.show360Views.transitionTime; switchingParams.transitionTime = transitionTime; switchingParams.flyIn = true; _this13.fade360View(currentCamera, switchingParams, _this13.afterchangeMode); } else { //普通情况: transitions$1.start(lerp.property(_this13.model, 'alpha', switchingParams.modelAlpha, null), transitionTime * switchingParams.modelAlphaLength, null, switchingParams.modelAlphaDelay, null, settings$3.freeze.FlyToNewMode); transitions$1.start(lerp.vector(_this13.position, currentCamera.position), transitionTime, null, settings$3.flydown.movementDelay, easing[settings$3.flydown.movementEasing], null, settings$3.freeze.FlyToNewMode); transitions$1.start(lerp.quaternion(_this13.quaternion, currentCamera.quaternion), transitionTime * switchingParams.rotationDuration, null, switchingParams.rotationDelay, easing[settings$3.flydown.rotationEasing], null, settings$3.freeze.FlyToNewMode); transitions$1.start(lerp.matrix4(_this13.camera.projectionMatrix, currentCamera.projectionMatrix), transitionTime * switchingParams.cameraMatrixDuration, null, switchingParams.cameraMatrixDelay, switchingParams.cameraMatrixEase, null, settings$3.freeze.FlyToNewMode); transitions$1.start(function () { _this13.camera.projectionMatrixInverse.copy(_this13.camera.projectionMatrix).invert(); }, transitionTime * switchingParams.cameraMatrixDuration, null, switchingParams.cameraMatrixDelay, switchingParams.cameraMatrixEase, null, settings$3.freeze.FlyToNewMode); transitions$1.start(lerp.uniform(_this13.model.skybox, 'opacity', switchingParams.skyboxOpacity), transitionTime * switchingParams.skyboxOpacityLength, null, switchingParams.skyboxOpacityDelay, null, settings$3.freeze.FlyToNewMode); transitions$1.start(lerp.property(_this13.reticule.material.uniforms.opacity, 'value', 0), transitionTime, null, settings$3.freeze.FlyToNewMode); } transitions$1.setTimeout(function () { this.flying = !1; if (currentMode === Viewmode$1.PANORAMA && mode !== Viewmode$1.PANORAMA) { this.currentPano.exit(); } else if (currentMode !== Viewmode$1.PANORAMA && mode === Viewmode$1.PANORAMA) { this.currentPano !== currentPano && currentPano.exit(); this.currentPano.enter(); } currentMode === Viewmode$1.DOLLHOUSE && this.cameraControls.controls[Viewmode$1.DOLLHOUSE].resetRanges(); this.mode = mode; this.afterChangeMode(currentMode, mode); //this.emit(PlayerEvents.FlyingEnded, currentPosition, playerPosition, this.currentPano, currentPano) this.emit(PlayerEvents.FlyingEnded, { targetPosition: currentPosition, currentPosition: playerPosition, targetPano: this.currentPano, currentPano: currentPano }); callback && callback(); deferred.resolve(); }.bind(_this13), transitionTime, settings$3.freeze.FlyToNewMode); _this13.mode = Viewmode$1.TRANSITIONING; }; if (this.mode == 'panorama' && !(this.isOutsideMode(mode) && this.is360View(currentMode, currentPano))) { this.$app.core.get('SceneRenderer').once(SceneRendererEvents.AfterRender, function () { //console.log('等待时间', Date.now() - startTime) startChange(); //300block 的需要近1秒才能飞出,最好加个提示 如KJ-t-ThxGwmC91Z0 }); } else { startChange(); } /* ----若要显示loading条换这块代码 一点点变换modelAlpha let startIndex = 0, curCount, maxUpdateBlock = 100, len=this.model.chunks.length let startTime = Date.now() let update = { update:()=>{ curCount = 0 for(let i=startIndex; i maxUpdateBlock)return } console.log('cost', Date.now()-startTime) this.$app.core.get('SceneRenderer').removeComponent(update) startChange() } } this.$app.core.get('SceneRenderer').addComponent(update) */ this.beforeChangeMode(currentMode, mode, pano, transitionTime); return deferred.promise(); }; _this.setSize = function (width, height) { var aspect = width / height; this.baseFov = cameraLight.clampVFOV(settings$3.insideFOV, settings$3.insideFOVMax, width, height); var fov = cameraLight.getHFOVFromVFOV(settings$3.insideFOV, width, height); if (fov > settings$3.insideFOVMax) { this.baseFov = cameraLight.getVFOVFromHFOV(settings$3.insideFOVMax, width, height); } else { this.baseFov = settings$3.insideFOV; } for (var cameraType in this.cameraControls.cameras) { var camera = this.cameraControls.cameras[cameraType]; camera.fov = camera.staticFov ? camera.staticFov : this.baseFov * (1 / this.zoomLevel); //许钟文 加camera.staticFov camera.updateAspect(aspect); } this.emit('setSize', width, height); }; _this.toJSON = function () { var e = {}; if (this.cameraControls.activeControl) { e = this.cameraControls.activeControl.toJSON(); e.camera_mode = Viewmode$1.toInt(this.mode); if (this.isOutsideMode()) { if (this.model.allFloorsVisible) { e.floor_visibility = []; } else { e.floor_visibility = this.model.floors.list.map(function (e) { return e.hidden ? 0 : 1; }); } } else if (Viewmode$1.PANORAMA) { e.scan_id = this.currentPano.id; } // this.isOutsideMode() ? this.model.allFloorsVisible ? e.floor_visibility = [] : e.floor_visibility = this.model.floors.list.map(function(e) { // return e.hidden ? 0 : 1 // }) : Viewmode.PANORAMA && (e.scan_id = this.currentPano.id); return e; } else { return e; } // return this.cameraControls.activeControl ? (e = this.cameraControls.activeControl.toJSON(), // e.camera_mode = Viewmode.toInt(this.mode), // this.isOutsideMode() ? this.model.allFloorsVisible ? e.floor_visibility = [] : e.floor_visibility = this.model.floors.list.map(function(e) { // return e.hidden ? 0 : 1 // }) : Viewmode.PANORAMA && (e.scan_id = this.currentPano.id), // e) : e }; _this.zoomBy = function (e) { this.zoomTo(this.zoomLevel * e); }; _this.zoomIn = function () { this.zoomBy(1 + this.zoomSpeed); }; _this.zoomOut = function () { this.zoomBy(1 - this.zoomSpeed); }; _this.zoomTo = function (zoomLevel, flag) { if (flag || settings$3.zoom.enabled && this.mode === Viewmode$1.PANORAMA && this.zoomEnabled) { zoomLevel < settings$3.zoom.min && (zoomLevel = settings$3.zoom.min); zoomLevel > settings$3.zoom.max && (zoomLevel = settings$3.zoom.max); if (zoomLevel > this.zoomLevel) { this.emit(ZoomEvents.ZoomIn); zoomLevel === settings$3.zoom.max && this.emit(ZoomEvents.ZoomMax); } else if (zoomLevel < this.zoomLevel) { this.emit(ZoomEvents.ZoomOut); zoomLevel === settings$3.zoom.min && this.emit(ZoomEvents.ZoomMin); } if (this.cameraControls.activeControl) { var camera = this.cameraControls.activeControl.camera; this.zoomLevel = zoomLevel; camera.fov = this.baseFov * (1 / this.zoomLevel); camera.updateProjectionMatrix(); this.zoomFov = camera.fov; this.emit('zoomTo', zoomLevel); } } }; _this.zoomDefault = function () { this.zoomTo(1, !0); }; _this.smoothZoomToDefault = function (e, t) { var i, n = this.zoomLevel, r = function (e) { e > 1 && (e = 1), i = n * (1 - e) + e, this.zoomTo(i, !0); }.bind(this), o = function () { this.zoomDefault(), t && window.setTimeout(t, 50); }.bind(this); transitions$1.start(r, e, o, null, 0, easing[settings$3.transition.blendEasing]); }; _this.smoothZoomFovTo = function (fov, dur, callback) { //add var aimLevel = this.baseFov / fov; this.smoothZoomLevelTo(aimLevel, dur, callback); }; _this.smoothZoomLevelTo = function (level, dur, callback) { //add if (this.zoomLevel == level) return; var oldLevel = this.zoomLevel; var currentLevel; var fun = function (e) { e > 1 && (e = 1), currentLevel = oldLevel * (1 - e) + e * level, this.zoomTo(currentLevel, !0); }.bind(this); transitions$1.start(fun, dur, callback, null, 0, easing[settings$3.transition.blendEasing]); }; _this.updateZoomPano = function () { var _this14 = this; var qualityManager = this.$app.core.get('QualityManager'); var panoRenderer = this.$app.core.get('PanoRenderer'); var currentPano = this.currentPano; if (!panoRenderer.zoomPanoRenderingDisabled && this.mode === Viewmode$1.PANORAMA && currentPano.tiled) { //xzw add tiled if (currentPano) { var threshold4k = 1.8; var activationThreshold = qualityManager.navTileClass == '2k' && qualityManager.tileClass == '4k' ? threshold4k : settings$3.zoom.activationThreshold; //1.1 var t = settings$3.highestQualityTile || this.zoomLevel > activationThreshold, i = this.flying && this.nextPano && this.nextPano !== this.currentPano, n = !i && !this.isWarping(), r = t && n; this.$app.core.get('TileDownloader').tilePrioritizer.setZoomingActive(r); panoRenderer.setZoomingActive(r, currentPano, !0); var o = function (pano, zoomedFlag) { panoRenderer.resetRenderStatus(pano.id, !1, !0, qualityManager.getMaxNavPanoSize()); panoRenderer.clearAllQueuedUploadsForPano(pano.id); panoRenderer.renderPanoTiles(pano.id, null, !1, !1); pano.setZoomed(zoomedFlag); }.bind(this); if (r && (!currentPano.zoomed || qualityManager.zoomLevelResolution && qualityManager.zoomLevelResolution != '4k')) { currentPano.zoomed || o(currentPano, !0); if (qualityManager.navTileClass == '1k' && qualityManager.tileClass != '1k' && this.zoomLevel < 2) { panoRenderer.enableHighQuality(function () { //开启2k if (qualityManager.tileClass != '4k') o(currentPano, !0); }.bind(this)); } else { panoRenderer.enableUltraHighQualityMode(function () { //开启4k getMaxZoomPanoSize qualityManager.useUltraHighResolutionPanos && !settings$3.zoom.overridemax && (settings$3.zoom.max = settings$3.ultraHighQualityMaxZoom); o(currentPano, !0); }.bind(this)); } } else { !t && currentPano.zoomed && o(currentPano, !1); } if (r && qualityManager.navTileClass == '1k' && qualityManager.tileClass == '4k') { //目前只有手机端navTileClass == '1k' var change = function change(zoomedFlag) { qualityManager.updateMaximums(); //更新maxZoomPanoSize panoRenderer.setupZoomRenderTarget(); //更新renderTarget //currentPano.setZoomed(t);//更新uniforms贴图 if (qualityManager.zoomLevelResolution == '4k') { _this14.model.showHighMap(); } else { _this14.model.hideHighMap(); } }; qualityManager.zoomLevelResolution = this.zoomLevel >= threshold4k ? '4k' : this.zoomLevel > settings$3.zoom.activationThreshold ? '2k' : '1k'; if (this.oldZoomLevel < threshold4k && this.zoomLevel >= threshold4k) { //1k/2k-4k change(); o(currentPano, t); } else if (this.oldZoomLevel <= settings$3.zoom.activationThreshold && this.zoomLevel > settings$3.zoom.activationThreshold) { //1k-2k change(); } else if (this.oldZoomLevel > threshold4k && this.zoomLevel <= threshold4k) { //4k-2k/1k change(); o(currentPano, t); } else if (this.oldZoomLevel > settings$3.zoom.activationThreshold && this.zoomLevel <= settings$3.zoom.activationThreshold) { //2k-1k change(); } this.oldZoomLevel = this.zoomLevel; } /* if (r && !currentPano.zoomed) { o(currentPano, !0); panoRenderer.enableUltraHighQualityMode(function() {//开启4k getMaxZoomPanoSize qualityManager.useUltraHighResolutionPanos && !settings.zoom.overridemax && (settings.zoom.max = settings.ultraHighQualityMaxZoom); o(currentPano, !0) }.bind(this)); } else { !t && currentPano.zoomed && o(currentPano, !1); } */ } } }; _this.hasChanged = function (e) { if (!this.previousState) { this.previousState = { allFloorsVisible: this.model.allFloorsVisible, position: this.position.clone(), quaternion: this.quaternion.clone(), mouse: this.mouse.clone(), //labelScaleFactor: this.getLabelScaleFactor(), currentFloor: this.model.currentFloor, projectionMatrix: this.camera.projectionMatrix.clone(), worldMatrix: this.camera.matrixWorld.clone(), mode: this.mode, modelPosition: this.model.position.clone(), modelCenter: this.model.center.clone(), zoomLevel: this.zoomLevel }; e.cameraChanged = true, (e.cameraChanged2 = true, e.cameraChanged3 = true); return !0; } //许钟文改 分成相机是否改变cameraChanged 和其他 var a = this.position.equals(this.previousState.position) && this.quaternion.equals(this.previousState.quaternion) && this.camera.matrixWorld.equals(this.previousState.worldMatrix) && this.camera.projectionMatrix.equals(this.previousState.projectionMatrix) && this.mode === this.previousState.mode && this.zoomLevel === this.previousState.zoomLevel && this.model.center.equals(this.previousState.modelCenter) && this.model.position.equals(this.previousState.modelPosition); var t = a && this.mouse.equals(this.previousState.mouse) && this.model.allFloorsVisible === this.previousState.allFloorsVisible /* && this.getLabelScaleFactor() === this.previousState.labelScaleFactor */ && this.model.currentFloor === this.previousState.currentFloor && null === this.nextPano; e.cameraChanged = !a || e.cameraProjectionChanged; e.allFlVisiChanged = this.model.allFloorsVisible !== this.previousState.allFloorsVisible, e.moved = !this.position.equals(this.previousState.position), e.rotated = !this.quaternion.equals(this.previousState.quaternion), e.mouseMoved = !this.mouse.equals(this.previousState.mouse), e.floorChanged = this.model.currentFloor !== this.previousState.currentFloor, e.cameraProjectionChanged = !this.camera.projectionMatrix.equals(this.previousState.projectionMatrix), e.cameraWorldMatrixChanged = !this.camera.matrixWorld.equals(this.previousState.worldMatrix), e.modeChanged = this.mode !== this.previousState.mode, e.modelPositionChanged = !this.model.position.equals(this.previousState.modelPosition), e.modelCenterChanged = !this.model.center.equals(this.previousState.modelCenter), e.nextPanoActive = null !== this.nextPano, e.zoomLevel = this.zoomLevel !== this.previousState.zoomLevel; if (!t) { //主要判断相机是否旋转 e.cameraChanged2 = e.cameraProjectionChanged || !MathLight.closeTo(this.quaternion, this.previousState.quaternion, 5) || !MathLight.closeTo(this.position, this.previousState.position, 4); e.cameraChanged3 = e.cameraProjectionChanged || !MathLight.closeTo(this.quaternion, this.previousState.quaternion, 3) || !MathLight.closeTo(this.position, this.previousState.position, 3); } else { e.cameraChanged2 = false; e.cameraChanged3 = false; } this.previousState.allFloorsVisible = this.model.allFloorsVisible, this.previousState.position.copy(this.position), this.previousState.quaternion.copy(this.quaternion), this.previousState.mouse.copy(this.mouse), this.previousState.currentFloor = this.model.currentFloor, this.previousState.projectionMatrix.copy(this.camera.projectionMatrix), this.previousState.worldMatrix.copy(this.camera.matrixWorld), this.previousState.mode = this.mode, this.previousState.modelPosition.copy(this.model.position), this.previousState.modelCenter.copy(this.model.center), this.previousState.zoomLevel = this.zoomLevel; //console.log('cameraChanged3 ' + e.cameraChanged3 + ', mouseMoved ' + e.mouseMoved) return !t; }; _this.getToMode = function () { return this.modeTran.split('-')[1]; }; _this.flyToMode = function (mode, f1, duration) { var _this15 = this; if (this.mode == mode) { f1 && f1(); } else { if (this.mode == 'transitioning') { //先飞完然后再执行一遍 this.once(PlayerEvents.FlyingEnded, function () { _this15.flyToMode(mode, f1, duration); }); } else { f1 && this.once(PlayerEvents.FlyingEnded, function () { f1(); }); try { //在场景刚开始加载 control还没建好时这句可能会报错所以用try。 不用callback而用 afterCModeFuc也是这个原因,因为会有别的函数可以飞入然后执行它 this.flyToNewMode({ mode: mode, pano: mode == 'panorama' && this.currentPano, duration: duration }); } catch (e) { console.log('flyToMode遇到问题?', e); } } } }; _this.vrModeChange = function () { if (settings$3.vrEnabled) { //关闭 settings$3.vrEnabled = false; /* if (!window.VRScreenNotFull) { browser.exitFullscreen() } */ } else { //开启: settings$3.vrEnabled = true; /* if (!window.VRScreenNotFull) { browser.requestFullscreen(document.body) } */ } }; _this.focusPoint = function () { var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; console.log('focusPoint'); if (this.mode == 'floorplan') { var modelSize = o.modelSize || new THREE.Vector3(5, 5, 5); //可视范围 var control = this.cameraControls.controls.floorplan; var absoluteScale = control.getDefaultAbsoluteScale(modelSize); var currentScale = control.absoluteScale; var currentTarget = control.target.clone(); var lowest = this.model.boundingBox.max.y + constants$4.orthoNear + constants$4.planeHeightShift + 1; var aim = o.aim.clone().setY(lowest); transitions$1.cancelById(settings$3.freeze.outsideFocus, true); transitions$1.start(function (progress) { control.absoluteScale = absoluteScale * progress + currentScale * (1 - progress); control.target = aim.clone().multiplyScalar(progress).add(currentTarget.clone().multiplyScalar(1 - progress)); control.camera.position.copy(control.target.clone().add(control.offset)); //维持角度 }.bind(this), o.dur || 600, null /* cancelFuc */ , 0, easing[settings$3.transition.blendEasing], 'outsideFocus', settings$3.freeze.outsideFocus, null /* cancelFuc */ ); } else if (this.mode == 'dollhouse') { var control = this.cameraControls.controls.dollhouse; var radius = o.radius || 10; var currentTarget = control.target.clone(); var dir = control.offset.clone().normalize(); var currentRadius = control.offset.length(); transitions$1.cancelById(settings$3.freeze.outsideFocus, true); transitions$1.start(function (progress) { control.target = o.aim.clone().multiplyScalar(progress).add(currentTarget.clone().multiplyScalar(1 - progress)); var radius_ = radius * progress + currentRadius * (1 - progress); control.camera.position.copy(control.target.clone().add(dir.clone().multiplyScalar(radius_))); }.bind(this), o.dur || 600, null /* cancelFuc */ , 0, easing[settings$3.transition.blendEasing], 'outsideFocus', settings$3.freeze.outsideFocus, null /* cancelFuc */ ); } }; _this.getSnapAngleInfo = function () { //得到截图的位置和视角 var info = { metadata: {} }; var q = this.camera.quaternion.clone(); switch (this.mode) { case 'panorama': info.metadata.scan_id = this.currentPano.id; break; case 'floorplan': var _this$getSize = this.getSize(), clientWidth = _this$getSize.clientWidth, clientHeight = _this$getSize.clientHeight; q = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(90)); q.multiply(this.camera.quaternion); info.metadata.camera_mode = 1; info.metadata.ortho_zoom = math$1.toPrecision(this.cameraControls.activeControl.currentScale / (clientWidth / clientHeight), 4); break; case 'dollhouse': info.metadata.camera_mode = 2; break; } info.metadata.camera_position = this.camera.position.clone(); info.metadata.camera_quaternion = q; info.metadata.lon = this.cameraControls.activeControl.lon; //兼容旧版 info.metadata.lat = this.cameraControls.activeControl.lat; info.sid = '4dkk' + new Date().getTime(); info.name = ''; info.mode = this.mode; //暂时需要用到 return info; }; _this.model = new Model(_this.$app); _this.currentPano = null; _this.nextPano = null; _this.camera = null; _this.paused = !1; _this.flying = !1; _this.sceneIntersectionPlane = null; _this.target = new THREE.Vector3(); _this.mouse = new THREE.Vector3(1.1, 1.1, 0.5); _this.mouseAtMouseDown = new THREE.Vector2(); _this.mouseCouldBeClickToMove = !1; _this.mouseLastMoveTime = Date.now(); _this.mouseDown = !1; _this.mouseDownTimer = null; _this.couldBeLongTap = !1; _this.containsMouse = !1; //!0 //xzw改为false,否则触屏一直是true _this.isTouchEvent = !1; _this.isPanoHover = !1; _this.reticule = new Reticule(_assertThisInitialized(_this)); _this.panoMarkers = []; //this.spider = new NSpider(this); _this.quaternion = new THREE.Quaternion(); _this.position = new THREE.Vector3(15, 10, 15); _this.previousState = null; _this.lastInsideView = new View(); _this.last360View = new View(); _this.raycaster = new THREE.Raycaster(); _this.raycaster.params.Line.threshold = 0.01; _this.raycaster.layers.enable(RenderLayers.PANOMARKERS); _this.intersect = null; _this.lastChangeTime = Date.now(); _this.history = new History(); _this.cameraControls = null; //this.path = null, _this.domElement = null; _this.cachedPanoCandidates = null; _this.basePanoSize = 0; _this.standardPanoSize = 0; _this.highPanoSize = 0; _this.ultraHighPanoSize = 0; _this.zoomLevel = 1; _this.zooming = 0; _this.zoomSpeed = 0.5; _this.scrollZoomSpeed = 0.06; _this.zoomSpeedAdjust = 0.05; _this.defaultZoomIncrement = 0.2; _this.baseFov = settings$3.insideFOV; _this.zoomFov = _this.baseFov; _this.zoomEnabled = !0; _this.measureRulers = []; //测距 _this.cornerRulers = []; //标尺 _this.planLabels = []; //floorplan时的label _this.dollLabels = []; //dollhouse时的label _this.doorLabels = []; _this.defaultRoomLabels = []; //非编辑墙时的 _this.polygonmarkLabels = []; //多边形标记模块label _this.modeTran = ''; _this.preRenderingEnabled = !1; _this.setupCustomProperties(Viewmode$1.PANORAMA); _this.zoomStats = new ZoomStats(); _this.lastFrameChanged = true; /* this.afterCModeFuc = { //Flytonewmode后需要执行的 unique: null, //唯一的,新的会替代旧的,适用于只允许选择其中一项执行的函数 multi: [], //可多个, 到时候都执行 } */ _this.cameraControls = _this.$app.core.get('CameraControls'); _this.modelManager = _this.$app.core.get('ModelManager'); //this.imagePanos = this.listImagePanos() //是否开启(键盘上1,2,3分别对应飞入,飞出dollhouse,飞出floorplan) _this.started = false; //xst _this._locked = false; _this._flying = false; _this.clearPanosTaskList(); //持续行走的任务 _this.setPanoTaskEnable(true); _this.viewLinkManager = new ViewLinkManager(_this.$app, _assertThisInitialized(_this)); _this.paintEditor = new Paint$1(_this.$app, _assertThisInitialized(_this)); _this.modelSideManager = new ModelSideManager(_assertThisInitialized(_this)); //this.createIntersectLabel() return _this; } _createClass(Player, [{ key: "init", value: function init() { this.domElement = this.$app.dom.querySelector('.player'); this.camera = this.$app.core.get('SceneRenderer').camera; this.path = new ShowPath(this.director, this, this.cameraControls); this.basePanoSize = this.$app.core.get('QualityManager').getPanoSize(PanoSizeClass.BASE); this.standardPanoSize = this.$app.core.get('QualityManager').getPanoSize(PanoSizeClass.STANDARD); this.highPanoSize = this.$app.core.get('QualityManager').getPanoSize(PanoSizeClass.HIGH); this.ultraHighPanoSize = this.$app.core.get('QualityManager').getPanoSize(PanoSizeClass.ULTRAHIGH); this.$app.core.get('TileDownloader').processPriorityQueue = !1; this.$app.core.get('TileDownloader').tilePrioritizer = new TilePrioritizer(this.$app.core.get('QualityManager'), this.basePanoSize, this.standardPanoSize, this.highPanoSize, this.ultraHighPanoSize); this.bindEvents(this.domElement); this.updateModel(); CursorDeal.init(this); LineMaterial.init(this.$app); this.model.createTranControl(this); } }, { key: "locked", get: function get() { return this._locked; }, set: function set(value) { // customer时marker隐藏 // let role = location.search // .replace('?', '') // .split('&') // .find(arg => arg.split('=')[0] == 'role') // role = role && role.split('=')[1] // this.model.panos.forEach(item => { // item.marker && (item.marker.visible = role == 'customer' ? false : !value) // }) this._locked = value; if (this._locked) { this.model.fadePanoMarkers(0, 0, { vrCustomer: true, hideVideoFlag: true }); } else if (!this.$app.VRScreenSYNC) { this.model.fadePanoMarkers(1, 0, { vrCustomer: true, hideVideoFlag: false }); } if (value) { this.clearPanosTaskList(); //清空 } } }, { key: "flying", get: function get() { return this._flying; }, set: function set(v) { this._flying = v; //console.log('flying',v) } }, { key: "setPanoTaskEnable", value: //canConstantlyWalk 当加入一个可以持续性行走的任务时,当前未走完的任务变为匀速,任务中最后一个还是easeOut。时间重新计算。 //若当前任务是带转向的,不允许加入可以持续性行走的任务。否则转向要更改时间麻烦。 function setPanoTaskEnable(state) { this.canConstantlyWalk = state; state || this.clearPanosTaskList(); } /* let player = __sdk.core.get('Player') player.addTourPanoTask({ panoList:[ {pano:player.model.panos.index[168], }, //quaternion:new THREE.Quaternion(), lookAtPoint:new THREE.Vector3() ], flySpeed: 0.003, }) */ //导览连续匀速漫游 }, { key: "setTourPanoTask", value: function setTourPanoTask(_ref2, fastFirstPano) { var _ref2$panoList = _ref2.panoList, panoList = _ref2$panoList === void 0 ? [] : _ref2$panoList, flySpeed = _ref2.flySpeed, callback = _ref2.callback; if (panoList.length == 0) return; this.panosTaskList.length = 0; this.addTourPanoTask({ panoList, flySpeed, callback }, fastFirstPano); //console.log('setTourPanoTask') } //导览连续匀速漫游 }, { key: "addTourPanoTask", value: function addTourPanoTask(_ref3, fastFirstPano) { var _this16 = this; var _ref3$panoList = _ref3.panoList, panoList = _ref3$panoList === void 0 ? [] : _ref3$panoList, _ref3$flySpeed = _ref3.flySpeed, flySpeed = _ref3$flySpeed === void 0 ? settings$3.transition.flySpeed : _ref3$flySpeed, callback = _ref3.callback; //panoList存储的是下一个终点 this.dontInterruptPanoTask = true; //期间不允许打扰(飞向其他点),如果要立即停止再说 var panosTaskList = panoList.map(function (e, i) { var toPano = Object.assign({ flySpeed, easeType: 'constant', gotQua: true }, e, { sid: Math.random(), dealingTask: true, callback: i == panoList.length - 1 ? function (flydone) { //到最后一个点时要执行: flydone = flydone || e.pano == _this16.currentPano; if (flydone) { _this16.dontInterruptPanoTask = false; e.callback && e.callback(); callback && callback(); //console.log('playForFlyToPano最后的点:' + e.pano.id) } } : e.callback }); var _this16$getAimToNextP = _this16.getAimToNextPano(e.pano, e.lookAtPoint, e.quaternion), aimQua = _this16$getAimToNextP.aimQua; _this16$getAimToNextP.hasVideo; //提前获取以计算时间 toPano.quaternion = aimQua; return toPano; }); //const len = this.panosTaskList.length //还是需要执行回调的,所以得注释 //len > 0 && delete this.panosTaskList[len - 1].callback console.log('addTourPanoTask', panosTaskList.map(function (e) { return [e.pano.id /* , e.flySpeed */ ]; }) + ''); if (fastFirstPano) { //非匀速到第一个点 panosTaskList[0].easeType = null; } this.panosTaskList = this.panosTaskList.concat(panosTaskList); this.flying || this.flyToPano(this.panosTaskList[0]); } }, { key: "stopTourPanoTask", value: function stopTourPanoTask() { var stopTime = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 400; if (this.panosTaskList.length) { var currentTask = this.panosTaskList[0]; if (currentTask.flyCount) { //正在执行 //迅速停止: var restDis = this.position.distanceTo(currentTask.pano.position); if (restDis > 0) { currentTask.flySpeed = Math.max(restDis / stopTime, currentTask.flySpeed || 0); currentTask.aimQua = null; //停止旋转 currentTask.forceStop = true; if (currentTask.easeFun != easing.linearTween) { currentTask.easeFun = easing.linearTween; var currentSpeed = Math.max(currentTask.currentSpeed || 0, 0.002); //避免起步过慢 currentTask.duration = restDis / currentSpeed; //初始速度和原先一致, 为了衔接。 this.startTransition(currentTask); } } } } this.clearPanosTaskList(); this.dontInterruptPanoTask = false; } }, { key: "clearPanosTaskList", value: function clearPanosTaskList() { this.panosTaskList = []; } }, { key: "computeDuration", value: function computeDuration(toPano) { var dis = this.currentPano.position.distanceTo(toPano.pano.position); var dur; if (toPano.flySpeed && toPano.easeType == 'constant') { //导览不根据距离来调速度,但需要防止转弯速度过快 dur = dis / toPano.flySpeed; } else { var maxDistance = toPano.maxDistanceOverride || settings$3.transition.flytimeMaxDistanceThreshold; dis = Math.min(dis, maxDistance); dur = dis * settings$3.transition.flytimeDistanceMultiplier + settings$3.transition.flyTime; } if (toPano.quaternion) { var rotSpeed = toPano.maxRotSpeed || settings$3.transition.maxRotSpeed; if (toPano.flySpeed && toPano.easeType == 'constant') { rotSpeed *= toPano.flySpeed / 0.002; //根据导览速度调整 } var quaOri = this.cameraControls.activeControl.camera.quaternion.clone(); var vec1 = Vectors$1.FORWARD.clone().applyQuaternion(quaOri); var vec2 = Vectors$1.FORWARD.clone().applyQuaternion(toPano.quaternion); var angle = vec1.angleTo(vec2); //不能直接用quaterniion求angleTo,因为要排除绕着Vectors.FORWARD轴转的角度。 var time = Math.pow(angle, 0.3) / rotSpeed * 1e3; // for videoPano、导览、热点等 //console.log('最小旋转时间', time) dur = Math.max(time, dur); if (toPano.flySpeed && toPano.easeType == 'constant') { toPano.flySpeed = dis / dur; //修改速度,以免过后一直变速 } } return dur; } /* 飞向下一个pano */ }, { key: "getSize", value: function getSize() { var _this$$app$dom$queryS = this.$app.dom.querySelector('.player[name="main"]'), clientWidth = _this$$app$dom$queryS.clientWidth, clientHeight = _this$$app$dom$queryS.clientHeight; return { clientWidth, clientHeight }; } }, { key: "beforeChangeMode", value: function beforeChangeMode(fromMode, toMode, toPano, dur) { var _this17 = this; if (fromMode == Viewmode$1.PANORAMA) { this.labelManager && this.labelManager.updateEntryVisi(true, this.model.currentFloor.floorIndex); this.chosenMeasureRuler && this.chosenMeasureRuler.showOptionLabel(false); common.updateVisible(this.model.floorLogos.firstLogo, 'outside', false); common.updateVisible(this.model.floorLogos.secondLogo, 'outside', false); this.model.skybox.material.depthTest = false; //防止飞出后遮住别的mesh xzw add this.model.skybox.material.transparent = true; this.$app.core.get('PanoRenderer').disposeIdelTargets(); //提前把不需要的dispose防止崩溃 setTimeout(function () { if (_this17.panosTaskList.length) { //如果还在flyToPano //还没到终点就飞出时的toPano、以及无缝过渡途中加载的下一个点 都要dispose var transitionsId = _this17.$app.resource.num + settings$3.freeze.FlyToPano; transitions$1.cancelById(transitionsId, true); _this17.panosTaskList.forEach(function (e) { e.pano.exit(); }); } }, 1); } else if (fromMode == Viewmode$1.FLOORPLAN) { EntryArrow.switchDepthTest(true); } else if (fromMode == Viewmode$1.DOLLHOUSE) ; if (toMode == Viewmode$1.PANORAMA) { this.model.floorLogos.firstLogo.position.copy(toPano.floorPosition.clone().sub(this.model.position)); //改 this.model.floorLogos.secondLogo.position.copy(this.model.floorLogos.firstLogo.position); //for floorIcon position //this.model.floorLogos.adjustfloorLogoHeight(); this.compass && this.compass.autoJudgeDisplay(); this.labelManager && this.labelManager.updateEntryVisi(false, this.model.currentFloor.floorIndex); } else if (toMode == Viewmode$1.FLOORPLAN) { setTimeout(EntryArrow.switchDepthTest.bind(this, false), dur * 0.5); this.labelManager && this.labelManager.setPlanLabelVisi(true, this.model.currentFloor.floorIndex); } else if (toMode == Viewmode$1.DOLLHOUSE) ; this.$app.Camera.emit('mode.beforeChange', { fromMode, toMode, floorIndex: this.model.currentFloor.floorIndex, allVisible: this.model.allFloorsVisible }); } }, { key: "afterChangeMode", value: function afterChangeMode(fromMode, toMode, toPano, dur) { if (fromMode == Viewmode$1.PANORAMA) { this.compass && this.compass.autoJudgeDisplay(); this.$app.core.get('PanoRenderer').disposeIdelTargets(); } else if (fromMode == Viewmode$1.FLOORPLAN) { this.labelManager && this.labelManager.setPlanLabelVisi(false, this.model.currentFloor.floorIndex); } else if (fromMode == Viewmode$1.DOLLHOUSE) ; if (toMode == Viewmode$1.PANORAMA) { common.updateVisible(this.model.floorLogos.firstLogo, 'outside', true); common.updateVisible(this.model.floorLogos.secondLogo, 'outside', true); this.model.floorLogos.changefloorLogoOpa({ index: 0, from: 0, opa: 1, dur: 150 }); //this.model.floorLogoShow(0,150); this.doorLabels.forEach(function (label) { return label.updateVisible(); }); this.model.skybox.material.depthTest = true; //防止飞出后遮住别的mesh的恢复 xzw add this.model.skybox.material.transparent = false; //透明时vr模式某些角度圆圈看不见; this.model.showLowestTile(true); /* this.model.chunks.forEach(chunk=>{//4.6.0 xzw common.updateVisible(chunk,'atPano',false) //在漫游点处隐藏chunk///无法隐藏模型,因为需要遮挡其他物体。虽然考虑过使用copyCubeMap渲染深度图,但没准这样也耗gpu。15个chunk的损耗1-2毫秒,当降4倍性能之后。 }) */ } else if (toMode == Viewmode$1.FLOORPLAN) { this.model.showLowestTile(false); } else if (toMode == Viewmode$1.DOLLHOUSE) { this.model.floors.forEach(function (floor) { floor.entryArrow.forEach(function (arrow) { return arrow.dollLabel.update(); }); //提前更新下,elem.getBoundingClientRect才有效 }); this.model.showLowestTile(false); } this.$app.Camera.emit('mode.afterChange', { fromMode, toMode, floorIndex: this.model.currentFloor.floorIndex, allVisible: this.model.allFloorsVisible }); this.clearPanosTaskList(); //清空 } /** * 获取截图位置和视角 * @returns */ }, { key: "setAnimateMakerPano", value: //xst,获得需要带动画marker的pano function setAnimateMakerPano() { var _this18 = this; if (!this.currentPano) { return; } var pano; if (this.mode === Viewmode$1.PANORAMA && !this.flying && !this.enteringView && this.currentPano.isAligned()) { var filterFuncs = [Panorama.filters.isPanoAligned()]; var direction = this.getDirection(); filterFuncs.push(Panorama.filters.not(this.currentPano)); filterFuncs.push(Panorama.filters.isNeighbourPanoTo(this.currentPano)); //filterFuncs.push(Panorama.filters.inFloorDirection_2d(this.currentPano.floorPosition, direction, 0.7)) filterFuncs.push(Panorama.filters.inFloorDirection(this.currentPano.position, direction, 0.707)); //45度范围内 filterFuncs.push(Panorama.filters.isClampDisSquaredTo(this.currentPano.floorPosition, 0.5, 16)); /* const pano = this.model.panos.find(filterFuncs, [ Panorama.sortFunctions.floorDistanceToPoint(this.currentPano.floorPosition), ]) */ var sorts = common.sortByScore(this.model.panos.list, filterFuncs, [Panorama.scoreFunctions.distanceSquared(this.currentPano, -0.6), Panorama.scoreFunctions.directionFloor(this.currentPano.position, direction)]); if (sorts.length > 1) { //最后计算下保证 尽量选择在屏幕范围内的 var p = sorts.slice(0, 4).find(function (e) { //最多只计算头几个,多了会卡 var r = convertTool.getPos2d(e.item.floorPosition, _this18); return r.inSight; }); if (p) { pano = p.item; } } if (!pano) { pano = sorts[0] && sorts[0].item; } } if (pano && pano.id != this.model.panos.animatePanoId) { this.model.panos.animatePanoId != void 0 && this.model.panos.get(this.model.panos.animatePanoId).updateMakerStyle(); pano.updateMakerStyle('animate'); this.model.panos.animatePanoId = pano.id; } else if (!pano && this.model.panos.animatePanoId != void 0) { this.model.panos.get(this.model.panos.animatePanoId).updateMakerStyle(); this.model.panos.animatePanoId = null; } } }, { key: "createIntersectLabel", value: function createIntersectLabel() { this.intersectLabel = new TextSprite({ text: 'intersectLabel', textColor: { r: 255, g: 255, b: 255, a: 1 }, backgroundColor: { r: 0, g: 0, b: 0, a: 0.1 }, borderColor: { r: 255, g: 255, b: 255, a: 1 }, //textBorderColor: { r: bgcolor.r * 255, g: bgcolor.g * 255, b: bgcolor.b * 250, a: a || 0.9 }, //textBorderThick: 2, margin: { x: 10, y: 10 }, borderRadius: 10, rectBorderThick: 2, player: this, sizeInfo: { width2d: 180 }, fontsize: 25 }); this.intersectLabel.sprite.position.set(0, 2, 0); this.model.add(this.intersectLabel); } }]); return Player; }(EventEmitter); }); defineComponent('QualityManager', function () { return /*#__PURE__*/function () { function QualityManager(e, t, i) { _classCallCheck(this, QualityManager); this.maxNavPanoSize = -1; this.maxZoomPanoSize = -1; this.devicePixelDensity = e; this.deviceScreenSize = t; this.clientBandwidth = i; this.panoSizeClassMap = {}; this.useHighResolutionPanos = !0; this.useUltraHighResolutionPanos = !1; this.modelHasUltraHighPanos = !1; this.maxRenderTargetSize = config$4.mobile ? 2048 : 4096; //add } _createClass(QualityManager, [{ key: "init", value: function init() { this.buildPanoSizeClassMap(this.devicePixelDensity, this.deviceScreenSize, this.clientBandwidth); this.ultraHighSize = this.getPanoSize(PanoSizeClass.ULTRAHIGH); this.highSize = this.getPanoSize(PanoSizeClass.HIGH); this.standardSize = this.getPanoSize(PanoSizeClass.STANDARD); this.baseSize = this.getPanoSize(PanoSizeClass.BASE); if (settings$3.tiling.maxZoomPanoQuality && this.ultraHighSize <= settings$3.tiling.maxZoomPanoQuality) { settings$3.tiling.allowUltraHighResolution = !0; } this.highQualityThreshold = browser$1.valueFromHash('threshold2k', constants$4.windowHeightHighQualityThreshold); this.updateMaximums(); this.$app.core.get('ModelManager').on(ModelManagerEvents.ActiveModelChanged, this.onModelChanged.bind(this)); var metadata = this.$app.store.getValue('metadata'); var resolution = metadata.sceneResolution || '2k'; if (resolution.indexOf('/') != -1) { this.tileClass = resolution.split('/')[1]; } else { this.tileClass = resolution; } this.navTileClass = '2k'; if (this.tileClass == '1k') { this.navTileClass = '1k'; this.useHighResolutionPanos = false; // 只加载1k } if (browser$1.urlHasValue('1k')) { this.navTileClass = '1k'; } this.limitQuality = true; //this.navTileClass = '1k' } }, { key: "updateFromModel", value: function updateFromModel(e) { this.updateUltraHighResolutionSettings(e); } }, { key: "updateHighResolutionSettings", value: function updateHighResolutionSettings(e) { showcase.modelDataPromisesTiles(e.data) ? this.useHighResolutionPanos = !0 : this.useHighResolutionPanos = !1, this.updateMaximums(); } }, { key: "updateUltraHighResolutionSettings", value: function updateUltraHighResolutionSettings(e) { if (settings$3.tiling.allowUltraHighResolution && this.modelHasUltraHighPanos) { this.useUltraHighResolutionPanos = !0; } else { this.useUltraHighResolutionPanos = !1; } this.updateMaximums(); } }, { key: "enableUltraHighQualityMode", value: function enableUltraHighQualityMode() { this.modelHasUltraHighPanos = !0; this.updateUltraHighResolutionSettings(null); } }, { key: "ultraHighQualityModeEnabled", value: function ultraHighQualityModeEnabled() { return this.modelHasUltraHighPanos; } }, { key: "onModelChanged", value: function onModelChanged(e) { this.updateFromModel(e.model), this.updateMaximums(); } }, { key: "updateMaximums", value: function updateMaximums() { this.maxNavPanoSize = settings$3.tiling.maxNavPanoQuality || this.detectMaxNavPanoSize(); this.maxZoomPanoSize = settings$3.tiling.maxZoomPanoQuality || this.detectMaxZoomPanoSize(); this.maxZoomPanoSize < this.maxNavPanoSize && (this.maxNavPanoSize = this.maxZoomPanoSize); } }, { key: "buildPanoSizeClassMap", value: function buildPanoSizeClassMap() { this.panoSizeClassMap[PanoSizeClass.BASE] = 512; this.panoSizeClassMap[PanoSizeClass.STANDARD] = 1024; this.panoSizeClassMap[PanoSizeClass.HIGH] = 2048; this.panoSizeClassMap[PanoSizeClass.ULTRAHIGH] = 4096; } }, { key: "getPanoSize", value: function getPanoSize(e) { return this.panoSizeClassMap[e]; } }, { key: "getMaxPossiblePanoSize", value: function getMaxPossiblePanoSize() { return this.getPanoSize(PanoSizeClass.ULTRAHIGH); } }, { key: "getMaxPanoSize", value: function getMaxPanoSize() { return this.maxZoomPanoSize; } }, { key: "getMaxNavPanoSize", value: function getMaxNavPanoSize() { return this.maxNavPanoSize; } }, { key: "getMaxZoomPanoSize", value: function getMaxZoomPanoSize() { return this.maxZoomPanoSize; } }, { key: "detectMaxNavPanoSizeClass", value: function detectMaxNavPanoSizeClass() { /* return this.useHighResolutionPanos ? browser.isMobile() ? PanoSizeClass.STANDARD : window.innerHeight < this.highQualityThreshold ? PanoSizeClass.STANDARD : PanoSizeClass.HIGH : PanoSizeClass.STANDARD */ switch (this.navTileClass) { case '1k': return PanoSizeClass.STANDARD; case '512': return PanoSizeClass.BASE; case '2k': default: return PanoSizeClass.HIGH; } } }, { key: "detectMaxNavPanoSize", value: function detectMaxNavPanoSize() { var e = this.detectMaxNavPanoSizeClass(); return this.getPanoSize(e); } }, { key: "detectMaxZoomPanoSize", value: function detectMaxZoomPanoSize() { if (this.zoomLevelResolution) { if (this.zoomLevelResolution == '4k' && this.useUltraHighResolutionPanos) { return this.getPanoSize(PanoSizeClass.ULTRAHIGH); } else if (this.zoomLevelResolution == '1k' || !this.useHighResolutionPanos) { return this.getPanoSize(PanoSizeClass.STANDARD); } else { return this.getPanoSize(PanoSizeClass.HIGH); } } else { if (this.useHighResolutionPanos) { /* if (browser.isMobile()) {//手机版如果要2k的将这里去掉 if (settings.tiling.mobileHighQualityOverride) { return this.getPanoSize(PanoSizeClass.HIGH); } else { return this.getPanoSize(PanoSizeClass.STANDARD); } } else */ if (this.useUltraHighResolutionPanos) { return this.getPanoSize(PanoSizeClass.ULTRAHIGH); } else { return this.getPanoSize(PanoSizeClass.HIGH); } } else { return this.getPanoSize(PanoSizeClass.STANDARD); } } } }]); return QualityManager; }(); }); var panorama = {}; panorama.getCubemapUrls = function (e, t, i) { var a = [0, 1, 2, 3, 4, 5]; return a.map(function (n, o) { return e.get('pan/' + i + '/' + t + '_skybox' + r(n) + '.jpg'); }.bind(this)); }; panorama.mapFaceToCubemapFace = function (e) { var s = { 0: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 2: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 3: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 4: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 5: GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y }; return s[e]; }; var TileDownloaderEvents = { TileDownloadSuccess: 'tiledownloader.download.success', TileDownloadFailure: 'tiledownloader.download.failure', PanoDownloadComplete: 'tiledownloader.pano.download.complete' }; function _createSuper$10(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$10(); 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 _isNativeReflectConstruct$10() { 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; } } defineComponent('TileDownloader', function () { var _class, _temp; return _temp = _class = /*#__PURE__*/function (_EventEmitter) { _inherits(TileDownloader, _EventEmitter); var _super = _createSuper$10(TileDownloader); function TileDownloader(_e) { var _this; _classCallCheck(this, TileDownloader); _this = _super.call(this); _this.forceQueueTilesForPano = function () { var e = [], t = []; return function (i, n, r, o, a, s) { e.length = 0; for (var u = this.getTileDownloadDescriptors(i, n), d = 0; d < u.length; d++) { var p = u[d]; p.status !== DownloadStatus.None && p.status !== DownloadStatus.Queued || e.push(p); } if (r && e.length > 0) { TilePrioritizer.sortPanoTiles(e, i, r), t.length = 0, TileUtils.matchingTilesInDirection(i, n, r, o, a, t); for (var f = 0, g = function g(e) { return e.face === m.face && e.faceTileIndex === m.faceTileIndex; }; f < e.length;) { var m = e[f], v = t.findIndex(g); v < 0 ? e.splice(f, 1) : f++; } } for (var A = 0; A < e.length; A++) { this.forceQueue.push(e[A]); } this.setStatusForAllDescriptors(this.forceQueue, DownloadStatus.ForceQueued), this.clearFromQueue(this.priorityQueue, DownloadStatus.ForceQueued, !1), s && this.processQueueForDownloading(this.forceQueue, !0); }; }(); _this.cleanupActiveDownloads = function () { var e = []; return function () { e.length = 0; for (var t = 0; t < this.activeDownloads.length; t++) { var i = this.activeDownloads[t]; i.status !== DownloadStatus.Downloaded && i.status !== DownloadStatus.Failed && e.push(i); } this.activeDownloads.length = 0, this.activeDownloads.push.apply(this.activeDownloads, e); }; }(); _this.getTileUrl = function () { var e = { 256: '256', 512: '512', 1024: '1k', 2048: '2k', 4096: '4k' }, t = { face: -1, faceTileIndex: -1, tileX: -1, tileY: -1 }; return function (pano, n, r, a, panoType) { TileUtils.getTileLocation(n, a, t); var s = Math.floor(n / r), l = s * s, h = Math.floor(a / l), d = ''; 1 === settings$3.tiling.customCompression && ('_' + settings$3.tiling['q' + e[n]]); //8目 //else if (metadata.sceneScheme == 11) { //阿里云oss的规则 //let tileClass = settings.tileClass var metadata = this.$app.store.getValue('metadata'); var tileClass = metadata.sceneKind || 'tiles'; var resolution = metadata.sceneResolution || '2k'; if (resolution.indexOf('/') != -1) { var temp = resolution.split('/'); tileClass = temp[0]; resolution = temp[1]; } // let tileClass = metadata.sceneKind // let resolution = metadata.sceneResolution // let temp = resolution.split('/') // // 临时方案 // if (temp.length == 1) { // tileClass = resolution // } else { // tileClass = temp[0] // resolution = temp[1] // } // if (pano.panoType == '360view') { // if (this.$app.config.deploy === 'local' || tileClass === 'face') { // d = this.getTiles('tiles/' + i + '/' + e[n] + '_face' + h + '_' + t.tileX + '_' + t.tileY + '.jpg') // g = '?' // } else { // d = `tiles/${pano.view.resolution}/${pano.view.imgSid}` // } // } else { // if (this.$app.config.deploy === 'local' || tileClass === 'face') { // } else { // d = tileClass + '/' + resolution + '/' + pano.id // } // } if (this.$app.config.deploy === 'local' || tileClass === 'face') { if (pano.panoType == '360view') { d = 'tiles/' + pano.view.imgSid + '/' + e[n] + '_face' + h + '_' + t.tileX + '_' + t.tileY + '.jpg'; } else { d = 'tiles/' + pano.id + '/' + e[n] + '_face' + h + '_' + t.tileX + '_' + t.tileY + '.jpg'; } } else { if (pano.panoType == '360view') { d = "tiles/".concat(pano.view.resolution, "/").concat(pano.view.imgSid); } else { d = tileClass + '/' + resolution + '/' + pano.id; } d += '_skybox' + h + '.jpg?x-oss-process='; if (e[n] == '512') { d += 'image/resize,h_512'; } else { //移动端是1k,pc端是2k if (e[n] == '1k' || e[n] == '2k') { d += 'image/resize,m_lfit,w_' + n + '/crop,w_512,h_512,'; } else { d += 'image/crop,w_512,h_512,'; } if (t.tileX == 0) { d += 'x_0,'; } else { d += 'x_' + 512 * t.tileX /* - 1 */ + ','; //2022.12.12去掉了 -1, 否则https://www.4dkankan.com/spg.html?m=KJ-2HnN97rU51&lang=zh点位18的 18_skybox0 和 18_skybox3对不上 } if (t.tileY == 0) { d += 'y_0'; } else { d += 'y_' + 512 * t.tileY; /* - 1 */ } } /* 腾讯云适配 */ // d += '_skybox' + h + '.jpg?imageMogr2/' // if (e[n] == '512') { // d += 'thumbnail/512x' // } else { // if (e[n] == '1k' || e[n] == '2k') { // d += `crop/${n}x${n}/cut/512x512x${t.tileX == 0 ? 0 : 512 * t.tileX}x${t.tileY == 0 ? 0 : 512 * t.tileY}` // } else { // d += `cut/512x512x${t.tileX == 0 ? 0 : 512 * t.tileX}x${t.tileY == 0 ? 0 : 512 * t.tileY}` // } // } } if (pano.panoType == '360view') { if (!this.$app.core.get('Player').viewLinkManager.views[pano.id]) return; d = this.$app.resource.getUserImagesURL("panorama/".concat(pano.view.imgSid, "/").concat(d)); } else { d = this.getTiles(d); } return d; }; }(); _this.panos = null; _this.retryMinimumTime = 1e4; _this.urls = null; _this.panoLoadCallbacks = {}; _this.downloadDescriptors = {}; _this.priorityQueue = []; _this.forceQueue = []; _this.activeDownloads = []; _this.tilePrioritizer = null; _this.refreshInterval = null; _this.processPriorityQueue = !1; _this.concurrentDownloads = _e.concurrentDownloads || 1; _this.downloadTestResults = {}; _this.freeze = Object.freeze({ Testing: 1, Success: 2, Fail: 3 }); _this.$app = _e.$app; return _this; } _createClass(TileDownloader, [{ key: "init", value: function init() {// Todo } }, { key: "setUrls", value: function setUrls(e) { this.urls = e; } }, { key: "setPanoData", value: function setPanoData(e, t, i) { //xzw 改。不直接使用model.panos,因为要去掉其中非tiled的pano this.panos = e.clone(); this.panos.filter(function (e) { return e.tiled; }); this.imagePanos = t; //没什么用?heroLocation的 this.panoGroupId = i; } /*start() { this.refreshUpdateInterval(0) } stop() { window.cancel(this.refreshInterval) } */ }, { key: "refreshUpdateInterval", value: function refreshUpdateInterval(e) { //还未加入sceneRenderer的component时使用 e || (e = 0), this.refreshInterval = window.setTimeout(function () { var e = this.update(); e ? this.refreshUpdateInterval(TileDownloader.ACTIVE_REFRESH_DELAY) : this.refreshUpdateInterval(TileDownloader.IDLE_REFRESH_DELAY); }.bind(this), e); } //xzw 改 }, { key: "start", value: function start() { this.started = true; if (this.refreshEveryFrame) this.$app.core.get('SceneRenderer').addComponent(this, true);else this.refreshUpdateInterval(0); } }, { key: "useComponent", value: function useComponent() { this.refreshEveryFrame = true; window.clearTimeout(this.refreshInterval); this.start(); } }, { key: "stop", value: function stop() { window.clearTimeout(this.refreshInterval); this.$app.core.get('SceneRenderer').removeComponent(this); } }, { key: "update", value: function update() { var _this2 = this; var e = this.forceQueue.length > 0; this.processQueueForDownloading(this.forceQueue); if (this.processPriorityQueue) { common.intervalTool.isWaiting('processPriorityQueue_' + this.$app.resource.num, function () { //延时update,防止崩溃 , 未到时间就拦截(第一次直接执行) _this2.queuePrioritizedTilesForPanos(_this2.panos); //这句比较耗时 降四倍时大概1-2毫秒 }, this.$app.config.mobile ? 120 : 66); this.priorityQueue.length > 0 && (e = !0); this.processQueueForDownloading(this.priorityQueue); } return e; } }, { key: "clearForceQueue", value: function clearForceQueue() { this.clearQueue(this.forceQueue); } }, { key: "queuePrioritizedTilesForPanos", value: function queuePrioritizedTilesForPanos(e) { if (this.tilePrioritizer) { var player = this.$app.core.get('Player'); var maxLoadTileCount = player.lowTile == 'level2' ? 6 : player.lowTile == 'level1' ? 10 : 30; this.clearQueue(this.priorityQueue); this.tilePrioritizer.filterAndPrioritize(this.priorityQueue, e, this, maxLoadTileCount); this.clearFromQueue(this.priorityQueue, DownloadStatus.None, !0); this.setStatusOrRemoveForAllDescriptors(this.priorityQueue, DownloadStatus.Queued); } } }, { key: "clearQueue", value: function clearQueue(e) { this.setStatusForAllDescriptors(e, DownloadStatus.None), e.length = 0; } }, { key: "clearFromQueue", value: function clearFromQueue(e, t, i) { for (var n = 0; n < e.length; n++) { var r = e[n]; r && (t === r.status && !i || t !== r.status && i) && (e[n] = null); } } }, { key: "setStatusForAllDescriptors", value: function setStatusForAllDescriptors(e, t) { for (var i = 0; i < e.length; i++) { var n = e[i]; n && (n.status = t); } } }, { key: "setStatusOrRemoveForAllDescriptors", value: function setStatusOrRemoveForAllDescriptors(e, t) { for (var i = 0; i < e.length; i++) { var n = e[i]; n && (n.status !== t ? n.status = t : e[i] = null); } } }, { key: "getTileDownloadDescriptors", value: function getTileDownloadDescriptors(e, t) { var i = this.getAllTileDownloadDescriptorsForPano(e), n = i[t]; return n || (n = this.buildDownloadDescriptorArray(t), i[t] = n, this.initTileDownloadDescriptors(n, e, t)), n; } }, { key: "getAllTileDownloadDescriptorsForPano", value: function getAllTileDownloadDescriptorsForPano(e) { var t = this.downloadDescriptors[e.id]; return t || (t = {}, this.downloadDescriptors[e.id] = t), t; } }, { key: "processQueueForDownloading", value: function processQueueForDownloading(e, t) { this.cleanupActiveDownloads(); /* let flying = this.$app.core.get('Player').flying let isMobile = this.$app.config.mobile */ // xzw 改 4.6.0 if (e.length) { //let concurrentDownloads = common.getBestCount('concurrentDownloads', 1, 6) //flying ? (isMobile ? 2 : 3) : 6 var concurrentDownloads = common.getBestCount({ name: 'concurrentDownloads', minCount: 0, maxCount: 6, durBound1: 1, durBound2: 12, //8以下太小,模型大的场景加载慢 ifLog: false, maxHistory: 4, isMobile: this.$app.config.mobile }); //最小值设置为0,否则4k放大快速过渡会崩溃,之前v3不会崩是因为用setTimeout加载慢 if (this.activeDownloads.length < concurrentDownloads || t) { var i = t ? e.length : concurrentDownloads - this.activeDownloads.length; for (var n = 0, r = 0; n < i && e.length > 0; r++) { var o = e.shift(); o && (this.startDownload(o), n++); } } } } }, { key: "testDownload", value: function testDownload(e, t, i) { var n = this.downloadTestResults[e]; if (n) return void (n === this.freeze.Success ? i(!0) : n === this.freeze.Fail && i(!1)); this.downloadTestResults[e] = this.freeze.Testing; var r = this.panos.list[0], o = this.getTileUrl(r, e, t, 0), a = function (t) { this.downloadTestResults[e] = this.freeze.Success, i(!0); }.bind(this), s = function () { this.downloadTestResults[e] = this.freeze.Fail, i(!1); }.bind(this); this.loadImage(o, 0, a, s); } }, { key: "startDownload", value: function startDownload(e) { //开始下载啦 e.status = DownloadStatus.Downloading; var t = this.getTileUrl(e.pano, e.panoSize, e.tileSize, e.tileIndex); this.activeDownloads.push(e); this.loadImage(t, TileDownloader.DOWNLOAD_RETRIES, this.downloadComplete.bind(this, e), this.downloadFailed.bind(this, e)); //console.log('begin Download ',e.pano.id,e.panoSize, e.tileSize, e.tileIndex) } // //xst,加载一个点的所有图片 // loadAllImgsForOnePano(pano,size){ // if(!size){ // size = 2048 // } // //是否存在 // this.downloadDescriptor // let queue = this.getTileDownloadDescriptors(pano, size) // for(let i=0;i= TileUtils.TILE_SIZE ? TileUtils.TILE_SIZE : i; e.face = TileUtils.getFaceForTile(i, n); e.cubeFace = panorama.mapFaceToCubemapFace(e.face); e.panoGroupId = this.panoGroupId; e.pano = t; e.panoSize = i; e.tileSize = r; e.tileIndex = n; e.totalTiles = TileUtils.getTileCountForSize(i); e.status = DownloadStatus.None; e.image = null; TileUtils.getTileLocation(e.panoSize, e.tileIndex, e); TileUtils.getTileVector(e.panoSize, e.tileSize, e.cubeFace, e.tileX, e.tileY, TileUtils.LocationOnTile.Center, 0, e.direction); } }, { key: "loadImage", value: function loadImage(e, t, i, n) { http.getImage(e, t).then(function (e) { i(e); }).fail(n); } }, { key: "getTiles", value: function getTiles(d) { return this.urls.get(d); //config.urls.tileImgPath+d; } }]); return TileDownloader; }(EventEmitter), _class.IDLE_REFRESH_DELAY = 500, _class.ACTIVE_REFRESH_DELAY = 16, _class.DOWNLOAD_RETRIES = 4, _temp; }); window.TileTree = function (e, t) { this.levels = t, this.tileSize = e, this.root = null, this.allNodes = [], a$3(this); }; function r$3(e, t) { this.tree = e, this.parent = t, this.children = [], this.id = ++u; } function o$2(e, t, i, r, a, s, l, h) { if (e) { l = l || TileTree.TraversalType.PreOrder; var u = r * c$1 + i; if (l === TileTree.TraversalType.PreOrder && (a && a(e, t, u, i, r), s && s.push(e)), e.children && 0 !== e.children.length) { for (var d = r * c$1, p = i * c$1, f = 0; f < c$1; f++) { for (var g = 0; g < c$1; g++) { o$2(e.children[g * c$1 + f], t + 1, p + f, d + g, a, s, l); } } l === TileTree.TraversalType.PostOrder && (a && a(e, t, u, i, r), s && s.push(e)); } } } function a$3(e) { e.root = s$3(e, null, 0); } function s$3(e, t, i) { if (i > e.levels) return null; var n = new r$3(e, t); e.allNodes.push(n); for (var o = 0; o < h; o++) { n.children[o] = s$3(e, n, i + 1); } return n; } function l$2(e, t, i, n, r) { if (!e) return null; if (0 === i) return e; if (!e.children || 0 === e.children.length) return null; var o = Math.pow(c$1, i), a = o / c$1, s = n % a, h = r % a, u = Math.floor(r / a), d = Math.floor(n / a), p = u * c$1 + d, f = e.children[p]; return l$2(f, t + 1, i - 1, s, h); } var c$1 = 2, h = c$1 * c$1; TileTree.TraversalType = Object.freeze({ PreOrder: 0, PostOrder: 1 }); var u = 0; TileTree.getLevelCountForSize = function (e, t) { var i = 0; for (t < e && (t = e);;) { if (t /= c$1, t < e) break; i++; } return i; }, TileTree.getSizeForLevel = function (e, t) { return Math.pow(c$1, t) * e; }, TileTree.prototype.getSubNode = function (e, t, i) { (!t || e < this.tileSize) && (t = 0), (!i || e < this.tileSize) && (i = 0), e < this.tileSize && (e = this.tileSize); var r = TileTree.getLevelCountForSize(this.tileSize, e), o = l$2(this.root, 0, r, t, i); return o; }, TileTree.prototype.breadthFirst = function (e) { e = e || {}; var t = !!e.nullLevelEnd, i = e.maxLevel, n = e.minLevel, r = e.callback, o = e.saveVisited, a = [], s = {}, l = 0; for (a.push(this.root), a.push(s); a.length > 0 && !(i != void 0 && l > i);) { var h = a.shift(); if (h === s) (!n || l >= n) && (r && t && r(null), o && t && o.push(null)), a.length > 0 && a.push(s), l++;else { if (h.children) for (var u = 0; u < h.children.length; u++) { var d = h.children[u]; d && a.push(h.children[u]); } var p = this.getFaceIndexFromNode(h); (!n || l >= n) && (r && r(h, l, p), o && o.push(h)); } } }, TileTree.prototype.getFaceIndexFromNode = function (e) { if (!e) return -1; for (var t = 1, i = e, n = 0, r = 0;;) { var o = i.parent; if (!o) break; for (var a = -1, s = 0; s < o.children.length; s++) { o.children[s] === i && (a = s); } var l = a % c$1, h = Math.floor(a / c$1); n = l * t + n, r = h * t + r, t *= c$1, i = o; } return r * t + n; }, TileTree.prototype.depthFirst = function (e, t, i) { o$2(this.root, 0, 0, 0, e, t, i, this.tileSize); }; var TileTree$1 = TileTree; 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 _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 createDescriptor() { var e = { renderTarget: null, inUse: !1, size: -1, pano: null }; return e; } /* 测试崩溃时,最好每次都清除缓存,因为清除后不容易崩溃了 */ function getMaxCount($app) { var isMobile = $app.config.mobile, maxCount; if (isMobile) { //手机的gpu相比cpu可能弱的多,个数要降低 maxCount = common.getBestCount({ name: 'maxTileRender', minCount: 0, maxCount: 4, durBound1: 1, durBound2: 4, ifLog: false, maxHistory: 3 }); } else { maxCount = common.getBestCount({ name: 'maxTileRender', minCount: 0, maxCount: 6, durBound1: 1, durBound2: 6, ifLog: false, maxHistory: 2 }); } return maxCount; } function upload() { if (!this.uploadIntervalCancelled) { b$1 = !0; /* let flying = this.$app.core.get('Player').flying let isMobile = this.$app.config.mobile let maxNonBaseUploadsPerFrame = (flying || isMobile) ? 1 : 2 //this.maxNonBaseUploadsPerFrame //原先2。这是每帧uploadTile非512的瓦片tex的数量。之前的2太卡了,降为1。(检测卡顿方法:在一个pano点旋转至所有2048的tile都加载完,然后之后到这个点看看卡不卡。因为该点tiles都下载完了所以会在飞过来时陆续都加载,所以容易卡) let maxBaseUploadsPerFrame = flying ? (isMobile ? 1 : 3) : 6//this.maxBaseUploadsPerFrame //原先6. 但持续前进过程中会请求加载下一个漫游图,一次加6张会卡的。 this.updateUploadQueue(maxNonBaseUploadsPerFrame, maxBaseUploadsPerFrame) let time = flying ? 20 : 15 //w // 飞行有时候会卡,增长间隔 */ var maxCount = getMaxCount(this.$app); this.updateUploadQueue(2, 6, maxCount); var time = 16; this.peekNextFromUploadQueue() ? this.refreshUploadInterval(time) : this.uploadInterval = null; //定时下一次更新 /* this.updateUploadQueue(this.maxNonBaseUploadsPerFrame, this.maxBaseUploadsPerFrame), this.peekNextFromUploadQueue() ? this.refreshUploadInterval(w) : (this.uploadInterval = null) */ } } var b$1 = !1, w = settings$3.tiling.uploadIntervalDelay, _ = settings$3.tiling.initialIntervalDelay, T$1 = settings$3.tiling.maxNonBaseUploadsPerFrame, x$2 = settings$3.tiling.maxBaseUploadsPerFrame, S = { Base: 0, Remaining: 1 }; /* , M = []; */ defineComponent('PanoRenderer', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(PanoRenderer, _EventEmitter); var _super = _createSuper$$(PanoRenderer); function PanoRenderer(index) { var _this; _classCallCheck(this, PanoRenderer); _this = _super.call(this); _this.updateActivePanos = function () { var e = []; return function (t, i) { e.length = 0; for (var n = 0; n < this.activePanos.length; n++) { t && e.length === i && e.push(t); var r = this.activePanos[n], o = this.getActiveRenderTargetDescriptor(r.id); t && r.id === t.id || !this.isRenderTargetDescriptorValid(o) || e.push(r); } t && i >= e.length && e.push(t), this.activePanos.length = 0, this.activePanos.push.apply(this.activePanos, e); }; }(); _this.renderPanoTiles = function () { var e = []; return function (panoId, i, n, r, quality) { this.zoomRenderTarget && this.zoomRenderTarget.width === this.$app.core.get('QualityManager').getMaxZoomPanoSize() || this.zoomPanoRenderingDisabled || this.setupZoomRenderTarget(), i = i || this.direction || Vectors.FORWARD; var o = this.getActiveRenderTargetDescriptor(panoId); if (!this.isRenderTargetDescriptorValid(o)) console.error('PanoRenderer.renderPanoTiles() -> Cannot render to a pano that is not activated.'); for (var a = 0; a < TileUtils.FACES_PER_PANO; a++) { var s = this.getTileTree(panoId, a); e.length = 0; s.breadthFirst({ //获取所有node, 从512到4096的共85个tiles saveVisited: e, maxLevel: quality ? quality == 512 ? 0 : quality == 1024 ? 1 : quality == 2048 ? 2 : 3 : 3 }); var dontDraw = this.$app.config.mobile && this.$app.core.get('Player').mode == 'panorama'; //从外面飞入时似乎不容易崩溃,直接加载吧否则等很久 for (var l = 0; l < e.length; l++) { var c = e[l]; this.queueTileUpload(c.tile, !1, !dontDraw && (r || 0 === l && n)); //isMobile手机端不直接uploadTile base的6张贴图, 容易卡甚至崩溃 } } this.updateDirection(i); }; }(); _this.getNextFromUploadQueue = function () { //获取第一项并在列表中删除它 var e = function e(_e) { var t = _e.shift(); return t.uploadQueued = !1, t; }; return function () { if (this.forceQueue.length > 0) return e(this.forceQueue); var t = this.getTopUploadQueue(); return t && t.length > 0 ? e(t) : null; }; }(); _this.refreshUploadInterval = function () { var e = null; return function (t) { if (!this.uploadIntervalCancelled) { e || (e = upload.bind(this)); null !== t && void 0 !== t || (t = w); b$1 || (t = _); this.uploadInterval = window.setTimeout(e, t); this.uploadIntervalDelay = t; } }; }(); _this.update = function () { this.uploadIntervalCancelled = true; //不使用setTimeout,而是在sceneRenderer每帧都update this.$app.core.get('Player').lastFrameChanged; var maxCount = getMaxCount(this.$app); //注:静止时看不出卡顿所以全速加载 this.updateUploadQueue(2, 6, maxCount); }; _this.uploadTile = function () { var collection = {}, overlayStyle = settings$3.tiling.overlayStyle; var failHistory = {}; return function (info, n) { var _this2 = this; var sceneRenderer = this.index == 1 ? this.sceneRenderer2 : this.$app.core.get('SceneRenderer'); var id = info.panoId, img = info.image, tileSize = info.tileSize, panoSize = info.panoSize, tileIndex = info.tileIndex, totalTiles = info.totalTiles, tileX = info.tileX, tileY = info.tileY, p = !0, g = !1, ignore = false, //add LodDescripor = (this.getPanoDescriptor(id), this.getPanoLODDescriptor(id, panoSize)), activeDescripor = this.getActiveRenderTargetDescriptor(id), renderTarget = activeDescripor.renderTarget, size = activeDescripor.size; //当前要渲染的面的分辨率,也就是MaxNavPanoSize if (this.isPanoZoomed(id) && this.zoomRenderTarget) { renderTarget = this.zoomRenderTarget; size = this.zoomRenderTarget.width; //this.qualityManager.getMaxZoomPanoSize(); //放大后可能2048或4096 } var done = function done() { if (!LodDescripor.uploaded.includes(tileIndex)) { //已经upload过(本来这时候直接返回,但发现缩放后这不会归零,导致清晰度不更新,所以还是redraw且emit吧) //console.log('try to reupload and return',tileIndex) LodDescripor.uploaded.push(tileIndex); LodDescripor.uploadCount++; } _this2.emit(PanoRendererEvents.TileRenderSuccess, id, panoSize, tileIndex, totalTiles); LodDescripor.uploadCount === totalTiles && _this2.emit(PanoRendererEvents.PanoRenderComplete, id, panoSize, totalTiles); _this2.setUploaded(info, !0); _this2.addCoverageForNode(info.node); }; { this.isRenderTargetDescriptorValid(activeDescripor) || (p = !1, g = !1); if (!n) { if (this.anyUploaded(info.node)) { p = !1, g = !0; ignore = true; } this.isTileUploaded(info) && (p = !1, g = !1, ignore = true); } } if (p) { /* if(failHistory[id+':'+ panoSize+ ':' +tileIndex]){ console.log('uploadTile retry',id, panoSize, tileIndex) } */ // console.log('uploadTile 成功', id, panoSize, tileIndex) var C = tileX * tileSize, I = tileY * tileSize, E = tileSize / panoSize * size, // tile在renderTarget上渲染出的宽度 b = C / panoSize * size, // tile在renderTarget上渲染的startX w = I / panoSize * size; // tile在renderTarget上渲染的startY if (panoSize > this.$app.core.get('QualityManager').maxRenderTargetSize) { //4096 改 //var tex = sceneRenderer.initSizedTexture2D(tileSize, THREE.ClampToEdgeWrapping) //var loaded = this.$app.core.get('Player').model.isHighMapLoaded(info.cubeFace, tileX, tileY) this.$app.core.get('Player').model.getHighImage(img, info.cubeFace, tileX, tileY); } else { collection[tileSize] || (collection[tileSize] = sceneRenderer.initSizedTexture2D(tileSize, THREE.ClampToEdgeWrapping)); var tex = collection[tileSize]; sceneRenderer.uploadTexture2D(img, tex, 0, 0, tileSize, tileSize); //只替换tex对应的img,不新建 if (1 === overlayStyle || 2 === overlayStyle) { var T = 1 === overlayStyle ? this.overlayTilesBasic : this.overlayTilesEnhanced; sceneRenderer.renderToCubeMap(tex, renderTarget, tileSize, tileSize, 0, 0, tileSize, tileSize, b, w, E, E, info.cubeFace); sceneRenderer.renderToCubeMap(T[panoSize], renderTarget, tileSize, tileSize, 0, 0, tileSize, tileSize, b, w, E, E, info.cubeFace, THREE.NormalBlending, !0, 0.5); } else { sceneRenderer.renderToCubeMap(tex, renderTarget, tileSize, tileSize, 0, 0, tileSize, tileSize, b, w, E, E, info.cubeFace); } } done(); } else if (ignore) { //console.log('finish because anyUploaded',id,panoSize,tileIndex) done(); //改: 如果因为这部分更高清的贴图已加载所以才不绘制的话,直接完成 } else { /* console.log('uploadTile 失败', id, panoSize, tileIndex) if(panoSize == 512){ console.log("!!!!!!!!!!!!!") } */ failHistory[id + ':' + panoSize + ':' + tileIndex] = true; this.setUploaded(info, !1); } info.uploadAttempted || (LodDescripor.uploadAttempts++, this.emit(PanoRendererEvents.TileUploadAttempted, id, panoSize, tileIndex, totalTiles)), info.uploadAttempted = !0; LodDescripor.uploadAttempts === totalTiles && this.emit(PanoRendererEvents.UploadAttemptedForAllTiles, id, panoSize, totalTiles); return g; }; }(); _this.tileDirectory = {}; _this.activeRenderTargetDescriptors = {}; _this.activePanos = []; _this.panoLODDescriptors = {}; _this.panoDescriptors = {}; _this.tileTrees = {}; _this.forceQueue = []; _this.uploadQueues = {}; _this.uploadInterval = null; _this.uploadIntervalCancelled = !1; _this.usingTileOverlay = !1; _this.overlayTilesLoaded = !1; _this.overlayTileBase = null; _this.overlayTilesBasic = {}; _this.overlayTilesEnhanced = {}; _this.zoomRenderTarget = null; //用于缩放的rendertarget _this.zoomPano = null; _this.zoomingActive = !1; _this.zoomPanoId = null; _this.zoomPanoRenderingDisabled = !1; _this.direction = new THREE.Vector3(); _this.initTime = -1; _this.maxBaseUploadsPerFrame = x$2; _this.maxNonBaseUploadsPerFrame = T$1; _this.M = []; //move M to here 似乎列表里会有两个 _this.index = index || 0; //改 return _this; } _createClass(PanoRenderer, [{ key: "init", value: function init(e, t, i) { if (this.index == 1) { this.sceneRenderer2 = e; this.tileDownloader2 = t; } this.initTime = performance.now(); this.bindEvents(); } }, { key: "getActivePanoTextures", value: function getActivePanoTextures(e) { e = e || []; for (var t = 0; t < M.length; t++) { var i = M[t]; i.renderTarget && i.renderTarget.texture && e.push(i.renderTarget.texture); } } }, { key: "hasQueuedTiles", value: function hasQueuedTiles() { var e = this.peekNextFromUploadQueue(); return null !== e && void 0 !== e; } }, { key: "getActiveRenderTargetDescriptor", value: function getActiveRenderTargetDescriptor(e) { return this.activeRenderTargetDescriptors[e]; } }, { key: "setActiveRenderTargetDescriptor", value: function setActiveRenderTargetDescriptor(e, t) { this.activeRenderTargetDescriptors[e] = t; } }, { key: "bindEvents", value: function bindEvents() { this.index == 1 ? this.tileDownloader2.on(TileDownloaderEvents.TileDownloadSuccess, this.onTileDownloaded.bind(this)) : this.$app.core.get('TileDownloader').on(TileDownloaderEvents.TileDownloadSuccess, this.onTileDownloaded.bind(this)); } }, { key: "setupZoomRenderTarget", value: function setupZoomRenderTarget() { var QualityManager = this.$app.core.get('QualityManager'); if (QualityManager.maxRenderTargetSize == 2048 && QualityManager.getMaxNavPanoSize() == 2048) return; //不使用zoomTarget 直接用pano的tiledPanoRenderTarget,防崩溃 //if (QualityManager.getMaxZoomPanoSize() >= QualityManager.getMaxNavPanoSize() && (QualityManager.tileClass != '2k' || QualityManager.tileClass != '1k')) { if (QualityManager.tileClass > QualityManager.navTileClass) { //如果tileClass=='4k'即使还没加载出4k也先创建2k的Target //部分手机2k时copyCubeMap会重载 , 所以如果没有超出当前分辨率,就不使用zoomRenderTarget。但在微信依旧会重载,只是优化了些,safari几乎不会。 var sceneRenderer = this.index == 1 ? this.sceneRenderer2 : this.$app.core.get('SceneRenderer'); if (this.zoomRenderTarget && this.zoomRenderTarget.width === QualityManager.getMaxZoomPanoSize()) return; var e = this.zoomRenderTarget; var size = QualityManager.getMaxZoomPanoSize(); if (size > QualityManager.maxRenderTargetSize) { return; } this.zoomRenderTarget = this.initTiledPano(QualityManager.getMaxZoomPanoSize(), !1); if (e) { //将旧的zoomRenderTarget渲染到新zoomRenderTarget上 var t = e.width, i = this.zoomRenderTarget.width; sceneRenderer.copyCubeMap(e.texture, this.zoomRenderTarget, t, t, i, i); e.texture.dispose(); e.texture.loaded = !1; e.texture.version = 0; sceneRenderer.deallocateCubeTexture(e.texture); e.texture = null; } this.zoomPanoRenderingDisabled = !1; } else this.zoomPanoRenderingDisabled = !0; } }, { key: "enableHighQuality", value: function enableHighQuality(e) { //xzw add 如果最多只要2k图的话enableUltraHighQualityMode替换成这个 if (!this.$app.core.get('QualityManager').highQualityModeStarted) { this.setupZoomRenderTarget(); e(); this.$app.core.get('QualityManager').highQualityModeStarted = true; } } }, { key: "enableUltraHighQualityMode", value: function enableUltraHighQualityMode(e) { var QualityManager = this.$app.core.get('QualityManager'); if (QualityManager.tileClass == '2k' || QualityManager.tileClass == '1k') return this.enableHighQuality(e); //xzw add if (!QualityManager.ultraHighQualityModeEnabled()) { var t = QualityManager.getPanoSize(PanoSizeClass.ULTRAHIGH); this.$app.core.get('TileDownloader').testDownload(t, TileUtils.TILE_SIZE, function (t) { if (t) { this.$app.core.get('QualityManager').enableUltraHighQualityMode(); this.setupZoomRenderTarget(); e(); } }.bind(this)); } } }, { key: "activateTiledPano", value: function activateTiledPano(pano, size, i, dontReSetTree) { i && this.clearAllQueuedUploads(); if (!dontReSetTree) { //重新initTileTree会重新uploadTile for (var n = 0; n < TileUtils.FACES_PER_PANO; n++) { this.initTileTree(pano.id, n, this.$app.core.get('QualityManager').getMaxPossiblePanoSize()); } //得到this.tileTrees[pano.id],arr[6] this.linkAllTilesAndNodes(pano); } var r = this.getActiveRenderTargetDescriptor(pano.id), l = size; l > this.$app.core.get('QualityManager').getMaxNavPanoSize() && (l = this.$app.core.get('QualityManager').getMaxNavPanoSize()); if (!r || l !== r.size) { r && this.deactiveDescripor(r.renderTarget); r = this.activeDescripor(l); if (!r) { //console.log('创建cubeRenderTarget', size) var ren = this.initTiledPano(l, !this.$app.config.mobile /* !1 */ ); //xzw 但是有发现某个win7 ram4G的电脑会因抗锯齿在封面加载多3秒以上的时间。 r = this.initDescriptor(ren.width); r.renderTarget = ren; } r.pano = pano; this.resetPanoDescriptor(pano.id); if (!dontReSetTree) { this.resetPanoLODDescriptors(pano.id); this.resetRenderStatus(pano.id, !0, !0); } } this.setActiveRenderTargetDescriptor(pano.id, r); var h = i ? 0 : 1; this.updateActivePanos(pano, h); //console.log(`index:${this.viewer.index} ${r.renderTarget.texture.id} ${pano.id}`) return r.renderTarget; } }, { key: "deactivateTiledPano", value: function deactivateTiledPano(e) { var t = this.getActiveRenderTargetDescriptor(e.id); if (this.isRenderTargetDescriptorValid(t)) { this.deactiveDescripor(t.renderTarget); this.setActiveRenderTargetDescriptor(e.id, null); } var i = this.getUploadQueueForPano(e.id); this.clearUploadQueue(i); this.updateActivePanos(); } }, { key: "getActivePanoCount", value: function getActivePanoCount() { return this.activePanos.length; } }, { key: "resetRenderStatus", value: function resetRenderStatus(e, t, i, n) { var r = null; n && (r = TileTree$1.getLevelCountForSize(TileUtils.TILE_SIZE, n) + 1); for (var o = function o(e, n, r, _o) { i && (n.tile.zoomUploaded = !1), t && (n.tile.uploaded = !1); }, a = 0; a < TileUtils.FACES_PER_PANO; a++) { var s = this.getTileTree(e, a); s.breadthFirst({ callback: o.bind(this, a), minLevel: r }); } } }, { key: "copyBaseRenderStatusToZoomed", value: function copyBaseRenderStatusToZoomed(e) { for (var t = TileTree$1.getLevelCountForSize(TileUtils.TILE_SIZE, this.$app.core.get('QualityManager').getMaxNavPanoSize()), i = function i(e, t, _i, n) { t.tile.zoomUploaded = t.tile.uploaded, t.zoomCovered = t.covered; //标记 }, n = 0; n < TileUtils.FACES_PER_PANO; n++) { var r = this.getTileTree(e, n); r.breadthFirst({ callback: i.bind(this, n), maxLevel: t }); } } }, { key: "isRenderTargetDescriptorValid", value: function isRenderTargetDescriptorValid(e) { return e && e.renderTarget; } }, { key: "isPanoActive", value: function isPanoActive(e) { var t = this.getActiveRenderTargetDescriptor(e); return this.isRenderTargetDescriptorValid(t); } }, { key: "isPanoZoomed", value: function isPanoZoomed(e) { return this.zoomingActive && this.zoomPanoId === e; } }, { key: "initTileTree", value: function initTileTree(e, t, i) { var n = this.tileTrees[e]; n || (n = [], this.tileTrees[e] = n); var r = n[t]; if (!r) { var o = TileTree$1.getLevelCountForSize(TileUtils.TILE_SIZE, i); r = new TileTree$1(TileUtils.TILE_SIZE, o), n[t] = r; } } }, { key: "getTileTree", value: function getTileTree(e, t) { var i = this.tileTrees[e]; if (!i) console.error('PanoRenderer.getTileTree() -> Tree array not yet initialized!'); var n = i[t]; if (!n) console.error('PanoRenderer.getTileTree() -> Tree not yet initialized!'); return n; } /* * 创建tile的renderTarget, 包括pano.tiledPanoRenderTarget和zoomRenderTarget * @param {number} size 当前的panoSize,每个面的分辨率 */ }, { key: "initTiledPano", value: function initTiledPano(size, antialias) { //创建 RenderTargetCube var renderTarget = new THREE.WebGLCubeRenderTarget(size, { stencilBuffer: !1, //xzw add antialias , 手机可false generateMipmaps: antialias, minFilter: antialias ? THREE.LinearMipMapLinearFilter : THREE.LinearFilter }); //antialias: 如果抗锯齿的话,采用mipmap,会增加一倍的存储消耗。原版本都是不抗锯齿的。但是抗锯齿效果更柔和 //console.log('initTiledPano', size, antialias) return renderTarget; } }, { key: "getUploadQueueForPano", value: function getUploadQueueForPano(e) { var t = this.uploadQueues[e]; if (!t) t = [], this.uploadQueues[e] = t; return t; //return t || ((t = []), (this.uploadQueues[e] = t)), t } }, { key: "isTileUploaded", value: function isTileUploaded(e) { return this.isPanoZoomed(e.panoId) ? e.zoomUploaded : e.uploaded; } }, { key: "setUploaded", value: function setUploaded(e, t) { this.isPanoZoomed(e.panoId) ? e.zoomUploaded = t : e.uploaded = t; //console.log('setUploaded', e.panoId,e.tileIndex, e.uploaded, t ) } }, { key: "queueTileUpload", value: function queueTileUpload(e, t, i) { var n = this.getActiveRenderTargetDescriptor(e.panoId); if (this.isRenderTargetDescriptorValid(n) && e.downloaded && !this.isTileUploaded(e) && (!e.uploadQueued || i) && (!(e.panoSize > this.$app.core.get('QualityManager').getMaxNavPanoSize()) || this.zoomingActive)) { var r = this.getUploadQueueForPano(e.panoId); i ? this.uploadTile(e, !1) : (this.shoulPushToFrontOfQueue(e) ? this.forceQueue.push(e) : t && this.direction ? TilePrioritizer.insertSortedPanoTile(r, e, n.pano, this.direction) : r.push(e), e.uploadQueued = !0, this.uploadInterval || this.uploadIntervalCancelled || this.refreshUploadInterval(0)); } } }, { key: "shoulPushToFrontOfQueue", value: function shoulPushToFrontOfQueue(e) { return 0 === TileTree$1.getLevelCountForSize(TileUtils.TILE_SIZE, e.panoSize); } }, { key: "getTopUploadQueue", value: function getTopUploadQueue() { for (var e = null, t = null, i = S.Base; i <= S.Remaining; i++) { for (var n = 0; n < this.activePanos.length; n++) { e = this.activePanos[n]; t = this.getUploadQueueForPano(e.id); if (t.length > 0) { switch (i) { case S.Base: if (0 === t[0].level) return t; break; case S.Remaining: return t; } } } } return null; } }, { key: "peekNextFromUploadQueue", value: function peekNextFromUploadQueue() { //获取第一项 if (this.forceQueue.length > 0) return this.forceQueue[0]; var e = this.getTopUploadQueue(); return e && e.length > 0 ? e[0] : null; } }, { key: "clearAllQueuedUploads", value: function clearAllQueuedUploads() { this.clearAllUploadQueues(null, 0); } }, { key: "clearAllQueuedUploadsForPano", value: function clearAllQueuedUploadsForPano(e) { this.clearAllUploadQueues(e, 0); } }, { key: "clearAllUploadQueues", value: function clearAllUploadQueues(e, t) { if (e) this.clearUploadQueue(this.getUploadQueueForPano(e), t), this.clearUploadQueue(this.forceQueue, t, e);else { for (var i = 0; i < this.activePanos.length; i++) { var n = this.activePanos[i]; this.clearUploadQueue(this.getUploadQueueForPano(n.id), t); } this.clearUploadQueue(this.forceQueue, t); } } /* clearUploadQueue(e, t, i) { ;(void 0 !== t && null !== t) || (t = 0) for (var n = 0; n < e.length; ) { var r = e[n] ;(!i || (i && i === r.tile.panoId)) && r.level >= t ? ((r.uploadQueued = !1), e.splice(n, 1)) : n++ } } */ }, { key: "clearUploadQueue", value: function clearUploadQueue(e, t, i) { void 0 !== t && null !== t || (t = 0); for (var n = 0; n < e.length;) { var r = e[n]; (!i || i && i === r.panoId) && r.level >= t ? (r.uploadQueued = !1, //(!i || i && i === r.tile.panoId) && r.level >= t ? (r.uploadQueued = !1, //上传下载页面刚上传后刷新会报错。原因未知。 e.splice(n, 1)) : n++; } } }, { key: "updateUploadQueue", value: function updateUploadQueue(e, t, maxCount) { for (var i = 0, n = 0, sum = 0;;) { /* var r = this.peekNextFromUploadQueue() if (!r) break if ((n >= t || i >= e || sum >= maxCount) && !(r.level == 0 && sum == 0) ) break */ if (n >= t || i >= e || sum >= maxCount) break; var r = this.getNextFromUploadQueue(); //获取并从列表中删除, 和前面的r一样的 if (!r) break; 0 !== r.level ? i++ : n++; //if(0 == r.level)console.log('0000000', sum, maxCount) sum++; if (!(r.panoSize > this.$app.core.get('QualityManager').getMaxNavPanoSize()) || this.zoomingActive) { var o = this.getActiveRenderTargetDescriptor(r.panoId); this.isRenderTargetDescriptorValid(o) && this.uploadTile(r, r.forceUpload); } } } /* updateUploadQueue(e, t) { //e || (e = 1) //啊啊啊啊啊 for (var i = 0, n = 0; ; ) { if (n >= t || i >= e) break var r = this.getNextFromUploadQueue() if (!r) break 0 !== r.level ? i++ : n++ if (!(r.panoSize > this.$app.core.get('QualityManager').getMaxNavPanoSize()) || this.zoomingActive) { var o = this.getActiveRenderTargetDescriptor(r.panoId) this.isRenderTargetDescriptorValid(o) && this.uploadTile(r, r.forceUpload) } } } */ }, { key: "updateDirection", value: function updateDirection(e) { if (e = e || this.direction) { this.direction = e; for (var t = 0; t < this.activePanos.length; t++) { var i = this.activePanos[t], n = this.getUploadQueueForPano(i.id); TilePrioritizer.sortPanoTiles(n, i, this.direction); } } } }, { key: "linkTileAndNode", value: function linkTileAndNode(e, t) { t.tile = e, e.node = t; } }, { key: "linkAllTilesAndNodes", value: function linkAllTilesAndNodes(e) { var t = function t(_t, i, n, r, o) { var a = this.getTileDirectoryEntry(e.id, i, r, o); this.linkTileAndNode(a, n); }; for (var i = 0; i < TileUtils.FACES_PER_PANO; i++) { var n = this.getTileTree(e.id, i); n.breadthFirst({ callback: t.bind(this, n, i) }); } } }, { key: "anyUploaded", value: function anyUploaded(e) { if (!e) return !1; if (e.tile && this.isTileUploaded(e.tile)) return !0; if (e.children) for (var t = 0; t < e.children.length; t++) { var i = e.children[t]; if (this.anyUploaded(i)) return !0; } return !1; } }, { key: "setNodeCovered", value: function setNodeCovered(e, t) { this.isPanoZoomed(e.tile.panoId) ? e.zoomCovered = t : e.covered = t; } }, { key: "isNodeCovered", value: function isNodeCovered(e) { return !!e && (this.isPanoZoomed(e.tile.panoId) ? e.zoomCovered : e.covered); } }, { key: "addCoverageForNode", value: function addCoverageForNode(e) { if (this.setNodeCovered(e, !0), e.parent && e.covered) { var t = e.parent; this.nodeSubcovered(t) && this.addCoverageForNode(t, !0); } } }, { key: "calcFullCoverage", value: function calcFullCoverage(e) { var t = !1; if (e.children) for (var i = 0; i < e.children.length; i++) { var n = e.children[i]; t = t || this.calcFullCoverage(n); } e.covered = e.tile.uploaded || t; } }, { key: "nodeSubcovered", value: function nodeSubcovered(e) { if (!e.children) return !1; for (var t = 0; t < e.children.length; t++) { if (!e.children[t] || !this.isNodeCovered(e.children[t])) return !1; } return !0; } }, { key: "resetPanoDescriptor", value: function resetPanoDescriptor(e) { this.getPanoDescriptor(e); } }, { key: "getPanoDescriptor", value: function getPanoDescriptor(e) { var t = this.panoDescriptors[e]; return t || (t = {}, this.panoDescriptors[e] = t), t; } }, { key: "resetPanoLODDescriptors", value: function resetPanoLODDescriptors(e) { var t = this.getPanoLODDescriptors(e); for (var i in t) { if (t.hasOwnProperty(i)) { var n = t[i]; n.uploadCount = 0, n.uploadAttempts = 0; n.uploaded = []; } } } }, { key: "getPanoLODDescriptor", value: function getPanoLODDescriptor(e, t) { var i = this.getPanoLODDescriptors(e), n = i[t]; return n || (n = { uploadCount: 0, uploadAttempts: 0, uploaded: [] //add }, i[t] = n), n; } }, { key: "getPanoLODDescriptors", value: function getPanoLODDescriptors(e) { var t = this.panoLODDescriptors[e]; return t || (t = {}, this.panoLODDescriptors[e] = t), t; } }, { key: "onTileDownloaded", value: function onTileDownloaded(e) { var t = TileTree$1.getLevelCountForSize(TileUtils.TILE_SIZE, e.panoSize), i = this.getTileDirectoryEntry(e.panoId, e.face, t, e.faceTileIndex); i.downloaded = !0; i.image = e.image; i.panoSize = e.panoSize; i.tileX = e.tileX; i.tileY = e.tileY; i.totalTiles = e.totalTiles; i.tileIndex = e.tileIndex; i.faceTileIndex = e.faceTileIndex; i.face = e.face; i.cubeFace = panorama.mapFaceToCubemapFace(e.face); i.panoId = e.panoId; i.tileSize = e.tileSize; i.direction = new THREE.Vector3().copy(e.direction); i.node = null; i.level = TileTree$1.getLevelCountForSize(TileUtils.TILE_SIZE, i.panoSize); if (this.isPanoActive(i.panoId)) { var n = this.getTileTree(i.panoId, i.face); var r = n.getSubNode(i.panoSize, i.tileX, i.tileY); this.linkTileAndNode(i, r); this.queueTileUpload(i, !0); } } }, { key: "getTileDirectoryEntry", value: function getTileDirectoryEntry(panoId, t, i, n) { var r = this.tileDirectory[panoId]; r || (r = {}, this.tileDirectory[panoId] = r); var o = 16384 * t + 1024 * i + n, //t:4096级别 a = r[o]; return a || (a = { downloaded: !1, uploaded: !1, zoomUploaded: !1 }, r[o] = a), a._key = panoId + ':' + t + ':' + i + ':' + n, a._tileKey = o, a; } }, { key: "setZoomingActive", value: function setZoomingActive(active, pano, i) { //设置当前正在zoom的pano this.zoomPanoRenderingDisabled || active === this.zoomingActive && this.zoomPanoId === pano.id || (this.zoomingActive = active, this.zoomPanoId = pano.id, this.zoomingActive && (this.zoomPanoId !== pano.id || i) && this.updateZoomedPanoFromBase(pano)); } }, { key: "updateZoomedPanoFromBase", value: function updateZoomedPanoFromBase(pano) { //因更换pano所以将pano的rendertarget渲染到panoRenderer的zoomRenderTarget上 if (!this.zoomPanoRenderingDisabled) { var QualityManager = this.$app.core.get('QualityManager'); var sceneRenderer = this.index == 1 ? this.sceneRenderer2 : this.$app.core.get('SceneRenderer'); var t = this.getActiveRenderTargetDescriptor(pano.id); if (t && t.renderTarget) { if (this.zoomRenderTarget) { var i = Math.min(QualityManager.maxRenderTargetSize, QualityManager.getMaxZoomPanoSize()), //change n = t.renderTarget, r = t.size; sceneRenderer.copyCubeMap(n.texture, this.zoomRenderTarget, r, r, i, i); } this.copyBaseRenderStatusToZoomed(pano.id); } } } //xzw add 转换pano加载的tile的质量。 为了降低总的renderTarget的size, 尤其手机的2048cube个数只能存在一个 }, { key: "switchPanoQuality", value: function switchPanoQuality(pano, _ref) { var useIdel = _ref.useIdel, size = _ref.size; if (useIdel) { var rt; if (size) rt = this.activeDescripor(size, true); //使用空闲的,优先使用此size的 if (!rt) rt = this.activeDescripor(null, true); //任何size都可以 if (rt) { size = rt.size; } } pano.updateTileQuality(size); if (!pano.tiledPanoRenderTarget) return; var oldSize = pano.tiledPanoRenderTarget.width; if (size != oldSize) { //console.log('switchPanoQuality', pano.id, oldSize, size) this.deactiveDescripor(this.tiledPanoRenderTarget); var newTarget = this.activateTiledPano(pano, size, false, true); //第三个参数决定是否clearAllQueuedUploads, clear的话会造成tiles加载不全 this.$app.core.get('SceneRenderer').copyCubeMap(pano.tiledPanoRenderTarget.texture, newTarget, oldSize, oldSize, size, size); //这一句后台耗时高 pano.tiledPanoRenderTarget = newTarget; this.renderPanoTiles(pano.id, null, null, null, size /* , dir, a */ ); pano.updateSkyboxForZoomLevel(); //材质更新 } } /* 注意 由于copyCubeMap耗时大,所以不能在无缝过渡中执行。 综合考虑下最佳组合: pc:2048两个, 1024一个 mobile:2048一个, 1024两个 (lowTile为level2时多一个512) 其中无缝过渡时在中途加载的首选1024(除非1024用完了),直到无缝过渡结束后才会提升。 */ }, { key: "add", value: function add(e) { this.M.push(e); } }, { key: "initDescriptor", value: function initDescriptor(size) { var t = createDescriptor(); t.inUse = !0; t.size = size; this.add(t); return t; } }, { key: "activeDescripor", value: function activeDescripor(e, onlyCheck) { for (var t = 0; t < this.M.length; t++) { var i = this.M[t]; if (!i.inUse && (!e || i.size === e)) { //xzw改 if (!onlyCheck) i.inUse = !0; //console.log('activeDescripor', onlyCheck, this.M.map(e=>e.inUse)) return i; } } return null; } }, { key: "deactiveDescripor", value: function deactiveDescripor(e) { for (var t = 0; t < this.M.length; t++) { var i = this.M[t]; if (i.renderTarget === e) { i.inUse = !1; //console.log('deactiveDescripor', this.M.map(e=>e.inUse)) return !0; } } return !1; } //xzw add: 飞出后dispose所有cubeRenderTarget,避免因模型贴图较多而造成的崩溃 }, { key: "disposeIdelTargets", value: function disposeIdelTargets() { for (var t = 0; t < this.M.length; t++) { var i = this.M[t]; if (!i.inUse) { i.renderTarget.dispose(); } } //console.log('disposeIdelTargets ', disposeCount, 'of', this.M.length) } }]); return PanoRenderer; }(EventEmitter); }); var PanoVideoRendererEvents = { ParamsUpdated: 'panorama.videorenderer.paramsupdated', SuspendRender: 'panorama.videorenderer.suspendrender', ResumeRender: 'panorama.videorenderer.resumerender', TextureUpdate: 'panorama.videorenderer.textured', CanPlayVideo: 'panorama.videorenderer.canplayvideo', StartPlayVideo: 'panorama.videorenderer.startvideo' }; 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 _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; } } defineComponent('ModelManager', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(ModelManager, _EventEmitter); var _super = _createSuper$_(ModelManager); function ModelManager() { var _this; _classCallCheck(this, ModelManager); _this = _super.call(this); _this.modelMap = {}; _this.activeModel = null; _this.modelCount = 0; return _this; } _createClass(ModelManager, [{ key: "init", value: function init() { this.bindEvents(); } }, { key: "bindEvents", value: function bindEvents() { this.$app.core.get('PanoRenderer').on(PanoRendererEvents.TileRenderSuccess, this.onTileRendered.bind(this)); this.$app.core.get('PanoVideoRenderer').on(PanoVideoRendererEvents.TextureUpdate, this.onVideoTextureUpdate.bind(this)); this.$app.core.get('PanoVideoRenderer').on(PanoVideoRendererEvents.SuspendRender, this.onSuspendVideoRender.bind(this)); this.$app.core.get('PanoVideoRenderer').on(PanoVideoRendererEvents.ResumeRender, this.onResumeVideoRender.bind(this)); } }, { key: "onTileRendered", value: function onTileRendered(e, t, i, n) {} }, { key: "onVideoTextureUpdate", value: function onVideoTextureUpdate(texture) { this.activeModel && this.activeModel.updateVideoTexture(texture); } }, { key: "onSuspendVideoRender", value: function onSuspendVideoRender() { this.activeModel && this.activeModel.suspendVideoRender(); } }, { key: "onResumeVideoRender", value: function onResumeVideoRender() { this.activeModel && this.activeModel.resumeVideoRender(); } }, { key: "addModel", value: function addModel(model) { this.modelMap[model.sid] = model; 0 === this.modelCount && this.activateModel(model.sid); this.modelCount++; this.emit(ModelManagerEvents.ModelAdded); } }, { key: "activateModel", value: function activateModel(projectNum) { var model = this.modelMap[projectNum]; if (!model) { throw new BasicException('Tried to activate invalid model!'); } var oldModel = this.activeModel; this.activeModel = model, this.$app.core.get('TileDownloader').setPanoData(model.panos, [] /* model.listImagePanos() */ , model.sid), this.$app.core.get('TileDownloader').setUrls(model.urls), model.panos.forEach(function (e) { e.attachToPanoRenderer(this.$app.core.get('PanoRenderer')), e.attachToPanoVideoRenderer(this.$app.core.get('PanoVideoRenderer')), e.tileDownloader = this.$app.core.get('TileDownloader'), e.qualityManager = this.$app.core.get('QualityManager'); }.bind(this)), this.emit(ModelManagerEvents.ActiveModelChanged, { oldModel: oldModel, model: model }); } }, { key: "getActiveModel", value: function getActiveModel() { return this.activeModel; } }]); return ModelManager; }(EventEmitter); }); function _createSuper$Z(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$Z(); 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 _isNativeReflectConstruct$Z() { 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; } } var PanoramaCamera = /*#__PURE__*/function (_THREE$PerspectiveCam) { _inherits(PanoramaCamera, _THREE$PerspectiveCam); var _super = _createSuper$Z(PanoramaCamera); function PanoramaCamera(dom) { var _this; _classCallCheck(this, PanoramaCamera); _this = _super.call(this, cameraLight.clampVFOV(settings$3.insideFOV), window.innerWidth / window.innerHeight, settings$3.insideNear, settings$3.insideFar); _this.controls = null; return _this; } _createClass(PanoramaCamera, [{ key: "updateAspect", value: function updateAspect(aspect) { this.aspect = aspect; this.updateProjectionMatrix(); } }]); return PanoramaCamera; }(THREE.PerspectiveCamera); function _createSuper$Y(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$Y(); 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 _isNativeReflectConstruct$Y() { 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; } } var DollhouseCamera = /*#__PURE__*/function (_THREE$PerspectiveCam) { _inherits(DollhouseCamera, _THREE$PerspectiveCam); var _super = _createSuper$Y(DollhouseCamera); function DollhouseCamera(dom) { var _this; _classCallCheck(this, DollhouseCamera); _this = _super.call(this, cameraLight.clampVFOV(constants$4.dollhouseFOV), window.innerWidth / window.innerHeight, constants$4.dollhouseNear, constants$4.dollhouseFar); _this.controls = null; return _this; } _createClass(DollhouseCamera, [{ key: "updateAspect", value: function updateAspect(aspect) { if (isNaN(aspect)) aspect = 1; //xzw add this.aspect = aspect; this.controls.updateDistance(aspect); this.updateProjectionMatrix(); } /* updateFov() { //add if (this.aspect < this.suitModelAspect) { //屏宽缩小时,不变hFov, 改变vHov this.fov = cameraLight.getVFOVFromHFOV(this.suitModelAspectHFov, this.aspect, 1) } else this.fov = constants.dollhouseFOV } */ }]); return DollhouseCamera; }(THREE.PerspectiveCamera); function _createSuper$X(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$X(); 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 _isNativeReflectConstruct$X() { 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; } } var FloorplanCamera = /*#__PURE__*/function (_THREE$OrthographicCa) { _inherits(FloorplanCamera, _THREE$OrthographicCa); var _super = _createSuper$X(FloorplanCamera); function FloorplanCamera(dom) { var _this; _classCallCheck(this, FloorplanCamera); _this = _super.call(this); var aspect = window.innerWidth / window.innerHeight; _this = _super.call(this, -constants$4.orthoBase, constants$4.orthoBase, constants$4.orthoBase / aspect, -constants$4.orthoBase / aspect, constants$4.orthoNear, constants$4.orthoFar); _this.controls = null; _this.updateAspect(aspect); return _this; } //xzw 修改 _createClass(FloorplanCamera, [{ key: "updateAspect", value: function updateAspect(aspect) { if (isNaN(aspect)) aspect = 1; this.aspect = aspect; // this.top = constants.orthoBase / aspect // this.bottom = -constants.orthoBase / aspect // this.updateProjectionMatrix() } }]); return FloorplanCamera; }(THREE.OrthographicCamera); var MouseButton = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; function _createSuper$W(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$W(); 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 _isNativeReflectConstruct$W() { 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; } } var PanoramaControls = /*#__PURE__*/function (_EventEmitter) { _inherits(PanoramaControls, _EventEmitter); var _super = _createSuper$W(PanoramaControls); function PanoramaControls(camera, dom, player) { var _this; _classCallCheck(this, PanoramaControls); _this = _super.call(this); _this.camera = camera; //被控制的相机 _this.camera.controls = _assertThisInitialized(_this); _this.player = player; _this.config = player.$app.config; _this.dom = dom; _this.target = new THREE.Vector3(0, 0, 0); //相机视点,鼠标交互主要影响的对象 _this.lookVector = new THREE.Vector3(); //相机方向,以单位向量表示 _this.lookSpeed = 0.05; //没发现下文用到??? _this.rotationAcc = new THREE.Vector2(); //旋转角加速度 _this.rotationSpeed = new THREE.Vector2(); //旋转角速度 _this.speed = 1; // 相机拖拽旋转速度 /** * 球坐标系的相关参数lat,lon 与 phi,theta 两种表示形式 * 注:少了半径参数,因为是用于约束相机的方向,半径长短在此没有意义,单位1即可,体现在方向向量lookVector上 */ _this.lat = 0; //纬度,角度表示,直观 _this.lon = 0; //经度,角度表示,直观 _this.phi = 0; //phi,标准球坐标系的参数,弧度表示,用于进行直接计算 _this.theta = 0; //theta,标准球坐标系的参数,弧度表示,用于进行直接计算 _this.enabled = !1; //是否启用 _this.locked = !1; //是否锁定 /** * 交互行为相关,有鼠标点击与触摸,点击或触摸的地方在此约定统称为交互点 */ _this.pointer = new THREE.Vector2(0, 0); //交互点的屏幕坐标,有别于DOM坐标,在此存放NDC坐标。(NDC,三维常用坐标系,二维坐标,整个屏幕映射范围(-1,1),屏幕中心为原点,+Y朝上,+X朝右) _this.pointersLimit = 2; //触摸事件的触摸点的限制个数 _this.pointers = []; //存储交互点的坐标 _this.rotationDifference = new THREE.Vector2(); //记录帧之间的要进行的旋转量 _this.rotationHistory = []; //记录一次拖拽过程中每帧产生的rotationDifference,用于拖拽完成后计算平均值进而得到惯性角速度 _this.pointerDragOn = !1; //拖拽的标记,用于处理各种交互行为下的冲突问题 _this.pointerDragStart = new THREE.Vector2(0, 0); //拖拽开始位置,也作为两帧之间前一帧的坐标位置 _this.pinchDistance = 0; //触控下,“捏合”交互下,两触摸点的距离 _this.moveStart = new THREE.Vector2(); //交互点移动行为开始的最表 _this.moveTolerance = 0.01; //产生拖拽行为的鼠标移动最小阈值,用于解决点击,和其他行为的误触操作 _this.limitAngleIsBound = true; // 配置俯仰角 if (_this.config.camera && _this.config.camera.lookLimitUp != null && _this.config.camera.lookLimitDown != null) { _this.limitAngleIsBound = false; _this.insideLookLimitUp = _this.config.camera.lookLimitUp; _this.insideLookLimitDown = _this.config.camera.lookLimitDown; } return _this; } /** * 启用状态 */ _createClass(PanoramaControls, [{ key: "usable", value: function usable() { return this.enabled && !this.locked; } /** * 根据新的方向向量计算所指向的球面坐标(lat,lon),用到了笛卡尔坐标系转球面坐标系的数学方法 * 注:THREE 的 Vector3 与 Spherical 两个数学类有互转的方法 * @param {THREE.Vector3} aim 目标点 */ }, { key: "lookAt", value: function lookAt(aim, dir) { var t = dir || this.camera.position.clone().sub(aim); //aim所指相反点的笛卡尔坐标系 /** * 以下全为笛卡尔坐标->球座标,不多赘述 */ var i = Math.atan(t.z / t.x); i += t.x < 0 ? Math.PI : 0; i += t.x > 0 && t.z < 0 ? 2 * Math.PI : 0; this.lon = THREE.MathUtils.radToDeg(i) + 180; var n = Math.sqrt(t.x * t.x + t.z * t.z), o = Math.atan(t.y / n); this.lat = -THREE.MathUtils.radToDeg(o); } /** * 记录一次拖拽旋转开始时的一些状态 * @param {number} clientX 屏幕坐标 * @param {number} clientY 屏幕坐标 */ }, { key: "startRotationFrom", value: function startRotationFrom(clientX, clientY) { //以屏幕中心为原点,得到pointer在屏幕的百分比 var mouse = math$1.handelPadding(clientX, clientY, this.dom); math$1.convertScreenPositionToNDC(mouse.x, mouse.y, this.pointer, this.dom); this.pointerDragOn = !0; this.pointerDragStart.copy(this.pointer); this.moveStart.copy(this.pointer); this.rotationHistory = []; this.rotationSpeed.set(0, 0); } }, { key: "onMouseOver", value: function onMouseOver(mouseEvent) { !this.pointerDragOn || 0 !== mouseEvent.which && 0 !== mouseEvent.buttons || this.onMouseUp(mouseEvent); } }, { key: "onTouchStart", value: function onTouchStart(pointerEvent) { if (this.usable()) { pointerEvent.preventDefault(); pointerEvent.stopPropagation(); switch (pointerEvent.touches.length) { case 1: this.startRotationFrom(pointerEvent.touches[0].clientX, pointerEvent.touches[0].clientY); break; case 2: var t = (pointerEvent.touches[0].clientX - pointerEvent.touches[1].clientX) / window.innerWidth, i = (pointerEvent.touches[0].clientY - pointerEvent.touches[1].clientY) / window.innerHeight; this.pinchDistance = Math.sqrt(t * t + i * i); } this.emit(ControlEvents.InputStart, 'touch'); } } }, { key: "onPointerDown", value: function onPointerDown(pointerEvent) { if (this.usable() && 'touch' === pointerEvent.pointerType) { if (this.pointers.length < this.pointersLimit) { this.pointers.push({ id: pointerEvent.pointerId, clientX: pointerEvent.clientX, clientY: pointerEvent.clientY }); } pointerEvent.touches = this.pointers; this.onTouchStart(pointerEvent); this.emit(ControlEvents.InputStart, 'pointer'); } } }, { key: "onMouseDown", value: function onMouseDown(mouseEvent) { if (this.usable()) { mouseEvent.preventDefault(); mouseEvent.stopPropagation(); switch (mouseEvent.button) { case MouseButton.LEFT: this.startRotationFrom(mouseEvent.clientX, mouseEvent.clientY); } this.emit(ControlEvents.InputStart, 'mouse'); } } /** * 根据两帧交互点坐标之间的差值,计算两帧角度差值(rotationDifference)用于旋转 * 1.将两次交互点坐标分别映射到3D空间 * 2.通过两坐标在XY平面上投影,分别计算与X轴夹角,再求差值作为竖直方向角度差值(rotationDifference.y) * 3.通过两坐标在XZ平面上投影,分别计算与X轴夹角,再求差值作为水平方向角度差值(rotationDifference.x) */ }, { key: "updateRotation", value: function updateRotation() { if (this.usable() && this.pointerDragOn) { this.camera.matrixWorld = new THREE.Matrix4(); //许钟文加 unproject前先把相机置于原点 (player的cameras里的panorama是不更新matrixworld的,只有player的camera才更新。 为了其他的camera加) //两交互点在3D空间的坐标 var pointerDragStart3D = new THREE.Vector3(this.pointerDragStart.x, this.pointerDragStart.y, -1).unproject(this.camera), pointer3D = new THREE.Vector3(this.pointer.x, this.pointer.y, -1).unproject(this.camera), //两交互点分别到原点的长度 pointerDragStart3DLength = Math.sqrt(pointerDragStart3D.x * pointerDragStart3D.x + pointerDragStart3D.z * pointerDragStart3D.z), pointer3DLength = Math.sqrt(pointer3D.x * pointer3D.x + pointer3D.z * pointer3D.z), //通过Math.atan2计算在XY面上与X轴的夹角弧度。 //注:因为 z = -1,所以两者到原点的长度近似为x分量(数值的大小也不需要绝对对应) anglePointerDragStart3DToX = Math.atan2(pointerDragStart3D.y, pointerDragStart3DLength), //近似为 anglePointerDragStart3DToX = Math.atan2( pointerDragStart3D.y, pointerDragStart3D.x ) anglePointer3DToX = Math.atan2(pointer3D.y, pointer3DLength); //近似为 anglePointer3DToX = Math.atan2( pointer3D.y, pointer3D.x ) this.camera.updateMatrix(); this.camera.updateMatrixWorld(); //算出两者角度差,作为竖直方向角度差值(rotationDifference.y) this.rotationDifference.y = THREE.MathUtils.radToDeg(anglePointerDragStart3DToX - anglePointer3DToX); //y分量清零,原向量等价于在XZ轴上的投影向量 pointerDragStart3D.y = 0; pointer3D.y = 0; //归一化(/length),求两者夹角作为 //判断方向,最后记为水平方向角度差值(rotationDifference.x) var anglePointerDragStart3DToPointer3D = Math.acos(pointerDragStart3D.dot(pointer3D) / pointerDragStart3D.length() / pointer3D.length()); // isNaN(s) || (this.rotationDifference.x = THREE.MathUtils.radToDeg(s), // this.pointerDragStart.x < this.pointer.x && (this.rotationDifference.x *= -1)), if (!isNaN(anglePointerDragStart3DToPointer3D)) { this.rotationDifference.x = THREE.MathUtils.radToDeg(anglePointerDragStart3DToPointer3D); if (this.pointerDragStart.x < this.pointer.x) { this.rotationDifference.x *= -1; } } this.rotationDifference.multiplyScalar(this.speed); //更新pointerDragStart记录当前帧坐标,用于下一帧求帧差值 this.pointerDragStart.copy(this.pointer); //console.log(pointerDragStart3DLength,pointer3DLength) } } /** * 处理鼠标移动事件 * 1.计算鼠标的NDC坐标 * 2.判断是否是拖拽来决定拖拽行为的执行 * 3.通过预定义的防误触偏差(moveTolerance),来防止一定的误触 */ }, { key: "onMouseMove", value: function onMouseMove(mouseEvent) { if (this.usable()) { var mouse = math$1.handelPadding(mouseEvent.clientX, mouseEvent.clientY, this.dom); math$1.convertScreenPositionToNDC(mouse.x, mouse.y, this.pointer, this.dom); if (this.pointerDragOn) { if (Math.abs(this.pointer.x - this.moveStart.x) > this.moveTolerance || Math.abs(this.pointer.y - this.moveStart.y) > this.moveTolerance) { this.emit(ControlEvents.Move, 'mouse'); } } } } /** * 处理触摸移动事件 * 1.单点触控记录NDC坐标 * 2.双点触控记录两触摸点距离(映射到[0-1]范围) */ }, { key: "onTouchMove", value: function onTouchMove(pointerEvent) { if (this.usable()) { this.emit(ControlEvents.Move, 'touch'); switch (pointerEvent.touches.length) { case 1: var mouse = math$1.handelPadding(pointerEvent.touches[0].clientX, pointerEvent.touches[0].clientY, this.dom); math$1.convertScreenPositionToNDC(mouse.x, mouse.y, this.pointer, this.dom); break; case 2: var offsetX = (pointerEvent.touches[0].clientX - pointerEvent.touches[1].clientX) / window.innerWidth, offsetY = (pointerEvent.touches[0].clientY - pointerEvent.touches[1].clientY) / window.innerHeight, n = this.pinchDistance - Math.sqrt(offsetX * offsetX + offsetY * offsetY); if (Math.abs(n) > 0.01) { this.emit(ControlEvents.InteractionDirect); this.emit(ControlEvents.Pinch, n); this.pinchDistance -= n; } } } } }, { key: "onPointerMove", value: function onPointerMove(pointerEvent) { if (this.usable() && 'touch' === pointerEvent.pointerType) { this.pointers.forEach(function (t) { if (pointerEvent.pointerId === t.id) { t.clientX = pointerEvent.clientX; t.clientY = pointerEvent.clientY; } }); pointerEvent.touches = this.pointers; this.onTouchMove(pointerEvent); } } /** * 旋转终止后的行为 * 1.通过已记录的一组帧旋转量(rotationDifference)求平均值作为停止后惯性速度参考值。 * 2.通过设置的rotationAfterMoveMultiplier(惯性速度决定因子,用于手动指定影响惯性速度大小),来计算最后的的惯性速度 */ }, { key: "endRotation", value: function endRotation() { this.pointerDragOn = !1; var averageVector = common.averageVectors(this.rotationHistory); if (this.player.$app.VRScreenSYNC) { // 不使用惯性 //this.rotationSpeed.set(0,0) this.rotationSpeed.set(averageVector.x * settings$3.rotationAfterMoveMultiplierX / 6, averageVector.y * settings$3.rotationAfterMoveMultiplierY / 6); } else { this.rotationSpeed.set(averageVector.x * settings$3.rotationAfterMoveMultiplierX, averageVector.y * settings$3.rotationAfterMoveMultiplierY); } } /** * 触摸结束触发endRotation行为 */ }, { key: "onTouchEnd", value: function onTouchEnd(pointerEvent) { if (this.usable()) { pointerEvent.preventDefault(); pointerEvent.stopPropagation(); this.endRotation(); } } /** * 鼠标抬起触发endRotation行为 */ }, { key: "onMouseUp", value: function onMouseUp(mouseEvent) { if (this.usable()) { mouseEvent.preventDefault(); mouseEvent.stopPropagation(); this.endRotation(); } } }, { key: "onPointerUp", value: function onPointerUp(pointerEvent) { if (this.usable() && 'touch' === pointerEvent.pointerType) { this.pointers.forEach(function (t, i) { pointerEvent.pointerId === t.id && this.pointers.splice(i, 1); }.bind(this)); pointerEvent.touches = this.pointers; this.onTouchEnd(pointerEvent); } } /** * 主循环更新,主要通过物理上的刚体旋转行为(角位移,角速度,角加速度,摩擦等)计算得到新的相机视点target,主要是每帧瞬时的状态 * * updateRotation()计算每帧对应的旋转量 rotationDifference * * 角位移:rotationDifference与原本lon,lat (等价于phi,theta)累加,得到新的角位移 * 角速度:(rotationDifference数组的平均值 * 速度因子rotationAccelerationInside + 角加速度) - 摩擦rotationFriction。 * * target坐标:新的角位移计算出新的球坐标,转换计算后的球坐标到笛卡尔坐标系 * * @param { number } deltaTime 帧间隔时间。 注:关于帧间隔时间,是个有关物理计算的很重要的值,用于保持物理量与绝对时间的对应而不受帧率的的干扰,下文计算角速度用到。更多请见 https://blog.csdn.net/ChinarCSDN/article/details/82914420 */ }, { key: "update", value: function update(deltaTime) { if (this.locked) return; //if(settings.vrEnabled) return; // 求出新的rotationDifference this.updateRotation(); //记录一组rotationDifference 用于求角速度 rotationSpeed。注:见 endRotation() for (this.rotationHistory.push(this.rotationDifference.clone()); this.rotationHistory.length > settings$3.rotationAfterMoveHistoryCount;) { this.rotationHistory.shift(); } //计算角位移(交互影响下的) this.lon += this.rotationDifference.x; this.lat += this.rotationDifference.y; this.rotationDifference.set(0, 0); //计算角速度(实际上deltaTime增大时,角速度下降幅度也应增大) var friction = Math.min(1, settings$3.rotationFriction * deltaTime * 60); //如果deltaTime > 1/ 60 (比较卡),就增加rotationFriction, 以防止转动过久 this.rotationSpeed.x = this.rotationSpeed.x * (1 - friction) + this.rotationAcc.x * settings$3.rotationAccelerationInside; this.rotationSpeed.y = this.rotationSpeed.y * (1 - friction) + this.rotationAcc.y * settings$3.rotationAccelerationInside; //计算角位移(交互后,物理定律影响下的) this.lon += this.rotationSpeed.x * deltaTime; this.lat += this.rotationSpeed.y * deltaTime; //this.lat = Math.max(constants.insideLookLimitDown, Math.min(settings.insideLookLimitUp, this.lat)) //通过预定义的俯仰角最大最小范围(insideLookLimitUp、insideLookLimitDown)来限制俯仰角。 注:这种数学计算很常见,因此API也很常见(clamp),等价于 this.lat = THREE.MathUtils.clamp( this.lat, constants.insideLookLimitDown, settings.insideLookLimitUp ); //许钟文 if (this.limitDownAngel == null) { //许钟文 在手机编辑墙壁时俯视角度可以增大 var insideLookLimitDown, insideLookLimitUp; if (this.limitAngleIsBound) { //根据fov调整insideLookLimitDown 以使得能看到的边界不变。此时insideLookLimitDown为边界而不是看的角度了 insideLookLimitDown = settings$3.insideLookLimitDown - settings$3.insideFOV / 2 + this.camera.fov / 2; insideLookLimitUp = settings$3.insideLookLimitUp + settings$3.insideFOV / 2 - this.camera.fov / 2; } else { insideLookLimitDown = this.insideLookLimitDown != void 0 ? this.insideLookLimitDown : settings$3.insideLookLimitDown; insideLookLimitUp = this.insideLookLimitUp != void 0 ? this.insideLookLimitUp : settings$3.insideLookLimitUp; } this.lat = Math.max(insideLookLimitDown, Math.min(insideLookLimitUp, this.lat)); //通过预定义的俯仰角最大最小范围(insideLookLimitUp、insideLookLimitDown)来限制俯仰角。 注:这种数学计算很常见,因此API也很常见(clamp),等价于 this.lat = THREE.Math.clamp( this.lat, settings.insideLookLimitDown, settings.insideLookLimitUp ); } else { this.lat = this.limitDownAngel; //固定垂直视角 } //转换为标准球坐标参数形式,并最终转换为笛卡尔坐标系下 this.phi = THREE.MathUtils.degToRad(90 - this.lat); this.theta = THREE.MathUtils.degToRad(this.lon); this.lookVector.x = Math.sin(this.phi) * Math.cos(this.theta); this.lookVector.y = Math.cos(this.phi); this.lookVector.z = Math.sin(this.phi) * Math.sin(this.theta); //求taget坐标: 当前相机位置 + 方向向量(对于此处旋转来说距离并无意义,方向向量的1即可) this.target.copy(this.lookVector).add(this.camera.position); //THREE的API来更新相机旋转。注:lookAt是四阶矩阵比较常见的API,因此此PanoramaControls计算流程,不算与THREE耦合 this.camera.lookAt(this.target); } /** * 滚轮行为: 触发自定义事件 */ }, { key: "onMouseWheel", value: function onMouseWheel(wheelEvent) { if (this.usable()) { var t = wheelEvent.wheelDelta || -wheelEvent.detail; this.emit(ControlEvents.InteractionDirect); this.emit(ControlEvents.Scroll, t); } } /** * 键盘按下:触发自定义事件 */ }, { key: "onKeyDown", value: function onKeyDown(keyboardEvent) { if (!this.player.$app.config.useShortcutKeys) { return; } if (this.usable()) { if (keyboardEvent.metaKey || keyboardEvent.ctrlKey) ; else { keyboardEvent.preventDefault(); this.handleKeyDown(keyboardEvent.which); } } } }, { key: "handleKeyDown", value: function handleKeyDown(keyValue) { var t = function (e, t) { this.rotationAcc[e] = t; }.bind(this); this.emit(ControlEvents.InteractionKey); var i = !0; switch (keyValue) { case Keys.LEFTARROW: case Keys.J: t('x', -1); break; case Keys.RIGHTARROW: case Keys.L: t('x', 1); break; case Keys.I: t('y', 1); break; case Keys.K: t('y', -1); break; default: i = !1; } i && this.emit(ControlEvents.Move, 'key'); } }, { key: "onKeyUp", value: function onKeyUp(keyboardEvent) { if (this.usable()) { keyboardEvent.preventDefault(); keyboardEvent.stopPropagation(); this.handleKeyUp(keyboardEvent.which); } } }, { key: "handleKeyUp", value: function handleKeyUp(keyValue) { switch (keyValue) { case Keys.LEFTARROW: case Keys.J: case Keys.RIGHTARROW: case Keys.L: this.rotationAcc.x = 0; break; case Keys.I: case Keys.K: this.rotationAcc.y = 0; } } /** * 给定角加速度,使开始旋转。 注:类似给定力推 */ }, { key: "startRotating", value: function startRotating(e, t) { e && (this.rotationAcc.x = e); t && (this.rotationAcc.y = t); } /** * 通过物理定律来终止旋转 */ }, { key: "stopRotating", value: function stopRotating(e) { e && (this.rotationSpeed.x = this.rotationSpeed.y = 0); this.rotationAcc.set(0, 0); } }, { key: "reset", value: function reset() { this.pointerDragOn = !1; this.rotationAcc.set(0, 0); this.rotationSpeed.set(0, 0); this.pointers = []; } /** * 序列化,用于保存状态。 */ }, { key: "toJSON", value: function toJSON() { var cameraSpatialInfo = { camera_position: { x: math$1.toPrecision(this.camera.position.x, 4), y: math$1.toPrecision(this.camera.position.y, 4), z: math$1.toPrecision(this.camera.position.z, 4) }, camera_quaternion: { x: math$1.toPrecision(this.camera.quaternion.x, 4), y: math$1.toPrecision(this.camera.quaternion.y, 4), z: math$1.toPrecision(this.camera.quaternion.z, 4), w: math$1.toPrecision(this.camera.quaternion.w, 4) } }; return cameraSpatialInfo; } /** * 反序列化,用于读取状态 */ }, { key: "setStateFromJSON", value: function setStateFromJSON(cameraSpatialInfo) { this.camera.position.copy(cameraSpatialInfo.camera_position); this.camera.quaternion.copy(cameraSpatialInfo.camera_quaternion); } /** * 3D图形变换的坐标系 https://blog.csdn.net/CALL_LKC/article/details/81411034 */ /** * 许钟文 加 看向某个位置 * 逐渐看向某个位置 通过改变lon和lat * @param {THREE.Vector3} aim * @param {THREE.Vector3} cameraPos * @param {JSON} option */ }, { key: "startLookAt", value: function startLookAt(aim, cameraPos, option) { var useLonLat = option && (option.lon != void 0 || option.lat != void 0); if (!useLonLat) { var e = cameraPos ? cameraPos.clone().sub(aim) : this.camera.position.clone().sub(aim), o = Math.atan(e.z / e.x); o += e.x < 0 ? Math.PI : 0, o += e.x > 0 && e.z < 0 ? 2 * Math.PI : 0; var lon = THREE.MathUtils.radToDeg(o) + 180; var n = Math.sqrt(e.x * e.x + e.z * e.z), i = Math.atan(e.y / n); var lat = -THREE.MathUtils.radToDeg(i); var add = (lon - this.lon) % 360; Math.abs(add) > 180 && (add > 0 ? add -= 360 : add += 360); lon = this.lon + add; var add = (lat - this.lat) % 360; Math.abs(add) > 180 && (add > 0 ? add -= 360 : add += 360); lat = this.lat + add; } var time = 1200, speedFuc = easing['easeInOutQuad']; if (option != void 0) { if (option.soon) { this.lon = lon; this.lat = lat; return; } if (option.speed) { /* var a = Math.abs(lon - this.lon) * Math.PI /180; var b = Math.abs(lat - this.lat) * Math.PI /180; var c0 = Math.sqrt(Math.pow(Math.sin(a/2),2) + Math.pow(Math.sin(b/2),2)); var c = Math.asin(c0) * 2; //得到旋转角度 cos(c/2)的方 = cos(a/2)的方 + cos(b/2)的方 time = c / option.speed; */ if (useLonLat) { var c1 = option.lon ? Math.abs(option.lon - this.lon) : 0; var c2 = option.lat ? Math.abs(option.lat - this.lat) : 0; var c = c1 + c2; } else var c = Math.abs(lon - this.lon) + Math.abs(lat - this.lat); time = c / option.speed; //总角度除以速度 if (option.time) time = Math.min(option.time, time); } else if (option.time) time = option.time; option.fuc && setTimeout(option.fuc, time); //匀速: option.constantSpeed && (speedFuc = null); } if (useLonLat) { if (option.lon) transitions$1.start(lerp.property(this, 'lon', option.lon), time, null, 0, speedFuc); if (option.lat) transitions$1.start(lerp.property(this, 'lat', option.lat), time, null, 0, speedFuc); } else { transitions$1.start(lerp.property(this, 'lon', lon), time, null, 0, speedFuc); transitions$1.start(lerp.property(this, 'lat', lat), time, null, 0, speedFuc); } } }]); return PanoramaControls; }(EventEmitter); var ControlActions = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, ROTATE_DOLLY: 3, PAN_DOLLY: 4 }; function _createSuper$V(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$V(); 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 _isNativeReflectConstruct$V() { 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; } } /** 注: * 1.球坐标:更方便计算球面位置 https://en.wikipedia.org/wiki/Spherical_coordinate_system * 2.轨道视角OrbitView: 常见的相机视图,相机绕一点(通常为3D模型中心)做球面运动,视点锁定球心 。参见THREE.OrbitControls https://threejs.org/examples/?q=controls#misc_controls_orbit * 3.刚体对象:刚体是图形应用物理引擎中重要的物理模型对象,只考虑平移,旋转的物理量。更多参见 Unity Rigibody类 https://docs.unity3d.com/Manual/class-Rigidbody.html */ /** * 功能:漫游场景之外视角控制,主要是实现了常见的轨道视角(OrbitView),即拖拽旋转(Rotate),平移(Pan),放大缩小(Zoom),PanoramaControls和FloorplanControls的父类,两个子类的视角是基于轨道视角进行不同的限制实现的 * 原理:实现轨道视角(通过球坐标计算相机位置,使相机绕一点做球面运动,相机视角保持锁定球心) * 注: Rotate 行为是改变相机位于球坐标的位置,引发的旋转,因为视角是锁定球心的 * Zoom 行为是改变球半径,使相机距不同位置得到不同视图大小,达到缩放 * Pan 行为是改变球心位置,使轨道偏移达到视图平移效果 */ var OutsideControls = /*#__PURE__*/function (_EventEmitter) { _inherits(OutsideControls, _EventEmitter); var _super = _createSuper$V(OutsideControls); function OutsideControls(camera, dom, player) { var _this; _classCallCheck(this, OutsideControls); _this = _super.call(this); _this.setAutoPanPosition = function (e, t) { var i = new THREE.Vector3(), n = new THREE.Vector3(); return function (e, t) { i.copy(this.camera.position), void 0 === e && null === e || i.setX(e), void 0 === t && null === t || i.setZ(t); var r = this.camera.position.distanceTo(this.target), settings = Vector3.FORWARD.clone().applyQuaternion(this.camera.quaternion); this.targetClamped = !1, n.copy(i).addScaledVector(settings, r), this.targetBounds.containsPoint(n) || (this.targetBounds.clampPoint(n, n), i.copy(n).addScaledVector(settings, -r), this.targetClamped = !0), this.autoPanPosition.x = i.x, this.autoPanPosition.z = i.z, this.autoPan && this.stopAutoPanning(); }; }(); _this.camera = camera; _this.camera.controls = _assertThisInitialized(_this); _this.player = player; _this.enabled = !1; _this.target = new THREE.Vector3(); //相机视点,轨道视角下也始终是相机轨道所处球坐标的球心 //Zoom _this.targetBounds = new THREE.Box3(); //包围盒,通过碰撞检测用于限定相机的远近范围 _this.zoomSpeed = /* config.isEdit ? 2.3 : */ 1; //视角缩放的速率 _this.minDistance = 0; //最小距离,相机离球心的最小距离 _this.maxDistance = 1 / 0; //最大距离,相机离球心的最大距离 _this.scale = 1; //缩放比率,zoom操作下的相机轨道半径与正常轨道半径的比率 _this.dollyStart = new THREE.Vector2(); //推拉镜头操作下记录前一帧的交互点 _this.dollyEnd = new THREE.Vector2(); //推拉镜头操作下记录当前帧的交互点 _this.dollyDelta = new THREE.Vector2(); //推拉镜头操作下相机当前帧的瞬时位移 //Rotate _this.noRotateUpDown = !1; //禁用竖直方向的旋转,此处即为禁止相机纬度上的移动,用于俯视视角FloorplanControls _this.rotateSpeed = 1; //相机绕球心旋转速率 _this.keyboardZoomSpeed = 0; //键盘控制下的视角缩放速率 _this.keyPanSpeed = 7; //键盘控制下的平移速率 _this.autoRotate = !1; //自动旋转 _this.autoRotateSpeed = 2; //自动旋转速率 _this.minPolarAngle = THREE.MathUtils.degToRad(25); //最小纬度,用于限时相机的视角 _this.maxPolarAngle = THREE.MathUtils.degToRad(65); //最大纬度,用于限时相机的视角 _this.rotationAcceleration = new THREE.Vector2(); //旋转角加速度 _this.rotationSpeed = new THREE.Vector2(); //旋转角速度 _this.rotateStart = new THREE.Vector2(); //旋转操作下记录上次交互事件产生的交互点坐标 _this.rotateEnd = new THREE.Vector2(); //旋转操作下记录本次交互事件产生的交互点坐标 _this.rotateDelta = new THREE.Vector2(); //旋转操作下最近两次交互事件之间的瞬时角位移 _this.phiDelta = 0; //每帧瞬时水平角位移,由rotateDelta.x累加得到 _this.thetaDelta = 0; //每帧瞬时竖直角位移,由rotateDelta.y累加得到 _this.rotateCenter = new THREE.Vector2(); _this.rotateStartVec = new THREE.Vector2(); _this.rotateEndVec = new THREE.Vector2(); //Pan _this.autoPan = !1; //自动平移 _this.autoPanPosition = new THREE.Vector3(); //自动平移的球心位置 _this.panAcceleration = new THREE.Vector2(); //平移加速度 _this.panSpeed = new THREE.Vector2(); //平移速度 _this.panStart = new THREE.Vector2(); //平移操作下上次交互事件产生的交互点坐标 _this.panEnd = new THREE.Vector2(); //平移操作下本次交互事件产生的交互点坐标 _this.panDelta = new THREE.Vector2(); //平移操作下最近两次交互事件之间的瞬时位移 _this.panOffset = new THREE.Vector3(); //panLeft(), panUp() 用到的瞬时位移 _this.panVector = new THREE.Vector3(); //每帧平移的总偏移量(交互产生的偏移量),由panDelta累加得到 _this.offset = new THREE.Vector3(); //每帧最终的有效偏移量(panVector 经过 clamp 操作限制范围后的偏移) //注:交互事件瞬时位移(delta)与 帧瞬时位移(offset),产生的原因是事件交互的频率与帧更新的频率不同,eg:mousemove 约8ms < deltaTime 16.6ms _this.lastPosition = new THREE.Vector3(); //记录当前帧相机位置 _this.state = ControlActions.NONE; //当前控制器的模式,决定了mouseAction //鼠标行为 在子类中定义 _this.mouseActions = {}; _this.touchActions = {}; _this.lastMoveTime = 0; _this.pointersLimit = 2; _this.pointers = []; _this.angle = 1e-6; return _this; } /** * 设定tagetBound * @param {THREE.Box3} bound */ _createClass(OutsideControls, [{ key: "setBounds", value: function setBounds(bound) { this.targetBounds = bound; } /** * 判断控制器空闲状态 */ }, { key: "isEngaged", value: function isEngaged() { return this.state !== ControlActions.NONE; } /** * 水平旋转,通过改变相机球坐标的经度 * @param {number} angle 旋转的角度(degree) */ }, { key: "rotateLeft", value: function rotateLeft(angle) { void 0 === angle && (angle = this.getAutoRotationAngle()); this.thetaDelta -= angle; //计算每帧瞬时角位移,与鼠标移动方向相反 } /** * 竖直旋转,通过改变相机球坐标的纬度 * @param {number} angle 旋转的角度(degree) */ }, { key: "rotateUp", value: function rotateUp(angle) { if (!this.noRotateUpDown) { void 0 === angle && (angle = this.getAutoRotationAngle()); this.phiDelta -= angle; } } /** * 水平平移,通过改变相机轨道的球心使轨道平移 */ }, { key: "panLeft", value: function panLeft(e) { if (isNaN(e)) e = 0; //防止floorplan模式屏幕宽度为0过后黑屏 var t = this.camera.matrix.elements; //从相机矩阵提取计算相机方向向量于XZ平面的投影 this.panOffset.set(t[0], 0, t[2]).normalize(), this.panOffset.multiplyScalar(-e), this.panVector.add(this.panOffset); } }, { key: "panUp", value: function panUp(e) { if (isNaN(e)) e = 0; //防止floorplan模式屏幕宽度为0过后黑屏 var t = this.camera.matrix.elements; this.panOffset.set(t[4], 0, t[6]).normalize(), this.panOffset.multiplyScalar(-e), this.panVector.add(this.panOffset); } }, { key: "stopAutoPanning", value: function stopAutoPanning() { var e = this.autoPan; this.autoPan = !1, this.emit(this.targetClamped ? ControlEvents.AutoPanClamped : e ? ControlEvents.AutoPanInterrupt : ControlEvents.AutoPanComplete); } /** * 俯视视角下的缩小 */ }, { key: "dollyIn", value: function dollyIn(e) { void 0 === e && (e = this.getZoomScale()), this.scale /= e; } /** * 俯视视角下的放大 */ }, { key: "dollyOut", value: function dollyOut(e) { void 0 === e && (e = this.getZoomScale()); //e<1时是放大 反之缩小 this.scale *= e; } /** * 更新Pan操作,主要是用刚体运动规则计算每一帧的瞬时球心坐标 */ }, { key: "updatePan", value: function updatePan(e) { this.panSpeed.multiplyScalar(1 - settings$3.panFriction).addScaledVector(this.panAcceleration, settings$3.panAccelerationOutside * e); //计算球心移动的瞬时速度 this.pan(-this.panSpeed.x, this.panSpeed.y); //球心移动的瞬时坐标 //自动Pan到一个设定的位置 if (this.autoPan) { var offset = new THREE.Vector3().copy(this.autoPanPosition).sub(this.camera.position); //根据当前位置算出偏移矢量 offset.setY(0).clampLength(0, 50 * e); //位移忽略Y轴 this.target.add(offset); //得到新的球心target this.camera.position.add(offset); //相应地相机的平移量与球心一致,于是相机移到新的球面轨道 if (this.autoPanPosition.x === this.camera.position.x && this.autoPanPosition.z === this.camera.position.z) { //如果相机位置与要Pan的位置一致,没必要进行自动Pan this.autoPan = !1; this.stopAutoPanning(); } } } /** * 主循环更新,更新轨道视角OrbitView 的 Roatate, Pan, Zoom 行为参数,根本上是计算球坐标下相机的球面轨道坐标,球心位置,运动规律符合刚体运动的物理法则 * 注:刚体是图形应用物理引擎中重要的物理模型对象,借助牛顿第二定律进行计算。更多参见 Unity Rigibody类 https://docs.unity3d.com/Manual/class-Rigidbody.html */ }, { key: "update", value: function update(e, type) { if (this.updateForCad && !this.screenshot) { return; } e || (e = 1 / 60); // e 即是 帧间隔时间deltaTime 用于稳定物理运动而不受帧率影响,更多请见 https://blog.csdn.net/ChinarCSDN/article/details/82914420 或 搜索Unity Time类 var friction = Math.min(1, settings$3.rotationFriction * e * 60); //add 如果deltaTime > 1/ 60 (比较卡),就增加rotationFriction, 以防止转动过久 this.rotationSpeed.multiplyScalar(1 - friction).addScaledVector(this.rotationAcceleration, settings$3.rotationAccelerationOutside * e); //计算瞬时角速度 this.rotateLeft(-this.rotationSpeed.x); //根据角速度进行角位移 this.noRotateUpDown || this.rotateUp(this.rotationSpeed.y); this.updatePan(e); //计算 球心坐标(target)到 相机坐标(cameraPosition)的向量(offset),包含方向和距离信息 var cameraPosition = this.camera.position; this.offset.copy(cameraPosition).sub(this.target); //Rotate var lon = Math.atan2(this.offset.x, this.offset.z), //根据offset与z轴夹角算出经度lon, lat = Math.atan2(Math.sqrt(this.offset.x * this.offset.x + this.offset.z * this.offset.z), this.offset.y); //与y轴夹角算出纬度lat this.autoRotate && this.rotateLeft(this.getAutoRotationAngle()); //计算自动旋转的每帧角位移thetaDelta lon += this.thetaDelta; //原本角位移与每帧角位移累加 lat += this.phiDelta; //原本角位移与每帧角位移累加 lat = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, lat)); //纬度限制在预定义的范围内,进而限制轨道相机的俯仰角 lat = Math.max(this.angle, Math.min(Math.PI - this.angle, lat)); this.lon = lon, this.lat = lat; //xzw add for cad compass //Zoom var radius = this.updateZoom(); //获取Zoom操作后的球半径 radius = Math.max(this.minDistance, Math.min(this.maxDistance, radius)); //半径限制在自定义范围内 //Pan 更新球轨道球心位置 this.target.add(this.panVector); //球心位置加上Pan操作后球心的偏移向量panVector this.targetBounds.clampPoint(this.target, this.target); //最终球心坐标限制在自定义BoudingBox的立方体范围内。 //新的半径求新的offset(球心->相机),用于得到新轨道下相机的位置。 //注:相机位置为什么不直接加上panVector? 因为此情况下相机偏移不等于panVector //1.Zoom改变球半径 //2.Pan操作被限制在自定义范围,球心偏移可能小于panVector this.offset.x = radius * Math.sin(lat) * Math.sin(lon); this.offset.y = radius * Math.cos(lat); this.offset.z = radius * Math.sin(lat) * Math.cos(lon); //根据新的offset与球心得到相机新的轨道坐标 //Position cameraPosition.copy(this.target).add(this.offset); //轨道视角下相机视点锁定球心 //Rotation this.camera.lookAt(this.target); //重置 防止干扰其他地方的引用 this.thetaDelta = 0; this.phiDelta = 0; this.scale = 1; this.panVector.set(0, 0, 0); //记录当前帧相机的位置 if (this.lastPosition.distanceTo(this.camera.position) > 0) { this.lastPosition.copy(this.camera.position); } } /** * 角速度 角度转弧度 */ }, { key: "getAutoRotationAngle", value: function getAutoRotationAngle() { return 2 * Math.PI / 60 / 60 * this.autoRotateSpeed; } }, { key: "getZoomScale", value: function getZoomScale() { return Math.pow(0.95, this.zoomSpeed); } /** * 鼠标点击行为 */ }, { key: "onMouseDown", value: function onMouseDown(mouseEvent) { if (this.enabled) { mouseEvent.preventDefault(); // this.player.model._3dTilesRuntime.pauseTilesetUpdate(true) // this.player.model._3dTilesRuntime.clearLoadingTiles() this.stopAutoPanning(); this.mouseDown = !0; this.state = this.mouseActions[mouseEvent.button]; switch (this.state) { case ControlActions.ROTATE: this.rotateStart.set(mouseEvent.clientX, mouseEvent.clientY); //this.rotateStart.set(mouseEvent.clientX, this.noRotateUpDown ? 0 : mouseEvent.clientY); this.rotationSpeed.set(0, 0); if (this.noRotateUpDown) { //floorplan this.rotateCenter = convertTool.getPos2d(this.target, this.player).pos; this.rotateStartVec.subVectors(this.rotateStart, this.rotateCenter); } break; case ControlActions.DOLLY: this.dollyStart.set(mouseEvent.clientX, mouseEvent.clientY); break; case ControlActions.PAN: this.panStart.set(mouseEvent.clientX, mouseEvent.clientY); } this.emit(ControlEvents.InputStart, 'mouse'); } } //控制模型 }, { key: "onMouseMove", value: function onMouseMove(mouseEvent) { if (this.enabled && this.mouseDown && 0 !== mouseEvent.buttons) { mouseEvent.preventDefault(); switch (this.state) { case ControlActions.ROTATE: this.rotateEnd.set(mouseEvent.clientX, mouseEvent.clientY); if (this.noRotateUpDown) { //floorplan this.rotateEndVec.subVectors(this.rotateEnd, this.rotateCenter); var angle = math$1.getVec2Angle(this.rotateStartVec, this.rotateEndVec); var rotateEndVec_ = new THREE.Vector3(this.rotateEndVec.x, this.rotateEndVec.y, 0); var rotateStartVec_ = new THREE.Vector3(this.rotateStartVec.x, this.rotateStartVec.y, 0); if (rotateEndVec_.clone().cross(rotateStartVec_).z < 0) { angle *= -1; } this.rotateLeft(angle); this.rotateStartVec.copy(this.rotateEndVec); } else { //dollhouse this.rotateDelta.subVectors(this.rotateEnd, this.rotateStart); this.rotateLeft(2 * Math.PI * this.rotateDelta.x / this.player.domElement.clientWidth * this.rotateSpeed); this.rotateUp(2 * Math.PI * this.rotateDelta.y / this.player.domElement.clientHeight * this.rotateSpeed); this.rotateStart.copy(this.rotateEnd); } break; case ControlActions.DOLLY: this.dollyEnd.set(mouseEvent.clientX, mouseEvent.clientY), this.dollyDelta.subVectors(this.dollyEnd, this.dollyStart); var t = this.dollyDelta.y > 0 ? this.dollyIn : this.dollyOut; t.call(this), this.dollyStart.copy(this.dollyEnd); break; case ControlActions.PAN: this.panEnd.set(mouseEvent.clientX, mouseEvent.clientY); this.panDelta.subVectors(this.panEnd, this.panStart); this.pan(this.panDelta.x, this.panDelta.y); this.panStart.copy(this.panEnd); } this.emit(ControlEvents.Move, 'mouse'); this.lastMoveTime = mouseEvent.timeStamp; this.update(); //同步 var info = {}; info.quaternion = { _w: this.camera.quaternion._w, _x: this.camera.quaternion._x, _y: this.camera.quaternion._y, _z: this.camera.quaternion._z }; info.position = { x: this.camera.position.x, y: this.camera.position.y, z: this.camera.position.z }; info.target = { x: this.target.x, y: this.target.y, z: this.target.z }; this.player.emit(PlayerEvents.MoveModel, { info: info, mode: this.player.mode, type: 'moveModel' }); } } }, { key: "onMouseUp", value: function onMouseUp(mouseEvent) { if (this.enabled) { this.mouseDown = !1; this.state = ControlActions.NONE; if ('mouseover' !== mouseEvent.type) { if (mouseEvent.timeStamp > this.lastMoveTime + 100) { this.rotationSpeed.set(0, 0); this.rotationAcceleration.set(0, 0); } else { this.rotationAcceleration.set(-this.rotateDelta.x, this.rotateDelta.y); } this.update(); this.rotationAcceleration.set(0, 0); this.rotateDelta.set(0, 0); } } } }, { key: "onMouseOver", value: function onMouseOver(mouseEvent) { 0 !== mouseEvent.which && 0 !== mouseEvent.buttons || this.onMouseUp(mouseEvent); } }, { key: "onMouseWheel", value: function onMouseWheel(wheelEvent) { if (this.enabled && settings$3.useWheel) { this.emit(ControlEvents.Move, 'wheel'); var t = wheelEvent.wheelDelta || -wheelEvent.detail; var func = this.dollyIn; if (t > 0) { func = this.dollyOut; } func.call(this); this.update(); //同步 var info = {}; //俯视图情况 if (this.player.mode === Viewmode$1.FLOORPLAN) { info.scale = this.absoluteScale; this.player.emit(PlayerEvents.MoveModel, { info: info, mode: Viewmode$1.FLOORPLAN, type: 'moveModel' }); } //dollhouse情况 else if (this.player.mode === Viewmode$1.DOLLHOUSE) { info.quaternion = this.camera.quaternion; info.position = this.camera.position; info.target = this.target; this.player.emit(PlayerEvents.MoveModel, { info: info, mode: Viewmode$1.DOLLHOUSE, type: 'moveModel' }); } } } }, { key: "onKeyDown", value: function onKeyDown(keyboardEvent) { if (this.enabled) { if (keyboardEvent.metaKey || keyboardEvent.ctrlKey) ; else { keyboardEvent.preventDefault(); this.handleKeyDown(keyboardEvent.which); } } } }, { key: "navRotationAcc", value: function navRotationAcc(e, t) { 'y' === e ? this.noRotateUpDown ? this.keyboardZoomSpeed = t : this.rotationAcceleration.y = t : this.rotationAcceleration.x = t; } }, { key: "navPanAcc", value: function navPanAcc(e, t) { this.stopAutoPanning(), this.panAcceleration[e] = t; } }, { key: "handleKeyDown", value: function handleKeyDown(keyValue) { var t = !0; switch (keyValue) { case Keys.UPARROW: case Keys.I: this.navRotationAcc('y', 1); break; case Keys.DOWNARROW: case Keys.K: this.navRotationAcc('y', -1); break; case Keys.LEFTARROW: case Keys.J: this.navRotationAcc('x', -1); break; case Keys.RIGHTARROW: case Keys.L: this.navRotationAcc('x', 1); break; case Keys.W: this.navPanAcc('y', 1); break; case Keys.S: this.navPanAcc('y', -1); break; case Keys.A: this.navPanAcc('x', -1); break; case Keys.D: this.navPanAcc('x', 1); break; default: t = !1; } t && this.emit(ControlEvents.Move, 'key'); } }, { key: "onKeyUp", value: function onKeyUp(keyboardEvent) { if (this.enabled) { keyboardEvent.preventDefault(); keyboardEvent.stopPropagation(); this.handleKeyUp(keyboardEvent.which); } } }, { key: "handleKeyUp", value: function handleKeyUp(keyValue) { switch (keyValue) { case Keys.I: case Keys.K: case Keys.UPARROW: case Keys.DOWNARROW: this.keyboardZoomSpeed = 0, this.rotationAcceleration.y = 0; break; case Keys.J: case Keys.L: case Keys.LEFTARROW: case Keys.RIGHTARROW: this.rotationAcceleration.x = 0; break; case Keys.S: case Keys.W: this.panAcceleration.y = 0; break; case Keys.A: case Keys.D: this.panAcceleration.x = 0; } } }, { key: "onTouchStart", value: function onTouchStart(pointerEvent) { if (this.enabled || this.state === ControlActions.NONE) { pointerEvent.preventDefault(); pointerEvent.stopPropagation(); this.stopAutoPanning(); var dolly = function () { if (2 === pointerEvent.touches.length) { var t = pointerEvent.touches[0].pageX - pointerEvent.touches[1].pageX, i = pointerEvent.touches[0].pageY - pointerEvent.touches[1].pageY; this.dollyStart.set(t, i); } }.bind(this), pan = function () { this.panStart.set(common.average(pointerEvent.touches, 'pageX'), common.average(pointerEvent.touches, 'pageY')); }.bind(this), rotate = function () { if (this.noRotateUpDown) { //floorplan if (!pointerEvent.touches[1]) { console.error('!pointerEvent.touches[0]11'); } var touch0 = new THREE.Vector2(pointerEvent.touches[0].pageX, pointerEvent.touches[0].pageY); var touch1 = new THREE.Vector2(pointerEvent.touches[1].pageX, pointerEvent.touches[1].pageY); this.rotateStartVec.subVectors(touch0, touch1); this.rotateStart = touch0; //上次的touch0 this.rotateCenter = convertTool.getPos2d(this.target, this.player).pos; //target在二维上的位置, 是旋转和缩放的中心 } else { //dollhouse this.rotateStart.set(common.average(pointerEvent.touches, 'pageX'), common.average(pointerEvent.touches, 'pageY')); } }.bind(this); this.state = this.touchActions[pointerEvent.touches.length]; switch (this.state) { case ControlActions.PAN_DOLLY: //switch语句原理是跳转到caseX位置执行剩下的语句,直到最后或者遇见break为止 dolly(); case ControlActions.PAN: pan(); break; case ControlActions.ROTATE_DOLLY: dolly(); case ControlActions.ROTATE: rotate(); //floorplan 单指会执行 2 双指34 //dollhouse 单指会执行 4 双指1 } this.rotationSpeed.set(0, 0); this.emit(ControlEvents.InputStart, 'touch'); } } }, { key: "onTouchMove", value: function onTouchMove(pointerEvent) { if (!pointerEvent.changedTouches) return; //#43188 测试发现有时候pointEvent会卡住,暂时只处理touchEvent对象 if (this.enabled && this.state !== ControlActions.NONE) { var stateNow = this.touchActions[pointerEvent.touches.length]; if (stateNow != this.state) { //iphoneX 在touchmove到别的ui时的时touches个数会与touchstart时不一样 return; //console.error('state更改') } pointerEvent.preventDefault(); pointerEvent.stopPropagation(); //console.log('onTouchMove',pointerEvent.touches) //缩放直接修改相机projectionMatrix (currentScale), 平移和旋转则修改相机modelMatrix var scale = function () { //根据双指距离直接缩放(假定手指所在的三维位置在缩放后应该不变,所以缩放比率为手指在屏幕上的距离变化) var t = pointerEvent.touches[0].pageX - pointerEvent.touches[1].pageX, i = pointerEvent.touches[0].pageY - pointerEvent.touches[1].pageY; this.dollyEnd.set(t, i); var scale = this.dollyEnd.length() / this.dollyStart.length(); if (scale > 1) { //放大 //this.dollyOut(1/scale); this.dollyIn(scale); //console.log("放大"+scale) } else { //this.dollyIn(scale); this.dollyOut(1 / scale); //console.log("缩小"+scale) } //dollyLen > 0 ? this.dollyOut(1 + dollyLen / 500) : this.dollyIn(1 - dollyLen / 500), this.dollyStart.copy(this.dollyEnd); return scale; }.bind(this), pan = function () { // 平移 if (pointerEvent.touches.length == 0) return; //手机从按钮处滑动到canvas时会有这种情况 this.panEnd.set(common.average(pointerEvent.touches, 'pageX'), common.average(pointerEvent.touches, 'pageY')); this.panDelta.subVectors(this.panEnd, this.panStart); window.logEnable && console.log('delta', Array.from(pointerEvent.touches).map(function (e) { return [e.pageX.toFixed(1), e.pageY.toFixed(1)]; }), pointerEvent.touches instanceof Array, pointerEvent.currentTarget.className + pointerEvent.currentTarget.nodeName); this.pan(this.panDelta.x, this.panDelta.y); this.panStart.copy(this.panEnd); this.rotateDelta.set(0, 0); }.bind(this), panTwoPointers = function (scale, angle) { // 双指平移。 平移向量为 上次的touch0到旋转中心的向量 加上 旋转中心到绕中心旋转后的新的touch0的向量的scale分之一。 (先把相机平移到上次的touch0然后旋转后退到合适的位置,将位移量的逆和上述几个向量作比较得出) //获取touch0在按照scale, angle的方式改变后的位置到实际手指移动到的新的位置的位移量 var touch0 = new THREE.Vector2(pointerEvent.touches[0].pageX, pointerEvent.touches[0].pageY); var rotResult = touch0.clone().rotateAround(this.rotateCenter, angle); var Op0 = rotResult.clone().sub(this.rotateCenter).multiplyScalar(1 / scale); var Op1 = this.rotateCenter.clone().sub(this.rotateStart); this.panDelta.addVectors(Op0, Op1); this.pan(this.panDelta.x, this.panDelta.y); this.rotateStart = touch0; }.bind(this), rot = function () { if (this.noRotateUpDown) { //floorplan var touch0 = new THREE.Vector2(pointerEvent.touches[0].pageX, pointerEvent.touches[0].pageY); var touch1 = new THREE.Vector2(pointerEvent.touches[1].pageX, pointerEvent.touches[1].pageY); this.rotateEndVec.subVectors(touch0, touch1); //当前双指角度 var angle = math$1.getVec2Angle(this.rotateStartVec, this.rotateEndVec); //和上次的双指角度求夹角,即为旋转角度 var rotateEndVec_ = new THREE.Vector3(this.rotateEndVec.x, this.rotateEndVec.y, 0); var rotateStartVec_ = new THREE.Vector3(this.rotateStartVec.x, this.rotateStartVec.y, 0); if (rotateEndVec_.clone().cross(rotateStartVec_).z < 0) { angle *= -1; } this.rotateLeft(angle); this.rotateStartVec.copy(this.rotateEndVec); return angle; } else { //dollhouse还是之前的方式:单指旋转,根据滑动距离来旋转 this.rotateEnd.set(common.average(pointerEvent.touches, 'pageX'), common.average(pointerEvent.touches, 'pageY')); this.rotateDelta.subVectors(this.rotateEnd, this.rotateStart); this.rotateLeft(2 * Math.PI * this.rotateDelta.x / this.player.domElement.clientWidth * this.rotateSpeed); this.rotateUp(2 * Math.PI * this.rotateDelta.y / this.player.domElement.clientHeight * this.rotateSpeed); this.rotateStart.copy(this.rotateEnd); } }.bind(this); /* rotOrScale = function() { console.log('rotOrScale') if (2 === pointerEvent.touches.length) { var i = window.devicePixelRatio || 1 , r = pointerEvent.touches[1].pageX - pointerEvent.touches[0].pageX , s = pointerEvent.touches[1].pageY - pointerEvent.touches[0].pageY , l = Math.sqrt(r * r + s * s) , h = Math.abs(this.dollyStart.length() - l); //修改为可以同时缩放平移旋转 if (h > settings.input.touchMoveThreshold * i) this.state = ControlActions.DOLLY, scale(); else { var u = common.average(pointerEvent.touches, "pageX") , d = common.average(pointerEvent.touches, "pageY") , p = this.rotateDelta.set(u, d).sub(this.rotateStart).length(); if(p > settings.input.touchMoveThreshold) { this.state = ControlActions.ROTATE; this.rotateStart.set(u, d); rot(); } } } }.bind(this); */ switch (this.state //floorplan会执行23,dollhouse会执行125 ) { case ControlActions.PAN_DOLLY: scale(); case ControlActions.PAN: pan(); break; case ControlActions.ROTATE_DOLLY: //floorplan双指改为可以缩放、旋转、 平移 //rotOrScale(); var s = scale(); var angle = rot(); panTwoPointers(s, angle); break; case ControlActions.DOLLY: scale(); break; case ControlActions.ROTATE: rot(); break; default: this.state = ControlActions.NONE; } //floorplan 单指会执行 2 双指3 //dollhouse 单指会执行 5 双指12 this.lastMoveTime = pointerEvent.timeStamp; this.emit(ControlEvents.Move, 'touch'); //同步 var info = { scale: this.absoluteScale }; info.quaternion = { _w: this.camera.quaternion._w, _x: this.camera.quaternion._x, _y: this.camera.quaternion._y, _z: this.camera.quaternion._z }; info.position = { x: this.camera.position.x, y: this.camera.position.y, z: this.camera.position.z }; info.target = { x: this.target.x, y: this.target.y, z: this.target.z }; this.player.emit(PlayerEvents.MoveModel, { info: info, mode: this.player.mode, type: 'moveModel' }); } } }, { key: "onTouchEnd", value: function onTouchEnd(pointerEvent) { if (this.enabled) { if (this.state === ControlActions.ROTATE) { if (pointerEvent.timeStamp > this.lastMoveTime + 100) { this.rotationSpeed.set(0, 0); this.rotationAcceleration.set(0, 0); } else { this.rotationAcceleration.set(-this.rotateDelta.x, this.rotateDelta.y); } } this.state = ControlActions.NONE; this.update(); this.rotationAcceleration.set(0, 0); this.rotateDelta.set(0, 0); } } }, { key: "onPointerDown", value: function onPointerDown(pointerEvent) { if (this.enabled) { if ('touch' === pointerEvent.pointerType) { if (this.pointers.length < this.pointersLimit && !this.pointers.find(function (pointer) { return pointer.id == pointerEvent.pointerId; })) { this.pointers.push({ id: pointerEvent.pointerId, pageX: pointerEvent.pageX, pageY: pointerEvent.pageY }); } pointerEvent.touches = this.pointers; this.onTouchStart(pointerEvent); } this.emit(ControlEvents.InputStart, 'pointer'); } } }, { key: "onPointerMove", value: function onPointerMove(pointerEvent) { if (this.enabled && 'touch' === pointerEvent.pointerType) { this.pointers.forEach(function (t) { if (pointerEvent.pointerId === t.id) { t.pageX = pointerEvent.pageX; t.pageY = pointerEvent.pageY; t.pressed = pointerEvent.pressed; } }); pointerEvent.touches = this.pointers; //转化为onTouchMove的touches //console.log('onPointerMove',pointerEvent.touches) this.onTouchMove(pointerEvent); } } }, { key: "onPointerUp", value: function onPointerUp(pointerEvent) { if (this.enabled && 'touch' === pointerEvent.pointerType) { /* this.pointers.forEach(function(t, i) { pointerEvent.pointerId === t.id && this.pointers.splice(i, 1)//这样肯定bug } .bind(this)); */ this.pointers = this.pointers.filter(function (pointer) { return pointer.id != pointerEvent.pointerId; }); pointerEvent.touches = this.pointers; this.onTouchEnd(pointerEvent); } } }, { key: "reset", value: function reset() { this.state = ControlActions.NONE, this.stopAutoPanning(), this.rotationSpeed.set(0, 0), this.rotationAcceleration.set(0, 0), this.panSpeed.set(0, 0), this.panAcceleration.set(0, 0); } }, { key: "toJSON", value: function toJSON() { var cameraSpatialInfo = { camera_position: { x: math$1.toPrecision(this.camera.position.x, 4), y: math$1.toPrecision(this.camera.position.y, 4), z: math$1.toPrecision(this.camera.position.z, 4) }, camera_quaternion: { x: math$1.toPrecision(this.camera.quaternion.x, 4), y: math$1.toPrecision(this.camera.quaternion.y, 4), z: math$1.toPrecision(this.camera.quaternion.z, 4), w: math$1.toPrecision(this.camera.quaternion.w, 4) } }; return cameraSpatialInfo; } }]); return OutsideControls; }(EventEmitter); function _createSuper$U(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$U(); 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 _isNativeReflectConstruct$U() { 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; } } /** * 迷你模式相机控制器 * 主要是在轨道视角的基础上限制Pan操作的范围 */ var DollhouseControls = /*#__PURE__*/function (_OutsideControls) { _inherits(DollhouseControls, _OutsideControls); var _super = _createSuper$U(DollhouseControls); function DollhouseControls(camera, dom, player) { var _this; _classCallCheck(this, DollhouseControls); //OutsideControls.call(this, camera); _this = _super.call(this, camera, dom, player); _this.minPolarAngle = settings$3.dollhouseDefault.minPolarAngle; //最小纬度 _this.maxPolarAngle = settings$3.dollhouseDefault.maxPolarAngle; //最大纬度 _this.minDistance = settings$3.dollhouseDefault.minDistance; //最小球半径 _this.maxDistance = settings$3.dollhouseDefault.maxDistance; //最大球半径 _this.adjustedMinDistance = _this.minDistance; _this.adjustedMaxDistance = _this.maxDistance; //鼠标所交互的界面元素 _this.dom = dom; _this.mode = 'model'; // "security" //鼠标、触点行为 _this.mouseActions[MouseButton.LEFT] = ControlActions.ROTATE; _this.mouseActions[MouseButton.MIDDLE] = ControlActions.DOLLY; _this.mouseActions[MouseButton.RIGHT] = ControlActions.PAN; _this.touchActions[1] = ControlActions.ROTATE; _this.touchActions[2] = ControlActions.PAN_DOLLY; return _this; } /** * 平移操作 */ _createClass(DollhouseControls, [{ key: "pan", value: function pan(panSpeedX, panSpeedY) { this.camera.updateMatrix(); var len = Math.max(this.camera.position.clone().sub(this.target).length(), this.mode == 'security' ? 1 : 0); len *= Math.tan(this.camera.fov / 2 * Math.PI / 180); this.panLeft(2 * panSpeedX * len / this.player.domElement.clientWidth); this.panUp(-2 * panSpeedY * len / this.player.domElement.clientHeight); } /** * 缩放,更改轨道半径 */ }, { key: "updateZoom", value: function updateZoom() { var offsetLen = this.offset.length(); //当前轨道半径,见父类OutsideControls return offsetLen * this.scale; } /** * 设置Zoom的碰撞范围,使相机在合适的范围内缩放 * 理论上的合理范围:[模型边界半径, 世界最大范围] 与 自定义范围:[settings.dollhouseDefault.minDistance, settings.dollhouseDefault.maxDistance] 的交集 */ }, { key: "setZoomBounds", value: function setZoomBounds(boundingBox) { boundingBox.min.distanceTo(boundingBox.max); //计算(模型)包围盒对角,得到模型的外边界范围 //this.suitableDistance = distance/2 / Math.tan(THREE.Math.degToRad(70/2)) var distanceHorizon = boundingBox.min.distanceTo(boundingBox.max.clone().setY(boundingBox.min.y)); //模型橫向最大距离 //var distanceVerti = (boundingBox.max.y - boundingBox.min.y) *1.1 //模型纵向最大距离 *1.1 是假定, 因为飞出后有一定俯视角度 var distanceVerti = (boundingBox.max.y - boundingBox.min.y) * 0.5 + distanceHorizon * 0.5; //模型纵向最大距离 + distanceHorizon: 飞出后有一定俯视角度 this.camera.suitModelAspect = distanceHorizon / distanceVerti; //模型比例。 用于和界面比例作比较 //this.camera.suitModelAspect = Math.min(this.camera.suitModelAspect, 1.7) //这个太大会导致fov太大,导致倾斜角度太大,然后距离很近,外侧被遮挡。 手动缩小后的损失是当屏幕宽度比大于该值时,横向不会占满,但是无大碍。 //假定飞出后当camera.aspect == camera.suitModelAspect时,刚好camera.vHov(也就是camera.fov)为默认值settings.dollhouseFOV,存储这时候的hFov(suitModelAspectHFov), 当界面宽度缩小时,模型的hFov不变,按比例变化vHov;当界面宽度放大时,fov则不变。 目的是防止模型缩得太小,自适应屏幕 this.distanceHorizon = distanceHorizon; this.distanceVerti = distanceVerti; this.updateDistance(this.camera.aspect); /* var distance = boundingBox.min.distanceTo(boundingBox.max) this.adjustedMinDistance = Math.max(Math.min(distance / 2, settings.dollhouseDefault.minDistance), 0) this.adjustedMaxDistance = Math.min(Math.max(distance, settings.dollhouseDefault.maxDistance), settings.skyboxRadius) this.minDistance = this.adjustedMinDistance this.maxDistance = this.adjustedMaxDistance */ } }, { key: "updateDistance", value: function updateDistance(aspect) { var oldDistance = this.suitableDistance; if (!this.player.model || isNaN(this.camera.suitModelAspect) || this.forbitSetRanges) return; var boundingBox = this.player.model.boundingBox; if (aspect <= this.camera.suitModelAspect) { var HFov = cameraLight.getHFOVFromVFOV(this.camera.fov, aspect, 1); this.suitableDistance = this.distanceHorizon / 2 / Math.tan(THREE.MathUtils.degToRad(HFov / 2)); //飞出时模型宽度占满屏宽时的距离 this.suitableDistance += Math.min(boundingBox.max.x - boundingBox.min.x, boundingBox.max.z - boundingBox.min.z) * 0.5; //console.log('w '+ this.suitableDistance) } else { this.suitableDistance = this.distanceVerti / 2 / Math.tan(THREE.MathUtils.degToRad(this.camera.fov / 2)); this.suitableDistance += Math.min(boundingBox.max.x - boundingBox.min.x, boundingBox.max.z - boundingBox.min.z) * 0.5; //console.log('h '+ this.suitableDistance) } this.adjustedMaxDistance = this.suitableDistance * 10; //1.2 //主要为了防止缩得太小 this.adjustedMinDistance = this.suitableDistance * 0.1; //设置为0会卡住 this.resetRanges(); if (this.enabled) { this.scale = this.suitableDistance / oldDistance; //this.updateZoom() } } /** * 重置轨道半径,纬度的取值范围。有参按参数取值否则为全局自定义值 */ }, { key: "resetRanges", value: function resetRanges(e, t) { if (this.forbitSetRanges) return; if (e) { this.minDistance = Math.min(e, this.minDistance); this.maxDistance = Math.max(e, this.maxDistance); } else { this.minDistance = this.adjustedMinDistance; this.maxDistance = this.adjustedMaxDistance; } if (t) { this.minPolarAngle = THREE.MathUtils.degToRad(-15); this.maxPolarAngle = THREE.MathUtils.degToRad(89.9); } else { this.minPolarAngle = settings$3.dollhouseDefault.minPolarAngle; this.maxPolarAngle = settings$3.dollhouseDefault.maxPolarAngle; } } }, { key: "toJSON", value: function toJSON() { return OutsideControls.prototype.toJSON.call(this); } }]); return DollhouseControls; }(OutsideControls); function _createSuper$T(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$T(); 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 _isNativeReflectConstruct$T() { 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; } } var FloorplanControls = /*#__PURE__*/function (_OutsideControls) { _inherits(FloorplanControls, _OutsideControls); var _super = _createSuper$T(FloorplanControls); function FloorplanControls(camera, dom, player) { var _this; _classCallCheck(this, FloorplanControls); _this = _super.call(this, camera, dom, player); _this.minDistance = 5; //最小球半径 _this.maxDistance = 100; //最大球半径 _this.noRotateUpDown = !0; //是否禁止竖直方向的旋转,即禁用纬度上的角位移 _this.minPolarAngle = 0; //最小纬度 (0度在北极往下看,180度在南极往上看) 对应lat _this.maxPolarAngle = 0; //最大纬度 _this.absoluteScale = 1; //当前控制器下的默认缩放 _this.currentScale = 1; //鼠标所交互的界面元素 _this.dom = dom; _this.$app = player.$app; _this.plane = null; _this.cadSize = null; _this.floorTexture = null; //鼠标、触点行为 _this.mouseActions[MouseButton.LEFT] = ControlActions.PAN; _this.mouseActions[MouseButton.MIDDLE] = ControlActions.DOLLY; _this.mouseActions[MouseButton.RIGHT] = ControlActions.ROTATE; _this.touchActions[1] = ControlActions.PAN; _this.touchActions[2] = ControlActions.ROTATE_DOLLY; return _this; } /** * 屏幕大小变化后,相应的也要调整 */ /* updateFloorCad() { if (this.plane != null && this.plane != 'nofile') { var planeWidth = this.plane.geometry.parameters.width; var planeHeight = this.plane.geometry.parameters.height; var modelWidth = this.player.model.boundingBox.max.x - this.player.model.boundingBox.min.x; var modelHeight = this.player.model.boundingBox.max.z - this.player.model.boundingBox.min.z; var width = this.camera.right - this.camera.left; var height = this.camera.top - this.camera.bottom; let scale = app.player.domElement.clientWidth / (this.camera.right - this.camera.left); this.plane.scale.x = (modelWidth + (this.cadSize.left + this.cadSize.right) / scale) / planeWidth; this.plane.scale.z = (modelHeight + (this.cadSize.left + this.cadSize.right) / scale) / planeHeight; } } */ /** * 相机通过缩放Zoom,使模型适当充满视口。 * 1.得到模型平面(XZ)尺寸 * 2.分别计算视口宽高比 大于1,小于1 两种情况下模型所占最大的视口尺寸 * 3.以模型所占最大视口尺寸为基准,调整绝对缩放比 * @param {Vector3} modelSize */ _createClass(FloorplanControls, [{ key: "zoomToContain", value: function zoomToContain(modelSize, ratio) { var absoluteScale = this.getDefaultAbsoluteScale(modelSize, ratio); //改 this.absoluteScale = absoluteScale; this.currentScale = this.absoluteScale; } /** * * @param {Vector3} modelSize */ }, { key: "getDefaultAbsoluteScale", value: function getDefaultAbsoluteScale(modelSize, ratio, angle) { //const metadata = app.store.getters['scene/metadata'] || {} var absoluteScale; /* if(metadata.floorPlanAngle || config.floorPlanNoRotate ){//指定了角度的话,就和browser.aspectRatio()无关,总使用纵向 var angle = 0; if(metadata.floorPlanAngle ){//规定了cadImage旋转值的话 angle = parseFloat(metadata.floorPlanAngle) } else if ( config.floorPlanNoRotate )//为了让cadImage的字是正的,所以当有labels的时候恒定这个方向 { angle = 0; } modelSize = modelSize.clone().applyEuler(new THREE.Euler(0, angle, 0)) var n = Math.max(Math.abs(modelSize.x), Math.abs(modelSize.z) * this.camera.aspect) //视口宽高比 >= 1 情况下,模型所占最大视口尺寸 var screenSize = Math.min($("#player").width(), $("#player").height()) var maxSize = 800;//模型最大占据像素 ratio = ratio != void 0 ? ratio : Math.max(screenSize * 1.2 / maxSize, 1.2) ; absoluteScale = n / 2 / settings.orthoBase * ratio; //根据模型所占最大视口尺寸调整缩放 }else{ */ /* xst var maxModelSize = Math.max(modelSize.x, modelSize.z), minModelSize = Math.min(modelSize.x, modelSize.z), n = Math.max(maxModelSize, minModelSize * this.camera.aspect), //视口宽高比 >= 1 情况下,模型所占最大视口尺寸 r = Math.max(minModelSize, maxModelSize * this.camera.aspect) //视口宽高比 < 1 情况下,模型所占最大视口尺寸 absoluteScale = ((browser.aspectRatio() < 1 ? r : n) / 2 / settings.orthoBase) * (ratio != void 0 ? ratio : 1.2) //根据模型所占最大视口尺寸调整缩放 */ //} //xst if (angle == null || typeof angle == 'undefined') { angle = this.$app.store.getValue('metadata').floorPlanAngle; if (typeof angle == 'undefined') { angle = 0; } angle = parseFloat(angle); } modelSize = modelSize.clone().applyEuler(new THREE.Euler(0, angle, 0)); var n = Math.max(Math.abs(modelSize.x), Math.abs(modelSize.z) * this.camera.aspect); //视口宽高比 >= 1 情况下,模型所占最大视口尺寸 var player = this.$app.core.get('Player'); var screenSize = Math.min(player.domElement.clientWidth - 400, player.domElement.clientHeight - 200); var maxSize = 800; //模型最大占据像素 var maxRatio = player.linkEditor && (player.linkEditor.setTagVisible || player.linkEditor.setPanoVisible) ? 1.2 : 2; ratio = ratio != void 0 ? ratio : Math.max(screenSize * maxRatio / maxSize, maxRatio); absoluteScale = n / 2 / settings$3.orthoBase * ratio; //根据模型所占最大视口尺寸调整缩放 return absoluteScale; } /** * 相机通过旋转Rotate,使模型尺寸长宽比匹配相机视野宽高比 * @param {Vector3} modelSize * @param {Vector3} direction */ }, { key: "rotateToView", value: function rotateToView(modelSize, direction) { var i = 0, n = browser$1.aspectRatio() < 1, //是否模型尺寸显“细长” r = modelSize.x < modelSize.z; //是否视口为“窄屏” var metadata = this.$app.store.getValue('metadata'); if (metadata.floorPlanAngle !== void 0) { //规定了cadImage旋转值的话 i = 2 * Math.PI - 1 * parseFloat(metadata.floorPlanAngle); //i = parseFloat(metadata.floorPlanAngle) } else if (n === r /* || config.floorPlanNoRotate */ ) { //为了让cadImage的字是正的,所以当有labels的时候恒定这个方向 i = 0; } else { i = Math.PI / 2; } //i = Math.PI / 2 this.rotateLeft(i); this.update(0); } /** * 平移操作,相对相机的本地坐标 * @param {Number} panSpeedX * @param {Number} panSpeedY */ }, { key: "pan", value: function pan(panSpeedX, panSpeedY) { this.camera.updateMatrix(); this.panLeft(panSpeedX * (this.camera.right - this.camera.left) / this.player.domElement.clientWidth); //括号内是移动模型的距离,单位米 this.panUp(-panSpeedY * (this.camera.top - this.camera.bottom) / this.player.domElement.clientHeight); } /** * 缩放操作,与透视相机不同,此模式下采用正交相机,通过改变相机轨道半径从而改变相机距离无意义,缩放是通过调整相机投影视口大小的方式 */ }, { key: "updateZoom", value: function updateZoom() { //计算缩放比 this.absoluteScale *= this.scale - 0.03 * this.keyboardZoomSpeed; //滚轮缩放 this.absoluteScale = Math.max(settings$3.zoomNearLimit, Math.min(this.absoluteScale, settings$3.zoomFarLimit)); //if(this.farestScale) this.absoluteScale = Math.min(this.farestScale, this.absoluteScale);//add for cadImg this.currentScale = 0.8 * this.currentScale + 0.2 * this.absoluteScale; //----许钟文------------------------------------ //默认根据屏幕宽度变化大小。当截取俯视图时,保留截取时绝对大小,无论截取什么比例,房子都不会被缩放。 //而后导览时,无论什么比例下飞到这个导览点,房子都是这个大小。 //本意是如果想设置在某窗口比例下的房子大小时,比如手机大小,当截取成功后缩略图和满屏时房子都不会变化大小。 //在满屏时截取,缩小宽度后点击房子也不会变小。缺点:当窗口很窄时,房子会略大。 var s = this.snapshotTopAspect ? this.camera.aspect / this.snapshotTopAspect : 1; //通过相机视口参数来调整相机投影视口大小 this.camera.left = -settings$3.orthoBase * this.currentScale * s; //* this.camera.aspect; this.camera.right = settings$3.orthoBase * this.currentScale * s; //* this.camera.aspect; this.camera.top = settings$3.orthoBase * this.currentScale * s / this.camera.aspect; this.camera.bottom = -settings$3.orthoBase * this.currentScale * s / this.camera.aspect; this.camera.updateProjectionMatrix(); return this.offset.length(); } //=========================================== /* * 通过传参直接控制camera,不通过update里那些参数。 用于cad控制模型 */ }, { key: "updateDirect", value: function updateDirect(info) { //相机视口大小,如left为最左侧看到的三维边界坐标到视口中心的距离 // var height = info.width / this.camera.aspect // this.camera.left = -info.width / 2 // this.camera.right = info.width / 2 // this.camera.top = height / 2 // this.camera.bottom = -height / 2 // this.camera.updateProjectionMatrix() if (!info.floorPlanAngle) { info.floorPlanAngle = 0; } //console.log('updateDirect' + JSON.stringify(info)) this.camera.left = -info.width / 2; this.camera.right = info.width / 2; this.camera.top = info.height / 2; this.camera.bottom = -info.height / 2; this.camera.updateProjectionMatrix(); //相机中心,若相机有旋转,需要把相机位置也旋转下: this.camera.rotation.set(-Math.PI / 2, 0, info.floorPlanAngle); var center = new THREE.Vector2(info.center.x, -info.center.y); //旋转中心 (和CAD那边一致就行) var pos = new THREE.Vector2().copy(center).rotateAround(new THREE.Vector2(info.defaultCenter.x, -info.defaultCenter.y), -info.floorPlanAngle); this.camera.position.setX(pos.x); this.camera.position.setZ(pos.y); //let model = this.$app.core.get('Player').model //if(info.floorPlanAngle!=0){ // this.absoluteScale = this.getDefaultAbsoluteScale(model.size, null,info.floorPlanAngle) //改 // this.currentScale = this.absoluteScale // var s = this.snapshotTopAspect ? this.camera.aspect / this.snapshotTopAspect : 1 // //通过相机视口参数来调整相机投影视口大小 // this.camera.left = -settings.orthoBase * this.currentScale * s //* this.camera.aspect; // this.camera.right = settings.orthoBase * this.currentScale * s //* this.camera.aspect; // this.camera.top = (settings.orthoBase * this.currentScale * s) / this.camera.aspect // this.camera.bottom = (-settings.orthoBase * this.currentScale * s) / this.camera.aspect //} this.updateForCad = true; } }, { key: "updateForRotateCad", value: function updateForRotateCad(info) { if (!info.floorPlanAngle) { info.floorPlanAngle = 0; } //console.log('updateForRotateCad' + JSON.stringify(info)) //相机中心,若相机有旋转,需要把相机位置也旋转下: this.camera.rotation.set(-Math.PI / 2, 0, info.floorPlanAngle); var center = new THREE.Vector2(info.center.x, -info.center.y); //旋转中心 (和CAD那边一致就行) //var pos = new THREE.Vector2().copy(center).rotateAround(center, -info.floorPlanAngle) var pos = new THREE.Vector2().copy(center).rotateAround(new THREE.Vector2(info.defaultCenter.x, -info.defaultCenter.y), -info.floorPlanAngle); this.camera.position.setX(pos.x); this.camera.position.setZ(pos.y); var model = this.$app.core.get('Player').model; this.absoluteScale = this.getDefaultAbsoluteScale(model.size, null, info.floorPlanAngle); //改 this.currentScale = this.absoluteScale; var s = this.snapshotTopAspect ? this.camera.aspect / this.snapshotTopAspect : 1; //通过相机视口参数来调整相机投影视口大小 this.camera.left = -settings$3.orthoBase * this.currentScale * s; //* this.camera.aspect; this.camera.right = settings$3.orthoBase * this.currentScale * s; //* this.camera.aspect; this.camera.top = settings$3.orthoBase * this.currentScale * s / this.camera.aspect; this.camera.bottom = -settings$3.orthoBase * this.currentScale * s / this.camera.aspect; this.camera.updateProjectionMatrix(); this.updateForCad = true; } /* * 恢复使用update, 并使俯视图看起来和cad时一样。 */ }, { key: "recoverToUpdate", value: function recoverToUpdate() { this.updateForCad = false; //旋转(target、thetaDelta) //通过计算target恢复到旋转角度为0的状态(得到的dir都是一样的) /* var dir = new THREE.Vector3(0, 0, -1).applyQuaternion(this.camera.quaternion) this.target = this.camera.position.clone().add(dir) */ this.target.copy(this.camera.position); //通过rotateLeft来旋转,保持刚才的角度: var metadata = this.$app.store.getValue('metadata'); var floorPlanAngle = parseFloat(metadata.floorPlanAngle || 0); this.thetaDelta = floorPlanAngle; //console.log("recoverToUpdate "+floorPlanAngle) //缩放 this.absoluteScale = this.currentScale = this.camera.right / settings$3.orthoBase; this.update(1); //立即应用thetaDelta } //=========================================== }, { key: "toJSON", value: function toJSON() { var e = new THREE.Quaternion(), t = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(90)), i = new THREE.Quaternion(); var func = function func() { var n = OutsideControls.prototype.toJSON.call(this); e.copy(n.camera_quaternion); i.copy(t); i.multiply(e); n.camera_quaternion.x = math.toPrecision(i.x, 4); n.camera_quaternion.y = math.toPrecision(i.y, 4); n.camera_quaternion.z = math.toPrecision(i.z, 4); n.camera_quaternion.w = math.toPrecision(i.w, 4); n.ortho_zoom = math.toPrecision(this.currentScale * this.camera.aspect, 4); return n; }; return func; } }, { key: "setZoomBounds", value: function setZoomBounds(bound) { //根据模型大小修改zoom的边界. 和模型大小成正比 //settings.zoomNearLimit, Math.min(this.absoluteScale, settings.zoomFarLimit) var size = bound.getSize(new THREE.Vector3()); var max = Math.max(size.x, size.z) / 2 / settings$3.orthoBase; //top最大值可能是 max = Math.max(0.1, max); //avoid 0 settings$3.zoomFarLimit = parseInt(max * 10); settings$3.zoomNearLimit = settings$3.zoomFarLimit / 100; settings$3.floorplan.cameraHeight = THREE.MathUtils.clamp(Math.ceil(2.4 * size.length()), 5, 5000); //小模型如果高度太高,dollhouse和floorplan互转时动态过大 this.maxDistance = Math.max(settings$3.floorplan.cameraHeight + 1, this.maxDistance); } }]); return FloorplanControls; }(OutsideControls); function _createSuper$S(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$S(); 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 _isNativeReflectConstruct$S() { 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; } } defineComponent('CameraControls', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(CameraControls, _EventEmitter); var _super = _createSuper$S(CameraControls); function CameraControls() { var _this; _classCallCheck(this, CameraControls); _this = _super.call(this); _this.activeControl = null; _this.controls = {}; _this.cameras = {}; return _this; } _createClass(CameraControls, [{ key: "init", value: function init(dom, modes) { this.setUpControls(dom, modes); this.bindEvents(dom); } }, { key: "activateControls", value: function activateControls(mode) { if (this.activeControl) { this.activeControl.reset(); this.activeControl.enabled = !1; } this.controls[mode] && (this.controls[mode].enabled = !0); this.activeControl = this.controls[mode]; } }, { key: "setUpControls", value: function setUpControls(dom, modes) { //许钟文改 支持control加在其他dom上 var cameras = {}, controls = {}; var modes = modes || [Viewmode$1.PANORAMA, Viewmode$1.DOLLHOUSE, Viewmode$1.FLOORPLAN], cameraClasses = [PanoramaCamera, DollhouseCamera, FloorplanCamera], controlClasses = [PanoramaControls, DollhouseControls, FloorplanControls]; modes.forEach(function (mode, index) { cameras[mode] = new cameraClasses[index](dom); controls[mode] = new controlClasses[index](cameras[mode], dom, this.$app.core.get('Player')); controls[mode].on(ControlEvents.Move, this.emit.bind(this, ControlEvents.Move)); controls[mode].on(ControlEvents.InputStart, this.emit.bind(this, ControlEvents.InputStart)); controls[mode].on(ControlEvents.InteractionDirect, this.emit.bind(this, ControlEvents.InteractionDirect)); controls[mode].on(ControlEvents.InteractionKey, this.emit.bind(this, ControlEvents.InteractionKey)); controls[mode].on(ControlEvents.Pinch, this.emit.bind(this, ControlEvents.Pinch)); controls[mode].on(ControlEvents.Scroll, this.emit.bind(this, ControlEvents.Scroll)); }.bind(this)); this.controls = controls; this.cameras = cameras; } }, { key: "bindEvents", value: function bindEvents(dom) { var _this2 = this; dom.addEventListener('mousemove', this.onMouseMove.bind(this)); dom.addEventListener('mousedown', this.onMouseDown.bind(this)); dom.addEventListener('mouseup', this.onMouseUp.bind(this)); dom.addEventListener('mouseover', this.onMouseOver.bind(this)); if (settings$3.useWheel) { dom.addEventListener('mousewheel', this.onMouseWheel.bind(this), { passive: false }); dom.addEventListener('DOMMouseScroll', this.onMouseWheel.bind(this), { passive: false }); } dom.addEventListener('touchstart', this.onTouchStart.bind(this), { passive: false }); dom.addEventListener('touchmove', this.onTouchMove.bind(this), { passive: false }); dom.addEventListener('touchend', this.onTouchEnd.bind(this)); dom.addEventListener('contextmenu', function (e) { e.preventDefault(); }); dom.addEventListener('pointerdown', this.onPointerDown.bind(this)); dom.addEventListener('pointermove', this.onPointerMove.bind(this)); dom.addEventListener('pointerup', this.onPointerUp.bind(this)); dom.addEventListener('pointerout', this.onPointerCancel.bind(this)); dom.addEventListener('pointercancel', this.onPointerCancel.bind(this)); document.addEventListener('keydown', this.onKeyDown.bind(this)); document.addEventListener('keyup', this.onKeyUp.bind(this)); this.$app.core.get('ModelManager').on(ModelManagerEvents.ActiveModelChanged, function (e) { this.setModelForControls(e.model); }.bind(this)); this.on('syncCadAnd3D', function (info) { _this2.controls[Viewmode$1.FLOORPLAN].updateDirect(info); }); // info = {width:..,height:...,center:...} this.on('syncCadAnd3DForRotate', function (info) { _this2.controls[Viewmode$1.FLOORPLAN].updateForRotateCad(info); }); } }, { key: "setModelForControls", value: function setModelForControls(model) { //this.controls[Viewmode.DOLLHOUSE].setZoomBounds(model.boundingBox) var boundingBox = model.boundingBox.clone().expandByScalar(settings$3.modelBoundsPadding); [Viewmode$1.DOLLHOUSE, Viewmode$1.FLOORPLAN].forEach(function (mode) { this.controls[mode].setZoomBounds(model.boundingBox); this.controls[mode].setBounds(boundingBox); }.bind(this)); } }, { key: "onMouseDown", value: function onMouseDown(e) { e.preventDefault(); this.activeControl && this.activeControl.onMouseDown(e); } }, { key: "onMouseMove", value: function onMouseMove(e) { e.preventDefault(); this.activeControl && this.activeControl.onMouseMove(e); } }, { key: "onMouseUp", value: function onMouseUp(e) { e.preventDefault(); this.activeControl && this.activeControl.onMouseUp(e); } }, { key: "onMouseOver", value: function onMouseOver(e) { e.preventDefault(); this.activeControl && this.activeControl.onMouseOver(e); } }, { key: "onMouseWheel", value: function onMouseWheel(e) { e.preventDefault(); this.activeControl && this.activeControl.onMouseWheel(e); } }, { key: "onTouchStart", value: function onTouchStart(e) { e.preventDefault(); this.activeControl && this.activeControl.onTouchStart(e); } }, { key: "onTouchMove", value: function onTouchMove(e) { var _this3 = this; var func = function func() { e.preventDefault(); _this3.activeControl && _this3.activeControl.onTouchMove(e); }; if (this.$app.VRScreenSYNC) { common.debounce(func, 1000 / 60, true)(); //会导致带看leader触屏缩放摇晃。 } else { func(); } } }, { key: "onTouchEnd", value: function onTouchEnd(e) { e.preventDefault(); this.activeControl && this.activeControl.onTouchEnd(e); } }, { key: "onPointerDown", value: function onPointerDown(e) { e.preventDefault(); if (this.activeControl) switch (e.pointerType) { case 'mouse': this.activeControl.onMouseDown(e); break; default: this.activeControl.onPointerDown(e); } } }, { key: "onPointerMove", value: function onPointerMove(e) { var _this4 = this; var func = function func() { e.preventDefault(); if (_this4.activeControl) switch (e.pointerType) { case 'mouse': _this4.activeControl.onMouseMove(e); break; default: _this4.activeControl.onPointerMove(e); } }; if (this.$app.VRScreenSYNC) { common.debounce(func, 1000 / 60, true)(); } else { func(); } } }, { key: "onPointerUp", value: function onPointerUp(e) { e.preventDefault(); if (this.activeControl) { switch (e.pointerType) { case 'mouse': this.activeControl.onMouseUp(e); break; default: this.activeControl.onPointerUp(e); } this.emit('pointerUp'); } } }, { key: "onPointerCancel", value: function onPointerCancel(e) { e.preventDefault(); this.activeControl && 'mouse' !== e.pointerType && this.activeControl.onPointerUp(e); } }, { key: "onKeyDown", value: function onKeyDown(e) { if (!this.$app.config.useShortcutKeys) { return; } if (e.metaKey || e.ctrlKey) ; else { e.preventDefault(); this.activeControl && this.activeControl.onKeyDown(e); } } }, { key: "onKeyUp", value: function onKeyUp(e) { e.preventDefault(); this.activeControl && this.activeControl.onKeyUp(e); } }]); return CameraControls; }(EventEmitter); }); var PanoVideoEvents = { CanPlay: 'panovideo.canplay', StartPlay: 'panovideo.start', Resume: 'panovideo.resume', Pause: 'panovideo.pause', Stop: 'panovideo.stop', Switch: 'panovideo.switch' }; function _createForOfIteratorHelper$6(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$6(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$6(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$6(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$6(o, minLen); } function _arrayLikeToArray$6(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _createSuper$R(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$R(); 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 _isNativeReflectConstruct$R() { 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; } } var H5VideoPlayer$1 = /*#__PURE__*/function (_EventEmitter) { _inherits(H5VideoPlayer, _EventEmitter); var _super = _createSuper$R(H5VideoPlayer); function H5VideoPlayer(dom, videos) { var _this; _classCallCheck(this, H5VideoPlayer); _this = _super.call(this); // this.listeneNum = 0 _this.domElement = dom; _this.os = ''; //Android | Ios | PC _this.environment = ''; //WeChat | WeChatMiniProgram | Other // this.videos = new Map(); // this.textures = new Map(); _this._resource = new Map(); videos.forEach(function (value, key) { var video = _this._createVideoElement(value.mp4.url, // config.appenv == 'shipin' && _this._resource.size == 0); _this._resource.set(key, { url: value.mp4.url, video: video, texture: _this._createTexture(video), loaded: true }); /* if(key == 350){ } */ }); _this.video = null; // this.texture = new THREE.VideoTexture(document.createElement('video')) // this.texture.minFilter = THREE.LinearFilter _this.isFirstPlay = true; _this.isMuted = true; _this.events = { onDomElementTouchStart: function onDomElementTouchStart() { //---ios //console.log('onDomElementTouchStart') if (_this.shouldPlay) { _this.video.muted = _this.isMuted; _this.video.play(); console.log('onDomElementTouchStart muted', _this.video.muted, 'paused', _this.video.paused); _this.domElement.removeEventListener('touchstart', _this.events.onDomElementTouchStart, true); } }, onDomElementTouchEnd: function onDomElementTouchEnd() { if (_this.shouldPlay) { _this.video.muted = _this.isMuted; _this.domElement.removeEventListener('touchend', _this.events.onDomElementTouchEnd, true); } }, onDomElementMouseDown: function onDomElementMouseDown() { if (_this.shouldPlay) { _this.video.muted = _this.isMuted; _this.domElement.removeEventListener('mousedown', _this.events.onDomElementMouseDown, true); } } }; return _this; } _createClass(H5VideoPlayer, [{ key: "_createTexture", value: function _createTexture(videoElement) { var texture = new THREE.VideoTexture(videoElement); texture.minFilter = THREE.LinearFilter; texture.uploaded = false; return texture; } }, { key: "_createVideoElement", value: function _createVideoElement(src) { var video; // if (config.appenv == 'shipin' && isInPage) { // video = parent.document.querySelector('#video-' + config.projectNum) // video._isPrepload = true // } else { video = document.createElement('video'); video.setAttribute('crossOrigin', 'anonymous'); video.setAttribute('playsinline', 'true'); video.setAttribute('x5-playsinline', 'true'); video.setAttribute('webkit-playsinline', 'true'); video.setAttribute('x5-video-player-type', 'h5'); video.setAttribute('controls', 'true'); // video.preload = true //"none"; video.autoplay = false; video.muted = this.isMuted; video.loop = true; video.src = src; video.style.position = 'fixed'; video.style.left = '0'; video.style.top = '0'; video.style.width = browser$1.urlHasValue('debug') ? '300px' : '1px'; video.style.height = browser$1.urlHasValue('debug') ? '300px' : '1px'; video.style.display = 'block'; // 关于视频卡顿问题,经测试,通过设置zIndex=-1、opacity=0来隐藏video可规避 video.style.zIndex = browser$1.urlHasValue('debug') ? '1000' : '0'; video.style.opacity = browser$1.urlHasValue('debug') ? '1' : '0'; //this.domElement.appendChild(video) } /* if (!H5VideoPlayer.videoReady) { H5VideoPlayer.videoReady = true function iosInitAutoPlay() { console.log('iosInitAutoPlay', video.src) video.play() setTimeout(()=>{ console.log('iosInitAutoPlay result', video.paused, __sdk.core.get('Player').model.skybox.material.defines.HasVideo) video.pause() },100) window.listener.removeEventListener('touchstart', iosInitAutoPlay, true) } //避免重复监听 window.listener = window //window.document.body window.listener.addEventListener('touchstart', iosInitAutoPlay, true) } */ return video; } }, { key: "_onCanPlay", value: function _onCanPlay() { this.emit(PanoVideoEvents.CanPlay); } }, { key: "_onPlaying", value: function _onPlaying() { var _this2 = this; //console.log('_onPlaying muted', this.video.muted) this.emit(PanoVideoEvents.Switch, this.texture); this.video.ontimeupdate = function (event) { if (_this2.video.currentTime > 0.5) { _this2.emit(PanoVideoEvents.Resume); _this2.video.ontimeupdate = null; _this2.isFirstPlay = false; //console.log('播放成功') } }; if (this.isFirstPlay) this.emit(PanoVideoEvents.StartPlay); } }, { key: "_onPause", value: function _onPause(event) { if (this.video) { this.video._isPaused = true; } this.emit(PanoVideoEvents.Pause); } }, { key: "preload", value: function preload(video) { var _this3 = this; if (video == this.video || video._isPrepload) return; video.muted = true; try { top.WeixinJSBridge && top.WeixinJSBridge.invoke('getNetworkType', {}, function (e) { video.play(); }, false); } catch (error) { video.play(); } video.onplaying = function () { video.pause(); video._isPrepload = true; if (_this3.video && !_this3.video._isPaused) { _this3.video.play(); } }; } }, { key: "preloadAll", value: function preloadAll() { if (this.video) { this.video._isPaused = this.video.paused; } var _iterator = _createForOfIteratorHelper$6(this._resource.values()), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var item = _step.value; this.preload(item.video); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } }, { key: "preloadPano", value: function preloadPano(pano) { var item = this._resource.get(pano.id); if (item) { this.preload(item.video); } } }, { key: "startVideo", value: function startVideo(panoId, tryIfFirstplay) { var item = this._resource.get(panoId); if (item) { item.video.autoplay = true; item.video.onplaying = this._onPlaying.bind(this); item.video.onpause = this._onPause.bind(this); item.video.oncanplay = this._onCanPlay.bind(this); this.video = item.video; this.texture = item.texture; // // debug // this.video.addEventListener("playing", () => console.error('mp4_debug_playing')) // this.video.addEventListener("pause", () => console.error('mp4_debug_pause')) // this.video.addEventListener("canplay", () => console.error('mp4_debug_canplay')) // this.video.onloadstart = () => console.error('mp4_debug_loadstart') // this.video.onloadedmetadata = () => console.error('mp4_debug_loadedmetadata', this.video.readyState) // this.video.onloadeddata = () => console.error('mp4_debug_loadeddata', this.video.readyState) // this.video.onprogress = () => { // console.error('mp4_debug_progress', this.video.readyState) // } // this.video.oncanplaythrough = () => console.error('mp4_debug_canplaythrough:视频源数据加载完成') // this.video.onwaiting = () => console.error('mp4_debug_waiting') // this.video.onerror = (e) => console.error('mp4_debug_error', e) // this.video.onabort = () => console.error('mp4_debug_abort: 客户端主动终止下载') // this.video.onemptied = () => console.error('mp4_debug_emptied: video元素变为未初始化状态') // this.video.onstalled = () => { // console.error('mp4_debug_stalled: 浏览器尝试获取媒体数据但数据不可用(网速异常)') // } // this.video.onseeking = () => console.error('mp4_debug_seeking: 浏览器正在请求数据(视频跳转中)') // this.video.onseeked = () => console.error('mp4_debug_seeked') // this.video.onsuspend = () => console.error('mp4_debug_suspend: 浏览器暂停获取媒体数据(延迟下载)') // this.video.style.display = "" /* if(tryIfFirstplay) { this.isFirstPlay && this.play(this.video ) */ /* }else */ if (this.video.paused) { this.play(this.video); } else { this._onPlaying(); } } } // 业务规定要自动播放而且带有声音,不符合Autoplay Policy (https://goo.gl/xX8pDD)。 // 微信平台可以绕过 Autoplay Policy,所以业务只考虑微信,但这里对普通H5也进行了处理 }, { key: "play", value: function play(videoElement) { var _this4 = this; this.shouldPlay = videoElement; if (this.isFirstPlay || !videoElement._isCanplay) { if (browser$1.detectWeixin()) { //用微信平台的 WeixinJSBridge 越过 Autoplay Policy try { top.WeixinJSBridge && top.WeixinJSBridge.invoke('getNetworkType', {}, function (e) { if (_this4.shouldPlay == videoElement) { console.log('play', videoElement.src.split('/').pop()); videoElement.play(); videoElement._isCanplay = true; } }, false); } catch (error) { videoElement.play(); videoElement._isCanplay = true; } } //符合Autoplay Policy的自动播放,处理方式为:先静音播放,再由用户触发打开声音 else { videoElement.play(); videoElement._isCanplay = true; //经测试,正确的事件为,IOS-touchstart,Android -- touchend 否则setMuted后会异常暂停播放 (细节挖坑!) //测试样本 IOS: safari chrome | Android: chrome if (browser$1.detectAndroidMobile()) { this.domElement.addEventListener('touchend', this.events.onDomElementTouchEnd, true); } else if (browser$1.detectIOS()) { this.domElement.addEventListener('touchstart', this.events.onDomElementTouchStart, true); } else { this.domElement.addEventListener('mousedown', this.events.onDomElementMouseDown, true); } } } else { videoElement.play(); } //console.log('try play', videoElement.paused, videoElement.src) } }, { key: "pauseVideo", value: function pauseVideo(panoId) { var item = this._resource.get(panoId); if (item) { //console.error('pauseVideo', panoId) item.video.pause(); item.video.muted = true; item.video.onplaying = null; if (this.shouldPlay == item.video) this.shouldPlay = false; } } }, { key: "pause", value: function pause() { if (this.video) { //console.error('pause', this.video.src.split('/').pop()) this.video._isPaused = true; this.video.pause(); this.shouldPlay = false; } } }, { key: "resume", value: function resume() { if (this.video) { this.play(this.video); this.video.onplaying = this._onPlaying.bind(this); } else { console.warn('PanoVideoRenderer: 没有可播放的视频'); } } }, { key: "setMuted", value: function setMuted(muted) { //console.log('setMuted', muted ) var _iterator2 = _createForOfIteratorHelper$6(this._resource.values()), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var item = _step2.value; item.video.muted = muted; } //this.video && (this.video.muted = muted) } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } this.isMuted = muted; } }]); return H5VideoPlayer; }(EventEmitter); H5VideoPlayer$1.videoReady = false; function _createForOfIteratorHelper$5(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$5(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$5(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$5(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$5(o, minLen); } function _arrayLikeToArray$5(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _createSuper$Q(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$Q(); 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 _isNativeReflectConstruct$Q() { 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; } } var FlvVideoPlayer$1 = /*#__PURE__*/function (_EventEmitter) { _inherits(FlvVideoPlayer, _EventEmitter); var _super = _createSuper$Q(FlvVideoPlayer); function FlvVideoPlayer(dom, videos) { var _this; _classCallCheck(this, FlvVideoPlayer); _this = _super.call(this); _this.domElement = dom; _this.instances = new Map(); _this.instanceTextures = new Map(); videos.forEach(function (value, key) { // if( config.appenv == "shipin" && this.instances.size>0){ // return // } _this.instances.set(key, _this._createVideo(value.flv.url)); var videoTexture = new THREE__namespace.VideoTexture(_this.instances.get(key).videoElement); videoTexture.minFilter = THREE__namespace.LinearFilter; _this.instanceTextures.set(key, videoTexture); }); _this.video = null; _this.texture = null; _this.isFirstPlay = true; _this.isMuted = true; _this.events = { onDomElementTouchStart: function onDomElementTouchStart() { //---ios //console.log('onDomElementTouchStart') /* if (this.shouldPlay) { this.video.muted = this.isMuted this.video.play() console.log('onDomElementTouchStart muted', this.video.muted, 'paused', this.video.paused) this.domElement.removeEventListener('touchstart', this.events.onDomElementTouchStart, true) }*/ _this.video.muted = _this.isMuted; _this.domElement.removeEventListener('touchstart', _this.events.onDomElementTouchStart, true); }, onDomElementTouchEnd: function onDomElementTouchEnd() { //if (this.shouldPlay) { _this.video.muted = _this.isMuted; _this.domElement.removeEventListener('touchend', _this.events.onDomElementTouchEnd, true); //} }, onDomElementMouseDown: function onDomElementMouseDown() { //if (this.shouldPlay) { _this.video.muted = _this.isMuted; _this.domElement.removeEventListener('mousedown', _this.events.onDomElementMouseDown, true); //} } }; return _this; } _createClass(FlvVideoPlayer, [{ key: "_createVideo", value: function _createVideo(url) { var video = document.createElement('video'); video.setAttribute('crossOrigin', 'anonymous'); video.setAttribute('playsinline', 'true'); video.setAttribute('webkit-playsinline', 'true'); video.setAttribute('controls', 'true'); video.setAttribute('unfullscreen', 'true'); video.autoplay = false; video.muted = true; video.loop = true; video.style.position = 'fixed'; video.style.left = '0'; video.style.top = '0'; video.style.width = browser$1.urlHasValue('debug') ? '200px' : '1px'; video.style.display = 'block'; // 关于视频卡顿问题,经测试,通过设置zIndex=-1、opacity=0来隐藏video可规避 video.style.zIndex = browser$1.urlHasValue('debug') ? '1000' : '0'; video.style.opacity = browser$1.urlHasValue('debug') ? '1' : '0'; this.domElement.appendChild(video); //bug:安卓似乎会在 browser.requestFullscreen(document.body) 后全屏(点击vr时)时播放显示视频 var player = flvjs.createPlayer({ type: 'flv', url: url }, { lazyLoad: true, lazyLoadMaxDuration: 5 }); player.videoElement = video; player.attachMediaElement(video); player.on(flvjs.Events.ERROR, this._onPlayerError.bind(this)); return player; } }, { key: "_onPlayerError", value: function _onPlayerError(error) { console.warn('球幕视频资源加载错误:', error); } }, { key: "_onPlaying", value: function _onPlaying() { var _this2 = this; this.emit(PanoVideoEvents.Switch, this.texture); this.video.ontimeupdate = function (event) { if (_this2.video.currentTime > 0.2) { _this2.emit(PanoVideoEvents.Resume); if (_this2.isFirstPlay) _this2.emit(PanoVideoEvents.StartPlay); _this2.isFirstPlay = false; _this2.video.ontimeupdate = null; } }; } }, { key: "_onPause", value: function _onPause() { this.emit(PanoVideoEvents.Pause); this.state = 0; } }, { key: "preloadPano", value: function preloadPano(pano) { var instance = this.instances.get(pano.id); if (instance && instance.buffered.length == 0) { instance.load(); } } }, { key: "startVideo", value: function startVideo(panoId) { var instance = this.instances.get(panoId); if (instance) { instance.buffered.length == 0 && instance.load(); this.video = instance.videoElement; this.video.onplaying = this._onPlaying.bind(this); this.video.onpause = this._onPause.bind(this); // 直接取提前准备好的VideoTexture // 不能直接给this.texture.image赋值this.video,会在手机上无法播放; // 也不能在这里new THREE.VideoTexture,有时会有一小段黑屏 this.texture = this.instanceTextures.get(panoId); if (this.video.paused) { this.play(this.video); } else { this._onPlaying(); } } } }, { key: "pauseVideo", value: function pauseVideo(panoId) { var instance = this.instances.get(panoId); if (instance) { instance.videoElement.pause(); instance.videoElement.onplaying = null; } } // 业务规定要自动播放而且带有声音,不符合Autoplay Policy (https://goo.gl/xX8pDD)。 // 微信平台可以绕过 Autoplay Policy,所以业务只考虑微信,但这里对普通H5也进行了处理 }, { key: "play", value: function play(videoElement) { if (this.isFirstPlay) { videoElement.play(); //经测试,正确的事件为,IOS-touchstart,Android -- touchend 否则setMuted后会异常暂停播放 (细节挖坑!) //测试样本 IOS: safari chrome | Android: chrome if (browser$1.detectAndroidMobile()) { this.domElement.addEventListener('touchend', this.events.onDomElementTouchEnd, true); } else if (browser$1.detectIOS()) { this.domElement.addEventListener('touchstart', this.events.onDomElementTouchStart, true); } else { this.domElement.addEventListener('mousedown', this.events.onDomElementMouseDown, true); } } else { videoElement.play(); } } }, { key: "pause", value: function pause() { this.video && this.video.pause(); } }, { key: "resume", value: function resume() { if (this.video) { this.play(this.video); } else { console.warn('FlvVideoPlayer: 没有可播放的视频'); } } }, { key: "setMuted", value: function setMuted(muted) { var _iterator = _createForOfIteratorHelper$5(this.instances.values()), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var instance = _step.value; instance.videoElement.muted = muted; } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } this.isMuted = muted; } /* onDomElementTouchStart() { this.setMuted(false) this.domElement.removeEventListener('touchstart', this.onDomElementTouchStart) } onDomElementTouchEnd() { this.setMuted(false) this.domElement.removeEventListener('touchstart', this.onDomElementTouchEnd) } onDomElementMouseDown() { this.setMuted(false) this.domElement.removeEventListener('mousedown', this.onDomElementMouseDown) } */ }]); return FlvVideoPlayer; }(EventEmitter); var PanoVideoRendererState = { Pause: 0, Playing: 1 }; function _createSuper$P(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$P(); 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 _isNativeReflectConstruct$P() { 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; } } defineComponent('PanoVideoRenderer', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(PanoVideoRenderer, _EventEmitter); var _super = _createSuper$P(PanoVideoRenderer); function PanoVideoRenderer() { var _this; _classCallCheck(this, PanoVideoRenderer); _this = _super.call(this); window.panoVideoRenderer = _assertThisInitialized(_this); _this.version = 1; _this.videoPlayer = null; _this.activePanorama = null; _this.nearestPano = null; _this.ready = false; _this._state = PanoVideoRendererState.Pause; _this.texture = null; _this.isGuiding = false; _this.isRecording = false; _this.isSoundRecording = false; _this.loadingAnimEnable = true; _this.loadingTimeStamp = 0; _this.loadingUITimer = 0; _this.loadingUIAnimHandler = 0; var uniforms = THREE.UniformsUtils.clone(shaders.videoLoading.uniforms); uniforms['uColor'].value = new THREE.Vector4(0, 0.7843137254901961, 0.6862745098039216, 0.7); _this.loadingUI = new THREE.Mesh(new THREE.PlaneBufferGeometry(0.4, 0.4), new THREE.RawShaderMaterial({ uniforms: uniforms, vertexShader: shaders.videoLoading.vertexShader, fragmentShader: shaders.videoLoading.fragmentShader, transparent: true })); _this.loadingUI.visible = false; return _this; } _createClass(PanoVideoRenderer, [{ key: "init", value: function init(videosInfo) { var _this2 = this; var player = this.$app.core.get('Player'); this.videosInfo = videosInfo; if (!videosInfo) { logger$1.warn('PanoVideoRenderer初始化失败,数据为空'); return; } this.version = videosInfo.version; // this.initVideoPlayer(this.$app.dom, videosInfo.videos) player.on('guide/play/start', function (index) { _this2.isGuiding = true; _this2.setMuted(true); }); player.on('guide/play/pause', function (index) { _this2.isGuiding = false; _this2.setMuted(false); }); this.$app.core.get('Player').on('guide/play/stop', function (index) { _this2.isGuiding = false; _this2.setMuted(false); }); this.ready = true; if (browser$1.detectIE() || navigator.userAgent.match('JSN-AL00')) { //之前的记录:JSN-AL00 荣耀8x Harmony OS2.0 微信8.0.28 无法显示球幕 2023.5.29又发现可以显示 场景:KK-t-Gw0q49v8k4W this.ready = false; console.warn('浏览器不支持球幕视频', navigator.userAgent); } this.$app.core.get('SceneRenderer').scene.add(this.loadingUI); /* let updateVideoMarkerDisplay = ()=>{ //---如果要在这些界面上隐藏video图标的话 if(player.mode != 'floorplan') return //? let showVideo = this.canShowMarker('floorplan') console.log('updateVideoMarkerDisplay', showVideo) player.model.panos.forEach((pano)=>{ let v = showVideo && (player.model.allFloorsVisible || !pano.floor.hidden) if(pano.flagSpot) pano.marker.material.opacity = v ? 1 : 0 }) } player.on('beginTagVisiSetting', updateVideoMarkerDisplay) player.on('exitTagVisiSetting', updateVideoMarkerDisplay) player.on('editViewStateChange', updateVideoMarkerDisplay) player.on('beginEditOverlay', updateVideoMarkerDisplay) player.on('endEditOverlay', updateVideoMarkerDisplay) */ var updateVideoMarkerDisplay = function updateVideoMarkerDisplay() { //---如果要在这些界面上隐藏video图标的话 if (player.mode != 'floorplan') return; //? var showVideo = _this2.canShowMarker('floorplan'); console.log('updateVideoMarkerDisplay', showVideo); player.model.panos.forEach(function (pano) { var v = showVideo && (player.model.allFloorsVisible || !pano.floor.hidden); if (pano.flagSpot) pano.marker.material.opacity = v ? 1 : 0; }); }; player.on('linkEditorSetVisible', function (s) { updateVideoMarkerDisplay(); }); var recoverVideoMarkers = function recoverVideoMarkers() { //---恢复video的marker显示 player.model.panos.forEach(function (pano) { var v = player.model.allFloorsVisible || !pano.floor.hidden; if (pano.flagSpot) pano.marker.material.opacity = v ? 1 : 0; }); }; player.on('editViewStateChange', function (state) { //退出view的编辑 if (state == false) recoverVideoMarkers(); }); } }, { key: "initVideoPlayer", value: function initVideoPlayer(dom, videos) { var _VersionControl$getEn = VersionControl.getEnvironment(), os = _VersionControl$getEn.os, environment = _VersionControl$getEn.environment; /* // if (window.navigator.userAgent.indexOf('WindowsWechat') === -1 && window.MediaSource && (os == 'Android' || environment == 'WeChat')) { // // 小米自带浏览器只能用FlvVideoPlayer // this.videoPlayer = new FlvVideoPlayer(dom, videos) // } else { this.videoPlayer = new H5VideoPlayer(dom, videos) // } */ //--------之前为什么注释呢? //oppo k5 自带的浏览器flv和h5均无法播放, google edge浏览器可以 //来自v3: if (window.MediaSource && (os == 'Android' || environment == 'WeChat')) { // 小米自带浏览器、安卓微信只能用FlvVideoPlayer this.videoPlayer = new FlvVideoPlayer$1(dom, videos); //console.log('use FlvVideoPlayer') } else { //console.log('use H5VideoPlayer') this.videoPlayer = new H5VideoPlayer$1(dom, videos); } this.videoPlayer.on(PanoVideoEvents.CanPlay, this.onVideoCanPlay.bind(this)); this.videoPlayer.on(PanoVideoEvents.StartPlay, this.onVideoStartPlay.bind(this)); this.videoPlayer.on(PanoVideoEvents.Switch, this.onVideoSwitch.bind(this)); this.videoPlayer.on(PanoVideoEvents.Resume, this.onVideoResume.bind(this)); this.videoPlayer.on(PanoVideoEvents.Pause, this.onVideoPause.bind(this)); this.videoPlayer.on(PanoVideoEvents.Stop, this.onVideoStop.bind(this)); } }, { key: "activatePanorama", value: function activatePanorama(panorama, isFirstPlay) { var _this3 = this; //console.log('activatePanorama', panorama && panorama.id) if (!panorama.hasVideo || !this.ready) { //console.log("renderVideo skip", panorama) return; } this.activePanorama = panorama; this.started = true; this.videoPlayer.startVideo(panorama.id, isFirstPlay); this.loadingUITimer = setTimeout(function () { _this3.showLoading(panorama); window.clearTimeout(_this3.loadingUITimer); }, 500); } }, { key: "deactivePanorama", value: function deactivePanorama(panorama) { //console.log('deactivePanorama', panorama && panorama.id) if (panorama != null && panorama.id != null) { this.videoPlayer.pauseVideo(panorama.id); } this.activePanorama = null; } }, { key: "preActivatePanorama", value: function preActivatePanorama(panorama) { this.videoPlayer.startVideo(panorama.id, true); } }, { key: "getActivePanorama", value: function getActivePanorama() { return this.activePanorama; } }, { key: "showLoading", value: function showLoading(pano) { if (!this.loadingAnimEnable) return; var target = new THREE.Vector3().copy(pano.position); var qua = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(this.$app.core.get('Player').model.supportsTiles ? 90 : 180)); var direction = new THREE.Vector3(0, 0, -1).applyQuaternion(qua.multiply(pano.quaternion)); this.loadingUI.position.copy(target).add(direction); this.loadingUI.lookAt(target); // this.loadingUI.visible = true this.loadingTimeStamp = performance.now(); this.loadingAnimte(0); } }, { key: "hideLoading", value: function hideLoading() { this.loadingUI.visible = false; window.cancelAnimationFrame(this.loadingUIAnimHandler); window.clearTimeout(this.loadingUITimer); } }, { key: "loadingAnimte", value: function loadingAnimte(elapsedTime) { this.loadingUI.material.uniforms['uTime'].value = performance.now() - this.loadingTimeStamp; this.loadingUIAnimHandler = window.requestAnimationFrame(this.loadingAnimte.bind(this)); } }, { key: "suspend", value: function suspend() { if (!this.ready) return false; this.videoPlayer.pause(); this.emit(PanoVideoRendererEvents.SuspendRender); } }, { key: "resume", value: function resume() { if (!this.ready) return false; this.videoPlayer.resume(); } }, { key: "canPhonate", value: function canPhonate() { return this.isGuiding == false && this.isRecording == false && this.isSoundRecording == false; } }, { key: "setMuted", value: function setMuted(muted) { if (this.videoPlayer) { if (!this.canPhonate()) muted = true; this.videoPlayer.setMuted(muted); } } }, { key: "getState", value: function getState() { return this._state; } }, { key: "onVideoPanoramasEnter", value: function onVideoPanoramasEnter(oldPanorama, newPanorama) {//this.activatePanorama(newPanorama) //console.log('onPanoEnter') } }, { key: "onVideoPanoramasExit", value: function onVideoPanoramasExit(panorama) {//console.log('onPanoExit') //this.deactivePanorama(panorama) } }, { key: "onVideoCanPlay", value: function onVideoCanPlay() { //console.log('onVideoCanPlay') this.emit(PanoVideoRendererEvents.CanPlayVideo); } }, { key: "onVideoStartPlay", value: function onVideoStartPlay() { //console.log('onVideoStartPlay') this.emit(PanoVideoRendererEvents.StartPlayVideo); } }, { key: "onVideoSwitch", value: function onVideoSwitch(texture) { if (this.texture) this.texture.dispose(); //xzw add this.texture = texture; this.emit(PanoVideoRendererEvents.TextureUpdate, texture); } }, { key: "onVideoResume", value: function onVideoResume() { this._state = PanoVideoRendererState.Playing; this.emit(PanoVideoRendererEvents.ResumeRender); this.hideLoading(); } }, { key: "onVideoPause", value: function onVideoPause() { this._state = PanoVideoRendererState.Pause; this.emit(PanoVideoRendererEvents.SuspendRender); } }, { key: "onVideoStop", value: function onVideoStop() { this._state = PanoVideoRendererState.Pause; this.emit(PanoVideoRendererEvents.SuspendRender); } }, { key: "ifEnable", value: function ifEnable() { //xzw add return ( /* !objects.tagManager.editSpot.enterSplitView && */ this.ready ); /* && (//其他写了好像没作用 就都播放吧 !config.isEdit || store.getters.page != 'screen' ) */ } }, { key: "canShowMarker", value: function canShowMarker() { var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'floorplan'; var player = this.$app.core.get('Player'); if (mode == 'floorplan') { return !(this.$app.Plugins.EditCAD && this.$app.Plugins.EditCAD.display || player.linkEditor && (player.linkEditor.setPanoVisible || player.linkEditor.setTagVisible)); } } }]); return PanoVideoRenderer; }(EventEmitter); }); // export default new PanoVideoRenderer() /* note: 初始点位球幕视频静音播放 */ function _createSuper$O(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$O(); 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 _isNativeReflectConstruct$O() { 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; } } defineComponent('DisplayController', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(DisplayController, _EventEmitter); var _super = _createSuper$O(DisplayController); function DisplayController(fadeInSpeed) { var _this; _classCallCheck(this, DisplayController); _this = _super.call(this); _this.fadeInSpeed = fadeInSpeed; null !== _this.fadeInSpeed && void 0 !== _this.fadeInSpeed || (_this.fadeInSpeed = 0); _this.panoVideoRenderer = null; return _this; } _createClass(DisplayController, [{ key: "init", value: function init() { this.container = this.$app.core.get('Player').domElement; this.panoVideoRenderer = this.$app.core.get('PanoVideoRenderer'); this.updateModel(); this.bindEvents(); } }, { key: "bindEvents", value: function bindEvents() { this.$app.core.get('Player').on(PlayerEvents.FlyingStarted, this.handlePlayerFlyingStarted.bind(this)); this.$app.core.get('Player').on(PlayerEvents.FlyingEnded, this.handlePlayerFlyingEnded.bind(this)); this.$app.core.get('Player').on(PlayerEvents.ModeChanging, this.handlePlayerModeChanging.bind(this)); this.$app.core.get('Player').on(PlayerEvents.ModeChanged, this.handlePlayerModeChanged.bind(this)); this.$app.core.get('Player').on(PlayerEvents.ClosestPanoChanging, this.handleClosestPanoChanging.bind(this)); this.$app.core.get('Player').on(PlayerEvents.StartInside, this.handleStartInside.bind(this)); //若初始画面在内 this.$app.core.get('Player').on(PlayerEvents.StartOutside, this.handleStartOutside.bind(this)); } }, { key: "updateModel", value: function updateModel() { this.model = this.$app.core.get('ModelManager').getActiveModel(); } }, { key: "handlePlayerFlyingStarted", value: function handlePlayerFlyingStarted(panoInfo) { var lastPano = this.model.panos.index[panoInfo.lastPanoId]; this.panoVideoRenderer.deactivePanorama(lastPano); this.panoVideoRenderer.setMuted(true); } }, { key: "handlePlayerFlyingEnded", value: function handlePlayerFlyingEnded(_ref) { var targetPano = _ref.targetPano; if (targetPano && this.model.mode == Viewmode$1.PANORAMA) { this.panoVideoRenderer.activatePanorama(targetPano); } this.panoVideoRenderer.setMuted(false); } }, { key: "handlePlayerModeChanging", value: function handlePlayerModeChanging(oldMode, newMode, pano) { var activeModel = this.$app.core.get('ModelManager').getActiveModel(); var opacity; //if(this.$app.core.get('Player').is360View(newMode, pano) || this.$app.core.get('Director').tourIsPlaying) if (this.$app.core.get('Player').is360View(newMode, pano)) { opacity = 0; } else { opacity = settings$3[newMode].markerOpacity; } //显示地面的白色圈圈 activeModel.fadePanoMarkers(opacity, 0, { mode: newMode }); //activeModel.setMode(newMode) //xzw改 没必要所以去掉,在handlePlayerModeChanged中写了。否则太乱了。 } }, { key: "handlePlayerModeChanged", value: function handlePlayerModeChanged(e, mode) { var activeModel = this.$app.core.get('ModelManager').getActiveModel(); var sid = mode === Viewmode$1.PANORAMA ? THREE.DoubleSide : THREE.FrontSide; activeModel.setSide(sid); activeModel.setMode(mode); } //地面的marker变清晰 }, { key: "handleClosestPanoChanging", value: function handleClosestPanoChanging(closestPano, newClosestPano, mode) { if (mode !== Viewmode$1.TRANSITIONING) { closestPano && closestPano.hoverOff(mode); newClosestPano && newClosestPano.hoverOn(mode); } } //add }, { key: "handleStartInside", value: function handleStartInside(duration) { var t = settings$3[this.$app.core.get('Player').mode], i = duration ? 0 : t.transitionTime * t.skyboxOpacityLength; this.fadeIn(this.fadeInSpeed); this.model.alpha = 0; this.model.skybox.material.uniforms.opacity.value = 1; //(this.model.skybox.originMat || this.model.skybox.material).uniforms.opacity.value = 1 this.model.fadePanoMarkers(null, null, { player: this.$app.core.get('Player') }); //(e ? 0 : t.markerOpacity); var reticule = this.$app.core.get('Player').reticule; transitions$1.start(lerp.property(reticule.material, 'opacity', 0), i, null, 0, null, 'retReOpac'); } }, { key: "handleStartOutside", value: function handleStartOutside(duration) { this.fadeIn(duration); } }, { key: "fadeIn", value: function fadeIn(duration) { null !== duration && void 0 !== duration || (duration = 2000, logger.warn('DisplayController.fadeIn -> no transition time specified, defaulting to 2000 ms.')); if (this.model) { //this.model.chunks.forEach(item => (item.visible = true)) //xzw 4.6.0 隐藏chunk this.model.panos.forEach(function (item) { return item.updateMakerStyle(); }); } } }]); return DisplayController; }(EventEmitter); }); defineComponent('QuickstartManager', function () { return /*#__PURE__*/function () { function QuickstartManager(qualityManager, scene, camera, controls, panoVideoRenderer) { _classCallCheck(this, QuickstartManager); this.locked = false; this.qualityManager = qualityManager; this.scene = scene; this.camera = camera; this.controls = controls; this.quickStartcamera = controls.camera; this.view = null; this.panoVideoRenderer = panoVideoRenderer; this.unlockDom = null; this.unlockHanlde = null; this.loadPromise = null; this.ready = false; this.touchStartPosition = new THREE.Vector2(0, 0); this.touchMoveDelta = new THREE.Vector2(0, 0); this.touchPrevPosition = new THREE.Vector2(0, 0); this.touchMoveOffset = new THREE.Vector2(0, 0); this.enter = false; this.canEnter = false; this.animFov = null; this.animRotation = null; this.initTarget = new THREE.Vector3(0, 0, 0); this.enterView = { pano: null, quaternion: new THREE.Quaternion(), position: new THREE.Vector3(), fov: settings$3.insideFOV }; } _createClass(QuickstartManager, [{ key: "init", value: function init(view, metadata) { this.dom = this.$app.core.get('Player').domElement; this.pano = view.pano; this.setSize(window.innerWidth, window.innerHeight); this.initView(view); this.skybox = new THREE.Mesh(new THREE.BoxBufferGeometry(1, 1, 1), new ModelTextureMaterial({ side: THREE.DoubleSide })); this.skybox.material.uniforms.map.value = view.pano.getSkyboxTexture(); this.skybox.quaternion.copy(view.quaternion); this.scene.add(this.skybox); this.skybox.material.depthTest = false; this.skybox.material.depthWrite = false; this.skybox.renderOrder = 1000; this.skybox.name = 'quickStartSkyBox'; this.skybox.material.uniforms.modelAlpha.value = 0; this.skybox.position.copy(this.pano.position); this.skybox.visible = true; this.scene.add(this.skybox); this.pano.attachToPanoVideoRenderer(this.$app.core.get('PanoVideoRenderer')); this.$app.core.get('PanoVideoRenderer').on(PanoVideoRendererEvents.StartPlayVideo, this.onVideoStartPlay.bind(this)); this.$app.core.get('PanoVideoRenderer').on(PanoVideoRendererEvents.TextureUpdate, this.onVideoTextureUpdate.bind(this)); this.$app.core.get('PanoVideoRenderer').on(PanoVideoRendererEvents.ResumeRender, this.onVideoRenderResume.bind(this)); this.$app.core.get('PanoVideoRenderer').on(PanoVideoRendererEvents.SuspendRender, this.onVideoRenderSuspend.bind(this)); if (this.$app.core.get('PanoVideoRenderer').videosInfo) { var parameters = this.$app.core.get('PanoVideoRenderer').videosInfo.parameters; this.skybox.material.uniforms.parameters.value.set(parameters.inputWidth, parameters.inputHeight, parameters.outputWidth, parameters.outputHeight, parameters.focal, parameters.pixel, parameters.centerX, parameters.centerY, parameters.translateX, parameters.translateY, parameters.translateZ, 0, parameters.lenOffsetX, parameters.lenOffsetY, parameters.videoWidth, parameters.videoHeight); if (parameters.cameraType == 8) { this.skybox.material.defines.HasVideo = 8; //8目 } else if (parameters.cameraType == 2) { this.skybox.material.defines.HasVideo = 2; //2目 } this.skybox.material.defines['VideoMapping'] = parameters.mapping; this.skybox.material.uniforms.videoReady.value = 0; this.skybox.material.uniforms.progress.value = 1; } } }, { key: "initView", value: function initView(view) { this.view = view; var pano = view.pano; view.mode; view.zoom; view.position; view.quaternion; this.controls.locked = false; this.controls.camera.position.copy(pano.position); // zeg 这部分代码使球幕点位初始化的相机旋转变为0 // if (pano.hasVideo && !view.setByUrl) { // if (pano.videoInfo.dir) { // this.initTarget.copy(pano.videoInfo.dir).add(pano.position) // } else { // var qua = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(!this.$app.core.get('Player').model.supportsTiles ? 90 : 180)) // this.initTarget.copy(Vectors.FORWARD.clone().applyQuaternion(qua.multiply(pano.quaternion))).add(pano.position) // } // this.controls.lookAt(this.initTarget) // } else { this.initTarget.copy(new THREE.Vector3(0, 0, -1).applyQuaternion(view.quaternion)).add(view.position); this.controls.lookAt(this.initTarget); // } this.quickStartcamera.fov = this.view.fov; this.quickStartcamera.aspect = window.innerWidth / window.innerHeight; this.quickStartcamera.updateProjectionMatrix(); this.camera.fov = this.view.fov; this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.position.copy(this.quickStartcamera.position); this.camera.quaternion.copy(this.quickStartcamera.quaternion); this.enterView.pano = pano; this.enterView.position.copy(this.view.position); this.enterView.quaternion.copy(this.view.quaternion); this.enterView.fov = this.view.fov; this.controls.update(0.016); /* this.controls.locked = true this.controls.limitDownAngel = this.controls.lat */ //xzw 2023.1.18注释 this.view.position.copy(this.quickStartcamera.position); this.view.quaternion.copy(this.quickStartcamera.quaternion); } }, { key: "load", value: function load(view) { var _this = this; if (this.loadPromise) return this.loadPromise; var metadata = this.$app.store.__store.metadata; this.view = view; this.view.pano.shouldRedrawOnBaseLoaded = !0; if (this.view.pano.tiled) { this.init(view, metadata); var $player = document.querySelector('.player[name=main]'); var lowSize = this.qualityManager.getPanoSize(PanoSizeClass.BASE), highSize = this.qualityManager.getPanoSize(PanoSizeClass.STANDARD), d = cameraLight.getHFOVForCamera(this.quickStartcamera, $player.clientWidth, $player.clientHeight), p = this.quickStartcamera.fov, r = Vectors$1.FORWARD.clone().applyQuaternion(this.view.quaternion); var promise1 = this.view.pano.loadTiledPano(highSize, r, { hFov: d, vFov: p }, !1, !1, !0); var promise2 = this.view.pano.loadTiledPano(lowSize, r.clone().negate(), null, !1, !1, !0); this.loadPromise = new Promise(function (resolve) { (_this.view.pano.hasVideo || _this.qualityManager.getMaxNavPanoSize() < 1024 ? promise2 : promise1).then(resolve); }); } else { this.init(view, metadata); this.loadPromise = new Promise(function (resolve) { _this.view.pano.hasVideo ? _this.view.pano.loadCube('low').then(function () { return resolve(); }) : _this.view.pano.loadCube('high').then(function () { return resolve(); }); }); } this.loadPromise.then(function () { _this.ready = true; _this.skybox.material.setProjectedPanos(_this.view.pano, _this.view.pano); // 此时已经显示初始点位了,所以也需要设置马赛克和滤镜 _this.$app.core.get('Player').paintEditor.updatePanoPaint(_this.view.pano.id, _this.view.pano.id); _this.$app.FilterManager.updatePanoFilters(_this.view.pano, _this.view.pano); }); return this.loadPromise; } }, { key: "onVideoStartPlay", value: function onVideoStartPlay() {} }, { key: "onVideoTextureUpdate", value: function onVideoTextureUpdate(texture) { this.skybox.material.uniforms.videoTexture.value = texture; } }, { key: "onVideoRenderResume", value: function onVideoRenderResume() { this.skybox.material.uniforms.videoReady.value = 1; // 暂停背景音乐 this.$app.Scene.emit('panorama.videorenderer.resumerender'); } }, { key: "onVideoRenderSuspend", value: function onVideoRenderSuspend() { // this.skybox.material.uniforms.videoReady.value = 0 //修改 球幕视频暂停时不要隐藏 // todo 播放导览时球目视频挂起不恢复背景音乐 // 播放背景音乐 this.$app.Scene.emit('panorama.videorenderer.suspendrender'); } }, { key: "watingUnlock", value: function watingUnlock() { var _this2 = this; this.locked = true; this.controls.locked = true; return new Promise(function (resolve) { _this2.unlockHanlde = resolve; }); } }, { key: "autoUnlock", value: function autoUnlock() { this.locked = false; this.app.active = true; this.controls.locked = false; this.controls.limitDownAngel = null; if (this.pano.hasVideo && browser$1.detectIOS()) { this.panoVideoRenderer.setMuted(false); } else { this.panoVideoRenderer.setMuted(true); } this.panoVideoRenderer.activatePanorama(this.pano); return Promise.resolve(true); } }, { key: "activate", value: function activate() { this.panoVideoRenderer.setMuted(browser$1.urlQueryValue('sound') == '0'); this.panoVideoRenderer.activatePanorama(this.pano); } }, { key: "unlock", value: function unlock(speed) { var _this3 = this; if (this.enter) { this.controls.rotationAcc.set(0, 0); return; } this.enter = true; this.app.emit('unlock'); this.controls.locked = false; this.controls.rotationAcc.set(speed.x > 0 ? 0.3 : -0.3, 0); this.controls.limitDownAngel = null; if (this.animFov) transitions$1.cancel(this.animFov); try { parent.postMessage({ num: config.projectNum, cmd: 'unlocking', isParent: top == self }, '*'); } catch (error) { console.error('跨域', error); } this.animFov = transitions$1.start(lerp.property(this.quickStartcamera, 'fov', 70), 3000, function () { _this3.unlockHanlde && _this3.unlockHanlde(); _this3.locked = false; _this3.enter = true; _this3.controls.locked = false; _this3.controls.rotationAcc.set(0, 0); _this3.controls.limitDownAngel = null; try { parent.postMessage({ num: config.projectNum, cmd: 'unlocked', isParent: top == self }, '*'); } catch (error) { console.error('跨域', error); } }, 0.0, easing.easeOutCubic); } }, { key: "exit", value: function exit() { this.enter = false; var pano = this.pano; pano.enter(); this.controls.rotationAcc.set(0, 0); this.controls.limitDownAngel = null; if (this.animFov) transitions$1.cancel(this.animFov); if (this.app.player.model) { this.app.player.flyToPano({ pano: this.pano }); } else { this.smoothLookAt(this.initTarget, 1000); } } }, { key: "smoothLookAt", value: function smoothLookAt(targetLookAt, duration) { var _this4 = this; duration = duration || 1000; var targetDir = targetLookAt.clone().sub(this.controls.camera.position).normalize(); var currDir = this.controls.lookVector.clone(); var dir = new THREE.Vector3(); new THREE.Vector3(); var lerp = function lerp(alpha) { dir.lerpVectors(currDir, targetDir, alpha); _this4.controls.lookAt(dir.add(_this4.controls.camera.position)); }; this.animFov = transitions$1.start(lerp, duration); } }, { key: "cancelRotate", value: function cancelRotate() { if (this.enter && this.app.startOption.needUnlock) this.controls.rotationAcc.set(0, 0); } }, { key: "update", value: function update(deltaTime) { if (this.locked) ; this.controls.update(deltaTime); this.camera.position.copy(this.quickStartcamera.position); this.camera.quaternion.copy(this.quickStartcamera.quaternion); this.camera.fov = this.quickStartcamera.fov; this.camera.updateProjectionMatrix(); this.view.position.copy(this.quickStartcamera.position); this.view.quaternion.copy(this.quickStartcamera.quaternion); this.view.fov = this.quickStartcamera.fov; } }, { key: "setSize", value: function setSize(width, height) { this.camera.aspect = width / height; this.camera.updateProjectionMatrix(); } }, { key: "destroy", value: function destroy() { this.scene.remove(this.skybox); this.controls.rotationAcc.set(0, 0); // this.dom.removeEventListener('touchstart', this.cancelRotate) // this.unlockDom.removeEventListener('touchstart', this.onTouchStart) // this.unlockDom.removeEventListener('touchmove', this.onTouchMove) // this.unlockDom.removeEventListener('touchend', this.onTouchEnd) } //swiper事件的原因,用于快速切换解锁需要给定dom }, { key: "attachDom", value: function attachDom(dom) { dom.addEventListener('touchstart', this.onTouchStart.bind(this)); dom.addEventListener('touchmove', this.onTouchMove.bind(this)); dom.addEventListener('touchend', this.onTouchEnd.bind(this)); } }, { key: "onTouchEvent", value: function onTouchEvent(eventType, event) { if (event.type == 'touchstart') { this.onTouchStart(event); } else if (event.type == 'touchmove') { this.onTouchMove(event); } else if (event.type == 'touchend') { this.onTouchEnd(event); } } }, { key: "onTouchStart", value: function onTouchStart(event) { this.touchStartPosition.set(event.touches[0].clientX, event.touches[0].clientY); this.touchPrevPosition.set(event.touches[0].clientX, event.touches[0].clientY); this.touchMoveDelta.set(0, 0); this.touchMoveOffset.set(0, 0); if (this.enter || this.app.needUnlock == false) { this.controls.rotationAcc.set(0, 0); this.controls.onTouchStart(event); } else { //this.controls.onTouchStart( event ); this.canEnter = false; } this._start = { x: event.touches[0].clientX, y: event.touches[0].clientY }; } }, { key: "onTouchMove", value: function onTouchMove(event) { this._move = { x: event.touches[0].clientX, y: event.touches[0].clientY }; this.touchMoveDelta.set(event.touches[0].clientX - this.touchPrevPosition.x, event.touches[0].clientY - this.touchPrevPosition.y); this.touchPrevPosition.set(event.touches[0].clientX, event.touches[0].clientY); this.touchMoveOffset.set(event.touches[0].clientX - this.touchStartPosition.x, event.touches[0].clientY - this.touchStartPosition.y); if (this.enter || this.app.needUnlock == false) { this.controls.onTouchMove(event); } else { var speedX = -this.touchMoveDelta.x; var slideHor = Math.abs(this.getAngle(this._start, this._move)) < 15; //(Math.abs(this.touchMoveOffset.y) / Math.abs(this.touchMoveOffset.x)) < 0.15 var canEnter = slideHor && this.enter == false; canEnter && this.unlock(new THREE.Vector2(speedX, 0)); } } }, { key: "onTouchEnd", value: function onTouchEnd(event) { if (this.enter || this.app.needUnlock == false) { this.controls.onTouchEnd(event); } } }, { key: "getAngle", value: function getAngle(start, end) { var diff_x = end.x - start.x, diff_y = end.y - start.y; return 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI); } }]); return QuickstartManager; }(); }); var effects$1 = { currentBlur: 0, aspect: settings$3.aspect, blurStrength: 1, hblurPass: settings$3.HorizontalBlurShader, vblurPass: settings$3.VerticalBlurShader, bindEvents(e) { e.on(PlayerEvents.ModeChanged, function (mode, t) { if (mode === Viewmode$1.PANORAMA) { transitions$1.cancel(effects$1.blur); transitions$1.cancel(effects$1.addBlur); transitions$1.start(effects$1.removeBlur, 500, null, 0, null, 'deblur'); } }); }, blur(blur) { effects$1.currentBlur = blur; var t = blur * effects$1.blurStrength; settings$3.VerticalBlurShader.uniforms.v.value = t / 512 * effects$1.aspect; settings$3.HorizontalBlurShader.uniforms.h.value = t / 512; }, addBlur(blur) { blur = Math.max(blur, effects$1.currentBlur); effects$1.blur(blur); }, removeBlur(blur) { blur = Math.min(1 - blur, effects$1.currentBlur); effects$1.blur(blur); } }; effects$1.blur(0); var BasicException$1 = function BasicException(message) { _classCallCheck(this, BasicException); this.message = message; }; function _createSuper$N(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$N(); 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 _isNativeReflectConstruct$N() { 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; } } var RendererCreationException$1 = /*#__PURE__*/function (_BasicException) { _inherits(RendererCreationException, _BasicException); var _super = _createSuper$N(RendererCreationException); function RendererCreationException(e) { _classCallCheck(this, RendererCreationException); return _super.call(this, e); } return RendererCreationException; }(BasicException$1); function _createSuper$M(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$M(); 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 _isNativeReflectConstruct$M() { 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; } } var sceneRenderer$1, player$7; var hasInit; // zeg加 否则分屏时会重复初始化 //window.settings = settings //window.ifTest = true // 调试不会开启陀螺仪 //window.VRScreenType="portrait" //: 不分屏,没有空中小球 //const flickerThreshold = 0.001 var avoidFlicker; window.screenFaceOrient = 0; var vrPermission = {}; var vrPermissionCallBack = function vrPermissionCallBack(info1, info2) { if (info1 == 'reset') { vrPermission = {}; } else { vrPermission[info1] = info2; if (Object.keys(vrPermission).length == 2 && (vrPermission.deviceMotion != 'granted' || vrPermission.deviceOrientation != 'granted')) { //$alert({content:"运动和方向访问失败", "这会导致画面视角一直固定。您需要完全关闭" + (Config.app ?"App":"此浏览器") + ",然后再次打开,并允许访问运动与方向。"}) // if (!window.VRScreenNotFull) { // $alert({ content: i18n.t('modules.base.vr_fail_reopen_tips') }) // } console.error('运动和方向访问失败'); } } }; var vr = /*#__PURE__*/function (_THREE$EventDispatche) { _inherits(vr, _THREE$EventDispatche); var _super = _createSuper$M(vr); function vr() { _classCallCheck(this, vr); return _super.call(this); } _createClass(vr, [{ key: "Init", value: function Init(_sceneRenderer, _player) { //初始化 外部使用 sceneRenderer$1 = _sceneRenderer; player$7 = _player; player$7.VR = this; if (!sceneRenderer$1.renderer || sceneRenderer$1.newRenderer || hasInit) return; //还未准备好renderer或已经Init过了 var vrTexture = common.loadTextureFromCache(texture.getImageURL('images/circleMarker.png')); player$7.model.panos.list.forEach(function (pano) { pano.createVrMarker(vrTexture, player$7); }); sceneRenderer$1.newRenderer = new vrRenderer(sceneRenderer$1.renderer, sceneRenderer$1, sceneRenderer$1.camera); sceneRenderer$1.isHuawei5X = browser$1.detectHUAWEI5X(); sceneRenderer$1.oldRenderer = sceneRenderer$1.renderer; webxr.init(sceneRenderer$1.renderer); initFlicker(); if (player$7.$app.config.vr.markerHeight != null && !isNaN(player$7.$app.config.vr.markerHeight)) { var height = player$7.$app.config.vr.markerHeight; player$7.model.panos.forEach(function (pano) { if (!pano.vrMarker) return; //pano.vrMarker.position.y = pano.floorPosition.y + (v != void 0 ? v : pano.height - 0.2) pano.vrMarker.position.y = pano.floorPosition.y + height; }); } var _vrEnabled = !1; //vr状态是否开启(开启陀螺仪) var _vrSplitScreen = false; //是否分屏 var events = { // get aspect setSize: function setSize(b, c) { sceneRenderer$1.camera.aspect = b / c; } }; //if (!settings.hasOwnProperty('vrEnabled')) { Object.defineProperty(settings$3, 'vrEnabled', { get: function get() { return _vrEnabled; }, set: function set(b) { b = !!b; player$7.cameraControls.controls.panorama.locked = b; player$7.model.chunks.forEach(function (c) { return c.visible = !(b && (webxr.xrType || settings$3.vrSplitScreen)); }); //vr模式下 改变chunks显示会让画面分离度改变,可能和眼睛看物体远近不同的夹角有关。 而一直显示模型会有穿墙危险,所以改为一直不显示模型。// 为什么注释掉了? //注: 2022.10.19: 调试pico的webxr时,发现若显示模型,会看出模型轮廓,画面被割裂(原地非过渡)。原因可能是头盔是两个camera,且都与原位置有偏差,所以不在pano中心。(但是之前vr眼镜似乎没有此现象?) 故而关闭模型显示,代价就是过渡时无法贴合模型,多楼层看起来像悬空的。 if (webxr.xrType) { return b ? webxr.enterVR() : webxr.leaveVR(); } else { //交换renderer b && settings$3.vrSplitScreen ? (sceneRenderer$1.renderer = sceneRenderer$1.newRenderer, player$7.cameraControls.cameras.panorama.staticFov = 70 //为了使镜头不变形 ) : (sceneRenderer$1.renderer = sceneRenderer$1.oldRenderer, player$7.cameraControls.cameras.panorama.staticFov = null); } _vrEnabled = b; //注:pico3的xr全屏会黑屏 if (!window.VRScreenNotFull) { b ? browser$1.requestFullscreen( /* player.domElement */ document.body) : browser$1.exitFullscreen(); } //是否全屏:!!document.fullscreenElement //objects.gui.showVrHorizonTip(_vrEnabled && !_vrSplitScreen) if (!VR.cursor) createCursor(0.5, true, 1, 16777215, 0); //transparent改为true,旧版竟然可以是false if (window.VRScreenType != 'portrait') { //普通模式( 不是这种不需要分屏和vrMarker的情况) VR.cursor.visible = b; sceneRenderer$1.updateScreenSize({ forceUpdateSize: true }); //sceneRenderer.setSize(window.innerWidth, window.innerHeight) player$7.model.updateVrMarker(b, player$7); } if (!b) { var pos = player$7.position; var qur = new THREE.Quaternion().copy(player$7.camera.quaternion); var lookAtPoint = new THREE.Vector3(0, 0, -1).applyQuaternion(qur).add(pos); if (lookAtPoint.x == pos.x && lookAtPoint.z == pos.z) { console.log('看向正地面时无法lookAt,无法更新camera转向,直接退出vr'); } else player$7.cameraControls.activeControl.lookAt(lookAtPoint); //退出时更新一下camera的方向 player$7.viewLinkManager.showAllViews(); VR.shiftQuaternion = null; var index = sceneRenderer$1.resizeListeners.indexOf(events); sceneRenderer$1.resizeListeners.splice(index, 1); } else { player$7.viewLinkManager.hideAllViews(); sceneRenderer$1.resizeListeners.push(events); //处理失败: setTimeout(function () { console.log('orientEnable' + window.orientEnable); if (settings$3.vrEnabled && !window.orientEnable) { //很可能没能触发陀螺仪事件 if (browser$1.detectIOS() /* && browser.detectSafari() */ ) { var b = browser$1.iosVersion(); //{major: 10, minor: 3, patch: 1} //console.log("开始获取权限 major"+b.major) if (b.major == 12 && b.minor >= 2) { if (!window.VRScreenNotFull) { if (browser$1.detectSafari()) $alert({ content: i18n.t('modules.base.vr_fail_safari_tips') });else { //app?? $alert({ content: i18n.t('modules.base.vr_fail_app_tips') }); } } } else if (b.major >= 13) { var hasFailed = window.vrPermission && (window.vrPermission.deviceMotion != 'granted' || window.vrPermission.deviceOrientation != 'granted'); //hasFailed || $tips({content: i18n.t('modules.base.please_click_tips')}) setTimeout(function () { if (!settings$3.vrEnabled || window.orientEnable) return; vrPermissionCallBack('reset'); if (window.DeviceMotionEvent && window.DeviceMotionEvent.requestPermission && typeof window.DeviceMotionEvent.requestPermission === 'function') { console.log('开始获取权限1'); ///注意:需要https 本地服务器permissionState会得到denied window.DeviceMotionEvent.requestPermission().then(function (permissionState) { console.log('permissionState1: ' + permissionState); vrPermissionCallBack('deviceMotion', permissionState); }).catch(function (e) { vrPermissionCallBack('deviceMotion', false); console.log(e); }); } else { console.log('window.DeviceMotionEvent undefined'); vrPermissionCallBack('deviceMotion', false); } if (window.DeviceOrientationEvent && window.DeviceOrientationEvent.requestPermission && typeof window.DeviceOrientationEvent.requestPermission === 'function') { console.log('开始获取权限2'); window.DeviceOrientationEvent.requestPermission().then(function (permissionState) { console.log('permissionState2: ' + permissionState); vrPermissionCallBack('deviceOrientation', permissionState); }).catch(function (e) { vrPermissionCallBack('deviceOrientation', false); console.log(e); }); } else { console.log('window.DeviceOrientationEvent undefined'); vrPermissionCallBack('deviceOrientation', false); } }, hasFailed ? 0 : 150); /* /* setTimeout(function(){ if(settings.vrEnabled && !window.orientEnable){ $alert("若画面视角一直固定,您需要完全关闭Safari浏览器,然后再次打开以开启运动和方向访问。") } },4000) */ } else console.log('陀螺仪似乎未能启用 ios ' + b.major + '.' + b.minor); } } }, 200); } player$7.emit('vrStateChanged'); } }); Object.defineProperty(settings$3, 'vrSplitScreen', { //分屏 许钟文加 get: function get() { return _vrSplitScreen; }, set: function set(b) { b = !!b; if (_vrSplitScreen == b) return; _vrSplitScreen = b; if (!settings$3.vrEnabled || window.VRScreenType == 'portrait') return; b ? (sceneRenderer$1.renderer = sceneRenderer$1.newRenderer, player$7.cameraControls.cameras.panorama.staticFov = 70) : (sceneRenderer$1.renderer = sceneRenderer$1.oldRenderer, player$7.cameraControls.cameras.panorama.staticFov = null); player$7.model.chunks.forEach(function (c) { return c.visible = !b; }); sceneRenderer$1.updateScreenSize({ forceUpdateSize: true }); //sceneRenderer.setSize(window.innerWidth, window.innerHeight)//不这么写因刚旋转时 window.innerWidth, window.innerHeight 不准确 //console.log('vrSplitScreen', b, window.innerWidth, window.innerHeight, player.domElement.clientWidth, player.domElement.clientHeight) player$7.emit('vrStateChanged'); } }); //} if (window.orientation == 90 || window.orientation == 270) { //横屏 settings$3.vrSplitScreen = true; } // let vrMarkerHeight // Object.defineProperty(settings, 'vrMarkerHeight', { // get: function () { // return vrMarkerHeight // }, // set: function (v) { // vrMarkerHeight = v // player.model.panos.forEach(pano => { // if (!pano.vrMarker) return // pano.vrMarker.position.y = pano.floorPosition.y + (v != void 0 ? v : pano.height - 0.2) // }) // }, // }) //window.sett = settings window.addEventListener('orientationchange', function (e) { //console.log(`vr orientation ${window.orientation}`) if (window.orientation == 0 || window.orientation == 180) { //竖屏 settings$3.vrSplitScreen = false; } else { settings$3.vrSplitScreen = true; } }); hasInit = true; } }, { key: "isSupportXR", value: function isSupportXR() { return !!webxr.xrType; } }]); return vr; }(THREE.EventDispatcher); var VR; window.VR = VR = new vr(); //vr对焦 var createCursor = function createCursor(a, b, c, d, e) { var g, h = new THREE.SpriteMaterial({ opacity: c, color: d, transparent: b, map: boluoloadTextureFromCache(texture.getImageURL('images/vrCursor.png')), side: THREE.DoubleSide }); h.map.offset = new THREE.Vector2(1 / 17 * e, 0); h.map.repeat = new THREE.Vector2(1 / 17, 1); h.depthTest = !1, h.blending = THREE.AdditiveBlending; g = new THREE.Sprite(h); g.scale.set(a, a, a); g.position.z = -5, g.visible = !1, g.name = 'cursor', g.renderOrder = RenderOrder.panoMarker; //add sceneRenderer$1.camera.add(g); sceneRenderer$1.scene.add(sceneRenderer$1.camera); VR.cursor = g; var i = new VROrientation(sceneRenderer$1.scene, g, sceneRenderer$1.camera); VR.cursor.triggerTargetEvent = i.triggerTargetEvent.bind(i), sceneRenderer$1.updateListeners = [i].concat(sceneRenderer$1.updateListeners); //before player }; window.orientEnable = 0; //是否能触发deviceorientation var VROrientation = function VROrientation(a, b, c) { var _this2 = this; function d() { g.orient = THREE.MathUtils.degToRad(window.orientation || 0); } var updateRot = function updateRot(a) { //deviceorientation 需要https if (!settings$3.vrEnabled && window.orientEnable) return; window.orientEnable || (window.orientEnable = 1); //if(this.alpha == a.alpha || this.beta == a.beta || this.gamma == a.gamma)return; var b = THREE.MathUtils.degToRad(a.alpha), c = THREE.MathUtils.degToRad(a.beta), d = THREE.MathUtils.degToRad(a.gamma); //console.log(a.alpha.toFixed(3), c.toFixed(3), a.gamma.toFixed(3)) //console.log((b-this.alpha).toFixed(3), (c-this.beta).toFixed(3), (d-this.gamma).toFixed(3)) if (_this2.isHuawei5X) { -1e3 === _this2.alpha && (_this2.alpha = b), -1e3 === _this2.beta && (_this2.beta = c), -1e3 === _this2.gamma && (_this2.gamma = d), Math.abs(b - _this2.alpha) > 0.06 && (_this2.alpha = b), Math.abs(c - _this2.beta) > 0.006 && (_this2.beta = c), Math.abs(d - _this2.gamma) > 0.006 && (_this2.gamma = d); } else { _this2.alpha = b, _this2.beta = c, _this2.gamma = d; } /* if ( SceneRenderer.vrDebug ) { $("#info-device-orientation").css("display", "block"); var e = ""; e += "alpha=(" + g.alpha + ")
", e += "beta=(" + g.beta + ")
", e += "gamma=" + g.gamma + "
", document.getElementById("info-device-orientation").innerHTML = e } */ }; this.cursor = b, this.raycaster = new THREE.Raycaster(), this.targetEventObj = {}, this.type = 1, this.canStartAnimation = !0; var g = this; this.target = c, this.euler = new THREE.Euler(), this.q0 = new THREE.Quaternion(), this.q1 = new THREE.Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)), this.zee = new THREE.Vector3(0, 0, 1), this.alpha = -1e3, this.beta = -1e3, this.gamma = -1e3, this.lastQua = new THREE.Quaternion(), this.orient = THREE.MathUtils.degToRad(window.orientation || 0), window.addEventListener('orientationchange', d), window.addEventListener('deviceorientation', updateRot), this.setObjectQuaternion = function (quaternion, alpha, beta, gamma, f) { if (alpha == -1000) return; // 利用player.updatefromControl来最终更新camera var aimQua = quaternion.clone(); g.euler.set(beta, alpha, -gamma, 'YXZ'); aimQua.setFromEuler(g.euler); aimQua.multiply(g.q1); aimQua.multiply(g.q0.setFromAxisAngle(g.zee, -f)); var diffAngle = this.lastQua.angleTo(aimQua); if (diffAngle < 1e-7) return; //防抖: if (avoidFlicker && VR.shiftQuaternion) { quaternion.copy(this.lastQua); var useRatio = math$1.linearClamp(diffAngle, avoidFlicker.threshold.min, avoidFlicker.threshold.max, avoidFlicker.useRatio, 0.9); //越小越延迟 //const useRatio = diffAngle > avoidFlicker.threshold ? 1 : avoidFlicker.useRatio //越小越延迟 lerp.quaternion(quaternion, aimQua)(useRatio); //diffAngle > avoidFlicker.threshold.min && console.log(useRatio) } else { quaternion.copy(aimQua); } this.lastQua.copy(quaternion); if (VR.shiftQuaternion == void 0) { //标记初始水平朝向(进入vr时的) var dir = new THREE.Vector3(0, 0, -1).applyQuaternion(player$7.camera.quaternion); //初始的相机对应的朝向 dir.setY(0).normalize(); //水平 var mat = new THREE.Matrix4().lookAt(new THREE.Vector3(), dir, new THREE.Vector3(0, 1, 0)); var startQuaternion = new THREE.Quaternion().setFromRotationMatrix(mat); var dir2 = new THREE.Vector3(0, 0, -1).applyQuaternion(quaternion); //初始的陀螺仪对应的朝向 dir2.setY(0).normalize(); //水平 var mat2 = new THREE.Matrix4().lookAt(new THREE.Vector3(), dir2, new THREE.Vector3(0, 1, 0)); var invertQuaternion = new THREE.Quaternion().setFromRotationMatrix(mat2).invert(); VR.shiftQuaternion = startQuaternion.clone().premultiply(invertQuaternion); //将此刻陀螺仪的朝向dir2矫正到此刻相机朝向dir所要乘的quaternion } quaternion.premultiply(VR.shiftQuaternion); updateScreenFaceOrient(quaternion); }; parent !== window && window.addEventListener('message', function (a) { //针对iframe的?? if (!a.data || a.data && a.data.type && a.data.type.indexOf('webpack') > -1) { return; } var b = typeof a.data == 'string' ? JSON.parse(a.data) : a.data, c = -1 !== window.navigator.userAgent.indexOf('KIW-TL00H'); b && b.alpha && b.beta && b.gamma && function (a) { var c = THREE.MathUtils.degToRad(b.alpha), d = THREE.MathUtils.degToRad(b.beta), e = THREE.MathUtils.degToRad(b.gamma); a ? (-1e3 === g.alpha && (g.alpha = c), -1e3 === g.beta && (g.beta = d), -1e3 === g.gamma && (g.gamma = e), Math.abs(c - g.alpha) > 0.06 && (g.alpha = c), Math.abs(d - g.beta) > 0.006 && (g.beta = d), Math.abs(e - g.gamma) > 0.006 && (g.gamma = e)) : (g.alpha = c, g.beta = d, g.gamma = e); }(c); }), this.update = function (a) { TWEEN.update(); if (window.ifTest && settings$3.vrEnabled) this.triggerTargetEvent(); //测试时不根据陀螺仪来转向 else settings$3.vrEnabled && (this.setObjectQuaternion(player$7.cameraControls.activeControl.camera.quaternion /* this.target.quaternion */ , this.alpha, this.beta, this.gamma, this.orient), this.triggerTargetEvent()); }, this.triggerTargetEvent = function () { //判断vr cursor是否选中物体 var a = this.choseObj(), b = a ? a.object : void 0; this.targetEventObj.currentObj = b; b !== this.targetEventObj.lastObj && (b && this.autoCursorPosition(a), 1 === this.type ? (this.cursorAnimate && this.cursorAnimate.stop(), b && b.enabled && this.startAnimate(function () { this.clickCallback(b); }.bind(this))) : this.type, this.targetEventObj.lastObj = b); }, this.choseObj = function () { this.raycaster.setFromCamera({ x: 0, y: 0 }, c); var b = this.raycaster.intersectObjects(player$7.model.vrMarkers.filter(function (e) { return e.visible; })); if (b.length > 0) return b[0]; }, this.clickCallback = function (a) { this.runTHREEAction(a, 'onclick'); }, this.runTHREEAction = function (a, b) { switch (b) { case 'onclick': a._listeners && a._listeners.click && a._listeners.click.forEach(function (a) { a(); }); break; case 'onhover': a._listeners && a._listeners.hover && a._listeners.hover.forEach(function (a) { a(); }); break; case 'onout': a._listeners && a._listeners.out && a._listeners.out.forEach(function (a) { a(); }); } }, this.startAnimate = function (a) { //vr cursor's circle animation this.canStartAnimation && this.initAnimation(a); }, this.initAnimation = function (done) { var b = this, offset = this.cursor.material.map.offset, f = function f(a) { return Math.floor(17 * a) / 17; //对应17个精灵图片段 }; b.canStartAnimation = !1, this.cursorAnimate = new TWEEN.Tween(offset).to({ x: 1 //100% }, 1e3).onStart(function () { b.canStartAnimation = !1; }).onStop(function () { b.canStartAnimation = !0, this.x = 0, offset.x = 0; }).onUpdate(function () {}).onComplete(function () { done(), offset.x = 0, setTimeout(function () { b.canStartAnimation = !0; }, 1500); }), this.cursorAnimate.easing(f), this.cursorAnimate.start(); }, this.autoCursorPosition = function (a) { var b = Math.abs(a.distance - 10); this.cursor.position.z = -b, b /= 10, this.cursor.scale.set(b, b, b); }; }; /* 为分屏重新创建了个renderer,分别渲染左右两个矩形区域,对应左右相机。 替换sceneRenderer.renderer即可 */ var vrRenderer = function vrRenderer(renderer, sceneRenderer, camera) { // vrRenderer类 var VRCamera = new vrCamera(camera); //d window.VRCamera = VRCamera; VRCamera.bananaAspect = 0.8, this.width, this.height; this.name = 'vrRenderer'; var b = this; this.setSize = function (c, d) { renderer.setSize.call(this, c, d /* , false */ ), b.width = c, b.height = d; }; this.render = function (b, c, e, f) { var g, h; if (c.__RESS__SKIP__STEREO__) { var V = renderer.autoClear; renderer.autoClear = !1; renderer.setRenderTarget(e); if (f) renderer.clear(); renderer.render(b, c); renderer.setRenderTarget(null); renderer.autoClear = V; return; // renderer.render(b, c, e, f) } if ('PerspectiveCamera' === c.type) g = VRCamera.cameraL, h = VRCamera.cameraR, b.updateMatrixWorld(), null === c.parent && c.updateMatrixWorld(), VRCamera.vrCameraUpdate(c);else { if ('OrthographicCamera' !== c.type) return DEBUG && console.error('Unsupported renderer: ', c.type); g = h = c; } renderer.setScissorTest(!0), renderer.setScissor(0, 0, this.width / 2, this.height), renderer.setViewport(0, 0, this.width / 2, this.height), renderer.render.call(this, b, g, e, f), renderer.setScissor(this.width / 2, 0, this.width / 2, this.height), renderer.setViewport(this.width / 2, 0, this.width / 2, this.height), renderer.render.call(this, b, h, e, f), renderer.setScissorTest(!1); }; this.__proto__ = { //? 这句会使sceneRenderer.renderer指向这个vrRenderer __proto__: renderer }; }; var vrCamera = function vrCamera(a) { this.type = 'StereoCamera', this._aspect = 1, this._overlap = 0.064, this.cameraL = new THREE.PerspectiveCamera(), this.cameraL.layers.enable(0), this.cameraL.near = 0.01, this.cameraL.matrixAutoUpdate = !1, this.cameraR = new THREE.PerspectiveCamera(), this.cameraR.layers.enable(0), this.cameraR.near = 0.01, this.cameraR.matrixAutoUpdate = !1, this.eyeRight = new THREE.Matrix4(), this.eyeLeft = new THREE.Matrix4(), this.vrCameraNeedsUpdate = !0, Object.defineProperty(this, 'bananaAspect', { //这个为什么不是随着画面的比例? get: function get() { return this._aspect; }, set: function set(a) { this._aspect !== a && (this.vrCameraNeedsUpdate = !0), this._aspect = a; } }), Object.defineProperty(this, 'overlap', { //瞳距 get: function get() { return this._overlap; }, set: function set(a) { this._overlap !== a && (this.vrCameraNeedsUpdate = !0), this._overlap = a; } }), this.vrCameraUpdate = function (a) { if (this.vrCameraNeedsUpdate = this.vrCameraNeedsUpdate || this.bananaFov !== a.fov || this.bananaReal_aspect !== a.aspect * this.bananaAspect || this.bananaNear !== a.near || this.bananaFar !== a.far, this.vrCameraNeedsUpdate) { this.vrCameraNeedsUpdate = !1, this.bananaFocus = a.focus, this.bananaFov = 50 //a.fov, 原本用的player.camera的fov应该是50,但这里player.camera设置了70,会让镜头变窄 ; this.bananaReal_aspect = a.aspect * this.bananaAspect, this.bananaNear = a.near, this.bananaFar = a.far, this.bananaFocus = 10; var left, right, d = a.projectionMatrix.clone(), e = this.overlap / 2, shift = e * this.bananaNear / this.bananaFocus, //bananaFocus是焦距吗 top = this.bananaNear * Math.tan(Math.PI / 180 * this.bananaFov * 0.5); this.eyeLeft.elements[12] = -e, this.eyeRight.elements[12] = e, left = -top * this.bananaReal_aspect + shift, right = top * this.bananaReal_aspect + shift; d.elements[0] = 2 * this.bananaNear / (right - left); //只改左右,不改上下,所以虽然bananaReal_aspect可能和原来一样,但调了vfov就会直接影响hfov d.elements[8] = (right + left) / (right - left); this.cameraL.projectionMatrix.copy(d); left = -top * this.bananaReal_aspect - shift, right = top * this.bananaReal_aspect - shift; d.elements[0] = 2 * this.bananaNear / (right - left); d.elements[8] = (right + left) / (right - left); this.cameraR.projectionMatrix.copy(d); } this.cameraL.matrixWorld.copy(a.matrixWorld).multiply(this.eyeLeft), this.cameraR.matrixWorld.copy(a.matrixWorld).multiply(this.eyeRight); }; }; var boluoloadTextureFromCache = function boluoloadTextureFromCache(a) { var b = new THREE.TextureLoader(); return b.crossOrigin = 'anonymous', b.load(a); }; /* bus.on("orientation", () => { console.log(`vr orientation ${window.orientation}`) if(window.orientation== 0||window.orientation==180) { //竖屏 settings.vrSplitScreen = false }else{ settings.vrSplitScreen = true } }) */ var webxr = { init(renderer) { var _this3 = this; this.renderer = renderer; renderer.xr.enabled = true; var xr = this.renderer.xr; var cameraVR = xr.getCamera(); var makeit = function makeit() { //xr存在 VR.cursor.parent.remove(VR.cursor); cameraVR.add(VR.cursor); sceneRenderer$1.scene.add(cameraVR); /* cameraVR.layers.enable(RenderLayers.RETICULE) cameraVR.cameras.forEach(camera=>{//实际渲染的是这两个camera camera.layers.enable(RenderLayers.RETICULE) }) */ _this3.initHandler(); player$7.on('update', function (e) { if (_this3.entered && (e.hasChanged.cameraChanged2 || e.hasChanged.vrHandlerMoved)) { _this3.setHandlerLength(player$7.intersect); player$7.reticule.move(null, null, false); } }); }; if ('xr' in navigator && 'isSessionSupported' in navigator.xr) { //pico firefox var mode = 'immersive-vr'; navigator.xr.isSessionSupported(mode).then(function (supported) { if (!supported) { _this3.xrNotFound('isSessionSupported not supported'); } else { _this3.xrType = 'xr'; //showEnterXR(); makeit(); } }).catch(this.xrNotFound.bind(this, 'isSessionSupported error')); } else if ('getVRDisplays' in navigator) { //pico 的vr browser是这个 但该版本已被废弃,没有可供的浏览器可以调试 console.log('\n getVRDisplays!!!!!!!!!\n \n \n '); var setDevice = function setDevice(device) { _this3.xrType = 'vr'; _this3.device = device; _this3.renderer.xr.setDevice(device); //新版是renderer.vr makeit(); }; window.addEventListener('vrdisplayconnect', function (event) { setDevice(event.display); }, false); window.addEventListener('vrdisplaydisconnect', function () { console.log('vrdisplaydisconnect'); }, false); window.addEventListener('vrdisplaypresentchange', function (event) { console.log('vrdisplaypresentchange', event.display.isPresenting ? 'EXIT VR' : 'ENTER VR'); _this3.callback(!!event.display.isPresenting); }, false); window.addEventListener('vrdisplayactivate', function (event) { event.display.requestPresent([{ source: this.renderer.domElement }]); }, false); navigator.getVRDisplays().then(function (displays) { if (displays.length > 0) { setDevice(displays[0]); } else { this.xrNotFound('no displays'); } }).catch(this.xrNotFound.bind(this, 'getVRDisplays error')); } else { this.xrNotFound('xr not supported'); } { //修改three源代码: var originUpdateCamera = xr.updateCamera; var _this = this; xr.updateCamera = function (camera) { //if (!_this.tranCamMatrix) { //初始化,获取转换矩阵 originUpdateCamera(camera); //第一次计算得到的CameraVR的pose是未转换过的device的pose (注意:万一按了reset pose需要重新初始化device的pose,有reset事件吗) _this.getShiftPosMat(cameraVR.position); //本来以为local模式下设备是不会位移的,结果居然会,所以需要一直更新devicePos,以及转换函数 _this.getTranCamMatrix(cameraVR.position, cameraVR.quaternion); //new THREE.Matrix4().multiplyMatrices(originMatrix, cameraVR.matrixWorld.clone().invert()), //} cameraVR.cameras[0].matrix.premultiply(_this.tranCamMatrix); cameraVR.cameras[1].matrix.premultiply(_this.tranCamMatrix); cameraVR.cameras.concat([cameraVR]).forEach(function (camera) { //实际渲染的是两个cameras camera.layers.mask = player$7.camera.layers.mask; }); originUpdateCamera(camera); //根据cameraL和cameraR重算cameraVR matrixWorld //还需要将cameraVR同步到camera的,因为originUpdateCamera写的不太好,在半中间同步 //camera.position.copy(cameraVR.position); camera.quaternion.copy(cameraVR.quaternion); //camera.scale.copy(cameraVR.scale); //camera.matrix.copy(cameraVR.matrix); //camera.matrixWorld.copy(cameraVR.matrixWorld); player$7.quaternion.copy(cameraVR.quaternion); //这步不写的话方向有问题贴图模糊 //player.position.copy(cameraVR.position); //另外fov放大了,需要一致吗。但用的不是camera.fov, 搜topFov //updateScreenFaceOrient(cameraVR.quaternion) }; player$7.on('update', function (e) { //飞向下一个点时,因相机移动了而设备位置不能移动,相对位置改变,要重新绑定位置矩阵 if (!_this3.entered) return; if (e.hasChanged.moved && _this3.devicePos) { _this3.getShiftPosMat(_this3.devicePos); _this3.getTranCamMatrix(); } }); } }, enterVR() { var _this4 = this; if (!this.xrType) return; //不支持 console.log('enterVR', this.xrType); browser$1.exitFullscreen(); if (this.xrType == 'vr') { this.device.isPresenting ? this.device.exitPresent() : this.device.requestPresent([{ source: renderer.domElement }]); } else if (this.xrType == 'xr') { if (this.currentSession == void 0) { var getXRSessionInit = function getXRSessionInit(mode, options) { var space = (options || {}).referenceSpaceType || 'local-floor'; var sessionInit = options && options.sessionInit || {}; // Nothing to do for default features. if (space == 'viewer') return sessionInit; if (space == 'local' && mode.startsWith('immersive')) return sessionInit; // If the user already specified the space as an optional or required feature, don't do anything. if (sessionInit.optionalFeatures && sessionInit.optionalFeatures.includes(space)) return sessionInit; if (sessionInit.requiredFeatures && sessionInit.requiredFeatures.includes(space)) return sessionInit; // The user didn't request the reference space type as a feature. Add it to a shallow copy // of the user-supplied sessionInit requiredFeatures (if any) to ensure it's valid to // request it later. var newInit = Object.assign({}, sessionInit); newInit.requiredFeatures = [space]; if (sessionInit.requiredFeatures) { newInit.requiredFeatures = newInit.requiredFeatures.concat(sessionInit.requiredFeatures); } return newInit; }; console.log('this.currentSession == void 0 '); var onSessionEnded = function onSessionEnded() { console.log('onSessionEnded'); _this4.currentSession.removeEventListener('end', onSessionEnded); setTimeout(function () { _this4.renderer.xr.setSession(null); _this4.currentSession = null; _this4.callback(false); }, 1); //延迟原因:先使THREE里的onSessionEnded执行 }; var onReset = function onReset() { console.log('onReset'); }; var onSessionStarted = function onSessionStarted(session) { console.log('onSessionStarted'); /* var attributes = this.renderer.getContextAttributes(); console.log('xrCompatible', attributes.xrCompatible) */ session.addEventListener('end', onSessionEnded); session.addEventListener('reset', onReset); //在空间被重置时触发,例如,用户校准 XR 设备或 XR 设备重连后自动切回原点。 _this4.renderer.xr.setSession(session); _this4.currentSession = session; _this4.callback(true); }; var mode = 'immersive-vr'; var sessionInit = getXRSessionInit(mode); navigator.xr.requestSession(mode, sessionInit).then(onSessionStarted); } else { console.log('this.currentSession.end()', this.currentSession); this.currentSession.end(); } //为何我看到模拟器可以移动?但是并没有设置为bound } }, leaveVR() { if (this.xrType == 'xr') { this.currentSession && this.currentSession.end(); } else if (this.xrType == 'vr') ; }, switchRender(state) { if (state) { console.log('switchRender', state); this.renderer.setAnimationLoop(function () { //必须使用setAnimationLoop来渲染才能有画面 sceneRenderer$1.updateComponents(); sceneRenderer$1.render(); }); sceneRenderer$1.started = false; } else { this.renderer.setAnimationLoop(null); sceneRenderer$1.started = true; sceneRenderer$1.animate(); } }, callback(isEnter) { //开启或关闭之后 isEnter = !!isEnter; if (isEnter) ; else { settings$3.vrEnabled = false; //由系统关闭的话,需要执行一下这句,确保一些东西关闭 this.tranCamMatrix = this.shiftQuaMat = this.shiftPosMat = null; } this.switchRender(isEnter); this.handler.visible = isEnter; this.entered = isEnter; VR.dispatchEvent({ type: 'webxrEntered', isEnter }); }, xrNotFound(text) { console.log('xrNotFound:', text); }, //求陀螺仪相机和player相机的转换矩阵 getShiftQuaMat(deviceQua) { //根据初始的player的quaternion和设备陀螺仪的quaternion做一个绑定,得水平quaternion差 var dir = new THREE.Vector3(0, 0, -1).applyQuaternion(player$7.quaternion /* player.cameraControls.activeControl.camera.quaternion */ ); //初始的相机对应的朝向 dir.setY(0).normalize(); //水平 var mat = new THREE.Matrix4().lookAt(new THREE.Vector3(), dir, new THREE.Vector3(0, 1, 0)); var dir2 = new THREE.Vector3(0, 0, -1).applyQuaternion(deviceQua); //初始的陀螺仪对应的朝向 dir2.setY(0).normalize(); //水平 var mat2 = new THREE.Matrix4().lookAt(new THREE.Vector3(), dir2, new THREE.Vector3(0, 1, 0)); this.shiftQuaMat = mat.clone().premultiply(mat2.clone().invert()); //将此刻陀螺仪的朝向dir2矫正到此刻相机朝向dir所要乘的quaternion }, getShiftPosMat(devicePos) { this.shiftPosMat1 = new THREE.Matrix4().setPosition(devicePos.clone().negate()); this.shiftPosMat2 = new THREE.Matrix4().setPosition(player$7.position.clone()); this.devicePos = devicePos.clone(); //记录,下次可以直接使用 }, getTranCamMatrix(devicePos, deviceQua, reverse) { if (!this.shiftQuaMat) this.getShiftQuaMat(deviceQua); if (!this.shiftPosMat1) this.getShiftPosMat(devicePos); //先移到原点,再旋转,再移到终点 this.tranCamMatrix = new THREE.Matrix4().multiplyMatrices(this.shiftQuaMat, this.shiftPosMat1); this.tranCamMatrix = new THREE.Matrix4().multiplyMatrices(this.shiftPosMat2, this.tranCamMatrix); //this.controller1.children[0].matrix.copy(this.tranCamMatrix) }, initHandler() { var _this5 = this; var minAngleTorler = THREE.MathUtils.degToRad(5); var controller0 = this.renderer.xr.getController(0); //right //WebXRController._targetRay var controller1 = this.renderer.xr.getController(1); //left controller0.name = 'controller0-right'; controller1.name = 'controller1-left'; var material = new THREE.MeshBasicMaterial({ color: '#ffffff', opacity: 0.5, transparent: true, depthTest: false, depthWrite: false }); var stem = new THREE.Mesh(new THREE.BoxBufferGeometry(0.01, 0.01, 1), material); var translateMatrix = new THREE.Matrix4().makeTranslation(0, 0, -0.5); //使一端居于原点 stem.geometry.applyMatrix4(translateMatrix); var sphere = new THREE.Mesh(new THREE.SphereBufferGeometry(0.03, 6, 5), material); sphere.position.set(0, 0, -1); var handler = new THREE.Object3D(); handler.add(stem); handler.add(sphere); handler.matrixAutoUpdate = false; handler.name = 'handler'; handler.visible = false; sceneRenderer$1.scene.add(handler); this.handler = handler; this.handler.lastMatrix = this.handler.matrix.clone(); var currentControl = controller0; var init = function init(control) { var selectStartQua, selectStartTime; control.addEventListener('selectstart', function (e) { //相当于pointerdown 前面的按键 if (currentControl != control) { currentControl = control; /* return */ console.log('切换control', control.name); } selectStartQua = control.quaternion.clone(); selectStartTime = Date.now(); }); control.addEventListener('selectend', function (e) { //相当于pointerup var selectEndQua = control.quaternion.clone(); var selectEndTime = Date.now(); if (selectEndTime - selectStartTime < 1000 && selectEndQua.angleTo(selectStartQua) < minAngleTorler) { if (player$7.intersect) { return player$7.flyToPanoClosestToMouse(); } } }); /* control.addEventListener("squeezestart",(e)=>{//旁边的按键 console.log('squeezestart', control.name) }) */ control.addEventListener('connected', function (e) { //进入xr会执行 console.log('connected', control.name); }); control.addEventListener('disconnected', function (e) { //退出xr时会执行 console.log('disconnected', control.name); }); var update = function update() { if (currentControl != control) return; _this5.handler.lastMatrix = _this5.handler.matrix.clone(); _this5.tranCamMatrix || new THREE.Matrix4(); _this5.tranCamMatrix && _this5.handler.matrix.copy(control.matrix).premultiply(_this5.tranCamMatrix); _this5.handler.matrix.decompose(_this5.handler.position, _this5.handler.quaternion, new THREE.Vector3()); //material.opacity = player.reticule.material.uniforms.opacity.value }; //为何模拟器中手柄的旋转和渲染出的不同,模拟器中显示0,0,0, 实际是-0.49,0,0,模拟器的bug? control.addEventListener('move', update); update(); }; init(controller0); init(controller1); }, handlerMoved() { return !this.handler.lastMatrix.equals(this.handler.matrix); }, setRayCaster(raycaster) { //console.log('dir',dir) raycaster.set(this.handler.position, this.getHandlerDir()); }, getHandlerDir() { return new THREE.Vector3(0, 0, -1).applyQuaternion(this.handler.quaternion); }, setHandlerLength(intersect) { if (!intersect) return; this.handler.children[0].scale.z = intersect.distance; this.handler.children[1].position.set(0, 0, -intersect.distance); } }; VR.webxr = webxr; /* see: https://immersiveweb.dev/ https://github.com/immersive-web/webxr/blob/master/explainer.md https://blog.csdn.net/zhaoxinyao9/article/details/126290815 (中文) domo:https://www.4dmodel.com/test/webxr/ 目前 XRReferenceSpaceType 分为 5 种类型,分别如下。 viewer 表示具有原生原点的跟踪空间,一般用于不进行任何跟踪场景,任何设备都应该支持该类型 local 表示只跟踪用户旋转,不跟踪位置,可以理解为坐下,只用头部来观看场景 local-floor 与 local 类型相似,但是它是站立着的 bounded-floor 表示在安全区内跟踪旋转和位置,用户可以完全与场景进行交互 unbounded 表示用户可以自由在场景中移动和旋转,没有安全区限制 还可以改进的地方: 摇杆控制方向,向左向右旋转、向前进或者fov放大。直接加载4k。 似乎加载图有点慢?loading的三个球画一下。squeeze可以加功能。 disconnected的情况有哪些 参考的门户网站: 除了720外 https://www.ivrpano.com/p/a4135859726628b7?_s=56eadc3a2da6c16b pico2 vr browser: webxr案例用的three版本是111dev,而目前v4用的是143?,不知为何新版本会报错: cannot create XRWebGLLayer before first calling makeXRCompatible https://github.com/MozillaReality/FirefoxReality/issues/3420该网页提示升级firefox到10.1即可,故等升级中 */ function initFlicker() { //设置防抖 var list = [// userAgent列表 { name: 'nova 10z', //设备名称 //userAgent :自带浏览器 'Mozilla/5.0 (Linux; Android 10; HarmonyOS; CHA-AL80; HMSCore 6.10.4.302) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.93 HuaweiBrowser/11.1.5.315 Mobile Safari/537.36', //agent案例,不同浏览器不同 //QQ浏览器: Mozilla/5.0 (Linux; U; Android 10; zh-cn; CHA-AL80 Build/HUAWEICHA-AL80) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.102 MQQBrowser/13.5 Mobile Safari/537.36 COVC/046503 //edge: Mozilla/5.0 (Linux; Android 10; CHA-AL80) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36 EdgA/110.0.1587.66 words: ['CHA-AL80', '537.36'], threshold: { min: 0.005, max: 0.7 }, //变化大于这个角度不延迟, 为了防止移动过慢。只在相对静止要对准时防抖。 useRatio: 0.2 //越低代表抖动越强 //该设备平放桌面都在抖动 alpha等幅度0.02, 还有陀螺仪不准,有时转到背面画面还在当前。贝壳更是转不动。测过三个浏览器均是。可能是设备陀螺仪损坏 } //仍有的缺陷:因为移动延迟,对焦有点困难。 ]; var agent = window.navigator.userAgent; for (var i = 0, j = list.length; i < j; i++) { var item = list[i]; if (!item.words.some(function (word) { return !agent.includes(word); })) { //每个word都在agent中存在 avoidFlicker = item; break; } } //avoidFlicker = list[0] if (!avoidFlicker) { //给个默认 一点点的防抖 (对iphoneX表现有较明显的提升) avoidFlicker = { name: 'default', threshold: { min: 0.01, max: 0.3 }, useRatio: 0.5 //越低代表抖动越强 }; } //console.log('initFlicker', window.navigator.userAgent ) } function updateScreenFaceOrient(quaternion) { if (!settings$3.vrSplitScreen) { var dir = new THREE.Vector3(0, 0, -1).applyQuaternion(quaternion); //相机方向,也是屏幕旋转轴 player$7.camera.lookAt(player$7.camera.position.clone().add(dir)); //window.screenFaceOrient = THREE.MathUtils.radToDeg(player.camera.quaternion.angleTo(quaternion)) var dirCamera1 = new THREE.Vector3(1, 0, 0).applyQuaternion(quaternion); //相机横轴被旋转后的方向(如果得到的y还是0,说明没有歪) var dirCamera2 = new THREE.Vector3(1, 0, 0).applyQuaternion(player$7.camera.quaternion); //相机横轴被旋转后的方向(这里得到的y是0) window.screenFaceOrient = THREE.MathUtils.radToDeg(dirCamera1.angleTo(dirCamera2)); var crossAxis = dirCamera1.clone().cross(dirCamera2); // 通过朝dir还是-dir来判断逆时针还是顺时针 if (crossAxis.dot(dir) < 0) { window.screenFaceOrient *= -1; } } } var VR$1 = VR; function _createSuper$L(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$L(); 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 _isNativeReflectConstruct$L() { 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; } } new THREE.RawShaderMaterial({ fragmentShader: shaders.skysphere.fragmentShader, vertexShader: shaders.skysphere.vertexShader, uniforms: THREE.UniformsUtils.clone(shaders.skysphere.uniforms), side: THREE.BackSide, name: 'skysphereBG' }); window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame; var index$1 = 0; defineComponent('SceneRenderer', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(SceneRenderer, _EventEmitter); var _super = _createSuper$L(SceneRenderer); function SceneRenderer() { var _this; _classCallCheck(this, SceneRenderer); _this = _super.call(this); _this.createScene = function (model) { this.camera = new THREE.PerspectiveCamera(); this.camera.layers.enable(RenderLayers.PANOMARKERS); this.camera.layers.enable(RenderLayers.RETICULE); // this.camera.position.set(0, 5, 20) // this.camera.lookAt(0, 0, 0) this.scene = new THREE.Scene(); this.light = new THREE.AmbientLight(16777215); this.scene.add(this.light); // 灯光非常耗性能 // var directionalLight = new THREE.DirectionalLight(0xffffff, 0.3) // directionalLight.position.set(0, -1, 0).normalize() // this.scene.add(directionalLight) // var directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.7) // directionalLight1.position.set(-10, 3.5, 0).normalize() // this.scene.add(directionalLight1) // var directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.7) // directionalLight2.position.set(0, 3.5, 10).normalize() // this.scene.add(directionalLight2) // var directionalLight3 = new THREE.DirectionalLight(0xffffff, 0.7) // directionalLight3.position.set(0, 3.5, -10).normalize() // this.scene.add(directionalLight3) // var directionalLight4 = new THREE.DirectionalLight(0xffffff, 0.7) // directionalLight4.position.set(10, 3.5, 0).normalize() // this.scene.add(directionalLight4) // 照亮entryEntry var directionalLight = new THREE.DirectionalLight(0xffffff, 1); directionalLight.position.set(1, 10, 1).normalize(); this.scene.add(directionalLight); // this.scene.skyboxBG = new THREE.Mesh(new THREE.SphereBufferGeometry(2500, 20, 5), skyMat) // this.scene.add(this.scene.skyboxBG) }; _this.addComponent = function (e, ifAfterRender) { this.components.push(e); if (e.update) { if (ifAfterRender) this.updateLisAfter.push(e); //add else this.updateListeners.push(e); } if (e.setSize) { this.resizeListeners.push(e); this.forceUpdateSize = !0; } }; _this.removeComponent = function (e) { var t = function t(_t) { return _t !== e; }; this.components = this.components.filter(t); this.updateListeners = this.updateListeners.filter(t); this.resizeListeners = this.resizeListeners.filter(t); }; _this.start = function (dom) { if (this.started) { throw new BasicException$1("Can't start SceneRenderer, already started"); } this.createContext(dom); this.initComposer(); this.started = !0; if (this.$app.config.mobile) { try { VR$1.Init(this, this.$app.core.get('Player')); } catch (error) { console.error(error); } } (this.animate = this.animate.bind(this))(); }; _this.createContext = function (dom) { try { this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); //set alpha for renderTex this.renderer.autoClear = !0; this.renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1); this.renderer.setSize(window.innerWidth, window.innerHeight); this.renderer.setClearColor('#292929', 1.0); this.emit(SceneRendererEvents.ContextCreated); } catch (e) { throw new RendererCreationException$1('Unable to create a WebGL rendering context'); } //貌似没用 //settings.profiling.enabled && this.overrideTextures(); dom.appendChild(this.renderer.domElement); }; _this.initComposer = function () { this.composer = new THREE.EffectComposer(this.renderer); this.composer.addPass(new THREE.RenderPass(this.scene, this.camera)); this.composer.addPass(this.effects.hblurPass); this.composer.addPass(this.effects.vblurPass); }; _this.setSize = function (width, height) { this.renderWidth = width; this.renderHeight = height; this.effects.aspect = width / height; this.renderer.setSize(width, height); this.composer.setSize(width, height); this.css3dRenderer && this.css3dRenderer.setSize(width, height); for (var i = 0; i < this.resizeListeners.length; i++) { this.resizeListeners[i].setSize(width, height); } this.emit('resize', width, height); }; _this.render = function () { var size = this.renderer.getSize(new THREE.Vector2()); if (size.x == 0 || size.y == 0) return; //同屏时关闭一个屏 this.emit('render', this.updateClock2.getDelta()); this.update3dTiles(); this.effects.currentBlur > 0 ? this.composer.render() : this.renderer.render(this.scene, this.camera); if (this.css3dRenderer) { this.css3dRenderer.render(this.scene, this.camera); } }; _this.updateScreenSize = function () { //许钟文改 //xzw 改 为了截屏 要改canvas大小 以及缩放时不模糊 var W, H, pixelRatio; //当截屏时有setTimeout 期间不能恢复大小,所以要用W,H记录正常大小 return function () { var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var render = false; var ratio; var w, h; //记录应当render的大小 if (o.forceUpdateSize) this.forceUpdateSize = true; if (!o.resize && o.width != void 0 && o.height != void 0) { w = o.width, h = o.height, render = true, ratio = 1; } else { w = this.renderer.domElement.parentElement.clientWidth; h = this.renderer.domElement.parentElement.clientHeight; if (o.resize) { W = this.renderWidth; H = this.renderHeight; //console.log('updateScreenSize',w,h) } if (w !== W || h !== H || this.forceUpdateSize || pixelRatio != window.devicePixelRatio) { W = w, H = h, render = true; pixelRatio = window.devicePixelRatio; //如果player放在小窗口了,也要监测devicePixelRatio,因为缩放时client宽高不会改变 ratio = window.devicePixelRatio; } } if (render) { //console.log('setSize',w,h, ratio) this.setSize(w, h, ratio); this.forceUpdateSize = !1; } }; }(); _this.updateComponents = function () { //注意:transitions一定要放在最开头,计时才会准确 var delta = this.updateClock.getDelta(); /* if(this.$app.core.get('Player').flying){ console.log(this.index, delta) } */ for (var e = Math.min(1, delta), t = 0; t < this.updateListeners.length; t++) { this.updateListeners[t].update(e); } }; _this.updateAfterRender = function () { //add common.timeMeasuring.addTimeMark('afterRender', 'start'); for (var t = 0; t < this.updateLisAfter.length; t++) { this.updateLisAfter[t].update(); } common.timeMeasuring.addTimeMark('afterRender', 'end'); }; _this.suspend = function () { this.started = !1, this.suspendedObjects = this.scene.children.map(function (e) { return this.scene.remove(e), e; }.bind(this)), this.render(); }; _this.resume = function () { this.suspendedObjects.forEach(function (e) { this.scene.add(e); }.bind(this)); this.suspendedObjects = []; this.started = !0; this.animate(); }; _this.animate = function () { if (this.started) { performance.mark('loop-start'); // 无论有没有reportTimings都要获取,因为getBestCound需要 //-------------------- window.requestAnimationFrame(this.animate); this.updateScreenSize(); this.updateComponents(); //this.updateTextureMemory(); this.render(); this.updateAfterRender(); //注意:如果每一帧处理太多东西容易崩溃。 this.emit(SceneRendererEvents.AfterRender); //-------------------- common.timeMeasuring.addTimeMark('loop', 'end'); common.timeMeasuring.report(performance.now()); } }; _this.getImageData = function () { var e = document.createElement('canvas'), t = e.getContext('2d'); return function (i, SceneRenderer, r) { return e.width === SceneRenderer && e.height === r || (e.width = SceneRenderer, e.height = r), t.drawImage(i, 0, 0, SceneRenderer, r), t.getImageData(0, 0, SceneRenderer, r); }; }(); _this.initSizedTexture2D = function (size, wrap, i) { var renderer = this.renderer, ctx = renderer.getContext(), glState = renderer.state, texture = new THREE.Texture(); texture.flipY = false; texture.wrapS = wrap; texture.wrapT = wrap; i !== true && (i = false); texture.generateMipmaps = i; var glFormat = renderer.paramThreeToGL(texture.format), glType = renderer.paramThreeToGL(texture.type), h = renderer.properties.get(texture), glTexture = ctx.createTexture(); glState.bindTexture(ctx.TEXTURE_2D, glTexture); ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, texture.flipY); ctx.texImage2D(ctx.TEXTURE_2D, 0, glFormat, size, size, 0, glFormat, glType, null); var glWrap = renderer.paramThreeToGL(wrap); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, glWrap); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, glWrap); if (i) { texture.magFilter = THREE.LinearFilter; texture.minFilter = THREE.LinearMipMapLinearFilter; ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR_MIPMAP_NEAREST); ctx.generateMipmap(ctx.TEXTURE_2D); } else { texture.magFilter = THREE.LinearFilter; texture.minFilter = THREE.LinearFilter; ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MAG_FILTER, ctx.LINEAR); ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR); } glState.bindTexture(ctx.TEXTURE_2D, null); h.__webglTexture = glTexture; return texture; }; _this.deallocateCubeTexture = function (e) { var t = this.renderer; t.getContext(); t.properties.get(e); //i.deleteTexture(renderer.__image__webglTextureCube) //新版three没有这个耶 //改成自带的dispose , 虽然未被使用的zoomTarget没有dispose事件 e.dispose(); }; _this.renderToCubeMap = function () { var inited = false, scene = null, material = null, geo = null, plane = null, l = 1, cubeCamera = null; return function (tex, renderTarget, tileWidth, tileHeight, startXinTile, startYinTile, widthinTile, heightinTile, startX, startY, width, height, cubeFace, E, b, w) { var renderer = this.oldRenderer || this.renderer; //不知道为什么vr时一定要用原来的render,否则好像没有autoClear.. if (!inited) { scene = new THREE.Scene(); cubeCamera = new THREE.CubeCamera(0.1, 1000, renderTarget); scene.add(cubeCamera); material = new THREE.ShaderMaterial({ uniforms: { tDiffuse: { type: 'scene', value: null }, alpha: { type: 'startYinTile', value: 1 } }, vertexShader: shaders.basicTextured.vertexShader, fragmentShader: shaders.basicTextured.fragmentShader, depthWrite: !1, depthTest: !1, side: THREE.DoubleSide }); geo = new THREE.PlaneGeometry(l, l); plane = new THREE.Mesh(geo, material); scene.add(plane); inited = true; } // 必须更新cubeCamera的renderTarget cubeCamera.renderTarget = renderTarget; var uv = geo.getAttribute('uv'); uv.setUsage(THREE.DynamicDrawUsage); // .setDynamic(!0) uv.needsUpdate = true; var uvArr = uv.array, S = startXinTile / tileWidth, //uv这几个值基本是固定的startXinTile:0,startYinTile:0,widthinTile:512,widthinTile:512,tileWidth:512,tileHeight:512 也就是说uv不会变、每张tile的有效范围是100% M = startYinTile / tileHeight, R = widthinTile / tileWidth, P = heightinTile / tileHeight; uvArr[0] = S, uvArr[1] = M + P, uvArr[2] = S + R, uvArr[3] = M + P, uvArr[4] = S, uvArr[5] = M, uvArr[6] = S + R, uvArr[7] = M; //修改posistion,使该plane只占据需要绘制的部分。类似拼图。 //startX startY width height 都是在画布上的大小,比如画布大小为2048*2048,此tile为16分之一,tileX是1,tileY是1,则startX=2048/4,startY=2048/4 var pos = geo.getAttribute('position'); pos.setUsage(THREE.DynamicDrawUsage); // .setDynamic(!0) pos.needsUpdate = true; var posArr = pos.array, D = startX / renderTarget.width - l / 2, // 起始x N = startY / renderTarget.height - l / 2, // 起始y B = width / renderTarget.width, // 宽 F = height / renderTarget.height // 高 ; posArr[0] = D, posArr[1] = N + F, posArr[3] = D + B, posArr[4] = N + F, posArr[6] = D, posArr[7] = N, posArr[9] = D + B, posArr[10] = N; renderer.properties.get(scene); //this.renderer.properties.get(scene); material.uniforms.tDiffuse.value = tex; material.blending = E || THREE.NoBlending, material.transparent = !!b; void 0 !== w && null !== w || (w = 1); material.uniforms.alpha.value = w; material.needUpdate = !0; // cubeFace 0-5 应该是指定渲染h中的面 if (cubeFace == 0) { plane.scale.set(-1, -1, 1); plane.position.set(l / 2, 0, 0); } if (cubeFace == 1) { plane.scale.set(-1, -1, 1); plane.position.set(l / -2, 0, 0); } if (cubeFace == 2) { // 上 plane.scale.set(1, 1, 1); plane.position.set(0, l / 2, 0); } if (cubeFace == 3) { // 下 plane.scale.set(1, 1, 1); plane.position.set(0, l / -2, 0); } if (cubeFace == 4) { plane.scale.set(-1, -1, 1); plane.position.set(0, 0, l / 2); } if (cubeFace == 5) { plane.scale.set(-1, -1, 1); plane.position.set(0, 0, l / -2); } plane.lookAt(cubeCamera.position); /* renderer.setScissorTest(!0) //指定绘制区域,类似遮罩(相对于屏幕) renderer.setScissor(startX,startY,width,height) //加上这个会不会快一些,尤其是spherical //指定绘制视口位置和大小(相对于屏幕) */ renderTarget.viewport.set(0, 0, renderTarget.width, renderTarget.height); var V = renderer.autoClear; renderer.autoClear = !1; cubeCamera.update(renderer, scene); renderer.autoClear = V; //renderer.setScissorTest(!1) /* this.renderer.render(scene, camera, this.planeTargets[cubeFace], !1),//针对有的场景app第一个点图加载不成功的问题 console.log(`图index ${cubeFace} , ${startX}, ${startY}, ${width}, ${height}`) this.targetList[cubeFace] || (this.targetList[cubeFace] = []) this.targetList[cubeFace].push([startX,startY,width,height])*/ }; }(); _this.copyCubeMap = function () { //将texture渲染到zoomRenderTarget上 var inited = !1, scene = null, cubeCamera = null, material = null, geo = null, mesh = null, c = new THREE.Euler(); return function (texture, renderTarget, tWidth, tHeight, rWidth, rHeight, m, v, A) { if (!inited) { var w = 2; scene = new THREE.Scene(); cubeCamera = new THREE.CubeCamera(0.1, 1000, renderTarget); scene.add(cubeCamera); material = new THREE.ShaderMaterial({ uniforms: { tDiffuse: { type: 't', value: null }, alpha: { type: 'f', value: 1 } }, vertexShader: shaders.copyCubeMap.vertexShader, fragmentShader: shaders.copyCubeMap.fragmentShader, depthWrite: !1, depthTest: !1, side: THREE.DoubleSide }); geo = new THREE.BoxGeometry(w, w, w); mesh = new THREE.Mesh(geo, material); mesh.scale.set(-1, -1, 1); scene.add(mesh); inited = !0; } var renderer = this.oldRenderer || this.renderer; //不知道为什么vr时一定要用原来的render,否则好像没有autoClear.. // 必须更新cubeCamera的renderTarget cubeCamera.renderTarget = renderTarget; for (var C = 0; C < 6; C++) { this.getCubeOrientationForCubeFace(C, c); mesh.rotation.copy(c); mesh.matrixWorldNeedsUpdate = !0; mesh.updateMatrixWorld(); material.uniforms.tDiffuse.value = texture; material.blending = m || THREE.NoBlending; material.transparent = !!v; void 0 !== A && null !== A || (A = 1); material.uniforms.alpha.value = A; material.needUpdate = !0; // (renderTarget.activeCubeFace = C) renderTarget.viewport.set(0, 0, rWidth, rHeight); // this.renderer.render(scene, camera, renderTarget, !1) var V = renderer.autoClear; renderer.autoClear = !1; cubeCamera.update(renderer, scene); renderer.autoClear = V; } }; }(); _this.getCubeOrientationForCubeFace = function (e, t) { switch (e) { case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_X: t.set(0, -Math.PI / 2, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_X: t.set(0, Math.PI / 2, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Y: t.set(Math.PI / 2, Math.PI, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: t.set(-Math.PI / 2, Math.PI, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_POSITIVE_Z: t.set(0, -Math.PI, 0); break; case GLCubeFaces$1.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: t.set(0, 0, 0); } }; _this.index = index$1++; _this.scene = null; _this.camera = null; _this.light = null; _this.renderer = null; _this.effects = effects$1; _this.css3dRenderer = null; _this.animateCallback = null; _this.composer = null; _this.qualityManager = null; _this.updateClock = new THREE.Clock(); _this.updateClock2 = new THREE.Clock(); _this.components = []; _this.updateListeners = []; _this.resizeListeners = []; _this.updateLisAfter = []; //add _this.forceUpdateSize = !1; _this.started = !1; _this.textures = {}; _this.suspendedObjects = []; _this.vrMode = false; _this.autoUpdate3dTiles = false; common.timeMeasuring.reportTimings = false; common.timeMeasuring.registerCollect('loop', { minCount: 120, median: 3, refreshTime: 5 * 1000 }); // iphone13和电脑近似, iphonex很卡差别较大 //common.timeMeasuring.registerCollect('getMouseIntersect', { minCount: 120, median: 1, refreshTime: 10 * 1000 }) // iphone13和电脑近似, iphonex很卡差别较大 //写了一个针对多个iframe切换的事件,释放内存防止崩溃(因为iframe不像win页面那样会有unfocusPage的事件,即使隐藏了也会loop) window.addEventListener('unfocusPage', function (e) { console.log('unfocusPage', document.title); _this.suspend(); _this.$app.core.get('PanoRenderer').disposeIdelTargets(); }); window.addEventListener('focusPage', function (e) { console.log('focusPage', document.title); _this.resume(); }); return _this; } _createClass(SceneRenderer, [{ key: "update3dTiles", value: function update3dTiles() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var player = this.$app.core.get('Player'); var _3dTilesRuntime = player.model._3dTilesRuntime; if (_3dTilesRuntime) { var deltaTime = this.updateClock2.getDelta(); if (player.mode !== Viewmode$1.PANORAMA) { // 遍历tiles _3dTilesRuntime.getTileset().tiles.forEach(function (tile) { var tileContent = _3dTilesRuntime.getRenderMap()[tile.id]; if (tileContent && tileContent.modified !== 'remove') { deltaTime = 9999; // 因为需要实时计算可视范围内的tile,所以一旦相机发生变化就要tilesetUpdate if (tile.isVisibleAndInRequestVolume || player.mode === Viewmode$1.TRANSITIONING) { // 如果tile在可视范围内或相机过渡中,则添加会对应floor player.model.floors.get(tile.floorIndex).add(tileContent); } else { // 如果tile不在可视范围内,就从场景中remove tileContent.removeFromParent(); tileContent.traverse(function (obj) { if (obj.isChunk && obj.geometry) { obj.geometry.dispose(); obj.material.dispose(); obj.material.uniforms.map && obj.material.uniforms.map.value.dispose(); /*obj.material.uniforms.map.value = null obj.geometry = null obj.material = null */ } }); } } }); } if (this.autoUpdate3dTiles || options.force) { /** * tilesetUpdate需要满足条件: * 1. deltaTime累计超过UPDATE_INTERVAL * 2. 相机发生变化 lastFrameChanged //xzw 2023.11.27 * options.force==true时,会忽视上述两点进行更新 */ if (player.lastFrameChanged || options.force) { var camera = player.cameraControls.activeControl ? player.cameraControls.activeControl.camera : this.camera; _3dTilesRuntime.update(deltaTime, this.renderer, camera, options.force); _3dTilesRuntime.stats && _3dTilesRuntime.stats.update(); } } } } /* updateScreenSize = function () { ;(window.innerWidth !== this.renderWidth || window.innerHeight !== this.renderHeight || this.forceUpdateSize) && (this.setSize(window.innerWidth, window.innerHeight), (this.forceUpdateSize = !1)) } */ }, { key: "uploadTexture2D", value: /* uploadTexture2D = function (e, t, i, renderer, r, o) { var a = this.renderer, s = a.context, l = a.state, c = a.properties.get(t) l.bindTexture(s.TEXTURE_2D, c.__webglTexture) s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL, t.flipY) s.pixelStorei(s.UNPACK_PREMULTIPLY_ALPHA_WEBGL, t.premultiplyAlpha) s.pixelStorei(s.UNPACK_ALIGNMENT, t.unpackAlignment) s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_S, a.paramThreeToGL(t.wrapS)) s.texParameteri(s.TEXTURE_2D, s.TEXTURE_WRAP_T, a.paramThreeToGL(t.wrapT)) s.texParameteri(s.TEXTURE_2D, s.TEXTURE_MAG_FILTER, a.paramThreeToGL(t.magFilter)) s.texParameteri(s.TEXTURE_2D, s.TEXTURE_MIN_FILTER, a.paramThreeToGL(t.minFilter)) s.texSubImage2D(s.TEXTURE_2D, 0, i, renderer, s.RGBA, s.UNSIGNED_BYTE, e) t.generateMipmaps && s.generateMipmap(s.TEXTURE_2D) l.bindTexture(s.TEXTURE_2D, null) } */ function uploadTexture2D(img, tex, startX, startY, width, height) { var renderer = this.renderer, gl = renderer.getContext(), webglState = renderer.state, c = renderer.properties.get(tex); webglState.bindTexture(gl.TEXTURE_2D, c.__webglTexture); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, tex.flipY); gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, tex.premultiplyAlpha); gl.pixelStorei(gl.UNPACK_ALIGNMENT, tex.unpackAlignment); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, renderer.paramThreeToGL(tex.wrapS)); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, renderer.paramThreeToGL(tex.wrapT)); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, renderer.paramThreeToGL(tex.magFilter)); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, renderer.paramThreeToGL(tex.minFilter)); gl.texSubImage2D(gl.TEXTURE_2D, 0, startX, startY, gl.RGBA, gl.UNSIGNED_BYTE, img); tex.generateMipmaps && gl.generateMipmap(gl.TEXTURE_2D); webglState.bindTexture(gl.TEXTURE_2D, null); } /* 注:tileY的方向同UV,从下到上 renderToCubeMap里的画布or镜头的xy范围是-0.5到0.5 */ }, { key: "setBg", value: function setBg(color, opacity) { if (color) { this.renderer.setClearColor(color); } if (opacity != void 0) { this.renderer.setClearAlpha(opacity); } } }]); return SceneRenderer; }(EventEmitter); }); /* Copyright (c) 2008, Adobe Systems Incorporated All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Adobe Systems Incorporated nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ function JPEGEncoder$1(quality) { var ffloor = Math.floor; var YTable = new Array(64); var UVTable = new Array(64); var fdtbl_Y = new Array(64); var fdtbl_UV = new Array(64); var YDC_HT; var UVDC_HT; var YAC_HT; var UVAC_HT; var bitcode = new Array(65535); var category = new Array(65535); var outputfDCTQuant = new Array(64); var DU = new Array(64); var byteout = []; var bytenew = 0; var bytepos = 7; var YDU = new Array(64); var UDU = new Array(64); var VDU = new Array(64); var clt = new Array(256); var RGB_YUV_TABLE = new Array(2048); var currentQuality; var ZigZag = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63]; var std_dc_luminance_nrcodes = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]; var std_dc_luminance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; var std_ac_luminance_nrcodes = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d]; var std_ac_luminance_values = [0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa]; var std_dc_chrominance_nrcodes = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]; var std_dc_chrominance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; var std_ac_chrominance_nrcodes = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77]; var std_ac_chrominance_values = [0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa]; function initQuantTables(sf) { var YQT = [16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99]; for (var i = 0; i < 64; i++) { var t = ffloor((YQT[i] * sf + 50) / 100); if (t < 1) { t = 1; } else if (t > 255) { t = 255; } YTable[ZigZag[i]] = t; } var UVQT = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99]; for (var j = 0; j < 64; j++) { var u = ffloor((UVQT[j] * sf + 50) / 100); if (u < 1) { u = 1; } else if (u > 255) { u = 255; } UVTable[ZigZag[j]] = u; } var aasf = [1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.5411961, 0.275899379]; var k = 0; for (var row = 0; row < 8; row++) { for (var col = 0; col < 8; col++) { fdtbl_Y[k] = 1.0 / (YTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0); fdtbl_UV[k] = 1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0); k++; } } } function computeHuffmanTbl(nrcodes, std_table) { var codevalue = 0; var pos_in_table = 0; var HT = new Array(); for (var k = 1; k <= 16; k++) { for (var j = 1; j <= nrcodes[k]; j++) { HT[std_table[pos_in_table]] = []; HT[std_table[pos_in_table]][0] = codevalue; HT[std_table[pos_in_table]][1] = k; pos_in_table++; codevalue++; } codevalue *= 2; } return HT; } function initHuffmanTbl() { YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes, std_dc_luminance_values); UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes, std_dc_chrominance_values); YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes, std_ac_luminance_values); UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes, std_ac_chrominance_values); } function initCategoryNumber() { var nrlower = 1; var nrupper = 2; for (var cat = 1; cat <= 15; cat++) { //Positive numbers for (var nr = nrlower; nr < nrupper; nr++) { category[32767 + nr] = cat; bitcode[32767 + nr] = []; bitcode[32767 + nr][1] = cat; bitcode[32767 + nr][0] = nr; } //Negative numbers for (var nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) { category[32767 + nrneg] = cat; bitcode[32767 + nrneg] = []; bitcode[32767 + nrneg][1] = cat; bitcode[32767 + nrneg][0] = nrupper - 1 + nrneg; } nrlower <<= 1; nrupper <<= 1; } } function initRGBYUVTable() { for (var i = 0; i < 256; i++) { RGB_YUV_TABLE[i] = 19595 * i; RGB_YUV_TABLE[i + 256 >> 0] = 38470 * i; RGB_YUV_TABLE[i + 512 >> 0] = 7471 * i + 0x8000; RGB_YUV_TABLE[i + 768 >> 0] = -11059 * i; RGB_YUV_TABLE[i + 1024 >> 0] = -21709 * i; RGB_YUV_TABLE[i + 1280 >> 0] = 32768 * i + 0x807fff; RGB_YUV_TABLE[i + 1536 >> 0] = -27439 * i; RGB_YUV_TABLE[i + 1792 >> 0] = -5329 * i; } } // IO functions function writeBits(bs) { var value = bs[0]; var posval = bs[1] - 1; while (posval >= 0) { if (value & 1 << posval) { bytenew |= 1 << bytepos; } posval--; bytepos--; if (bytepos < 0) { if (bytenew == 0xff) { writeByte(0xff); writeByte(0); } else { writeByte(bytenew); } bytepos = 7; bytenew = 0; } } } function writeByte(value) { //byteout.push(clt[value]); // write char directly instead of converting later byteout.push(value); if (byteout.length === 1) ; } function writeWord(value) { writeByte(value >> 8 & 0xff); writeByte(value & 0xff); } // DCT & quantization core function fDCTQuant(data, fdtbl) { var d0, d1, d2, d3, d4, d5, d6, d7; /* Pass 1: process rows. */ var dataOff = 0; var i; var I8 = 8; var I64 = 64; for (i = 0; i < I8; ++i) { d0 = data[dataOff]; d1 = data[dataOff + 1]; d2 = data[dataOff + 2]; d3 = data[dataOff + 3]; d4 = data[dataOff + 4]; d5 = data[dataOff + 5]; d6 = data[dataOff + 6]; d7 = data[dataOff + 7]; var tmp0 = d0 + d7; var tmp7 = d0 - d7; var tmp1 = d1 + d6; var tmp6 = d1 - d6; var tmp2 = d2 + d5; var tmp5 = d2 - d5; var tmp3 = d3 + d4; var tmp4 = d3 - d4; /* Even part */ var tmp10 = tmp0 + tmp3; /* phase 2 */ var tmp13 = tmp0 - tmp3; var tmp11 = tmp1 + tmp2; var tmp12 = tmp1 - tmp2; data[dataOff] = tmp10 + tmp11; /* phase 3 */ data[dataOff + 4] = tmp10 - tmp11; var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ data[dataOff + 2] = tmp13 + z1; /* phase 5 */ data[dataOff + 6] = tmp13 - z1; /* Odd part */ tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; /* The rotator is modified from fig 4-8 to avoid extra negations. */ var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ var z2 = 0.5411961 * tmp10 + z5; /* c2-c6 */ var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ var z3 = tmp11 * 0.707106781; /* c4 */ var z11 = tmp7 + z3; /* phase 5 */ var z13 = tmp7 - z3; data[dataOff + 5] = z13 + z2; /* phase 6 */ data[dataOff + 3] = z13 - z2; data[dataOff + 1] = z11 + z4; data[dataOff + 7] = z11 - z4; dataOff += 8; /* advance pointer to next row */ } /* Pass 2: process columns. */ dataOff = 0; for (i = 0; i < I8; ++i) { d0 = data[dataOff]; d1 = data[dataOff + 8]; d2 = data[dataOff + 16]; d3 = data[dataOff + 24]; d4 = data[dataOff + 32]; d5 = data[dataOff + 40]; d6 = data[dataOff + 48]; d7 = data[dataOff + 56]; var tmp0p2 = d0 + d7; var tmp7p2 = d0 - d7; var tmp1p2 = d1 + d6; var tmp6p2 = d1 - d6; var tmp2p2 = d2 + d5; var tmp5p2 = d2 - d5; var tmp3p2 = d3 + d4; var tmp4p2 = d3 - d4; /* Even part */ var tmp10p2 = tmp0p2 + tmp3p2; /* phase 2 */ var tmp13p2 = tmp0p2 - tmp3p2; var tmp11p2 = tmp1p2 + tmp2p2; var tmp12p2 = tmp1p2 - tmp2p2; data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */ data[dataOff + 32] = tmp10p2 - tmp11p2; var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */ data[dataOff + 16] = tmp13p2 + z1p2; /* phase 5 */ data[dataOff + 48] = tmp13p2 - z1p2; /* Odd part */ tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */ tmp11p2 = tmp5p2 + tmp6p2; tmp12p2 = tmp6p2 + tmp7p2; /* The rotator is modified from fig 4-8 to avoid extra negations. */ var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */ var z2p2 = 0.5411961 * tmp10p2 + z5p2; /* c2-c6 */ var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */ var z3p2 = tmp11p2 * 0.707106781; /* c4 */ var z11p2 = tmp7p2 + z3p2; /* phase 5 */ var z13p2 = tmp7p2 - z3p2; data[dataOff + 40] = z13p2 + z2p2; /* phase 6 */ data[dataOff + 24] = z13p2 - z2p2; data[dataOff + 8] = z11p2 + z4p2; data[dataOff + 56] = z11p2 - z4p2; dataOff++; /* advance pointer to next column */ } // Quantize/descale the coefficients var fDCTQuant; for (i = 0; i < I64; ++i) { // Apply the quantization and scaling factor & Round to nearest integer fDCTQuant = data[i] * fdtbl[i]; outputfDCTQuant[i] = fDCTQuant > 0.0 ? fDCTQuant + 0.5 | 0 : fDCTQuant - 0.5 | 0; //outputfDCTQuant[i] = fround(fDCTQuant); } return outputfDCTQuant; } function writeAPP0() { writeWord(0xffe0); // marker writeWord(16); // length writeByte(0x4a); // J writeByte(0x46); // F writeByte(0x49); // I writeByte(0x46); // F writeByte(0); // = "JFIF",'\0' writeByte(1); // versionhi writeByte(1); // versionlo writeByte(0); // xyunits writeWord(1); // xdensity writeWord(1); // ydensity writeByte(0); // thumbnwidth writeByte(0); // thumbnheight } function writeSOF0(width, height) { writeWord(0xffc0); // marker writeWord(17); // length, truecolor YUV JPG writeByte(8); // precision writeWord(height); writeWord(width); writeByte(3); // nrofcomponents writeByte(1); // IdY writeByte(0x11); // HVY writeByte(0); // QTY writeByte(2); // IdU writeByte(0x11); // HVU writeByte(1); // QTU writeByte(3); // IdV writeByte(0x11); // HVV writeByte(1); // QTV } function writeDQT() { writeWord(0xffdb); // marker writeWord(132); // length writeByte(0); for (var i = 0; i < 64; i++) { writeByte(YTable[i]); } writeByte(1); for (var j = 0; j < 64; j++) { writeByte(UVTable[j]); } } function writeDHT() { writeWord(0xffc4); // marker writeWord(0x01a2); // length writeByte(0); // HTYDCinfo for (var i = 0; i < 16; i++) { writeByte(std_dc_luminance_nrcodes[i + 1]); } for (var j = 0; j <= 11; j++) { writeByte(std_dc_luminance_values[j]); } writeByte(0x10); // HTYACinfo for (var k = 0; k < 16; k++) { writeByte(std_ac_luminance_nrcodes[k + 1]); } for (var l = 0; l <= 161; l++) { writeByte(std_ac_luminance_values[l]); } writeByte(1); // HTUDCinfo for (var m = 0; m < 16; m++) { writeByte(std_dc_chrominance_nrcodes[m + 1]); } for (var n = 0; n <= 11; n++) { writeByte(std_dc_chrominance_values[n]); } writeByte(0x11); // HTUACinfo for (var o = 0; o < 16; o++) { writeByte(std_ac_chrominance_nrcodes[o + 1]); } for (var p = 0; p <= 161; p++) { writeByte(std_ac_chrominance_values[p]); } } function writeSOS() { writeWord(0xffda); // marker writeWord(12); // length writeByte(3); // nrofcomponents writeByte(1); // IdY writeByte(0); // HTY writeByte(2); // IdU writeByte(0x11); // HTU writeByte(3); // IdV writeByte(0x11); // HTV writeByte(0); // Ss writeByte(0x3f); // Se writeByte(0); // Bf } function processDU(CDU, fdtbl, DC, HTDC, HTAC) { var EOB = HTAC[0x00]; var M16zeroes = HTAC[0xf0]; var pos; var I16 = 16; var I63 = 63; var I64 = 64; var DU_DCT = fDCTQuant(CDU, fdtbl); //ZigZag reorder for (var j = 0; j < I64; ++j) { DU[ZigZag[j]] = DU_DCT[j]; } var Diff = DU[0] - DC; DC = DU[0]; //Encode DC if (Diff == 0) { writeBits(HTDC[0]); // Diff might be 0 } else { pos = 32767 + Diff; writeBits(HTDC[category[pos]]); writeBits(bitcode[pos]); } //Encode ACs var end0pos = 63; // was const... which is crazy for (; end0pos > 0 && DU[end0pos] == 0; end0pos--) {} //end0pos = first element in reverse order !=0 if (end0pos == 0) { writeBits(EOB); return DC; } var i = 1; var lng; while (i <= end0pos) { var startpos = i; for (; DU[i] == 0 && i <= end0pos; ++i) {} var nrzeroes = i - startpos; if (nrzeroes >= I16) { lng = nrzeroes >> 4; for (var nrmarker = 1; nrmarker <= lng; ++nrmarker) { writeBits(M16zeroes); } nrzeroes = nrzeroes & 0xf; } pos = 32767 + DU[i]; writeBits(HTAC[(nrzeroes << 4) + category[pos]]); writeBits(bitcode[pos]); i++; } if (end0pos != I63) { writeBits(EOB); } return DC; } function initCharLookupTable() { var sfcc = String.fromCharCode; for (var i = 0; i < 256; i++) { ///// ACHTUNG // 255 clt[i] = sfcc(i); } } this.encode = function (image, quality // image data object ) { new Date().getTime(); if (quality) setQuality(quality); // Initialize bit writer byteout = []; //new Array(); //新版QQ浏览器使用new Array()可能得到一个 [empty × 4]…… bytenew = 0; bytepos = 7; // Add JPEG headers writeWord(0xffd8); // SOI writeAPP0(); writeDQT(); writeSOF0(image.width, image.height); writeDHT(); writeSOS(); // Encode 8x8 macroblocks var DCY = 0; var DCU = 0; var DCV = 0; bytenew = 0; bytepos = 7; this.encode.displayName = '_encode_'; var imageData = image.data; var width = image.width; var height = image.height; var quadWidth = width * 4; var x, y = 0; var r, g, b; var start, p, col, row, pos; while (y < height) { x = 0; while (x < quadWidth) { start = quadWidth * y + x; p = start; col = -1; row = 0; for (pos = 0; pos < 64; pos++) { row = pos >> 3; // /8 col = (pos & 7) * 4; // %8 p = start + row * quadWidth + col; if (y + row >= height) { // padding bottom p -= quadWidth * (y + 1 + row - height); } if (x + col >= quadWidth) { // padding right p -= x + col - quadWidth + 4; } r = imageData[p++]; g = imageData[p++]; b = imageData[p++]; /* // calculate YUV values dynamically YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80 UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b)); VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b)); */ // use lookup table (slightly faster) YDU[pos] = (RGB_YUV_TABLE[r] + RGB_YUV_TABLE[g + 256 >> 0] + RGB_YUV_TABLE[b + 512 >> 0] >> 16) - 128; UDU[pos] = (RGB_YUV_TABLE[r + 768 >> 0] + RGB_YUV_TABLE[g + 1024 >> 0] + RGB_YUV_TABLE[b + 1280 >> 0] >> 16) - 128; VDU[pos] = (RGB_YUV_TABLE[r + 1280 >> 0] + RGB_YUV_TABLE[g + 1536 >> 0] + RGB_YUV_TABLE[b + 1792 >> 0] >> 16) - 128; } DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); x += 32; } y += 8; } //////////////////////////////////////////////////////////////// // Do the bit alignment of the EOI marker if (bytepos >= 0) { var fillbits = []; fillbits[1] = bytepos + 1; fillbits[0] = (1 << bytepos + 1) - 1; writeBits(fillbits); } writeWord(0xffd9); //EOI if (typeof module === 'undefined') return new Uint8Array(byteout); return Buffer.from(byteout); /* var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join('')); byteout = []; // benchmarking var duration = new Date().getTime() - time_start; //console.log('Encoding time: '+ duration + 'ms'); // return jpegDataUri */ }; function setQuality(quality) { if (quality <= 0) { quality = 1; } if (quality > 100) { quality = 100; } if (currentQuality == quality) return; // don't recalc if unchanged var sf = 0; if (quality < 50) { sf = Math.floor(5000 / quality); } else { sf = Math.floor(200 - quality * 2); } initQuantTables(sf); currentQuality = quality; //console.log('Quality set to: '+quality +'%'); } function init() { var time_start = new Date().getTime(); if (!quality) quality = 50; // Create tables initCharLookupTable(); initHuffmanTbl(); initCategoryNumber(); initRGBYUVTable(); setQuality(quality); new Date().getTime() - time_start; //console.log('Initialization '+ duration + 'ms'); } init(); } //module.exports = encode; function encode$4(imgData, qu) { if (typeof qu === 'undefined') qu = 50; var encoder = new JPEGEncoder$1(qu); var data = encoder.encode(imgData, qu); return { data: data, width: imgData.width, height: imgData.height }; } // helper function to get the imageData of an existing image on the current page. /* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ /* Copyright 2011 notmasteryet Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // - The JPEG specification can be found in the ITU CCITT Recommendation T.81 // (www.w3.org/Graphics/JPEG/itu-t81.pdf) // - The JFIF specification can be found in the JPEG File Interchange Format // (www.w3.org/Graphics/JPEG/jfif3.pdf) // - The Adobe Application-Specific JPEG markers in the Supporting the DCT Filters // in PostScript Level 2, Technical Note #5116 // (partners.adobe.com/public/developer/en/ps/sdk/5116.DCT_Filter.pdf) var JpegImage = function jpegImage() { var dctZigZag = new Int32Array([0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63]); var dctCos1 = 4017; // cos(pi/16) var dctSin1 = 799; // sin(pi/16) var dctCos3 = 3406; // cos(3*pi/16) var dctSin3 = 2276; // sin(3*pi/16) var dctCos6 = 1567; // cos(6*pi/16) var dctSin6 = 3784; // sin(6*pi/16) var dctSqrt2 = 5793; // sqrt(2) var dctSqrt1d2 = 2896; // sqrt(2) / 2 function constructor() {} function buildHuffmanTable(codeLengths, values) { var k = 0, code = [], i, j, length = 16; while (length > 0 && !codeLengths[length - 1]) { length--; } code.push({ children: [], index: 0 }); var p = code[0], q; for (i = 0; i < length; i++) { for (j = 0; j < codeLengths[i]; j++) { p = code.pop(); p.children[p.index] = values[k]; while (p.index > 0) { if (code.length === 0) throw new Error('Could not recreate Huffman Table'); p = code.pop(); } p.index++; code.push(p); while (code.length <= i) { code.push(q = { children: [], index: 0 }); p.children[p.index] = q.children; p = q; } k++; } if (i + 1 < length) { // p here points to last code code.push(q = { children: [], index: 0 }); p.children[p.index] = q.children; p = q; } } return code[0].children; } function decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) { frame.precision; frame.samplesPerLine; frame.scanLines; var mcusPerLine = frame.mcusPerLine; var progressive = frame.progressive; frame.maxH; frame.maxV; var startOffset = offset, bitsData = 0, bitsCount = 0; function readBit() { if (bitsCount > 0) { bitsCount--; return bitsData >> bitsCount & 1; } bitsData = data[offset++]; if (bitsData == 0xff) { var nextByte = data[offset++]; if (nextByte) { throw new Error('unexpected marker: ' + (bitsData << 8 | nextByte).toString(16)); } // unstuff 0 } bitsCount = 7; return bitsData >>> 7; } function decodeHuffman(tree) { var node = tree, bit; while ((bit = readBit()) !== null) { node = node[bit]; if (typeof node === 'number') return node; if (typeof node !== 'object') throw new Error('invalid huffman sequence'); } return null; } function receive(length) { var n = 0; while (length > 0) { var bit = readBit(); if (bit === null) return; n = n << 1 | bit; length--; } return n; } function receiveAndExtend(length) { var n = receive(length); if (n >= 1 << length - 1) return n; return n + (-1 << length) + 1; } function decodeBaseline(component, zz) { var t = decodeHuffman(component.huffmanTableDC); var diff = t === 0 ? 0 : receiveAndExtend(t); zz[0] = component.pred += diff; var k = 1; while (k < 64) { var rs = decodeHuffman(component.huffmanTableAC); var s = rs & 15, r = rs >> 4; if (s === 0) { if (r < 15) break; k += 16; continue; } k += r; var z = dctZigZag[k]; zz[z] = receiveAndExtend(s); k++; } } function decodeDCFirst(component, zz) { var t = decodeHuffman(component.huffmanTableDC); var diff = t === 0 ? 0 : receiveAndExtend(t) << successive; zz[0] = component.pred += diff; } function decodeDCSuccessive(component, zz) { zz[0] |= readBit() << successive; } var eobrun = 0; function decodeACFirst(component, zz) { if (eobrun > 0) { eobrun--; return; } var k = spectralStart, e = spectralEnd; while (k <= e) { var rs = decodeHuffman(component.huffmanTableAC); var s = rs & 15, r = rs >> 4; if (s === 0) { if (r < 15) { eobrun = receive(r) + (1 << r) - 1; break; } k += 16; continue; } k += r; var z = dctZigZag[k]; zz[z] = receiveAndExtend(s) * (1 << successive); k++; } } var successiveACState = 0, successiveACNextValue; function decodeACSuccessive(component, zz) { var k = spectralStart, e = spectralEnd, r = 0; while (k <= e) { var z = dctZigZag[k]; var direction = zz[z] < 0 ? -1 : 1; switch (successiveACState) { case 0: // initial state var rs = decodeHuffman(component.huffmanTableAC); var s = rs & 15, r = rs >> 4; if (s === 0) { if (r < 15) { eobrun = receive(r) + (1 << r); successiveACState = 4; } else { r = 16; successiveACState = 1; } } else { if (s !== 1) throw new Error('invalid ACn encoding'); successiveACNextValue = receiveAndExtend(s); successiveACState = r ? 2 : 3; } continue; case 1: // skipping r zero items case 2: if (zz[z]) zz[z] += (readBit() << successive) * direction;else { r--; if (r === 0) successiveACState = successiveACState == 2 ? 3 : 0; } break; case 3: // set value for a zero item if (zz[z]) zz[z] += (readBit() << successive) * direction;else { zz[z] = successiveACNextValue << successive; successiveACState = 0; } break; case 4: // eob if (zz[z]) zz[z] += (readBit() << successive) * direction; break; } k++; } if (successiveACState === 4) { eobrun--; if (eobrun === 0) successiveACState = 0; } } function decodeMcu(component, decode, mcu, row, col) { var mcuRow = mcu / mcusPerLine | 0; var mcuCol = mcu % mcusPerLine; var blockRow = mcuRow * component.v + row; var blockCol = mcuCol * component.h + col; decode(component, component.blocks[blockRow][blockCol]); } function decodeBlock(component, decode, mcu) { var blockRow = mcu / component.blocksPerLine | 0; var blockCol = mcu % component.blocksPerLine; decode(component, component.blocks[blockRow][blockCol]); } var componentsLength = components.length; var component, i, j, k, n; var decodeFn; if (progressive) { if (spectralStart === 0) decodeFn = successivePrev === 0 ? decodeDCFirst : decodeDCSuccessive;else decodeFn = successivePrev === 0 ? decodeACFirst : decodeACSuccessive; } else { decodeFn = decodeBaseline; } var mcu = 0, marker; var mcuExpected; if (componentsLength == 1) { mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn; } else { mcuExpected = mcusPerLine * frame.mcusPerColumn; } if (!resetInterval) resetInterval = mcuExpected; var h, v; while (mcu < mcuExpected) { // reset interval stuff for (i = 0; i < componentsLength; i++) { components[i].pred = 0; } eobrun = 0; if (componentsLength == 1) { component = components[0]; for (n = 0; n < resetInterval; n++) { decodeBlock(component, decodeFn, mcu); mcu++; } } else { for (n = 0; n < resetInterval; n++) { for (i = 0; i < componentsLength; i++) { component = components[i]; h = component.h; v = component.v; for (j = 0; j < v; j++) { for (k = 0; k < h; k++) { decodeMcu(component, decodeFn, mcu, j, k); } } } mcu++; // If we've reached our expected MCU's, stop decoding if (mcu === mcuExpected) break; } } // find marker bitsCount = 0; marker = data[offset] << 8 | data[offset + 1]; if (marker < 0xff00) { throw new Error('marker was not found'); } if (marker >= 0xffd0 && marker <= 0xffd7) { // RSTx offset += 2; } else break; } return offset - startOffset; } function buildComponentData(frame, component) { var lines = []; var blocksPerLine = component.blocksPerLine; var blocksPerColumn = component.blocksPerColumn; var samplesPerLine = blocksPerLine << 3; var R = new Int32Array(64), r = new Uint8Array(64); // A port of poppler's IDCT method which in turn is taken from: // Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, // "Practical Fast 1-D DCT Algorithms with 11 Multiplications", // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, // 988-991. function quantizeAndInverse(zz, dataOut, dataIn) { var qt = component.quantizationTable; var v0, v1, v2, v3, v4, v5, v6, v7, t; var p = dataIn; var i; // dequant for (i = 0; i < 64; i++) { p[i] = zz[i] * qt[i]; } // inverse DCT on rows for (i = 0; i < 8; ++i) { var row = 8 * i; // check for all-zero AC coefficients if (p[1 + row] == 0 && p[2 + row] == 0 && p[3 + row] == 0 && p[4 + row] == 0 && p[5 + row] == 0 && p[6 + row] == 0 && p[7 + row] == 0) { t = dctSqrt2 * p[0 + row] + 512 >> 10; p[0 + row] = t; p[1 + row] = t; p[2 + row] = t; p[3 + row] = t; p[4 + row] = t; p[5 + row] = t; p[6 + row] = t; p[7 + row] = t; continue; } // stage 4 v0 = dctSqrt2 * p[0 + row] + 128 >> 8; v1 = dctSqrt2 * p[4 + row] + 128 >> 8; v2 = p[2 + row]; v3 = p[6 + row]; v4 = dctSqrt1d2 * (p[1 + row] - p[7 + row]) + 128 >> 8; v7 = dctSqrt1d2 * (p[1 + row] + p[7 + row]) + 128 >> 8; v5 = p[3 + row] << 4; v6 = p[5 + row] << 4; // stage 3 t = v0 - v1 + 1 >> 1; v0 = v0 + v1 + 1 >> 1; v1 = t; t = v2 * dctSin6 + v3 * dctCos6 + 128 >> 8; v2 = v2 * dctCos6 - v3 * dctSin6 + 128 >> 8; v3 = t; t = v4 - v6 + 1 >> 1; v4 = v4 + v6 + 1 >> 1; v6 = t; t = v7 + v5 + 1 >> 1; v5 = v7 - v5 + 1 >> 1; v7 = t; // stage 2 t = v0 - v3 + 1 >> 1; v0 = v0 + v3 + 1 >> 1; v3 = t; t = v1 - v2 + 1 >> 1; v1 = v1 + v2 + 1 >> 1; v2 = t; t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12; v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12; v7 = t; t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12; v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12; v6 = t; // stage 1 p[0 + row] = v0 + v7; p[7 + row] = v0 - v7; p[1 + row] = v1 + v6; p[6 + row] = v1 - v6; p[2 + row] = v2 + v5; p[5 + row] = v2 - v5; p[3 + row] = v3 + v4; p[4 + row] = v3 - v4; } // inverse DCT on columns for (i = 0; i < 8; ++i) { var col = i; // check for all-zero AC coefficients if (p[1 * 8 + col] == 0 && p[2 * 8 + col] == 0 && p[3 * 8 + col] == 0 && p[4 * 8 + col] == 0 && p[5 * 8 + col] == 0 && p[6 * 8 + col] == 0 && p[7 * 8 + col] == 0) { t = dctSqrt2 * dataIn[i + 0] + 8192 >> 14; p[0 * 8 + col] = t; p[1 * 8 + col] = t; p[2 * 8 + col] = t; p[3 * 8 + col] = t; p[4 * 8 + col] = t; p[5 * 8 + col] = t; p[6 * 8 + col] = t; p[7 * 8 + col] = t; continue; } // stage 4 v0 = dctSqrt2 * p[0 * 8 + col] + 2048 >> 12; v1 = dctSqrt2 * p[4 * 8 + col] + 2048 >> 12; v2 = p[2 * 8 + col]; v3 = p[6 * 8 + col]; v4 = dctSqrt1d2 * (p[1 * 8 + col] - p[7 * 8 + col]) + 2048 >> 12; v7 = dctSqrt1d2 * (p[1 * 8 + col] + p[7 * 8 + col]) + 2048 >> 12; v5 = p[3 * 8 + col]; v6 = p[5 * 8 + col]; // stage 3 t = v0 - v1 + 1 >> 1; v0 = v0 + v1 + 1 >> 1; v1 = t; t = v2 * dctSin6 + v3 * dctCos6 + 2048 >> 12; v2 = v2 * dctCos6 - v3 * dctSin6 + 2048 >> 12; v3 = t; t = v4 - v6 + 1 >> 1; v4 = v4 + v6 + 1 >> 1; v6 = t; t = v7 + v5 + 1 >> 1; v5 = v7 - v5 + 1 >> 1; v7 = t; // stage 2 t = v0 - v3 + 1 >> 1; v0 = v0 + v3 + 1 >> 1; v3 = t; t = v1 - v2 + 1 >> 1; v1 = v1 + v2 + 1 >> 1; v2 = t; t = v4 * dctSin3 + v7 * dctCos3 + 2048 >> 12; v4 = v4 * dctCos3 - v7 * dctSin3 + 2048 >> 12; v7 = t; t = v5 * dctSin1 + v6 * dctCos1 + 2048 >> 12; v5 = v5 * dctCos1 - v6 * dctSin1 + 2048 >> 12; v6 = t; // stage 1 p[0 * 8 + col] = v0 + v7; p[7 * 8 + col] = v0 - v7; p[1 * 8 + col] = v1 + v6; p[6 * 8 + col] = v1 - v6; p[2 * 8 + col] = v2 + v5; p[5 * 8 + col] = v2 - v5; p[3 * 8 + col] = v3 + v4; p[4 * 8 + col] = v3 - v4; } // convert to 8-bit integers for (i = 0; i < 64; ++i) { var sample = 128 + (p[i] + 8 >> 4); dataOut[i] = sample < 0 ? 0 : sample > 0xff ? 0xff : sample; } } var i, j; for (var blockRow = 0; blockRow < blocksPerColumn; blockRow++) { var scanLine = blockRow << 3; for (i = 0; i < 8; i++) { lines.push(new Uint8Array(samplesPerLine)); } for (var blockCol = 0; blockCol < blocksPerLine; blockCol++) { quantizeAndInverse(component.blocks[blockRow][blockCol], r, R); var offset = 0, sample = blockCol << 3; for (j = 0; j < 8; j++) { var line = lines[scanLine + j]; for (i = 0; i < 8; i++) { line[sample + i] = r[offset++]; } } } } return lines; } function clampTo8bit(a) { return a < 0 ? 0 : a > 255 ? 255 : a; } constructor.prototype = { load: function load(path) { var xhr = new XMLHttpRequest(); xhr.open('GET', path, true); xhr.responseType = 'arraybuffer'; xhr.onload = function () { // TODO catch parse error var data = new Uint8Array(xhr.response || xhr.mozResponseArrayBuffer); this.parse(data); if (this.onload) this.onload(); }.bind(this); xhr.send(null); }, parse: function parse(data) { var offset = 0; data.length; function readUint16() { var value = data[offset] << 8 | data[offset + 1]; offset += 2; return value; } function readDataBlock() { var length = readUint16(); var array = data.subarray(offset, offset + length - 2); offset += array.length; return array; } function prepareComponents(frame) { var maxH = 0, maxV = 0; var component, componentId; for (componentId in frame.components) { if (frame.components.hasOwnProperty(componentId)) { component = frame.components[componentId]; if (maxH < component.h) maxH = component.h; if (maxV < component.v) maxV = component.v; } } var mcusPerLine = Math.ceil(frame.samplesPerLine / 8 / maxH); var mcusPerColumn = Math.ceil(frame.scanLines / 8 / maxV); for (componentId in frame.components) { if (frame.components.hasOwnProperty(componentId)) { component = frame.components[componentId]; var blocksPerLine = Math.ceil(Math.ceil(frame.samplesPerLine / 8) * component.h / maxH); var blocksPerColumn = Math.ceil(Math.ceil(frame.scanLines / 8) * component.v / maxV); var blocksPerLineForMcu = mcusPerLine * component.h; var blocksPerColumnForMcu = mcusPerColumn * component.v; var blocks = []; for (var i = 0; i < blocksPerColumnForMcu; i++) { var row = []; for (var j = 0; j < blocksPerLineForMcu; j++) { row.push(new Int32Array(64)); } blocks.push(row); } component.blocksPerLine = blocksPerLine; component.blocksPerColumn = blocksPerColumn; component.blocks = blocks; } } frame.maxH = maxH; frame.maxV = maxV; frame.mcusPerLine = mcusPerLine; frame.mcusPerColumn = mcusPerColumn; } var jfif = null; var adobe = null; var frame, resetInterval; var quantizationTables = [], frames = []; var huffmanTablesAC = [], huffmanTablesDC = []; var fileMarker = readUint16(); if (fileMarker != 0xffd8) { // SOI (Start of Image) throw new Error('SOI not found'); } fileMarker = readUint16(); while (fileMarker != 0xffd9) { // EOI (End of image) var i, j; switch (fileMarker) { case 0xff00: break; case 0xffe0: // APP0 (Application Specific) case 0xffe1: // APP1 case 0xffe2: // APP2 case 0xffe3: // APP3 case 0xffe4: // APP4 case 0xffe5: // APP5 case 0xffe6: // APP6 case 0xffe7: // APP7 case 0xffe8: // APP8 case 0xffe9: // APP9 case 0xffea: // APP10 case 0xffeb: // APP11 case 0xffec: // APP12 case 0xffed: // APP13 case 0xffee: // APP14 case 0xffef: // APP15 case 0xfffe: // COM (Comment) var appData = readDataBlock(); if (fileMarker === 0xffe0) { if (appData[0] === 0x4a && appData[1] === 0x46 && appData[2] === 0x49 && appData[3] === 0x46 && appData[4] === 0) { // 'JFIF\x00' jfif = { version: { major: appData[5], minor: appData[6] }, densityUnits: appData[7], xDensity: appData[8] << 8 | appData[9], yDensity: appData[10] << 8 | appData[11], thumbWidth: appData[12], thumbHeight: appData[13], thumbData: appData.subarray(14, 14 + 3 * appData[12] * appData[13]) }; } } // TODO APP1 - Exif if (fileMarker === 0xffee) { if (appData[0] === 0x41 && appData[1] === 0x64 && appData[2] === 0x6f && appData[3] === 0x62 && appData[4] === 0x65 && appData[5] === 0) { // 'Adobe\x00' adobe = { version: appData[6], flags0: appData[7] << 8 | appData[8], flags1: appData[9] << 8 | appData[10], transformCode: appData[11] }; } } break; case 0xffdb: // DQT (Define Quantization Tables) var quantizationTablesLength = readUint16(); var quantizationTablesEnd = quantizationTablesLength + offset - 2; while (offset < quantizationTablesEnd) { var quantizationTableSpec = data[offset++]; var tableData = new Int32Array(64); if (quantizationTableSpec >> 4 === 0) { // 8 bit values for (j = 0; j < 64; j++) { var z = dctZigZag[j]; tableData[z] = data[offset++]; } } else if (quantizationTableSpec >> 4 === 1) { //16 bit for (j = 0; j < 64; j++) { var z = dctZigZag[j]; tableData[z] = readUint16(); } } else throw new Error('DQT: invalid table spec'); quantizationTables[quantizationTableSpec & 15] = tableData; } break; case 0xffc0: // SOF0 (Start of Frame, Baseline DCT) case 0xffc1: // SOF1 (Start of Frame, Extended DCT) case 0xffc2: // SOF2 (Start of Frame, Progressive DCT) readUint16(); // skip data length frame = {}; frame.extended = fileMarker === 0xffc1; frame.progressive = fileMarker === 0xffc2; frame.precision = data[offset++]; frame.scanLines = readUint16(); frame.samplesPerLine = readUint16(); frame.components = {}; frame.componentsOrder = []; var componentsCount = data[offset++], componentId; for (i = 0; i < componentsCount; i++) { componentId = data[offset]; var h = data[offset + 1] >> 4; var v = data[offset + 1] & 15; var qId = data[offset + 2]; frame.componentsOrder.push(componentId); frame.components[componentId] = { h: h, v: v, quantizationIdx: qId }; offset += 3; } prepareComponents(frame); frames.push(frame); break; case 0xffc4: // DHT (Define Huffman Tables) var huffmanLength = readUint16(); for (i = 2; i < huffmanLength;) { var huffmanTableSpec = data[offset++]; var codeLengths = new Uint8Array(16); var codeLengthSum = 0; for (j = 0; j < 16; j++, offset++) { codeLengthSum += codeLengths[j] = data[offset]; } var huffmanValues = new Uint8Array(codeLengthSum); for (j = 0; j < codeLengthSum; j++, offset++) { huffmanValues[j] = data[offset]; } i += 17 + codeLengthSum; (huffmanTableSpec >> 4 === 0 ? huffmanTablesDC : huffmanTablesAC)[huffmanTableSpec & 15] = buildHuffmanTable(codeLengths, huffmanValues); } break; case 0xffdd: // DRI (Define Restart Interval) readUint16(); // skip data length resetInterval = readUint16(); break; case 0xffda: // SOS (Start of Scan) readUint16(); var selectorsCount = data[offset++]; var components = [], component; for (i = 0; i < selectorsCount; i++) { component = frame.components[data[offset++]]; var tableSpec = data[offset++]; component.huffmanTableDC = huffmanTablesDC[tableSpec >> 4]; component.huffmanTableAC = huffmanTablesAC[tableSpec & 15]; components.push(component); } var spectralStart = data[offset++]; var spectralEnd = data[offset++]; var successiveApproximation = data[offset++]; var processed = decodeScan(data, offset, frame, components, resetInterval, spectralStart, spectralEnd, successiveApproximation >> 4, successiveApproximation & 15); offset += processed; break; case 0xffff: // Fill bytes if (data[offset] !== 0xff) { // Avoid skipping a valid marker. offset--; } break; default: if (data[offset - 3] == 0xff && data[offset - 2] >= 0xc0 && data[offset - 2] <= 0xfe) { // could be incorrect encoding -- last 0xFF byte of the previous // block was eaten by the encoder offset -= 3; break; } throw new Error('unknown JPEG marker ' + fileMarker.toString(16)); } fileMarker = readUint16(); } if (frames.length != 1) throw new Error('only single frame JPEGs supported'); // set each frame's components quantization table for (var i = 0; i < frames.length; i++) { var cp = frames[i].components; for (var j in cp) { cp[j].quantizationTable = quantizationTables[cp[j].quantizationIdx]; delete cp[j].quantizationIdx; } } this.width = frame.samplesPerLine; this.height = frame.scanLines; this.jfif = jfif; this.adobe = adobe; this.components = []; for (var i = 0; i < frame.componentsOrder.length; i++) { var component = frame.components[frame.componentsOrder[i]]; this.components.push({ lines: buildComponentData(frame, component), scaleX: component.h / frame.maxH, scaleY: component.v / frame.maxV }); } }, getData: function getData(width, height) { var scaleX = this.width / width, scaleY = this.height / height; var component1, component2, component3, component4; var component1Line, component2Line, component3Line, component4Line; var x, y; var offset = 0; var Y, Cb, Cr, K, C, M, Ye, R, G, B; var colorTransform; var dataLength = width * height * this.components.length; var data = new Uint8Array(dataLength); switch (this.components.length) { case 1: component1 = this.components[0]; for (y = 0; y < height; y++) { component1Line = component1.lines[0 | y * component1.scaleY * scaleY]; for (x = 0; x < width; x++) { Y = component1Line[0 | x * component1.scaleX * scaleX]; data[offset++] = Y; } } break; case 2: // PDF might compress two component data in custom colorspace component1 = this.components[0]; component2 = this.components[1]; for (y = 0; y < height; y++) { component1Line = component1.lines[0 | y * component1.scaleY * scaleY]; component2Line = component2.lines[0 | y * component2.scaleY * scaleY]; for (x = 0; x < width; x++) { Y = component1Line[0 | x * component1.scaleX * scaleX]; data[offset++] = Y; Y = component2Line[0 | x * component2.scaleX * scaleX]; data[offset++] = Y; } } break; case 3: // The default transform for three components is true colorTransform = true; // The adobe transform marker overrides any previous setting if (this.adobe && this.adobe.transformCode) colorTransform = true;else if (typeof this.colorTransform !== 'undefined') colorTransform = !!this.colorTransform; component1 = this.components[0]; component2 = this.components[1]; component3 = this.components[2]; for (y = 0; y < height; y++) { component1Line = component1.lines[0 | y * component1.scaleY * scaleY]; component2Line = component2.lines[0 | y * component2.scaleY * scaleY]; component3Line = component3.lines[0 | y * component3.scaleY * scaleY]; for (x = 0; x < width; x++) { if (!colorTransform) { R = component1Line[0 | x * component1.scaleX * scaleX]; G = component2Line[0 | x * component2.scaleX * scaleX]; B = component3Line[0 | x * component3.scaleX * scaleX]; } else { Y = component1Line[0 | x * component1.scaleX * scaleX]; Cb = component2Line[0 | x * component2.scaleX * scaleX]; Cr = component3Line[0 | x * component3.scaleX * scaleX]; R = clampTo8bit(Y + 1.402 * (Cr - 128)); G = clampTo8bit(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128)); B = clampTo8bit(Y + 1.772 * (Cb - 128)); } data[offset++] = R; data[offset++] = G; data[offset++] = B; } } break; case 4: if (!this.adobe) throw new Error('Unsupported color mode (4 components)'); // The default transform for four components is false colorTransform = false; // The adobe transform marker overrides any previous setting if (this.adobe && this.adobe.transformCode) colorTransform = true;else if (typeof this.colorTransform !== 'undefined') colorTransform = !!this.colorTransform; component1 = this.components[0]; component2 = this.components[1]; component3 = this.components[2]; component4 = this.components[3]; for (y = 0; y < height; y++) { component1Line = component1.lines[0 | y * component1.scaleY * scaleY]; component2Line = component2.lines[0 | y * component2.scaleY * scaleY]; component3Line = component3.lines[0 | y * component3.scaleY * scaleY]; component4Line = component4.lines[0 | y * component4.scaleY * scaleY]; for (x = 0; x < width; x++) { if (!colorTransform) { C = component1Line[0 | x * component1.scaleX * scaleX]; M = component2Line[0 | x * component2.scaleX * scaleX]; Ye = component3Line[0 | x * component3.scaleX * scaleX]; K = component4Line[0 | x * component4.scaleX * scaleX]; } else { Y = component1Line[0 | x * component1.scaleX * scaleX]; Cb = component2Line[0 | x * component2.scaleX * scaleX]; Cr = component3Line[0 | x * component3.scaleX * scaleX]; K = component4Line[0 | x * component4.scaleX * scaleX]; C = 255 - clampTo8bit(Y + 1.402 * (Cr - 128)); M = 255 - clampTo8bit(Y - 0.3441363 * (Cb - 128) - 0.71413636 * (Cr - 128)); Ye = 255 - clampTo8bit(Y + 1.772 * (Cb - 128)); } data[offset++] = 255 - C; data[offset++] = 255 - M; data[offset++] = 255 - Ye; data[offset++] = 255 - K; } } break; default: throw new Error('Unsupported color mode'); } return data; }, copyToImageData: function copyToImageData(imageData, formatAsRGBA) { var width = imageData.width, height = imageData.height; var imageDataArray = imageData.data; var data = this.getData(width, height); var i = 0, j = 0, x, y; var Y, K, C, M, R, G, B; switch (this.components.length) { case 1: for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { Y = data[i++]; imageDataArray[j++] = Y; imageDataArray[j++] = Y; imageDataArray[j++] = Y; if (formatAsRGBA) { imageDataArray[j++] = 255; } } } break; case 3: for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { R = data[i++]; G = data[i++]; B = data[i++]; imageDataArray[j++] = R; imageDataArray[j++] = G; imageDataArray[j++] = B; if (formatAsRGBA) { imageDataArray[j++] = 255; } } } break; case 4: for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { C = data[i++]; M = data[i++]; Y = data[i++]; K = data[i++]; R = 255 - clampTo8bit(C * (1 - K / 255) + K); G = 255 - clampTo8bit(M * (1 - K / 255) + K); B = 255 - clampTo8bit(Y * (1 - K / 255) + K); imageDataArray[j++] = R; imageDataArray[j++] = G; imageDataArray[j++] = B; if (formatAsRGBA) { imageDataArray[j++] = 255; } } } break; default: throw new Error('Unsupported color mode'); } } }; return constructor; }(); function decode$6(jpegData, opts) { var defaultOpts = { useTArray: false, // "undefined" means "Choose whether to transform colors based on the image’s color model." colorTransform: undefined, formatAsRGBA: true }; if (opts) { if (typeof opts === 'object') { opts = { useTArray: typeof opts.useTArray === 'undefined' ? defaultOpts.useTArray : opts.useTArray, colorTransform: typeof opts.colorTransform === 'undefined' ? defaultOpts.colorTransform : opts.colorTransform, formatAsRGBA: typeof opts.formatAsRGBA === 'undefined' ? defaultOpts.formatAsRGBA : opts.formatAsRGBA }; } else { // backwards compatiblity, before 0.3.5, we only had the useTArray param opts = defaultOpts; opts.useTArray = true; } } else { opts = defaultOpts; } var arr = new Uint8Array(jpegData); var decoder = new JpegImage(); decoder.parse(arr); decoder.colorTransform = opts.colorTransform; var channels = opts.formatAsRGBA ? 4 : 3; var bytesNeeded = decoder.width * decoder.height * channels; try { var image = { width: decoder.width, height: decoder.height, data: opts.useTArray ? new Uint8Array(bytesNeeded) : new Buffer(bytesNeeded) }; } catch (err) { if (err instanceof RangeError) { throw new Error('Could not allocate enough memory for the image. ' + 'Required: ' + bytesNeeded); } else { throw err; } } decoder.copyToImageData(image, opts.formatAsRGBA); return image; } var JPEGEncoder = { encode: encode$4, decode: decode$6 }; function n$3(e, t, i) { e && (e = e.toLowerCase().trim()); var n = new I.UP.clone(), r = Math.PI / 3, o = Math.PI / 2; switch (e) { case 'left': i.copy(t), i.applyAxisAngle(n, o); break; case 'right': i.copy(t), i.applyAxisAngle(n, -o); break; case 'forwardleft': i.copy(t), i.applyAxisAngle(n, r); break; case 'forwardright': i.copy(t), i.applyAxisAngle(n, -r); break; case 'forward': default: i.copy(t); } return i; } function r$2(e, t) { if (e) { var i = { pano: e, lookAtPoint: null, duration: null, maxDistanceOverride: null, skipWarpingCheck: !1 }; this.player.flyToPano(i, function () { t && t({ success: !0, message: 'Transition complete.' }); }); } else R.warn('Showcase -> clickPanoObject: Unable to find pano.'), t && t({ success: !1, error: 'Unable to find pano.' }); } function o$1(e, t) { var i = this.findRankedPano(e, t); return i >= 0 ? this.handleToObject[i] : (R.warn('Showcase -> findRankedPanoObject: Unable to find nearby pano.'), null); } function a$2(e, t) { var i = this.findRankedtag(e, t); return i >= 0 ? this.handleToObject[i] : (R.warn('Showcase -> findRankedtagObject: Unable to find nearby tag.'), null); } function s$2(e, t) { t.copy(I.FORWARD), e.getDirection(t); } var myObjects = { director: null, player: null, controls: null, sceneRenderer: null, model: null, //app中会调用 init: function init(director, controls, player, sceneRenderer) { this.director = director; this.player = player; this.controls = controls; this.sceneRenderer = sceneRenderer; }, handleToObject: {}, objectToHandle: {}, handleCount: 0, onMessageReceive: function onMessageReceive(e) { if (e) { var t = e.targetFunction, i = e.params, n = e.onDone; t && this[t] && this[t](i, n); } }, waitForInit: function waitForInit(e, t) { F.then(t.bind({ success: !0, message: 'Init complete.' })); }, moveToPano: function (e, t) { var i = new THREE.Euler(0, 0, 0, 'YXZ'), n = new THREE.Quaternion(); return function (e, t) { var r = e.pano, o = e.rotation, a = e.transition; if (!this.model) return t({ success: !1, error: 'The model has not been loaded yet' }); var s = this.model.panos.get(r); if (!s) return t({ success: !1, error: r + ' does not exist in this model' }); if (!o) return t({ sucess: !1, erorr: o + ' is not a valid rotation' }); i.set(c.Math.degToRad(o.x || 0), c.Math.degToRad(o.y || 0), c.Math.degToRad(o.z || 0), 'YXZ'), logger$1.info(o.z); var l = { success: !0, message: r }; if (a === A.FADEOUT) n.setFromEuler(i), this.player.warpToPano(s, n, null, null, b.BLACK, null, null, t.bind(this, l));else { var h, u; a === A.INSTANT && (h = 0, u = 0); var d = I.FORWARD.clone().applyEuler(i).add(s.position); this.player.flyToPano({ pano: s, lookAtPoint: d, duration: h, aimDuration: u }, t.bind(this, l)); } }; }(), moveInDirection: function moveInDirection(e, t) { var i = e.direction; return 'undefined' == typeof v[i] ? (R.warn('Showcase -> moveInDirection: Cannot move in invalid direction.'), void (t && t({ success: !1, error: 'Invalid direction.' }))) : void this.player.flyLocalDirection(I[i].clone()).then(function (e) { t(e ? { success: !0, message: 'moved ' + i } : { success: !1, error: 'Cannot move in direction: ' + i }); }); }, getPose: function getPose(e, t) { this.player.camera.position, new THREE.Euler().setFromQuaternion(this.player.camera.quaternion, 'YXZ'); return t({ success: !0, message: B(this.player) }); }, //截图,我们有用到 takeScreenShot: function () { var camera = new THREE.PerspectiveCamera(), webGLRenderTarget = new THREE.WebGLRenderTarget(); //图片分辨率,图片质量,回调函数 return function (imgInfo, callFunc) { if (!imgInfo.resolution) return callFunc({ success: !1, error: 'An invalid resolution was specified' }); if (imgInfo.resolution.width === -1 || imgInfo.resolution.height === -1) { var size = this.sceneRenderer.renderer.getSize(); imgInfo.resolution.width = size.width; imgInfo.resolution.height = size.height; } camera.layers.set(RenderLayers.DEFAULT); if (imgInfo.visibleObjects) { imgInfo.visibleObjects.showPucks && camera.layers.enable(RenderLayers.PANOMARKERS); imgInfo.visibleObjects.showReticule && camera.layers.enable(RenderLayers.RETICULE); } var width = imgInfo.resolution.width, height = imgInfo.resolution.height, aspect = width / height; camera.position.copy(this.sceneRenderer.camera.position), camera.quaternion.copy(this.sceneRenderer.camera.quaternion), camera.projectionMatrix.copy(this.player.camera.projectionMatrix), camera.projectionMatrix.elements[0] = this.player.camera.projectionMatrix.elements[5] / aspect, camera.projectionMatrix.elements[5] = -camera.projectionMatrix.elements[5], //许钟文加 为了不flipY 但是只有side=2双面时有效否则是黑色的 webGLRenderTarget.setSize(width, height), this.sceneRenderer.renderer.setRenderTarget(webGLRenderTarget); if (imgInfo.bgOpacity != void 0) { imgInfo.bgOpacityOld = this.sceneRenderer.renderer.getClearAlpha(); this.sceneRenderer.setBg(null, imgInfo.bgOpacity); } var alpha = this.sceneRenderer.renderer.getClearAlpha(); this.sceneRenderer.renderer.render(this.sceneRenderer.scene, camera); this.sceneRenderer.renderer.setRenderTarget(null); if (imgInfo.bgOpacity != void 0) { this.sceneRenderer.setBg(null, imgInfo.bgOpacityOld); } //var pixelBuffer = new Uint8Array(width * height * 4) //this.sceneRenderer.renderer.readRenderTargetPixels(webGLRenderTarget, 0, 0, width, height, pixelBuffer) // var c = JPEGEncoder.encode({ // data: pixelBuffer, // width: width, // height: height, // heading: 180, // pitch: 0 // }, { // quality: imgInfo.quality || 75, // flipY: !1 //许钟文改 原本是true. 不在这里翻转,因为它翻转后会使顶部像素重复高10像素,底部少了10像素。 // }) // , imgBase64Url = "data:image/jpg;base64," + common.uint8ToBase64(c.data); //https://github.com/eugeneware/jpeg-js/blob/master/lib/encoder.js if (alpha < 1) { var imgBase64Url = common.renderTargetToDataUrl(webGLRenderTarget, webGLRenderTarget.width, webGLRenderTarget.height, this.sceneRenderer.renderer, imgInfo.quality, true); } else { var pixelBuffer = new Uint8Array(width * height * 4); this.sceneRenderer.renderer.readRenderTargetPixels(webGLRenderTarget, 0, 0, width, height, pixelBuffer); var rawImageData = JPEGEncoder.encode( //无法透明 { data: pixelBuffer, width: width, height: height, heading: 180, pitch: 0 }, imgInfo.quality); var imgBase64Url = 'data:image/png;base64,' + common.uint8ToBase64(rawImageData.data); } callFunc({ success: !0, message: imgBase64Url, camera: camera }); }; }(), findRankedPano: function (e, t) { var i = new THREE.Vector3(), r = new THREE.Vector3(); return function (e, t) { s$2(this.player, r), n$3(t, r, i); var o = this.player.rankedPanoInDirection(e, i); if (o) { var a = this.objectToHandle[o.id]; return a || (this.objectToHandle[o.id] = a = this.handleCount++, this.handleToObject[a] = o), a; } return R.warn('Showcase -> findRankedPano: Unable to find nearby pano.'), -1; }; }(), findRankedtag: function (e, t) { var i = new THREE.Vector3(), r = new THREE.Vector3(); return function (e, t) { s$2(this.player, r), n$3(t, r, i); var o = this.player.rankedtagInDirection(e, i); if (o) { var a = this.objectToHandle[o.sid]; return a || (this.objectToHandle[o.sid] = a = this.handleCount++, this.handleToObject[a] = o), a; } return R.warn('Showcase -> findRankedtag: Unable to find nearby tag.'), -1; }; }(), clickNearesttag: function clickNearesttag(e) { this.clickRankedtag(0, e); }, clickRankedtag: function clickRankedtag(e, t) { var i = a$2.call(this, e, t); i && O.call(this, i); }, clickNearestPano: function clickNearestPano(e, t) { this.clickRankedPano(0, e, t); }, clickRankedPano: function clickRankedPano(e, t, i) { var n = o$1.call(this, e, t); n ? r$2.call(this, n, i) : i(null); }, clickPano: function clickPano(e, t) { var i = this.handleTable[e]; i ? r$2.call(this, i, t) : t(null); }, rotateDirection: function () { return function (e, t) { var i = e.direction, n = e.angle; if (!P.active) { var r = 0, o = 0, a = 0, s = 0; if (!n || isNaN(n)) return R.warn('Showcase -> rotateDirection: Invalid rotation angle.'), void (t && t({ success: !1, error: 'Invalid rotation angle.' })); if (this.player.mode === E.TRANSITIONING) return R.warn('Automation -> rotateDirection: Cannot rotate while transitioning'), void (t && t({ success: !1, error: 'Cannot rotate while transitioning' })); if (i === v.RIGHT || i === v.LEFT) i === v.RIGHT && (n = -n), r = n > 0 ? -1 : 1, a = n;else { if (i !== v.UP && i !== v.DOWN) return R.warn('Showcase -> rotateDirection: Invalid direction for rotation: ' + i), void (t && t({ success: !1, error: 'Invalid direction for rotation.' })); if (this.player.mode === E.FLOORPLAN) return R.warn('Showcase -> rotateDirection: Cannot rotate ' + i + ' in floorplan mode'), void (t && t({ success: !1, error: 'Cannot rotate ' + i + ' in floorplan mode' })); if (i === v.DOWN && (n = -n), n = N.call(this, n), 0 === n) return R.warn('Showcase -> rotateDirection: Already at maximum rotation in direction: ' + i), void (t && t({ success: !1, error: 'Already at maximum rotation in direction: ' + i })); o = n > 0 ? 1 : -1, s = n; } var l = n; n = c.Math.degToRad(n), a = c.Math.degToRad(a), s = c.Math.degToRad(s); var h = this.controls.activeControl, u = function u() { h.stopRotating(!0), t && t({ success: !0, message: 'Rotated ' + l.toFixed(2) + '° in direction: ' + e.direction }); }; h.startRotating(r, o), P.start(a, s, this.player, u); } }; }(), rotate: function () { var e = new THREE.Vector3(), t = new THREE.Vector3(); return function (i, n) { var r = i.xAngle, o = i.yAngle; if (!P.active) { if (r = r || 0, o = o || 0, isNaN(r) || isNaN(o)) return R.warn('Showcase -> rotate: Invalid rotation angle.'), void (n && n({ success: !1, error: 'Invalid rotation angle.' })); if (this.player.mode === E.TRANSITIONING) return R.warn('Automation -> rotate: Cannot rotate while transitioning'), void (n && n({ success: !1, error: 'Cannot rotate while transitioning' })); Math.abs(r) < 0.01 && (r = 0), Math.abs(o) < 0.01 && (o = 0); var a = o; o = N.call(this, o), r = -r; var s = a > 0 ? 'UP' : 'DOWN'; if (!r && a && !o) return R.warn('Showcase -> rotate: Already at maximum rotation in direction: ' + s), void (n && n({ success: !1, error: 'Already at maximum rotation in direction: ' + s })); a > o && R.warn('Showcase -> rotate: Reached maximum rotation in direction: ' + s); var l = o; o = c.Math.degToRad(o), r = c.Math.degToRad(r), e.copy(this.player.mode === E.FLOORPLAN ? I.UP : I.FORWARD), this.player.getDirection(e), t.copy(e).applyAxisAngle(I.UP, r), t.applyAxisAngle(I.RIGHT, o); var h = (e.angleTo(t), r > 0 ? -1 : r < 0 ? 1 : 0), u = o > 0 ? 1 : o < 0 ? -1 : 0; Math.abs(r) > Math.abs(o) ? u *= Math.abs(o / r) : Math.abs(o) > Math.abs(r) && (h *= Math.abs(r / o)); var d = this.controls.activeControl, p = function p() { d.stopRotating(!0), n && n({ success: !0, message: 'Rotated ' + i.xAngle.toFixed(2) + '° horizontally, ' + l.toFixed(2) + '° vertically' }); }; d.startRotating(h, u), P.start(r, o, this.player, p); } }; }(), panCamera: function panCamera(e, t) { function i(e) { switch (r.removeAllListeners(T.AutoPanComplete), r.removeAllListeners(T.AutoPanInterrupt), r.removeAllListeners(T.AutoPanClamped), e) { case T.AutoPanInterrupt: t({ success: !0, message: 'Camera panning interrupted.' }); break; case T.AutoPanClamped: if (r.autoPanPosition.x !== n.x || r.autoPanPosition.z !== n.z) { if (Math.abs(this.player.position.x - r.autoPanPosition.x) < 0.01 && Math.abs(this.player.position.z - r.autoPanPosition.z) < 0.01) return void t({ success: !1, error: 'Already at edge of current model bounds.' }); var i = 'The view point is outside the bounds for the current model. '; i += 'The view point was clamped to ' + o(r.target.x, r.target.z), console.warn(i); } case T.AutoPanComplete: t({ success: !0, message: 'Panned camera to position ' + o(r.autoPanPosition.x, r.autoPanPosition.z) }); } } if (this.player.mode !== E.DOLLHOUSE && this.player.mode !== E.FLOORPLAN) return t({ success: !1, error: 'Camera panning is not available in the current mode: ' + this.player.mode }); var n = e.position, r = this.player.control; r.setAutoPanPosition(n.x, n.z), r.autoPan = !0; var o = function o(e, t) { return '(' + e.toFixed(2) + ', ' + t.toFixed(2) + ')'; }; r.on(T.AutoPanComplete, i.bind(this, T.AutoPanComplete)), r.on(T.AutoPanInterrupt, i.bind(this, T.AutoPanInterrupt)), r.on(T.AutoPanClamped, i.bind(this, T.AutoPanClamped)); }, click: function click(e, t) { var i = e.x, n = e.y, r = e.percentage; r === !0 && (i = i / 100 * $('#player').width(), n = n / 100 * $('#player').height()), this.player.handleInputStart(i, n), this.player.updateIntersect(), this.player.handleInputEnd(i, n); }, mouseOver: function mouseOver(e, t) { var i = e.x, n = e.y, r = e.percentage; r === !0 && (i = i / 100 * $('#player').width(), n = n / 100 * $('#player').height()), this.player.handleInputMove(i, n), this.player.updateIntersect(); }, moveToMode: function moveToMode(e, t) { function i(e) { t(e ? { success: !1, error: 'Failed to load new mode: ' + e } : { success: !0, message: 'Moved to new mode: ' + n }); } var n = e.mode; n === E.PANORAMA || n === E.DOLLHOUSE || n === E.FLOORPLAN ? this.director.changeMode(n).then(function () { i(); }, function (e) { i(e); }) : t({ success: !1, error: 'Invalid mode selection' }); } }; var automation = { init: function init(e, t, i, n, r) { myObjects.init(e, t, i, r); }, //许钟文加: takeScreenShot: function takeScreenShot(o, f) { myObjects.takeScreenShot(o, f); } }; defineComponent('Screenshot', function () { var _execute, _recover, _toFish, _unFish; return _execute = /*#__PURE__*/_classPrivateFieldKey("execute"), _recover = /*#__PURE__*/_classPrivateFieldKey("recover"), _toFish = /*#__PURE__*/_classPrivateFieldKey("toFish"), _unFish = /*#__PURE__*/_classPrivateFieldKey("unFish"), /*#__PURE__*/function () { function Screenshot() { _classCallCheck(this, Screenshot); Object.defineProperty(this, _execute, { value: _execute2 }); Object.defineProperty(this, _recover, { writable: true, value: function value(changeBefore) { this.player.reticule.visible = true; this.player.model.floorLogos.firstLogo.visible = changeBefore.fL0; this.player.model.floorLogos.secondLogo.visible = changeBefore.fL1; this.player.path.currentPanoMarker.mesh.visible = true; this.player.model.panos.list.forEach(function (pano) { pano.isAligned() && (pano.marker.visible = pano.marker.forceHide); }); this.$app.core.get('CameraControls').controls.floorplan.snapshotTopAspect = null; if (this.player.mode != Viewmode$1.PANORAMA) { if (ModelSide.side === null) { //兼容ModelSide this.player.model.chunks.forEach(function (chunk) { chunk.material.side = THREE.FrontSide; }); } var skyboxBG = this.$app.core.get('SceneRenderer').scene.skyboxBG; skyboxBG && (skyboxBG.material.side = THREE.BackSide); } this.player.model.skybox.material.side = THREE.BackSide; this.player.OverlayManager.show('all', true); this.player.GLTFEditor.show('all', true); changeBefore.notHideMonitors || this.player.$app.Camera.monitor.control.showAll(); } }); Object.defineProperty(this, _toFish, { writable: true, value: function value(changeBefore) { if (!this.player.model.fishSkybox) { this.player.model.fishSkybox = new THREE.Mesh(new THREE.SphereGeometry(constants$4.skyRadius, 80, 50), this.player.model.skybox.material); this.core.get('SceneRenderer').scene.add(this.player.model.fishSkybox); } this.player.model.fishSkybox.position.copy(this.player.position); this.player.model.fishSkybox.visible = true; this.player.model.skybox.visible = false; for (var i = 0; i < this.player.model.chunks.length; i++) { //场景过小的话可能比fishSkybox还小所以隐藏 this.player.model.chunks[i].visible = false; } changeBefore.cameraPosOld = this.player.camera.position.clone(); this.player.cameraControls.activeControl.fishState = true; //切换到鱼眼镜头 this.player.cameraControls.activeControl.camera.fov = settings$3.fish.insideFOV; this.player.cameraControls.activeControl.target.copy(this.player.position); this.player.updateFromControls(); } }); Object.defineProperty(this, _unFish, { writable: true, value: function value(changeBefore) { if (this.player.mode == Viewmode$1.PANORAMA) { this.player.cameraControls.activeControl.camera.position.copy(changeBefore.cameraPosOld); this.player.cameraControls.activeControl.fishState = false; //this.player.cameraControls.activeControl.update(0); this.player.model.fishSkybox.visible = false; this.player.model.skybox.visible = true; for (var i = 0; i < this.player.model.chunks.length; i++) { this.player.model.chunks[i].visible = true; } this.player.cameraControls.activeControl.camera.fov = settings$3.insideFOV; } this.player.updateFromControls(); } }); } _createClass(Screenshot, [{ key: "capture", value: function capture(options) { this.player = this.$app.core.get('Player'); if (this.player.flying || this.player.isWarping() || this.player.mode == Viewmode$1.TRANSITIONING) { logger$1.warn('you take a screenshot on flying or transitioning mode!!'); } //之前这么写,改变了当前canvas大小截图:R.updateScreenSize(options); var _this$player$getSize = this.player.getSize(), clientWidth = _this$player$getSize.clientWidth, clientHeight = _this$player$getSize.clientHeight; var fL0 = this.player.model.floorLogos.firstLogo.visible; var fL1 = this.player.model.floorLogos.secondLogo.visible; this.player.model.panos.list.forEach(function (pano) { pano.isAligned() && (pano.marker.forceHide = pano.marker.visible, pano.marker.visible = false); }); this.player.reticule.visible = false; this.player.model.floorLogos.firstLogo.visible = false; this.player.model.floorLogos.secondLogo.visible = false; this.player.path.currentPanoMarker.mesh.visible = false; //因为修改了截图时的projection中y的正负,如果side不反向,会黑(可能因为渲染到了背面?)。 if (this.player.mode != Viewmode$1.PANORAMA) { if (ModelSide.side === null) { //兼容ModelSide this.player.model.chunks.forEach(function (chunk) { chunk.material.side = THREE.BackSide; }); } //this.$app.core.get('SceneRenderer').scene.skyboxBG.material.side = THREE.FrontSide } this.player.model.skybox.material.side = THREE.DoubleSide; this.player.OverlayManager.hide('all'); this.player.GLTFEditor.hide('all'); options.notHideMonitors || this.player.$app.Camera.monitor.control.hideAll(); if (options.snapshotTopview && this.player.mode == Viewmode$1.FLOORPLAN) { this.$app.core.get('CameraControls').controls.floorplan.snapshotTopAspect = clientWidth / clientHeight; } options.changeBefore = Object.assign({}, options, { fL0, fL1 }); // fL0, fL1, notHideTags: options.notHideTags, notHideMonitors: options.notHideMonitors, _classPrivateFieldBase(this, _execute)[_execute](options); } /** * 按顺序在当前视角一个个截图 * @param {*} options * @param {*} lastState */ }]); return Screenshot; }(); function _execute2(options, lastState) { var _this = this; var task, state; if (options.tasks.unFish && options.tasks.unFish.length) { task = options.tasks.unFish.splice(0, 1)[0]; state = 'unFish'; } else if (options.tasks.fish && options.tasks.fish.length) { task = options.tasks.fish.splice(0, 1)[0]; state = 'fish'; } else { state = 'finish'; } //turn state: if (lastState == 'unFish' && state == 'fish') { //变成鱼眼 _classPrivateFieldBase(this, _toFish)[_toFish](options.changeBefore); } else if (lastState == 'fish' && state == 'finish') { //结束鱼眼 _classPrivateFieldBase(this, _unFish)[_unFish](options.changeBefore); _classPrivateFieldBase(this, _recover)[_recover](options.changeBefore); } else if (state == 'finish') { _classPrivateFieldBase(this, _recover)[_recover](options.changeBefore); } else { logger$1.info('other state:' + lastState + '|' + state); } if (state != 'finish') automation.takeScreenShot({ resolution: { width: task.width, height: task.height }, bgOpacity: task.bgOpacity, quality: options.quality || (settings$3.isSafari ? 50 : 65) }, function (d) { options.done && options.done(d.message, task.name, d); _classPrivateFieldBase(_this, _execute)[_execute](options, state); }); } }); var PathDisplayMode = Object.freeze({ Show: 0, Hide: 1, Retain: 2 }); var PathDiscardMode = Object.freeze({ Standard: 0, Slow: 1, Retain: 2 }); function _createSuper$K(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$K(); 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 _isNativeReflectConstruct$K() { 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; } } defineComponent('Director', function () { return /*#__PURE__*/function (_EventEmitter) { _inherits(Director, _EventEmitter); var _super = _createSuper$K(Director); function Director() { var _this; _classCallCheck(this, Director); _this = _super.call(this); _this.endlessLoop = settings$3.warp.loop; _this.clock = new THREE.Clock(true); _this.currentItem = null; _this.destinationItem = null; _this.tourIsPlaying = false; _this.nextFunc = null; _this.onTheBus = false; _this.reachSource = null; _this.interrupted = false; _this.nItems = 0; _this.currentScript = 0; _this.walkingSectionPaused = false; _this.C = Object.freeze({ None: 0, Moving: 1, Aiming: 2, Interlude: 3 }); _this.I = Object.freeze({ Forward: 1, NoChange: 0, Backwards: -1 }); _this.transitionStage = _this.C.None; _this.player = _this.$app.core.get('Player'); return _this; } _createClass(Director, [{ key: "init", value: function init() { this.updateModel(); this.resetAll(); this.bindEvents(); } }, { key: "resetAll", value: function resetAll() { this.currentItem = null; this.destinationItem = null; this.tourIsPlaying = false; this.transitionStage = this.C.None; this.nextFunc = null; this.onTheBus = false; this.reachSource = null; this.interrupted = false; if (this.player.model) { switch (this.player.model.switch_scene_type) { case 1: this.defaultWarpStyle = WarpStyle.BLACK; break; case 2: this.defaultWarpStyle = WarpStyle.WALK; break; case 3: this.defaultWarpStyle = WarpStyle.STD; break; default: this.defaultWarpStyle = WarpStyle.BLACK; break; } } else { this.defaultWarpStyle = WarpStyle.BLACK, logger$1.warn('No model yet, choosing "' + this.defaultWarpStyle + '" transitions'); } this.resetSpecialTransition(); } }, { key: "updateModel", value: function updateModel() { this.player.model = this.modelManager.getActiveModel(); this.nItems = 0; } }, { key: "bindEvents", value: function bindEvents() { this.modelManager.on(ModelManagerEvents.ActiveModelChanged, this.updateModel.bind(this)), this.player.on(PlayerEvents.WarpInterruptedWithFlyTo, this.handleFlyToWarpInterruption.bind(this)), this.player.on(PlayerEvents.Move, this.handlePlayerMove.bind(this)), this.player.on(PlayerEvents.PanoChosen, this.handlePlayerPanoChosen.bind(this)), this.player.on(PlayerEvents.ModeChanged, this.handlePlayerModeChanged.bind(this)), this.player.on(PlayerEvents.InputStart, this.handlePlayerInputStart.bind(this)), this.player.on(PlayerEvents.FlyingStarted, this.handlePlayerFlyingStarted.bind(this)); } }, { key: "handleFlyToWarpInterruption", value: function handleFlyToWarpInterruption(warpStyle, func) { if (warpStyle === WarpStyle.WALK) { this.interrupt(BlackoutStyle.NONE), this.pauseWalkingSection(), this.player.fastForwardActivePanoFlight(); } else if (this.transitionStage === this.C.Interlude) { this.interrupt(BlackoutStyle.NONE); func && func(); } } }, { key: "handlePlayerMove", value: function handlePlayerMove(t) { this.transitionStage === this.C.Interlude && this.interrupt(BlackoutStyle.NONE); } }, { key: "handlePlayerPanoChosen", value: function handlePlayerPanoChosen(e, t) { this.intermediateState() || e.id === t.id || (this.onTheBus = !1, this.emit('update.controls')); } }, { key: "handlePlayerModeChanged", value: function handlePlayerModeChanged(e, t) { this.intermediateState() || e === t || (this.onTheBus = !1, this.emit('update.controls')); } }, { key: "handlePlayerInputStart", value: function handlePlayerInputStart(e) { this.transitionStage === this.C.Interlude && this.interrupt(BlackoutStyle.NONE); } }, { key: "handlePlayerFlyingStarted", value: function handlePlayerFlyingStarted() { this.clearWalkingSectionPaused(); } }, { key: "describe", value: function describe() { return { nItems: this.nItems, currentItem: this.currentItem, destinationItem: this.destinationItem, tourIsPlaying: this.tourIsPlaying, onTheBus: this.onTheBus, endlessLoop: this.endlessLoop, viewMode: this.player.mode, inTransition: this._inTransition(), transitionStage: this.transitionStage, tourInProgress: this.tourInProgress }; } }, { key: "_inTransition", value: function _inTransition() { return this.player.flying || this.player.isWarping() || this.player.isWaitingToWarp() || this.player.mode === Viewmode.TRANSITIONING || this.tourIsPlaying; } }, { key: "bounceable", value: function bounceable() { var e = this.clock.getDelta(); return this.isInterrupted() || e < 0.9 && e > 0.01 || this.player.flying && !this.player.isWarping(); } }, { key: "currentMoveDirection", value: function currentMoveDirection() { return null === this.currentItem || void 0 === this.currentItem ? this.I.Forward : this.destinationItem === this.currentItem ? this.I.NoChange : this.destinationItem > this.currentItem ? this.I.Forward : I.Backwards; } }, { key: "clearPath", value: function clearPath() { this._inTransition() || this.player.path.discardPathObject(); } }, { key: "allFloors", value: function allFloors() { /* var t = this.player.controls[this.player.mode]; t && t.emit("move", "gui"), this.player.controls[ViewMode.PANORAMA].emit(ControlEvents.InteractionGui, "floor-control"),*/ this.player.model.toggleAllFloors(); } }, { key: "actionComplete", value: function actionComplete(t) { var state = this.transitionStage; this.interrupted = false, this.transitionStage = this.C.None, this.resetSpecialTransition(), null !== this.destinationItem && this.setCurrentItem(this.destinationItem), this.tourIsPlaying || this.player.mode === Viewmode$1.PANORAMA && this.player.currentPano.isAligned() && this.player.model.fadePanoMarkers(), this.emit('update.controls'); if (this.currentScript && (this.player.model.enableTagMovie && state === this.C.Interlude || this.player.model.enableTagMovie && state === this.C.Aiming && this.nextFunc === null)) { this.openTag(); } else { if (this.nextFunc) { var e = this.nextFunc; this.nextFunc = null; e(); } } } }, { key: "awaitCompletion", value: function awaitCompletion(e, t) { this.nextFunc = t; e(); } }, { key: "updateSuccessFunction", value: function updateSuccessFunction(e) { this.nextFunc = e; } }, { key: "interrupt", value: function interrupt(e, t) { if (!this.wouldInterrupt()) { return false; } this.tourIsPlaying && (this.player.zoomEnabled = this.wasZoomEnabled); this.tourIsPlaying = !1; this.interrupted = !0; this.nextFunc = null; this.emit(DirectorEvents.ActionInterrupted); null !== e && void 0 !== e || (e = BlackoutStyle.BEGINNING); this.player.interruptAndFastForward(e, t); return true; } }, { key: "wouldInterrupt", value: function wouldInterrupt() { return this.transitionStage !== this.C.None; } }, { key: "intermediateState", value: function intermediateState() { return this.transitionStage !== this.C.None; } }, { key: "isInterrupted", value: function isInterrupted() { return this.interrupted; } }, { key: "pauseWalkingSection", value: function pauseWalkingSection() { this.walkingSectionPaused = !0; } }, { key: "clearWalkingSectionPaused", value: function clearWalkingSectionPaused() { this.walkingSectionPaused = !1; } }, { key: "autoTour", value: function autoTour() { if (!settings$3.nestscenes || !settings$3.nestscenes.scenes || !settings$3.nestscenes.scenes.length || settings$3.nestscenes.scenes[0].script) return; if (settings$3.basic.menu.scene_autoplay) { settings$3.warp.auto = 0; $('#play').removeClass('play').addClass('pause'); G.playing = true; $('.gui-floor').hide(); $('.rightbar').hide(); $('#userlogo').hide(); $('#page-view').hide(); $('#back-url').hide(); $('.indoordir, .indoorscale').hide(); $('#virgule, #barrageShow, #barrageCon').hide(); } settings$3.warp.auto >= 0 && transitions.trigger({ duration: 1e3 * Math.min(300, settings$3.warp.auto), done: function () { this.playTour(); }.bind(this), name: '_atr' }); } }, { key: "atDestinationPano", value: function atDestinationPano() { if (!this.player.currentPano || null === this.destinationItem) return false; var t = this.player.currentPano.id; if (void 0 === t) return false; var e = this.player.model.heroLocations; return null !== this.destinationItem && void 0 !== e[this.destinationItem] && t == e[this.destinationItem].panoId; } }, { key: "redirectToItem", value: function redirectToItem(t, e) { if (null === t || void 0 === t) return void logger$1.warn('Director.redirectToItem() -> Redirecting to null item.'); if (!this.wouldInterrupt()) return void logger$1.warn('Director.redirectToItem() -> Director cannot redirect if there is nothing to interrupt.'); if (this.player.mode === Viewmode$1.TRANSITIONING) return void logger$1.debug('Director.redirectToItem() -> Cannot redirect while transitioning.'); logger$1.debug('Director.redirectToItem() -> Redirecting to ' + t + ' via ' + e); var i = function () { transitions.setTimeout(function () { this.setDestinationItem(t), logger$1.info('from redirectToItem'), this.goToDestination(true, BlackoutStyle.BEGINNING, settings$3.warp.warpInterruptionRedirectTime, false); }.bind(this), 0); }.bind(this); this.interrupt(BlackoutStyle.END, 0), this.updateSuccessFunction(i); } }, { key: "useSpecialTransition", value: function useSpecialTransition(t) { void 0 !== t && this.defaultWarpStyle !== WarpStyle.BLACK && logger$1.debug('useSpecialTransition(): ' + t), this.nextWarpStyle = this.defaultWarpStyle; } }, { key: "resetSpecialTransition", value: function resetSpecialTransition() { this.nextWarpStyle = this.defaultWarpStyle; } }, { key: "arrivedAtDestination", value: function arrivedAtDestination(e) { if (this.player.flying || this.player.isWarping()) logger$1.warn('Cannot advance to interlude or aiming while player is flying or warping.');else { this.transitionStage = this.C.Aiming; var t = this.tourIsPlaying ? this.tourInterlude.bind(this, this.nextItem(this.currentItem)) : null; this.player.model.fadePanoMarkers(0), this.awaitCompletion(function () { this.resetSpecialTransition(), e ? this.player.aimTourCamera(this.destinationItem, PathDisplayMode.Retain, PathDisplayMode.Slow, this.actionComplete.bind(this)) : this.actionComplete(); }.bind(this), t); } if (!this.play.control.canPlay) { this.play.control.canPlay = true; } if (this.play.control.wait && this.play.control.isPlaying) { this.record.updateFragmentUI(this.play.control.currentIndex); this.play.control.wait = false; } } }, { key: "toast", value: function toast(msg) { setTimeout(function () { document.getElementsByClassName('toast-wrap')[0].getElementsByClassName('toast-msg')[0].innerHTML = msg; var toastTag = document.getElementsByClassName('toast-wrap')[0]; toastTag.className = toastTag.className.replace('toastAnimate', ''); setTimeout(function () { toastTag.className = toastTag.className + ' toastAnimate'; }, 10); }, 10); } }, { key: "tour360view", value: function tour360view() { //360显示toast if (this.player.currentPano && this.player.currentPano.alignmentType === 2) { var language = this.player.model.language; this.toast(language.watchPr); // settings.basic.menu.compass_enable && $(".indoordir, .indoorscale").fadeOut(300); } else if ($('#play').hasClass('play')) ; } }, { key: "goToDestination", value: function goToDestination(e, t, i, n) { this.destinationItem = objects.play.control.currentIndex; if (this.onTheBus = !0, this.emit('update.controls'), !n && this.atDestinationPano()) return void this.arrivedAtDestination(!0); if (this.player.flying || this.player.isWarping()) logger$1.warn('Cannot go to new destination while player is flying or warping.');else { var r = this.player.model.getHeroDescriptorByIndex(this.destinationItem), o = null, a = null; if (r.pano != null && typeof r.pano != 'undefined') { var s = 0 === this.destinationItem || e ? WarpStyle.BLACK : this.nextWarpStyle; a = this.player.warpToPanoByHeroIndex.bind(this.player, this.destinationItem, PathDisplayMode.Show, PathDiscardMode.Slow, s, t, i, this.actionComplete.bind(this)), o = this.arrivedAtDestination.bind(this, !0); } else a = this.player.warpToNonPanoByHeroIndex.bind(this.player, this.destinationItem, this.actionComplete.bind(this)), o = this.arrivedAtDestination.bind(this, !1); this.transitionStage = this.C.Moving, this.player.model.fadePanoMarkers(0, null, { hideVideoFlag: true }), this.awaitCompletion(function () { a(); }.bind(this), o), this.emit('update.controls'); } } }, { key: "tourInterlude", value: function tourInterlude() { // if (h.trackAlways("reach_highlight", { // reach_source: this.reachSource // }), this.player.model.fadePanoMarkers(0); this.emit('update.controls'); if (this.tourIsPlaying) return this.atEndOfTour() && !this.endlessLoop ? (this.tourInProgress = !1, this.stopTour(), this.emit(DirectorEvents.TourEnd), void (this.player.mode === Viewmode.PANORAMA && this.player.model.fadePanoMarkers(settings$3.panorama.markerOpacity))) : void this.awaitCompletion(function () { this.transitionStage = this.C.Interlude, this.player.tourInterlude(this.nextItem(this.currentItem), this.actionComplete.bind(this)); }.bind(this), this.goNext.bind(this)); } }, { key: "playTour", value: function playTour() { if (!this.bounceable()) return this.tourIsPlaying ? void logger$1.info('tour is already playing') : void (this.wouldInterrupt() || (this.player.emit('tour_auto', this.defaultWarpStyle), this.tourInProgress = !0, this.reachSource = 'play', this.tourIsPlaying = !0, this.wasZoomEnabled = this.player.zoomEnabled, this.player.zoomEnabled = !1, this.resetSpecialTransition(), this.emit('update.controls'), this.emit(DirectorEvents.TourStart), this.player.enablePreRendering(), this.walkingSectionPaused ? (this.clearWalkingSectionPaused(), this.goToDestination()) : this.goNext())); } }, { key: "hideTourBar", value: function hideTourBar() { if (browser.isMobile()) { $('.btn-cat-play').removeClass('cat-mob-pause').addClass('cat-mob-play'); } else { $('.btn-cat-play').removeClass('cat-pc-pause').addClass('cat-pc-play'); } $('#gui').show(); } }, { key: "stopTour", value: function stopTour() { this.isInterrupted() || this.transitionStage === this.C.Moving && this.checkAndHandleWalkingtourInterruption(this.nextWarpStyle) || (this.tourIsPlaying && (this.player.zoomEnabled = this.wasZoomEnabled), this.tourIsPlaying = !1, this.interrupt(), this.clearWalkingSectionPaused(), this.resetSpecialTransition(), this.emit('update.controls')); } }, { key: "endTourProgress", value: function endTourProgress() { this.tourInProgress = !1, this.emit('update.controls'), this.emit(DirectorEvents.TourEnd); } }, { key: "goToHighlight", value: function goToHighlight(t) { this.clearWalkingSectionPaused(); this.destinationItem = t; this.useSpecialTransition('Hilight'); this.goToDestination(); } }, { key: "goToHighlightByLocation", value: function goToHighlightByLocation(location) { function getLocation(item) { if (item.panoId && item.panoId == location) { return true; } else { return false; } } var index = this.player.model.heroLocations.findIndex(getLocation); //if (this.canInterrupt() || !this.wouldInterrupt()) { if (!this.wouldInterrupt()) { if (logger$1.debug(''), this.wouldInterrupt() && (index === this.destinationItem ? this.interrupt() : this.redirectToItem(index, 'goToHighlight')), this.isInterrupted()) return; this.clearWalkingSectionPaused(), this.setDestinationItem(index), this.useSpecialTransition('Hilight'), this.goToDestination(); // analytics.trackAlways("USER", { // event_type: "reach_highlight", // reach_source: "thumb" // }) } } }, { key: "prevHighlight", value: function prevHighlight() { this.bounceable() || (this.player.emit('tour_manual', 'prev'), this.interrupt(BlackoutStyle.BEGINNING) || this.isInterrupted() || (this.clearWalkingSectionPaused(), this.reachSource = 'prev', this.goPrev())); } }, { key: "nextHighlight", value: function nextHighlight() { this.bounceable() || (this.player.emit('tour_manual', 'next'), this.interrupt(BlackoutStyle.BEGINNING) || this.isInterrupted() || (this.clearWalkingSectionPaused(), this.reachSource = 'next', this.goNext())); } }, { key: "changeMode", value: function changeMode(t, e) { var i = e || 'gui'; switch (this.wouldInterrupt() && this.interrupt(), this.player.controls[t].emit('interaction.' + i), this.clearWalkingSectionPaused(), t) { case Viewmode$1.PANORAMA: this.player.insideMode(); break; case Viewmode$1.DOLLHOUSE: case Viewmode$1.FLOORPLAN: this.player.flyToNewMode({ mode: t }); } } }, { key: "atEndOfTour", value: function atEndOfTour() { var t = this.currentItem >= this.nItems - 1; return t; } }, { key: "firstDestination", value: function firstDestination() { if (this.nItems <= 0) { return null; } for (var i = 0; i < this.nItems; i++) { if (this.player.model.images['list'][i].script === this.currentScript) { return i; } } return 0; } }, { key: "finalDestination", value: function finalDestination() { if (this.nItems <= 0) return null; for (var i = this.nItems - 1; i >= 0; i--) { if (this.player.model.images['list'][i].script === this.currentScript) { return i; } } return 0; } }, { key: "goPrev", value: function goPrev() { this.tourAdvance(-1); } }, { key: "goNext", value: function goNext() { this.tourAdvance(1); } }, { key: "setDestinationItem", value: function setDestinationItem(t) { if (t > this.nItems) { t = this.firstDestination(); } this.destinationItem = t; this.emit('update.controls'); } }, { key: "setCurrentItem", value: function setCurrentItem(t) { this.currentItem = t, this.emit('update.controls'); } }, { key: "nextItem", value: function nextItem(t) { return null === t ? this.firstDestination() : t >= this.nItems - 1 ? this.endlessLoop ? this.firstDestination() : null : t + 1; } }, { key: "prevItem", value: function prevItem(t) { return null === t ? this.firstDestination() : t < 0 ? this.endlessLoop ? this.lastDestination() : null : t - 1; } }, { key: "tourAdvance", value: function tourAdvance(t) { logger$1.debug('tourAdvance(' + t + ')'); null === this.currentItem || void 0 === this.currentItem ? this.setDestinationItem(this.firstDestination()) : this.setDestinationItem(this.currentItem + t); this.destinationItem < 0 ? (this.setDestinationItem(this.finalDestination()), this.useSpecialTransition('reverse-looping to end')) : this.destinationItem >= this.nItems && (this.setDestinationItem(this.firstDestination()), this.useSpecialTransition('looping back to start')); this.goToDestination(); } }]); return Director; }(EventEmitter); }); /* 热点markSpot的拖拽定位 */ var MoveCtrl = function MoveCtrl(o) { this.elem = o.elem; this.domParent = o.domParent; this.elem.addEventListener('mousedown', this.beginMove.bind(this)); this.elem.addEventListener('touchstart', this.beginMove.bind(this)); this.elem.addEventListener('pointerdown', this.beginMove.bind(this)); //this.elem.on('pointerdown mousedown touchstart', this.beginMove.bind(this)) document.addEventListener('mousedown', this.move.bind(this)); document.addEventListener('touchmove', this.move.bind(this)); document.addEventListener('pointermove', this.move.bind(this)); //$(document).on('pointermove mousemove touchmove', this.move.bind(this)) { //A screen(edit player屏幕的侦听难加上所以直接写在controls里吧 ) o.cameraControls.on('pointerUp', this.moveDone.bind(this)); //B screen document.addEventListener('pointerup', this.moveDone.bind(this)); document.addEventListener('mouseup', this.moveDone.bind(this)); document.addEventListener('touchend', this.moveDone.bind(this)); document.addEventListener('touchcancel', this.moveDone.bind(this)); //$(document).on('pointerup mouseup touchend touchcancel', this.moveDone.bind(this)) } this.beginMoveFuc = o.beginMoveFuc; this.moveDoneFuc = o.moveDoneFuc; this.hasBound = o.hasBound; this.useTransform = o.useTransform; //为true时适用于页面resize时,elem不需要 if (o.hasBound) { this.needGetBound = 1; window.addEventListener('resize', function () { this.needGetBound = 1; }.bind(this)); } this.recover(); }; MoveCtrl.prototype.beginMove = function (e) { //每次begin e.preventDefault(); //防止页面滑动 e.stopPropagation(); if (this.hasBound) this.getMoveBound(); if (this.moving) return; e = e.originalEvent || e; var isTouch = e.type.indexOf('touch') > -1; //console.log(isTouch) this.moving = true; if (this.useTransform) { //‘translate(55.5556px, 71.1111px)’ var transform = this.elem.style.transform; var x, y; if (!transform) { x = y = 0; } else { var a1 = transform.indexOf('('); var a2 = transform.indexOf(')'); transform = transform.slice(a1 + 1, a2).split(','); x = parseFloat(transform[0]); y = parseFloat(transform[1]); } this.dragInfo = { startElem: { x, y }, endElem: { x, y } }; } else { this.dragInfo = { startElem: { x: parseFloat(this.elem[0].style.left), y: parseFloat(this.elem[0].style.top) } /* , endElem: { x: 0, y: 0 } */ }; } this.dragInfo.startMouse = { x: isTouch ? e.changedTouches[0].clientX : e.clientX, y: isTouch ? e.changedTouches[0].clientY : e.clientY }; if (this.beginMoveFuc) this.beginMoveFuc(); //console.log('beginMove') //if(this.controlEvent)this.dealMoveCallBack(); }; MoveCtrl.prototype.move = function (e) { //位移 if (!this.moving) return; e = e.originalEvent || e; var isTouch = e.type.indexOf('touch') > -1; //console.log(isTouch) var x = isTouch ? e.changedTouches[0].clientX : e.clientX; var y = isTouch ? e.changedTouches[0].clientY : e.clientY; this.dragInfo.vector = { //位移 x: x - this.dragInfo.startMouse.x, y: y - this.dragInfo.startMouse.y }; this.dragInfo.endElem = { x: this.dragInfo.startElem.x + this.dragInfo.vector.x, y: this.dragInfo.startElem.y + this.dragInfo.vector.y }; //console.log(this.dragInfo.endElem) //限制移动范围 if (this.hasBound) { this.dragInfo.endElem.x = Math.max(this.bound.left, this.dragInfo.endElem.x); this.dragInfo.endElem.x = Math.min(this.bound.right, this.dragInfo.endElem.x); this.dragInfo.endElem.y = Math.max(this.bound.top, this.dragInfo.endElem.y); this.dragInfo.endElem.y = Math.min(this.bound.bottom, this.dragInfo.endElem.y); } if (this.useTransform) { this.elem.style.transform = 'translate(' + this.dragInfo.endElem.x + 'px,' + this.dragInfo.endElem.y + 'px)'; } else { this.elem.style.left = this.dragInfo.endElem.x + 'px'; this.elem.style.top = this.dragInfo.endElem.y + 'px'; } }; MoveCtrl.prototype.moveDone = function (e) { if (!this.moving) return; this.getMoveBound(); this.moving = false; this.move(e); if (this.moveDoneFuc) this.moveDoneFuc(this.reportPos()); //最后一次刷新一下位置 this.dragInfo.startElem = this.dragInfo.endElem; this.dragInfo.vector = { x: 0, y: 0 }; //console.log('moveDone') }; MoveCtrl.prototype.getMoveBound = function () { //限制移动范围 if (!this.needGetBound) return; var width = isMobile ? 68 : 100; var height = isMobile ? 32 : 60; //this.$elem[0].scrollHeight; //scrollHeight没用的 var w = ($('#player').width() - width) / 2; if (isMobile) { this.bound = { left: -w, right: w, top: -($('#player').height() / 2 - $('header')[0].offsetTop - $('header').height() - height / 2), bottom: $('#player').height() / 2 - $('footer').height() - height / 2 }; } else { this.bound = { left: -w, right: w, top: -($('#player').height() / 2 - 50 - height / 2), bottom: $('#player').height() / 2 - height / 2 }; } console.log(this.bound); this.needGetBound = 0; }; MoveCtrl.prototype.reportPos = function () { //输出创建热点所需要的平面上的坐标 return { x: this.dragInfo.endElem.x + this.domParent.clientWidth / 2, y: this.dragInfo.endElem.y + this.domParent.clientHeight / 2 }; }; //外部调用---------- MoveCtrl.prototype.recover = function () { //恢复到初始状态 this.dragInfo = { startElem: { x: 0, y: 0 }, endElem: { x: 0, y: 0 } }; if (this.useTransform) { this.elem.style.transform = ''; } else { this.elem.style.left = 0; this.elem.style.top = 0; } }; function _createSuper$J(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$J(); 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 _isNativeReflectConstruct$J() { 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; } } var Label2D = /*#__PURE__*/function (_EventEmitter) { _inherits(Label2D, _EventEmitter); var _super = _createSuper$J(Label2D); function Label2D() { var _this; var info = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var player = arguments.length > 1 ? arguments[1] : undefined; _classCallCheck(this, Label2D); _this = _super.call(this); if (info.pos3d) { _this.pos3d = new THREE.Vector3().copy(info.pos3d); } if (info.pos2d) { _this.pos2d = new THREE.Vector2().copy(info.pos2d); _this.setElemPos(); } _this.name = info.name; _this.elem = info.elem; _this.camera = info.camera; _this.domParent = info.domParent; _this.player = player; _this.useTransform = info.useTransform; _this.mayShelter = info.mayShelter; return _this; } _createClass(Label2D, [{ key: "update", value: function update() { /* if(objects.player.mode !== 'dollhouse' || !this.enable || !this.text || objects.model.currentFloor.floorIndex != this.floorIndex && !objects.model.allFloorsVisible || config.isEdit && (objects.mainDesign && objects.mainDesign.editing || objects.player.EditOverlay && objects.player.EditOverlay.editing|| objects.player.linkEditor && (objects.player.linkEditor.setPanoVisible || objects.player.linkEditor.setTagVisible) ) ){ this.elem.css('display','none'); return; } */ if (!this.pos3d || this.dragging) return; //console.log(this.name, this.camera.matrixWorldInverse.elements, this.camera.projectionMatrix.elements) var p = convertTool.getPos2d(this.pos3d, this.player, this.camera, this.domParent); if (!p.trueSide) { this.elem.style.display = 'none'; return; } //判断label是否被模型遮挡,遮挡则消失 if (this.mayShelter && convertTool.ifShelter(this.pos3d, this.player, { x: p.vector.x, y: p.vector.y }, this.camera /* , objects.model.allFloorsVisible ? null : this.floorIndex */ )) { this.elem.style.display = 'none'; return; } this.elem.style.display = 'block'; //先显示,driftDir才能计算位置 if (this.driftDir) { //针对入户门标识。 label位置相对position向外偏移一段(driftDir为箭头方向),保证label的外沿相对position距离spaceDis个像素,这样看上去就会贴近箭头且距离稳定。 var driftPoint = convertTool.getPos2d(this.pos3d.clone().add(this.driftDir)); //先将label置于position的位置,然后求从箭头开始到position的这条射线在label的rect中的二维交点(向外的那个交点) var rect = this.elem[0].children[0].getBoundingClientRect(); var crossPos2d = math$1.getCrossPointAtRect(driftPoint.pos, p.pos, rect.width, rect.height, p.pos.x - rect.width / 2, p.pos.y - rect.height / 2); var driftVec = crossPos2d.sub(p.pos.clone()); //得到二维偏移方向 var dis = this.pos3d.distanceTo(this.camera.position); var spaceDis = 100 / dis; //边距(距离position) 为了防止离远时看起来似乎较远,除以一下相机距离 //将label的二维位置向外偏移 长度为label的中心到label边缘(crossPos2d)的距离 外加一小段spaceDis this.pos2d = p.pos.clone().add(driftVec.multiplyScalar((spaceDis + driftVec.length()) / driftVec.length())); } else { this.pos2d = new THREE.Vector2().copy(p.vector); } this.setElemPos(); } }, { key: "setElemPos", value: function setElemPos() { if (this.useTransform) { var transformX = this.pos2d.x / 2 * this.domParent.clientWidth; var transformY = -this.pos2d.y / 2 * this.domParent.clientHeight; this.elem.style.transform = 'translate(' + Math.round(transformX) + 'px,' + Math.round(transformY) + 'px)'; } else { this.elem.style.left = this.pos2d.x + 'px', this.elem.style.top = this.pos2d.y + 'px'; } } }]); return Label2D; }(EventEmitter); function _createSuper$I(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$I(); 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 _isNativeReflectConstruct$I() { 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; } } var player$6; var isMobile$2; var playerB$1, markBmoveCtrl, lastMouseB = new THREE.Vector2(); var MatchDataGetWrong = {}; var MatchData = {}; var insideLookLimitDownOld, insideLookLimitUpOld; function mousedownB(e) { //editSpot.playerBmousedown = true lastMouseB = getMouseB(e); /* if (config.isEdit && editor.mainDesign.floorExamingStep == 2) { //模型地面高度 if (editor.mainDesign.hoverPull) { editor.mainDesign.dragLineBegin(editSpot); } return; } */ } function getMouseB(e) { e = e.originalEvent || e; var isTouch = e.type.indexOf('touch') > -1; var x = isTouch ? e.changedTouches[0].clientX : e.offsetX; var y = isTouch ? isMobile$2 ? e.changedTouches[0].clientY - player$6.domElement.clientHeight : e.changedTouches[0].clientY : e.offsetY; //手机的上下分屏有点麻烦。电脑触屏使用的后者没有测过 return { x: x, y: y }; } function getPoint(dir, panoB) { //获取B的click dir是经过matrix变换的方向,要变成没有变换的点击点 var dir = dir.clone(); var matrixWorld = panoB.matrixWorld.clone(); matrixWorld.invert(); //求逆矩阵 dir = math$1.crossRight(dir, matrixWorld); //dir右乘逆矩阵 得无matrix转化的向量O’B //console.log('B的dir(无matrix转化):') //console.log(dir.clone().normalize()) return panoB.position.clone().add(dir); } defineComponent('TagEditManager', function () { return /*#__PURE__*/function (_Emiter) { _inherits(Editspot, _Emiter); var _super = _createSuper$I(Editspot); function Editspot(splitView) { var _this; var info = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck(this, Editspot); _this = _super.call(this); _this.splitView = splitView; _this.panoA; //不同于splitView的panoA. 只有getA时才会改变 _this.paonB; //基本和splitView的paonB一样,因为右侧不能移动所以不会变 _this.markTagPos; //被计算出的热点位置 _this.init(info); /* splitView.on('leave', () => { //player.unableChangePano = false }) */ return _this; } _createClass(Editspot, [{ key: "init", value: function init(info) { var _this2 = this; if (this.inited) return; playerB$1 = this.$app.dom.querySelector('.player[name="copy"]'); //副屏 player$6 = this.$app.core.get('Player'); this.$app.core.get('TagManager'); isMobile$2 = this.$app.config.mobile; this.panosHistory = []; //每次定位时左侧走过的点位 /* this.mouseA = new THREE.Vector2(Infinity, Infinity) this.mouseB = new THREE.Vector2(Infinity, Infinity) */ //两个热点标记 this.markSpotA = new Label2D({ name: 'markSpotA', elem: info.spotA, domParent: player$6.domElement, camera: player$6.camera, useTransform: true }, player$6); //不使用panorama那个camera,因为在飞向下一个点时camera不更新 this.markSpotB = new Label2D({ name: 'markSpotB', elem: info.spotB, domParent: playerB$1, camera: this.splitView.panoramaCam, useTransform: true }, player$6); this.markSpotA.name = 'markSpotA'; this.markSpotB.name = 'markSpotB'; //热点的拖拽控制 new MoveCtrl({ elem: this.markSpotA.elem, domParent: player$6.domElement, useTransform: true, cameraControls: player$6.cameraControls, beginMoveFuc: function beginMoveFuc() { if (!_this2.editing) return; _this2.markSpotA.dragging = true; //this.markSpotA.elem.addClass("dragging") player$6.cameraControls.controls.panorama.locked = true; _this2.splitView.panoramaCtl.locked = true; }, moveDoneFuc: function moveDoneFuc(e) { if (!_this2.editing) return; _this2.markSpotA.dragging = false; //this.markSpotA.elem.removeClass("dragging") player$6.cameraControls.controls.panorama.locked = false; _this2.splitView.panoramaCtl.locked = false; e && _this2.moveToReGetA(e); player$6.mouseCouldBeClickToMove = false; } }); markBmoveCtrl = new MoveCtrl({ elem: this.markSpotB.elem, domParent: playerB$1, useTransform: true, cameraControls: player$6.cameraControls, beginMoveFuc: function beginMoveFuc() { _this2.markSpotB.dragging = true; //this.markSpotB.elem.addClass("dragging") _this2.splitView.panoramaCtl.locked = true; //防止相机移动 player$6.cameraControls.controls.panorama.locked = true; //避免在B区抬起不触发moveDone }, moveDoneFuc: function moveDoneFuc(e) { _this2.markSpotB.dragging = false; //this.markSpotB.elem.removeClass("dragging") _this2.splitView.panoramaCtl.locked = false; player$6.cameraControls.controls.panorama.locked = false; e && _this2.moveToReGetB(e); } }); playerB$1.addEventListener('pointerdown', mousedownB); playerB$1.addEventListener('touchstart', mousedownB); playerB$1.addEventListener('pointerup', this.clickToReGetB.bind(this)); //iphone pointerup无效 playerB$1.addEventListener('touchend', this.clickToReGetB.bind(this)); //player不断更新时,如果画面改变,要更新热点位置。 player$6.on('update', function (e) { if (_this2.editing) { if (e.hasChanged.cameraChanged2) { /* this.markSpotA.camera.updateMatrix() //没自动更新 this.markSpotA.camera.updateMatrixWorld() */ _this2.markSpotA.update(); } if (_this2.splitView.changed() /* || this.changed() */ ) { _this2.markSpotB.update(); } } }); //左屏改变漫游点 player$6.on('pano.chosen', function (pano1, pano2) { _this2.changePano(pano2); }); //左侧第一次点击确定位置 player$6.on('click', function (e) { if (_this2.editing && !_this2.clickA) { e.intersect && _this2.getA(e.intersect); e.consume(); //使用了,阻止后续进行 } }); //左屏改变漫游点时询问是否有要转向的aim target。 转向markTagPos player$6.on('ifFocusPoint', function (askAim) { if (_this2.editing && _this2.markTagPos) { var importance = 3; //设置当前的importance级别。如果askAim已高于该级别 就不操作 if (askAim.importance < importance) { askAim.importance = importance; askAim.aim = _this2.markTagPos.clone(); } } }); this.inited = true; } /* changed = (function () { var previousState = {} return function () { let changed = !previousState.mouseB || !this.mouseB.equals(previousState.mouseB) previousState.mouseB = this.mouseB.clone() return changed } })() */ //添加热点 }, { key: "enter", value: function enter() { var _this3 = this; /* var checkCanAddSpot = function(){ if(player.is360View(player.mode, player.currentPano)){ player.currentPano.view.backToPanorama(); $waiting.show() } return player.currentPano && (config.settings.visions != 2 || player.currentPano.assistPano) } if(!checkCanAddSpot()){ var timer = setInterval(() => { if(checkCanAddSpot()){ editSpot.addSpot() clearInterval(timer) } }, 50) return; } */ player$6.viewLinkManager.exitView().then(function () { if (player$6.flying || player$6.flyingToTag) { if (player$6.flyingToTag) ; player$6.once(PlayerEvents.FlyingEnded, function () { //等到飞行结束后再开始 _this3.enter(); }); return; } player$6.flyToMode('panorama', function () { var begin = function begin() { if (!player$6.currentPano) { setTimeout(begin, 50); return; } //$waiting.hide() _this3.editing = true; if (_this3.setSpotPos || player$6.flying) return; _this3.splitView.enter(); _this3.panosHistory = []; /* this.splitView.changePano(player.currentPano) //因为在enter之前已经分屏了,但之后可能飞到另一个漫游点了,所以同步下,保证右侧和左侧是对应的 this.splitView.setSceneB() */ _this3.panoB = _this3.splitView.panoB; _this3.markSpotA.elem.style.display = 'none'; _this3.markSpotB.elem.style.display = 'none'; _this3.markSpotA.pos3d = _this3.clickA = null; _this3.markSpotB.pos3d = _this3.clickB = null; _this3.markTagPos = null; //clear focus player$6.reticule.visible = false; player$6.locked = true; //左屏禁止移动,直到第一次点击 /* if (settings.visions == 1) { player.unableChangePano = true } */ if (insideLookLimitDownOld == void 0) { insideLookLimitDownOld = settings$3.insideLookLimitDown; insideLookLimitUpOld = settings$3.insideLookLimitUp; settings$3.insideLookLimitDown = -35; settings$3.insideLookLimitUp = 35; } }; begin(); }); }); } /* 开始热点位置修改 */ }, { key: "reSetPos", value: function reSetPos(pos) { var _this4 = this; this.markTagPos = new THREE.Vector3().copy(pos); player$6.viewLinkManager.exitView().then(function () { if (player$6.flying || player$6.flyingToTag) { if (player$6.flyingToTag) ; player$6.once(PlayerEvents.FlyingEnded, function () { //等到飞行结束后再开始 _this4.reSetPos(pos); }); return; } _this4.editing = true; _this4.panosHistory = []; //$waiting.hide() //objects.gui.showWaiting(false, "reSetPos") _this4.hotRePos = true; _this4.markSpotA.pos3d = _this4.clickA = _this4.markTagPos.clone(); _this4.markSpotA.enable = true; _this4.markSpotB.pos3d = _this4.clickB = _this4.markTagPos.clone(); _this4.markSpotA.elem.style.display = 'block'; _this4.markSpotB.elem.style.display = 'block'; //store.commit('SetPlayerOptions', { showPositionMarks: true }) //热点hotspot可见 _this4.markSpotB.enable = true; setTimeout(function () { _this4.markSpotA.update(); _this4.markSpotB.update(); }, 300); //console.log('reSetPos', player.currentPano.id) /* this.splitView.changePano(player.currentPano) this.splitView.setSceneB() */ _this4.splitView.enter(); _this4.panoA = _this4.splitView.panoA; _this4.panoB = _this4.splitView.panoB; if (insideLookLimitDownOld == void 0) { insideLookLimitDownOld = settings$3.insideLookLimitDown; insideLookLimitUpOld = settings$3.insideLookLimitUp; settings$3.insideLookLimitDown = -35; settings$3.insideLookLimitUp = 35; } //转向: player$6.flyToPano({ pano: player$6.currentPano, aimDuration: 500, lookAtPoint: _this4.markTagPos }); return true; }); } //确定热点位置 }, { key: "confirmPos", value: function confirmPos(Tag) { if (!this.editing) return; var sid = common.getRandomSid(); var pos = this.computeHotPos(); if (Tag) { //测试 player$6.model.add(new Tag(sid, { position: pos })); } if (!this.panoA) { return {}; } return { sid, position: pos, panoId: this.panoA.id //添加热点时,相机站在当前点 }; } }, { key: "exit", value: function exit() { var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (o.cancel) ; this.clickA = this.clickB = null; this.markSpotA.pos3d = this.markSpotB.pos3d = null; /* markSpotA.enable = false; markSpotB.enable = false; */ this.splitView.leave(); this.markSpotA.elem.style.display = 'none'; this.markSpotB.elem.style.display = 'none'; // 每次退出需要将markSpot位置重置屏幕中央 this.markSpotA.pos2d = new THREE.Vector2(); this.markSpotB.pos2d = new THREE.Vector2(); this.markSpotA.setElemPos(); this.markSpotB.setElemPos(); player$6.reticule.visible = true; if (this.hideMarker) { editSpot.hideMarker.visible = true; editSpot.hideMarker = null; } this.hotRePos = false; this.editing = false; player$6.locked = false; if (insideLookLimitDownOld != void 0) { settings$3.insideLookLimitDown = insideLookLimitDownOld; settings$3.insideLookLimitUp = insideLookLimitUpOld; insideLookLimitDownOld = insideLookLimitUpOld = null; } } //左方更改位置 }, { key: "changePano", value: function changePano(pano) { if (!this.editing) return; this.splitView.changePano(pano); //if (!this.markTagPos) return if (this.markTagPos) { this.markSpotA.pos3d = this.markTagPos.clone(); //使用计算出的坐标 this.panosHistory.push(pano); } if (pano.assistPano == this.splitView.panoB || pano == this.splitView.panoB) { this.splitView.pauseCameraBind = false; } else { if (!this.splitView.pauseCameraBind) { this.splitView.pauseCameraBind = true; this.markSpotB.pos3d && this.splitView.panoramaCtl.startLookAt(this.markSpotB.pos3d); //重新focus回tag一下,因为刚为了很可能转到别的方向了 } } } //在左边屏确定位置时 }, { key: "getA", value: function getA(intersect) { var _this5 = this; if (player$6.flying || !this.editing) return; this.panoA = player$6.currentPano; //记录改变位置时的左屏pano player$6.locked = false; //没有下相机的信息时,分屏后左右pano一样,当左屏确定位置后需要自动飞向别的pano if (settings$3.visions != 2 && this.panoA == this.panoB) { var modelViewMatrix = player$6.model.matrixWorld.clone().invert(); var pos = intersect.point.clone().applyMatrix4(modelViewMatrix); //自动飞到旁边最近的点:(为了避免走到的点可能看不见目标,所以取最近的) //var metadata = store.getters['scene/metadata']; if ( /* metadata.sceneSource != 12 && */ !this.clickA) { //123的点位在不同房间,全景图很不一样所以不飞(用户需尽量走到可以看到热点的其他位置进行校准,如果没有可见位置,就当做在该房间内的局部全景热点,因为其他房间看不到所以不准确没有关系) this.clickA = this.clickB = pos; var nearestPano = player$6.model.panos.find([function (pano) { return player$6.currentPano.neighbourPanos[pano.id] && player$6.currentPano != pano; }], [Panorama.sortFunctions.distanceToPoint(player$6.currentPano.position)]); //player.unableChangePano = false if (nearestPano) player$6.flyToPano({ pano: nearestPano, lookAtPoint: pos.clone() });else { console.log('当前场景只有一个pano,所以不走到下一个点'); } } this.clickA = this.clickB = pos; } else { if (player$6.currentPano.assistPano != this.splitView.panoB || this.panosHistory.length > 0) { //左屏已经到另一个点 或者又回来这个点,右侧都不用自动改位置 if (!this.clickA) { //测距第二步时左边走到别的地方,右边要加载对应的 this.splitView.setSceneB(); this.panoB = this.splitView.panoB; this.splitView.pauseCameraBind = false; if (settings$3.visions != 2) { //恢复到两边一样,再次执行,以类似第一步开始时 this.splitView.panoramaCtl.startLookAt(intersect.point); return this.getA(intersect); } } else { this.panoA = player$6.currentPano; var modelViewMatrix = player$6.model.matrixWorld.clone().invert(); //×模型矩阵的逆矩阵,是因为当飞出屋子再飞进去时模型位移了,现在要保证采集的点是模型没有任何变换下的点。在计算2d坐标时会乘以模型矩阵。 this.clickA = intersect.point.clone().applyMatrix4(modelViewMatrix); this.markSpotA.pos3d = this.clickA; this.markSpotA.update(); this.computeHotPos(); //objects.tagManager.markTag.rePos(markSpotA.computeHotPos({ onlyGetPos: true, dontRestric: editSpot.editType == "measure" })) //总是记录最新算出的坐标 A或B到下一个位置时就使用它 //console.log("远近:" + objects.tagManager.markTag.position.distanceTo(player.position)); return; } } if (settings$3.visions != 2) { console.warn('settings.visions != 2 ???'); } var data = this.getMatchData(); if (!data) { //$waiting.show() ////objects.gui.showWaiting(true, "getMatchData") var name = this.panoA.id + '_' + this.panoB.id; MatchDataGetWrong[name] = (MatchDataGetWrong[name] || 0) + 1; if (MatchDataGetWrong[name] > 5) { console.error('获取不到matchdata 放弃使用: ' + name); } else { setTimeout(function () { _this5.getA(intersect); }, 200); return; } } //if (texGetted) $waiting.hide() //objects.gui.showWaiting(false, "getMatchData") var modelViewMatrix = player$6.model.matrixWorld.clone().invert(); //×模型矩阵的逆矩阵,是因为当飞出屋子再飞进去时模型位移了,现在要保证采集的点是模型没有任何变换下的点。在计算2d坐标时会乘以模型矩阵。 this.clickA = intersect.point.clone().applyMatrix4(modelViewMatrix); this.dirA = math$1.getNormalDir(this.clickA, player$6.model.supportsTiles, player$6.currentPano); //经过matrix变换的方向 //通过A预测B this.UVa = math$1.getUVfromDir(this.dirA); this.UVb = this.searchPointAtLeft(this.UVa); if (!this.UVb) { //因为B相机相对A相机在y向偏移,所以预估UV console.log('找不到UVb,假设一个'); //$tips({ content: "辅助校准位置可能不准确,请检查并拖动到"+ (config.isMobile ? "上方":"左侧")+"相同位置" }) //$tips({ content: i18n.t('modules.hotspot.m_location_move_tips', { direction: i18n.t(`modules.hotspot.m_location_${config.isMobile?'up':'left'}`) }) }) var shiftY = -0.02; //最好根据历史统计一下。因为x也可能很不一样 this.UVb = { x: this.UVa.x, y: this.UVa.y + shiftY }; } else { this.UVb.x = this.UVb.x.toFixed(3) - 0; this.UVb.y = this.UVb.y.toFixed(3) - 0; } this.dirB = math$1.getDirFromUV(this.UVb); this.clickB = getPoint(this.dirB, this.splitView.panoB); //更新相机朝向,并记得要立刻updateMatrix,getPos2d需要用到matrix /* panoramaCam.lookAt(this.clickB) panoramaCam.updateMatrix(); panoramaCam.updateMatrixWorld(); */ //UV显示对照更新 /* $("#IMGparent > div").eq(0).find('.cursor1').css({"display":"block", "left": this.UVa.x*100+"100%", "top": this.UVa.y*100+"100%"}) $("#IMGparent > div").eq(1).find('.cursor1').css({"display":"block", "left": this.UVb.x*100+"100%", "top": this.UVb.y*100+"100%"}) */ } this.markSpotA.pos3d = this.clickA; this.markSpotB.pos3d = this.clickB; //热点标记可见 //store.commit('SetPlayerOptions', { showPositionMarks: true }) this.markSpotA.elem.style.display = 'block'; this.markSpotB.elem.style.display = 'block'; this.markSpotA.enable = true; this.markSpotB.enable = true; this.markSpotA.update(); this.markSpotB.update(); if (settings$3.visions != 2 && this.panoA == this.panoB) { this.markTagPos = this.markSpotA.pos3d.clone(); } else { this.computeHotPos(); } //$('#player').css('cursor', ''); this.$app.TagManager.emit('tagManager.markTagPos'); } //在右边屏确定位置时 }, { key: "getB", value: function getB(mouse) { var intersect = convertTool.getMouseIntersect(this.splitView.panoramaCam, [this.splitView.cube], mouse); var modelViewMatrix = player$6.model.matrixWorld.clone().invert(); //×模型矩阵的逆矩阵,是因为当飞出屋子再飞进去时模型位移了,现在要保证采集的点是模型没有任何变换下的点。在计算2d坐标时会乘以模型矩阵。 this.clickB = intersect.point.clone().applyMatrix4(modelViewMatrix); this.markSpotB.pos3d = this.clickB; //更新hotspot三维位置 this.markSpotB.update(); //更新hotspot二维位置 this.computeHotPos(); } }, { key: "moveToReGetA", value: function moveToReGetA(e) { //拖拽左侧热点到新的位置 player$6.handleInputStart(e.x, e.y, true, true); //更新mouse player$6.updateIntersect({}); //let intersect = player.getMouseIntersect(null, this.linkEditor.footIcons) player$6.intersect ? this.getA(player$6.intersect) : this.markSpotA.update(); //update:回到原来的位置 player$6.mouseDown = false; //移动端这个不会归零 所以手动 } }, { key: "moveToReGetB", value: function moveToReGetB(e) { //拖拽右侧热点到新的位置 var mouse = new THREE.Vector2(); math$1.convertScreenPositionToNDC(e.x, e.y, mouse, playerB$1); //获取在canvasB的mouse this.getB(mouse); } }, { key: "clickToReGetB", value: function clickToReGetB(e) { //点击右侧,热点到新的位置(左侧点击不能确定位置) //this.playerBmousedown = false if (markBmoveCtrl.moving) return; //这时候使用的是moveToReGetB 因为拖拽热点 var mouseB = getMouseB(e); if (Math.abs(lastMouseB.x - mouseB.x) > 3 || Math.abs(lastMouseB.y - mouseB.y) > 3) return; //在拖拽画布 if (!this.clickA && !this.hotRePos) { console.log('..?..'); this.$app.TagManager.emit('tagManager.firstMarkTagPosB'); //$tips({ content:i18n.t(`show.location_start_tips`,{direction: i18n.t(`show.location_${config.isMobile?'up':'left'}`)}) }); return; } var mouse = new THREE.Vector2(); math$1.convertScreenPositionToNDC(mouseB.x, mouseB.y, mouse, playerB$1); //获取在canvasB的mouse this.getB(mouse); } }, { key: "restricPosAtRoom", value: function restricPosAtRoom(pos3d) { var A = player$6.currentPano.position; //如果不支持编辑户型的话就得不到rooms 直接使用模型判断 但可能出门 能限制在skybox内 /* var group = objects.player.model.wallManager.roomInfo && objects.player.model.wallManager.roomInfo.oriRoomGroup; if(group){ group.visible = true; var intersect = convertTool.ifIntersectChunks(A, pos3d, {model: group.children}); if(intersect && intersect.length ){ console.log('热点飘出房间') var pos = intersect[0].point.clone().setY(intersect[0].point.y + 0.001)//+ 0.001防止重叠 pos3d.copy(pos) } group.visible = false; //新版只有一个房间,可能需要用柱子等其他物体隔开(不在oriRoomData内),还是用模型好。且oriRoomData需一开始就初始化mainDesign。 }else{ */ var B = pos3d; var dir = B.clone().sub(A).normalize(); var ray = new THREE.Raycaster(A, dir, 0, A.distanceTo(B)); var o = ray.intersectObjects(player$6.model.skyBoxTight /* .colliders */ ); //模型不准时热点就永远放不准 只有激光的比较准 if (o && o.length) { console.log('热点飘出skyBoxTight外,矫正:' + pos3d.toArray() + ' --> ' + o[0].point.toArray()); pos3d.copy(o[0].point).sub(dir.clone().multiplyScalar(0.001)); } //} return pos3d; } }, { key: "computeHotPos", value: function computeHotPos() { var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; //通过采集的两个点位信息,来计算3d坐标 if (!this.panoA || !this.clickA) { return null; } var A = this.panoA.position.clone(); var B = this.panoB.position.clone(); var p1 = this.clickA; var p2 = this.clickB; var _math$getLineIntersec = math$1.getLineIntersect({ A, B, p1, p2 }), pos3d = _math$getLineIntersec.pos3d; if (!o.dontRestric) this.restricPosAtRoom(pos3d); this.markTagPos = pos3d; console.log('markTagPos: ', pos3d.toArray()); return pos3d; } //-----------通过上下相机来预测初始位置------------- }, { key: "getMatchData", value: function getMatchData() { //获取上下相机的 view pair 对照数据 var name = this.panoA.id + '_' + this.panoB.id; if (MatchData[name]) return MatchData[name];else { http.get(this.$app.resource.getEditDataURL("mapping/".concat(name, ".json"))).then(function (data) { MatchData[name] = data; }); } } }, { key: "searchPointAtLeft", value: function searchPointAtLeft(UVa) { //借用view pair数据 通过UVa(热点在左屏的uv位置) 预测UVb var data = this.getMatchData(); if (!UVa) { console.log('!!!'); } if (!data || !data['view pair'] || !data['view pair']['uv']) return null; ///////////////////////// var tx = UVa.x; var ty = UVa.y; var leftTop = {}, rightTop = {}, leftBot = {}, rightBot = {}; var info = { leftTop: leftTop, rightTop: rightTop, leftBot: leftBot, rightBot: rightBot }; var result; //$('#IMGparent .cursor2').remove() data['view pair']['uv'].forEach(function (pair) { if (pair[0] < tx && pair[1] <= ty) { judge(leftTop, pair); } else if (pair[0] >= tx && pair[1] <= ty) { judge(rightTop, pair); } else if (pair[0] < tx && pair[1] >= ty) { judge(leftBot, pair); } else { judge(rightBot, pair); } }); function judge(o, pair) { var x = pair[0]; var y = pair[1]; //var dis = Math.abs(x-tx) + Math.abs(y-ty); var dis = (x - tx) * (x - tx) + (y - ty) * (y - ty); if (o.dis == void 0 || o.dis > dis) { o.dis = dis; o.pair = pair; } } var hasValue = 0; //四个方向有值的个数 for (var i in info) { if (info[i].pair) hasValue++; } var percent = {}; //根据距离算出比例 近似成左右边的uv比例 if (hasValue >= 3) { //有三个值就足够算出 result = compute(); } else if (hasValue == 2) { //两个值的需要 对角线上都有值 if (leftTop.pair && rightBot.pair || leftBot.pair && rightTop.pair) { result = compute(); } } else ; function getSmallest(dir1, dir2) { if (!dir1.pair) return dir2;else if (!dir2.pair) return dir1; if (dir1.dis < dir2.dis) return dir1;else return dir2; } function compute() { //线性插值计算(比例) uvA对应的uvB var left = getSmallest(leftTop, leftBot); var right = getSmallest(rightTop, rightBot); var top = getSmallest(leftTop, rightTop); var bottom = getSmallest(leftBot, rightBot); percent.x = (tx - left.pair[0]) / (right.pair[0] - left.pair[0]); percent.y = (ty - top.pair[1]) / (bottom.pair[1] - top.pair[1]); //得到对应的uv var x = left.pair[2] + (right.pair[2] - left.pair[2]) * percent.x; var y = top.pair[3] + (bottom.pair[3] - top.pair[3]) * percent.y; return { x: x, y: y }; } return result; } }]); return Editspot; }(tinyEmitter); }); /* 若关联全景中加热点, 热点仅在此pano可见。无需分屏 */ /* 初始画面 */ var FirstView = /*#__PURE__*/function () { function FirstView(metadata, panos) { _classCallCheck(this, FirstView); this.quickstart = true; this.mode = Viewmode$1.PANORAMA; this.zoom = -1, this.fov = browser$1.urlHasValue('fov') ? Number(browser$1.urlQueryValue('fov')) : settings$3.insideFOV; this.pano = null; this.position = new THREE.Vector3(); this.quaternion = new THREE.Quaternion(); this.init(metadata, panos); } _createClass(FirstView, [{ key: "init", value: function init(metadata, panos) { var urlFirstView = browser$1.urlHasValue('pose', true); //使用地址栏的信息 如 &pose=pano:2,qua:-0.2205,-0.718,-0.2613,0.605 if (urlFirstView) { try { urlFirstView = common.replaceAll(urlFirstView, 'pano', '"pano"'); urlFirstView = common.replaceAll(urlFirstView, 'qua:', '"qua":['); urlFirstView = '{' + urlFirstView + ']}'; var info = JSON.parse(urlFirstView); this.pano = panos.get(info.pano); if (!this.pano) { urlFirstView = false; console.error('检测到firstView但是 找不到该pano'); } else { this.quaternion = new THREE.Quaternion().fromArray(info.qua); this.zoom = -1; this.setByUrl = true; } } catch (e) { urlFirstView = false; console.error('检测到firstView但是解析出错' + e); } } else { if (metadata && metadata.entry) { var entry = metadata.entry; this.updateByEntry(entry, panos); } else { this.pano = panos.list[0]; this.quaternion.copy(this.pano.quaternion); } } this.position.copy(this.pano.position); if (this.quaternion.equals(new THREE.Quaternion(-0.5, 0.5, 0.5, 0.5))) { //俯视向下会黑屏 this.quaternion.set(0, 0, 0, 1); console.log('检测到初始画面quaternion为-0.5,0.5,0.5,0.5,强制更改为0,0,0,1'); } } }, { key: "updateByEntry", value: function updateByEntry(entry, panos) { if (typeof entry == 'string') { entry = JSON.parse(entry); } if (entry.pano) { this.pano = panos.get(entry.pano); } //有可能客户补拍,那时候这个id可能不存在了。 if (this.pano == void 0) { this.pano = panos.list[0]; } this.quaternion.copy(this.pano.quaternion); if (entry.camera) { this.quaternion = new THREE.Quaternion().fromArray(entry.camera.quaternion); this.zoom = entry.camera.zoom; } } }, { key: "fromGuideView", value: function fromGuideView(guidItem, panos) { this.mode = guidItem.value.mode; this.zoom = guidItem.value.zoom; this.position.copy(guidItem.value.pos); this.quaternion.set(guidItem.value.qua._x, guidItem.value.qua._y, guidItem.value.qua._z, guidItem.value.qua._w); this.pano = panos.get(guidItem.value.pano); } }]); return FirstView; }(); function _createSuper$H(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$H(); 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 _isNativeReflectConstruct$H() { 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; } } var renderer$1, playerB, player$5; var texWaitTimer = {}; var panos2; //分屏模块 var SplitView = /*#__PURE__*/function (_EventEmitter) { _inherits(SplitView, _EventEmitter); var _super = _createSuper$H(SplitView); function SplitView($app, editType) { var _this; _classCallCheck(this, SplitView); _this = _super.call(this); _this.changed = function () { //判断右边分屏是否移动了panoramaCam 即是否需要更新markB的位置 var previousState; return function () { var cameraChanged; var p = this.panoramaCam.position.clone(), q = this.panoramaCam.quaternion.clone(); if (!previousState || !MathLight.closeTo(previousState.position, p, 5) || !MathLight.closeTo(previousState.quaternion, q, 5)) cameraChanged = true; if (cameraChanged) { previousState = { position: p, quaternion: q }; } return cameraChanged; }; }(); window.SplitView = _assertThisInitialized(_this); _this.$app = $app; { _this.init(); } _this.editType = editType; _this.pauseCameraBind; //右屏是否不跟左屏动 return _this; } _createClass(SplitView, [{ key: "init", value: function init() { var _this2 = this; player$5 = this.$app.core.get('Player'); //-------------设置副屏------------- playerB = this.$app.dom.querySelector('.player[name="copy"]'); //创建新的renderer、 scene 和 相机控制 renderer$1 = new THREE.WebGLRenderer({ antialias: true /* !config.isMobile */ }); renderer$1.setPixelRatio(window.devicePixelRatio); renderer$1.setSize(300, 300, false); playerB.appendChild(renderer$1.domElement); var ctls = this.$app.withNewComponent('CameraControls'); ctls.init(playerB, ['panorama']); ctls.activateControls('panorama'); this.panoramaCtl = ctls.activeControl; this.panoramaCam = ctls.activeControl.camera; this.panoramaCam.fov = 60; this.panoramaCam.name = 'splitViewCam'; this.panoramaCam.layers.toggle(RenderLayers.DEFAULT); this.panoramaCam.layers.enable(RenderLayers.PANOMARKERS); this.panoramaCam.layers.enable(RenderLayers.BothAtMainAndSubScreen); this.panoramaCam.layers.enable(RenderLayers.SubScreen); if (settings$3.visions == 2 && !player$5.model.panos.list[0].assistPano) { //诊断出没有vision2的数据 settings$3.visions = 1; console.warn('自动更改 visions = 1'); } if (settings$3.visions != 2 && player$5.model.supportsTiles) { //没有下相机的单张全景图,所以只加载和左侧一样的tiles贴图,需要重新创建tiles相关,因贴图无法共用(会报错) var sceneRenderer2 = this.$app.withNewComponent('SceneRenderer', 1); var panoRenderer2 = this.$app.withNewComponent('PanoRenderer', 1); var tileDownloader2 = this.$app.withNewComponent('TileDownloader', { $app: this.$app }); tileDownloader2.index = 1; sceneRenderer2.renderer = renderer$1; tileDownloader2.processPriorityQueue = true; //? panoRenderer2.init(sceneRenderer2, tileDownloader2); panos2 = new PanoramaCollection(); panos2.extend(player$5.model.panos.list.map(function (pano) { var panoCopy = new Panorama(_this2.$app, pano.id, pano); panoCopy.attachToPanoRenderer(panoRenderer2); panoCopy.tileDownloader = tileDownloader2; panoCopy.qualityManager = _this2.$app.core.get('QualityManager'); return panoCopy; })); tileDownloader2.setPanoData(panos2, [], this.$app.core.get('ModelManager').projectNum); tileDownloader2.setUrls(player$5.model.urls); //? tileDownloader2.start(); //tileDownloader2.tilePrioritizer.updateCriteria(this.panoB)//? } { //添加天空盒 this.cube = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10), new ModelTextureMaterial({ side: THREE.BackSide, transparent: false, name: 'splitViewCubeMat', not_Cube: settings$3.visions == 2 || !player$5.model.supportsTiles //如果有下相机,右侧是单张图,否则和左侧一样 }, 'skybox')); this.cube.name = 'splitView-cube'; this.cube.layers.set(RenderLayers.SubScreen); this.$app.core.get('SceneRenderer').scene.add(this.cube); } { //--event player$5.on('updateFromControls', function (player, e) { if (_this2.editing) { if (_this2.pauseCameraBind) { _this2.panoramaCtl.update(e); } else { _this2.panoramaCtl.lon = player.cameraControls.controls.panorama.lon; _this2.panoramaCtl.lat = player.cameraControls.controls.panorama.lat; _this2.panoramaCtl.update(e); player.cameraControls.controls.panorama.lon = _this2.panoramaCtl.lon; player.cameraControls.controls.panorama.lat = _this2.panoramaCtl.lat; } //console.log('同步') } }); } } }, { key: "enter", value: function enter() { //开始分屏 if (this.editing) return; this.editing = true; this.$app.core.get('SceneRenderer').addComponent(this); var camera = player$5.cameraControls.cameras.panorama; camera.fov = camera.staticFov = 60; this.zoomEnabled = settings$3.zoom.enabled; settings$3.zoom.enabled = false; //这个决定滚轮是缩放或者前进 this.pauseCameraBind = false; //false时两个相机的旋转角度是一致的,互相影响 this.panoA = player$5.currentPano; this.setSize(); this.setSceneB(); this.emit('enter'); player$5.OverlayManager.hide('all'); player$5.GLTFEditor.hide('all'); } }, { key: "leave", value: function leave() { //结束分屏 if (!this.editing) return; this.$app.core.get('SceneRenderer').removeComponent(this); this.emit('leave'); this.editing = false; settings$3.zoom.enabled = this.zoomEnabled; player$5.OverlayManager.show('all', true); player$5.GLTFEditor.show('all', true); player$5.cameraControls.cameras.panorama.staticFov = null; if (this.panoB && this.panoB != this.panoA) { this.panoB.exit(); this.panoB.useAtScreenB = false; } } }, { key: "setSceneB", value: function setSceneB() { //设置右屏 var oldPanoB = this.panoB; if (settings$3.visions != 2) { this.panoB = this.panoA; this.cube.position.copy(this.panoB.position); this.panoramaCam.position.copy(this.panoB.position); } else if (this.panoB != this.panoA.assistPano) { this.panoB = this.panoA.assistPano; this.cube.position.copy(this.panoB.position); this.panoramaCam.position.copy(this.panoB.position); //隐藏marker /* if (!config.isMobile || this.editType != "measure") */ { this.hideMarker && (this.hideMarker.visible = true); this.hideMarker = this.panoA.marker; this.hideMarker.visible = false; } } this.getTextureForCube(this.panoB); this.panoB.useAtScreenB = true; if (oldPanoB && oldPanoB != this.panoB) { oldPanoB.exit(); oldPanoB.useAtScreenB = false; } } /* 注意:当visions==2时,才有下相机assistPano,而下相机没有tile */ }, { key: "getTextureForCube", value: function getTextureForCube(pano) { var _this3 = this; //获取右方贴图 console.log('getTextureForCube', pano.id); var pano = pano || this.panoB; if (settings$3.visions != 2 && player$5.model.supportsTiles) { pano = panos2.index[pano.id]; //加载tiles贴图需要换成panos2的pano } /* var wait = player.checkAndWaitForPanoLoad(pano, 'high', 'high', 2048, () => { //标准pc:2048 this.getTextureForCube(pano) }) */ var loaded = function loaded() { if (texWaitTimer[_this3.panoB.id]) { clearTimeout(texWaitTimer[_this3.panoB.id]); delete texWaitTimer[_this3.panoB.id]; } if (pano && _this3.panoB.id != pano.id) { console.log('getTextureForCube退出'); return; } //可能加载好就退出或者换到别的点 console.log('texGetted', pano.id); pano.ensureSkyboxReadyForRender(); var tex = pano.getSkyboxTexture(); _this3.cube.material.uniforms.pano1Map.value = tex; _this3.cube.material.uniforms.pano1Matrix.value.copy(_this3.panoB.matrixWorld); }; if (pano.tiled) { //若无下相机,使用和左侧一样的漫游点(的copy), 是tiled //先优先加载部分贴图 var size = 2048, d = cameraLight.getHFOVForCamera(player$5.camera, player$5.domElement.clientWidth / 2, player$5.domElement.clientHeight), p = player$5.zoomFov, r = player$5.getDirection(); //console.log('loadPromise', 'hFov', d, 'vFov',p ) var loadPromise = pano.loadTiledPano(size, r, { hFov: d, vFov: p }, !1, !1, !0); loadPromise.then(function () { loaded(); }); //然后加载所有 player$5.checkAndWaitForPanoLoad(pano, 'high', 'high', 2048, function () {}); } else { //单张贴图 if (!player$5.checkAndWaitForPanoLoad(pano, 'high', 'high', 2048, loaded)) { loaded(); } //修改位置时 右侧可能变黑 为何 } /* if (!wait) { if (texWaitTimer[this.panoB.id]) { clearTimeout(texWaitTimer[this.panoB.id]) delete texWaitTimer[this.panoB.id] } if (pano && this.panoB.id != pano.id) { console.log('getTextureForCube退出') return } //可能加载好就退出或者换到别的点 //$waiting.hide() texGetted = true console.log('texGetted ') pano.ensureSkyboxReadyForRender() var tex = pano.getSkyboxTexture() this.cube.material.uniforms.pano1Map.value = tex this.cube.material.uniforms.pano1Matrix.value.copy(this.panoB.matrixWorld) } else { if (!texWaitTimer[this.panoB.id]) { //如果20秒后还没加载好贴图就停止 texWaitTimer[this.panoB.id] = setTimeout(() => { //$waiting.hide() clearTimeout(texWaitTimer[this.panoB.id]) delete texWaitTimer[this.panoB.id] console.log('无法获取贴图,可能网络状态不佳') }, 20e3) } //$waiting.show() // objects.gui.showWaiting(true, "getTextureForCube") texGetted = false } */ } }, { key: "update", value: function update() { //渲染右屏 if (!this.editing) return; /* objects.tagManager.tagDiscs.forEach((disc) => { if (!disc.visible || disc.material.uniforms.opacity.value == 0) return; disc.canvasA_Qua = disc.quaternion.clone(); disc.canvasA_Scale = disc.scale.clone(); disc.tag.update(player.mode, panoramaCam, player.currentPano, player.flying) }) */ renderer$1.render(this.$app.core.get('SceneRenderer').scene, this.panoramaCam); /* objects.tagManager.tagDiscs.forEach((disc) => { if (!disc.visible || disc.material.uniforms.opacity.value == 0) return; disc.quaternion.copy(disc.canvasA_Qua) disc.scale.copy(disc.canvasA_Scale) }) */ } }, { key: "setSize", value: function setSize() { //右屏更改大小 if (!this.editing) return; renderer$1.setSize(playerB.clientWidth, playerB.clientHeight, true, Math.min(window.devicePixelRatio, 2)); this.panoramaCam.updateAspect(playerB.clientWidth / playerB.clientHeight); } }, { key: "changePano", value: function changePano(pano) { this.panoA = pano; } }]); return SplitView; }(EventEmitter); var Preloaders = /*#__PURE__*/function () { function Preloaders(model, player) { _classCallCheck(this, Preloaders); this.model = model; this.panos = model.panos; this.player = player; this.retryMinimumTime = 1e4; } _createClass(Preloaders, [{ key: "start", value: function start() { this.loadNextPano(function (e) { if (e) { this.start(); } else { logger$1.debug('No suitable pano loaded, waiting a little while before looking again'); setTimeout(function () { this.start(); }.bind(this), 1e3); } }.bind(this)); } }, { key: "validLoadTarget", value: function validLoadTarget(e) { return e && !e.isLoaded('high') && Date.now() - e.failedLoadingAt > this.retryMinimumTime; } }, { key: "listImagePanos", value: function listImagePanos() { var e = [], t = this; this.model.images.forEach(function (i) { if (i.metadata && i.metadata.scan_id) { var n = t.model.panos.get(i.metadata.scan_id); n && !n.isLoaded('high') && e.push(n); } }); return e; } }, { key: "loadNextPano", value: function loadNextPano(e) { var pano, i, n = this.model.waitQueue.filter(function (e) { return e.object instanceof Panorama; }); if (n.length > 0) { pano = n[0].object; logger$1.debug('Overrode pano selection: Flying to an unloaded pano ' + pano.id); } else if (this.validLoadTarget(this.player.currentPano)) { pano = this.player.currentPano; logger$1.debug('Overrode pano selection: Currently at an unloaded pano ' + pano.id); } else if (this.validLoadTarget(this.player.closestPano)) { pano = this.player.closestPano; logger$1.debug('Overrode pano selection: Hovering over an unloaded pano ' + pano.id); } else if (this.player.mode === Viewmode$1.PANORAMA) { pano = this.panos.lowestByScore([this.validLoadTarget.bind(this), Panorama.filters.isNeighbourPanoTo(this.player.currentPano)], [Panorama.scoreFunctions.distance(this.player.currentPano), Panorama.scoreFunctions.direction(this.player.position, this.player.getDirection()), Panorama.scoreFunctions.inFieldOfView(this.player.position, this.player.getDirection())]); pano && logger$1.debug('Normal pano selection: neighbor ' + pano.id); } if (pano) { i = i || pano.isLoaded('low') ? 'high' : 'low'; logger$1.debug('Preloading ' + i + '-res pano ' + pano.id); console.log('Preloading ' + i + '-res pano ' + pano.id); pano.loadCube(i).done(e).fail(function () { logger$1.warn('Failed preloading pano', pano.id, ', marking it as failed and forgetting it for a while'), e(); }); } else { e && e(null); } } }]); return Preloaders; }(); function _createForOfIteratorHelper$4(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$4(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$4(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$4(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$4(o, minLen); } function _arrayLikeToArray$4(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } defineComponent('Scene', function () { return /*#__PURE__*/function () { function Scene() { _classCallCheck(this, Scene); this.ready = false; this.loaded = false; this.tilegen = true; //应该放到setting里 this.quickstart = false; this.position = new THREE.Vector3(15, 10, 15); //默认初始点位置 this.splitViews = []; //分屏 // if (this.$app.config.view === false) { // this.locked = Deferred() // this.$app.store.on('auth', () => { // this.locked.resolve() // }) // } } _createClass(Scene, [{ key: "beforeLoad", value: function beforeLoad() { this.$app.withComponent('Screenshot'); this.$app.withComponent('SceneRenderer'); this.$app.withComponent('PanoRenderer'); this.$app.withComponent('PanoVideoRenderer'); this.$app.withComponent('QualityManager'); this.$app.withComponent('ModelManager'); this.$app.withComponent('CameraControls'); this.$app.withComponent('DisplayController'); this.$app.withComponent('TileDownloader', { concurrentDownloads: this.tilegen ? 6 : 2, $app: this.$app }); this.$app.withComponent('Player'); this.$app.withComponent('Director'); this.$app.core.get('SceneRenderer').createScene(); this.$app.core.get('CameraControls').init(this.$app.dom.querySelector('.player')); this.$app.core.get('QualityManager').init(); this.$app.core.get('TileDownloader').init(); this.$app.core.get('PanoRenderer').init(); } //启动 }, { key: "start", value: function () { var _start = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() { var _this = this; var auth, metadata, metadataForVideo, _iterator, _step, data, buildScene; return regenerator.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: if (!this.ready) { _context2.next = 2; break; } return _context2.abrupt("return"); case 2: if (!(this.$app.config.view === false && this.$app.config.useAuth)) { _context2.next = 14; break; } _context2.prev = 3; _context2.next = 6; return this.$app.resource.auth(); case 6: auth = _context2.sent; if (!(auth.success == false)) { _context2.next = 9; break; } return _context2.abrupt("return"); case 9: _context2.next = 14; break; case 11: _context2.prev = 11; _context2.t0 = _context2["catch"](3); return _context2.abrupt("return"); case 14: _context2.next = 16; return this.$app.resource.metadata(); case 16: metadata = _context2.sent; if (!(metadata == void 0)) { _context2.next = 19; break; } return _context2.abrupt("return"); case 19: if (!(metadata.filters && metadata.filters == 1)) { _context2.next = 22; break; } _context2.next = 22; return this.$app.store.get('filters'); case 22: if (!(metadata.cutModel && metadata.cutModel == 1)) { _context2.next = 26; break; } _context2.next = 25; return this.$app.store.get('cutModel'); case 25: this.$app.store.getValue('metadata').cutModel = _context2.sent; case 26: // if (metadata.sceneDraw && metadata.sceneDraw == 1) { // let data = await this.$app.store.get('sceneDraw') // this.$app.store.getValue('metadata').sceneDraw = { // data, // labelVisible: this.$app.store.getValue('metadata').controls.showDrawTitle, // } // } if (this.$app.store.getValue('metadata').controls.showAllModel === 1) { ModelSide.setSide(2); } else { ModelSide.setSide(null); } this.beforeLoad(); // 判断是否需要锁住场景不继续加载 if (!this.$app.Scene.locked) { _context2.next = 31; break; } _context2.next = 31; return this.$app.Scene.locked; case 31: // 判断你是否加载单张4k全景图 if (metadata.sceneKind && metadata.sceneKind == 'pano') { this.$app.core.get('Player').model.supportsTiles = false; } //是否加载tile图片 // if (this.$app.core.get('Player').model.supportsTiles) this.$app.core.get('TileDownloader').start(); metadataForVideo = JSON.parse(JSON.stringify(metadata)); _context2.next = 36; return VersionControl.handle(metadataForVideo, this.$app); case 36: this.$app.core.get('PanoVideoRenderer').init(metadataForVideo.videos); /** * 加载paint图片 */ // console.error("start load", new Date().getTime()) if (!(metadata.mosaic && metadata.mosaicList && metadata.mosaicList.length)) { _context2.next = 57; break; } _iterator = _createForOfIteratorHelper$4(metadata.mosaicList); _context2.prev = 39; _iterator.s(); case 41: if ((_step = _iterator.n()).done) { _context2.next = 49; break; } data = _step.value; _context2.t1 = data.fileName; if (!_context2.t1) { _context2.next = 47; break; } _context2.next = 47; return texture.loadWithoutUpdate(this.$app.resource.getUserResourceURL(data.fileName)); case 47: _context2.next = 41; break; case 49: _context2.next = 54; break; case 51: _context2.prev = 51; _context2.t2 = _context2["catch"](39); _iterator.e(_context2.t2); case 54: _context2.prev = 54; _iterator.f(); return _context2.finish(54); case 57: _context2.next = 59; return this.$app.resource.visions(); case 59: //步骤1 this.initPanos(metadata); //解析漫游点,步骤1的延伸 this.$app.FilterManager.initFilters(); // 初始化滤镜数据 _context2.next = 63; return this.isQuick(metadata); case 63: //步骤2 Quick Start /** * 基础资源已准备完毕 */ this.$app.Scene.emit('ready'); this.ready = true; buildScene = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee() { return regenerator.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return _this.$app.resource.flooruser(); case 2: _this.$app.core.get('SceneRenderer').addComponent(transitions$1); //将加载的模型构建好以便于直接使用 _this.$app.core.get('Player').model.build(); _this.afterLoad(); if (!_this.$app.core.get('Player').model.supportsTiles) { new Preloaders(_this.$app.core.get('Player').model, _this.$app.core.get('Player')).start(); } _context.next = 8; return _this.loadPanos(); case 8: case "end": return _context.stop(); } } }, _callee); })); return function buildScene() { return _ref.apply(this, arguments); }; }(); if (!(metadata.modelKind === '3dtiles')) { _context2.next = 72; break; } _context2.next = 69; return this.$app.resource.modelmesh3dTiles(); case 69: //步骤3 this.$app.Scene.on('3dTilesLoaded', buildScene); _context2.next = 78; break; case 72: _context2.next = 74; return this.$app.resource.modelmeshDam(); case 74: _context2.next = 76; return this.$app.resource.textures(); case 76: _context2.next = 78; return buildScene(); case 78: case "end": return _context2.stop(); } } }, _callee2, this, [[3, 11], [39, 51, 54, 57]]); })); function start() { return _start.apply(this, arguments); } return start; }() }, { key: "isQuick", value: function () { var _isQuick = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3(metadata) { return regenerator.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: if (!this.firstView.quickstart) { _context3.next = 3; break; } _context3.next = 3; return this.quickEnter(this.firstView, metadata /* , startOption */ ); case 3: case "end": return _context3.stop(); } } }, _callee3, this); })); function isQuick(_x) { return _isQuick.apply(this, arguments); } return isQuick; }() }, { key: "loadPanos", value: function () { var _loadPanos = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee5() { var _this2 = this; var loadData; return regenerator.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: _context5.next = 2; return this.$app.core.get('Player').start(this.firstView); case 2: if (this.firstView.quickstart) { this.$app.core.get('SceneRenderer').removeComponent(this.$app.core.get('QuickstartManager')); this.$app.core.get('QuickstartManager').destroy(); } // 第一个点位加载完后执行 this.loaded = true; this.$app.Scene.emit('loaded', this.$app.core.get('Player').currentPano); //-------这两个争取addComponent在最后------- this.$app.core.get('TileDownloader').useComponent(); this.$app.core.get('SceneRenderer').addComponent(this.$app.core.get('PanoRenderer'), true); //------------------------------------------ loadData = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee4() { return regenerator.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.next = 2; return _this2.$app.store.get('tags'); case 2: _context4.next = 4; return _this2.$app.store.get('tours'); case 4: _context4.next = 6; return _this2.$app.store.get('links'); case 6: _context4.next = 8; return _this2.$app.store.get('cameras'); case 8: _context4.next = 10; return _this2.$app.store.get('billboards'); case 10: _context4.next = 12; return _this2.$app.store.get('cutModel'); case 12: _context4.next = 14; return _this2.$app.store.get('sceneDraw'); case 14: // await this.$app.store.get('filters') // await this.$app.store.get('mosaics') _this2.$app.Scene.emit('loadeddata'); logSth(_this2.$app); case 16: case "end": return _context4.stop(); } } }, _callee4); })); return function loadData() { return _ref2.apply(this, arguments); }; }(); // TRANSITIONING时loadData会造成动画卡顿 if (!(this.$app.core.get('Player').mode !== Viewmode$1.TRANSITIONING)) { _context5.next = 13; break; } _context5.next = 11; return loadData(); case 11: _context5.next = 14; break; case 13: this.$app.Camera.once('mode.afterChange', loadData); case 14: case "end": return _context5.stop(); } } }, _callee5, this); })); function loadPanos() { return _loadPanos.apply(this, arguments); } return loadPanos; }() }, { key: "initPanos", value: function initPanos(metadata) { this.startSceneRenderer(); var model = this.$app.core.get('Player').model; this.$app.core.get('ModelManager').init(); this.$app.core.get('ModelManager').addModel(model); this.firstView = new FirstView(metadata, model.panos); this.firstView.quickstart = true; } }, { key: "afterLoad", value: function afterLoad() { this.$app.core.get('SceneRenderer').scene.add(this.$app.core.get('Player').model); this.$app.core.get('Player').init(); this.$app.core.get('Player').setScene(); this.$app.core.get('DisplayController').init(); effects$1.bindEvents(this.$app.core.get('Player')); this.$app.core.get('SceneRenderer').addComponent(this.$app.core.get('Player')); automation.init(this.$app.core.get('Director'), this.$app.core.get('CameraControls'), this.$app.core.get('Player'), this.$app.core.get('ModelManager'), this.$app.core.get('SceneRenderer')); } }, { key: "startSceneRenderer", value: function startSceneRenderer() { if (this.$app.core.get('SceneRenderer').started) return; try { this.$app.core.get('SceneRenderer').start(this.$app.dom.querySelector('.player')); } catch (msg) { logger$1.error(msg.message); } // 单实例才允许VR if (this.$app.uid == 1 && this.$app.config.mobile) { VR$1.Init(this.$app.core.get('SceneRenderer'), this.$app.core.get('Player')); } } }, { key: "quickEnter", value: function () { var _quickEnter = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee6(firstView, metadata) { var _this3 = this; var control, quickstartManager; return regenerator.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: //logger.warn('Quickstart engaged. Hold on to your knickers.') //var control = this.$app.core.get('CameraControls').controls[Viewmode.PANORAMA] this.$app.core.get('CameraControls').activateControls(Viewmode$1.PANORAMA); control = this.$app.core.get('CameraControls').controls[Viewmode$1.PANORAMA]; this.$app.withComponent('QuickstartManager', this.$app.core.get('QualityManager'), this.$app.core.get('SceneRenderer').scene, this.$app.core.get('SceneRenderer').camera, control); quickstartManager = this.$app.core.get('QuickstartManager'); //quickstartManager.init(firstView, metadata) _context6.next = 6; return quickstartManager.load(firstView); case 6: this.$app.core.get('SceneRenderer').addComponent(quickstartManager); this.$app.core.get('SceneRenderer').once(SceneRendererEvents.AfterRender, function () { logger$1.info("".concat(_this3.$app.config.num, "First render after quickstart load finished.")); }); case 8: case "end": return _context6.stop(); } } }, _callee6, this); })); function quickEnter(_x2, _x3) { return _quickEnter.apply(this, arguments); } return quickEnter; }() /** * 拆分 */ }, { key: "getSplit", value: function () { var _getSplit = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee7(editType, split) { return regenerator.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: this.$app.dom.classList.add('kankan-app__split'); _context7.prev = 1; _context7.next = 4; return this.$app.resource.visions2(); case 4: _context7.next = 9; break; case 6: _context7.prev = 6; _context7.t0 = _context7["catch"](1); logger$1.warn("".concat(this.$app.config.num, "[load visions2] fail")); case 9: //splitViews由许钟文定义 if (!this.splitViews[editType]) { this.splitViews[editType] = new SplitView(this.$app, editType); } split && this.splitViews[editType].enter(); return _context7.abrupt("return", this.splitViews[editType]); case 12: case "end": return _context7.stop(); } } }, _callee7, this, [[1, 6]]); })); function getSplit(_x4, _x5) { return _getSplit.apply(this, arguments); } return getSplit; }() /** * 还原 */ }, { key: "restore", value: function restore(editType) { this.$app.dom.classList.remove('kankan-app__split'); this.splitViews[editType].leave(); } }]); return Scene; }(); }); function logSth(app) { var player = app.core.get('Player'); var tagCount = app.TagManager.tags.length; var chunkLen = player.model.chunks.length; var vertexC = player.model.chunks.reduce(function (total, chunk) { return total + chunk.geometry.attributes.position.count; }, 0); var texSizeBlock = player.model.texSizeBlock; var panoCount = player.model.panos.list.length; var videoPanoCount = player.model.panos.list.filter(function (p) { return p.hasVideo; }).length; var overlayCount = player.OverlayManager.group.children.length; var overlayVideoCount = player.OverlayManager.group.children.filter(function (e) { return e.info.type == 'video'; }).length; var views = Object.keys(player.viewLinkManager.views); var viewLinkCount = views.length; var viewPanoLinkCount = views.filter(function (e) { return player.viewLinkManager.views[e].linkType == 'pano'; }).length; console.log('%c'.concat("\u5171\u6709\u521D\u59CBchunk ".concat(chunkLen, " \u4E2A ( \u9876\u70B9\u6570 ").concat(vertexC, " )\n \u6A21\u578B\u8D34\u56FE\u5C3A\u5BF8\u662F512\u7684 ").concat(texSizeBlock, " \u500D\u6570 \n \u70ED\u70B9 ").concat(tagCount, " \u4E2A \n \u6F2B\u6E38\u70B9 ").concat(panoCount, " \u4E2A ( \u89C6\u9891\u6F2B\u6E38\u70B9 ").concat(videoPanoCount, " \u4E2A )\n overlay ").concat(overlayCount, " \u4E2A ( \u89C6\u9891\u7C7B\u578B ").concat(overlayVideoCount, " \u4E2A )\n viewLink ").concat(viewLinkCount, " \u4E2A ( pano\u7C7B\u578B ").concat(viewPanoLinkCount, " \u4E2A )\n ")), 'color:#FF4399'); } /** * 解压采用protobuf的方式压缩的文件,比如:dam,vision.modeldata */ var Deompress = { damPro: Base64.decode('bWVzc2FnZSBiaW5hcnlfbWVzaCB7CglyZXBlYXRlZCBjaHVua19zaW1wbGUgY2h1bmsgPSAxOwoJcmVwZWF0ZWQgY2h1bmtfcXVhbnRpemVkIHF1YW50aXplZF9jaHVuayA9IDI7Cn0KCi8vIERlZmluaXRpb24gb2YgdmVydGljZXM6IDNEIGNvb3JkaW5hdGVzLCBhbmQgMkQgdGV4dHVyZSBjb29yZGluYXRlcy4KbWVzc2FnZSB2ZXJ0aWNlc19zaW1wbGUgewoJcmVwZWF0ZWQgZmxvYXQgeHl6ID0gMSBbcGFja2VkPXRydWVdOyAgLy8geF8wLHlfMCx6XzAsIHhfMSx5XzEsel8xLCAuLi4KCXJlcGVhdGVkIGZsb2F0IHV2ID0gMiBbcGFja2VkPXRydWVdOyAgLy8gdV8wLHZfMCwgdV8xLHZfMSwgLi4uCn0KCi8vIEluZGV4ZXMgb2YgdmVydGljZXMgb2YgZmFjZXMKbWVzc2FnZSBmYWNlc19zaW1wbGUgewoJcmVwZWF0ZWQgdWludDMyIGZhY2VzID0gMSBbcGFja2VkPXRydWVdOyAvLyBpMDAsaTAxLGkwMiwgaTEwLGkxMSxpMTIsIC4uLgp9CgovLyBBIHNpbXBseSBlbmNvZGVkIGNodW5rLgovLyBUT0RPOiBhZGQgY2h1bmsgcHJvcGVyaXRlcyAoc3VjaCBhcyAicmVmbGVjdGl2ZSIpCm1lc3NhZ2UgY2h1bmtfc2ltcGxlIHsKCW9wdGlvbmFsIHZlcnRpY2VzX3NpbXBsZSB2ZXJ0aWNlcyA9IDE7CglvcHRpb25hbCBmYWNlc19zaW1wbGUgZmFjZXMgPSAyOwoJb3B0aW9uYWwgc3RyaW5nIGNodW5rX25hbWUgPSAzOwoJb3B0aW9uYWwgc3RyaW5nIG1hdGVyaWFsX25hbWUgPSA0Owp9CgovLyBRdWFudGl6ZWQgdmVyc2lvbnMgZm9sbG93OgptZXNzYWdlIHZlcnRpY2VzX3F1YW50aXplZCB7CglvcHRpb25hbCBmbG9hdCBxdWFudGl6YXRpb24gPSAxOwoJcmVwZWF0ZWQgZmxvYXQgdHJhbnNsYXRpb24gPSAyOwoJcmVwZWF0ZWQgc2ludDMyIHggPSAzIFtwYWNrZWQ9dHJ1ZV07CglyZXBlYXRlZCBzaW50MzIgeSA9IDQgW3BhY2tlZD10cnVlXTsKCXJlcGVhdGVkIHNpbnQzMiB6ID0gNSBbcGFja2VkPXRydWVdOwp9CgptZXNzYWdlIHV2X3F1YW50aXplZCB7CglvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CglvcHRpb25hbCBmbG9hdCBxdWFudGl6YXRpb24gPSAyOwoJcmVwZWF0ZWQgc2ludDMyIHUgPSAzIFtwYWNrZWQ9dHJ1ZV07CglyZXBlYXRlZCBzaW50MzIgdiA9IDQgW3BhY2tlZD10cnVlXTsKfQoKLy8gSW5kZXhlcyBvZiB2ZXJ0aWNlcyBvZiBmYWNlcwptZXNzYWdlIGZhY2VzX2NvbXByZXNzZWQgewoJcmVwZWF0ZWQgc2ludDMyIGZhY2VzID0gMSBbcGFja2VkPXRydWVdOyAvLyBpMDAsaTAxLGkwMiwgaTEwLGkxMSxpMTIsIC4uLgp9CgptZXNzYWdlIGNodW5rX3F1YW50aXplZCB7CglvcHRpb25hbCBzdHJpbmcgY2h1bmtfbmFtZSA9IDE7CglvcHRpb25hbCBzdHJpbmcgbWF0ZXJpYWxfbmFtZSA9IDI7CglvcHRpb25hbCB2ZXJ0aWNlc19xdWFudGl6ZWQgdmVydGljZXMgPSAzOwoJcmVwZWF0ZWQgdXZfcXVhbnRpemVkIHV2cyA9IDQ7CglvcHRpb25hbCBmYWNlc19zaW1wbGUgZmFjZXMgPSA1Owp9Cg=='), visionmodeldataPro: Base64.decode( //'Ly8KLy8gUHJvdG9jb2wgQnVmZmVyIGZvciBwdWNrIHZpc2liaWxpdHkgYW5kIHJlbGF0ZWQgZGF0YQovLwovL3BhY2thZ2UgZW9zLnN0b3JhZ2U7CgovLyBpbXBvcnQgImVvcy9pbmZyYS9jb21tb24ucHJvdG8iOwovLyBUaGUgZm9sbG93aW5nIHdlcmUgbWFudWFsbHkgZXh0cmFjdGVkIGhlcmUsIEpTIGRvZXMgbm90IGxpa2UgcHJvdG9idWYgaW1wb3J0cwoKbWVzc2FnZSBBZmZpbmUzZiB7CglvcHRpb25hbCBRdWF0ZXJuaW9uZiByb3RhdGlvbiA9IDE7CglvcHRpb25hbCBWZWN0b3IzZiB0cmFuc2xhdGlvbiA9IDI7Cn0KCm1lc3NhZ2UgUXVhdGVybmlvbmYgewoJb3B0aW9uYWwgZmxvYXQgdyA9IDE7CglvcHRpb25hbCBmbG9hdCB4ID0gMjsKCW9wdGlvbmFsIGZsb2F0IHkgPSAzOwoJb3B0aW9uYWwgZmxvYXQgeiA9IDQ7Cn0KCm1lc3NhZ2UgVmVjdG9yM2YgewoJb3B0aW9uYWwgZmxvYXQgeCA9IDE7CglvcHRpb25hbCBmbG9hdCB5ID0gMjsKCW9wdGlvbmFsIGZsb2F0IHogPSAzOwp9CgovLwovLyBPbmUgc3dlZXAgLyBwYW5vCi8vCm1lc3NhZ2UgU3dlZXBMb2NhdGlvbiB7CglvcHRpb25hbCBieXRlcyB1dWlkID0gMTsgIC8qIHV1aWQgKi8KCW9wdGlvbmFsIEFmZmluZTNmIHBvc2UgPSAyOyAgLyogY2FtZXJhIHBvc2UgKHgsIHkseikgaW4gbWV0ZXIgYW5kIGEgcXVhdGVybmlvbiovCglvcHRpb25hbCBWZWN0b3IzZiBwdWNrID0gMzsgIC8qIHB1Y2sgbG9jYXRpb24gLSB4IGFueSBpcyBnZW5lcmFsbHkgdGhlIHNhbWUgYXMgcG9zZSwgeiBpcyB0aGUgaGVpZ2h0IG9mIHRoZSBjbG9zZXN0IGZsb29yIHVuZGVyIHRoZSBjYW1lcmEgKi8KCW9wdGlvbmFsIGludDMyIGdyb3VwID0gNDsgIC8qIGZsb29yIGluZGV4ICovCglvcHRpb25hbCBpbnQzMiBzdWJncm91cCA9IDU7ICAvKiByb29tIGluZGV4ICovCglyZXBlYXRlZCBpbnQzMiB2aXNpYmxlcyA9IDY7ICAvKiBsaXN0IG9mIGluZGljZXMgdG8gYWxsIHB1Y2tzIHZpc2libGUgZnJvbSB0aGlzIHB1Y2sgKi8KCXJlcGVhdGVkIGZsb2F0IHNjb3JlcyA9IDc7IC8qIHVzZWQgYXMgcGFydCBvZiBzY29yaW5nIGZ1bmN0aW9uIGZvciBkZXRlcm1pbmluZyB3aGljaCBwdWNrIHRvIGdvIHRvIG5leHQgKi8KfQoKLy8KLy8gQWxsIHB1Y2tzIGluIGEgbW9kZWwuIFB1Y2tzIGFyZSBzdG9yZWQgaW4gc2Nhbm5pbmcgb3JkZXIuCi8vCm1lc3NhZ2UgTmF2aWdhdGlvbkluZm8gewoJcmVwZWF0ZWQgU3dlZXBMb2NhdGlvbiBzd2VlcExvY2F0aW9ucyA9IDE7Cn0K' 'Ly8KLy8gUHJvdG9jb2wgQnVmZmVyIGZvciBwdWNrIHZpc2liaWxpdHkgYW5kIHJlbGF0ZWQgZGF0YQovLwovL3BhY2thZ2UgZW9zLnN0b3JhZ2U7CgovLyBpbXBvcnQgImVvcy9pbmZyYS9jb21tb24ucHJvdG8iOwovLyBUaGUgZm9sbG93aW5nIHdlcmUgbWFudWFsbHkgZXh0cmFjdGVkIGhlcmUsIEpTIGRvZXMgbm90IGxpa2UgcHJvdG9idWYgaW1wb3J0cwoKbWVzc2FnZSBBZmZpbmUzZiB7CglvcHRpb25hbCBRdWF0ZXJuaW9uZiByb3RhdGlvbiA9IDE7CglvcHRpb25hbCBWZWN0b3IzZiB0cmFuc2xhdGlvbiA9IDI7Cn0KCm1lc3NhZ2UgUXVhdGVybmlvbmYgewoJb3B0aW9uYWwgZmxvYXQgdyA9IDE7CglvcHRpb25hbCBmbG9hdCB4ID0gMjsKCW9wdGlvbmFsIGZsb2F0IHkgPSAzOwoJb3B0aW9uYWwgZmxvYXQgeiA9IDQ7Cn0KCm1lc3NhZ2UgVmVjdG9yM2YgewoJb3B0aW9uYWwgZmxvYXQgeCA9IDE7CglvcHRpb25hbCBmbG9hdCB5ID0gMjsKCW9wdGlvbmFsIGZsb2F0IHogPSAzOwp9CgovLwovLyBPbmUgc3dlZXAgLyBwYW5vCi8vCm1lc3NhZ2UgU3dlZXBMb2NhdGlvbiB7CglvcHRpb25hbCBieXRlcyB1dWlkID0gMTsgIC8qIHV1aWQgKi8KCW9wdGlvbmFsIEFmZmluZTNmIHBvc2UgPSAyOyAgLyogY2FtZXJhIHBvc2UgKHgsIHkseikgaW4gbWV0ZXIgYW5kIGEgcXVhdGVybmlvbiovCglvcHRpb25hbCBWZWN0b3IzZiBwdWNrID0gMzsgIC8qIHB1Y2sgbG9jYXRpb24gLSB4IGFueSBpcyBnZW5lcmFsbHkgdGhlIHNhbWUgYXMgcG9zZSwgeiBpcyB0aGUgaGVpZ2h0IG9mIHRoZSBjbG9zZXN0IGZsb29yIHVuZGVyIHRoZSBjYW1lcmEgKi8KCW9wdGlvbmFsIGludDMyIGdyb3VwID0gNDsgIC8qIGZsb29yIGluZGV4ICovCglvcHRpb25hbCBpbnQzMiBzdWJncm91cCA9IDU7ICAvKiByb29tIGluZGV4ICovCglyZXBlYXRlZCBpbnQzMiB2aXNpYmxlcyA9IDY7ICAvKiBsaXN0IG9mIGluZGljZXMgdG8gYWxsIHB1Y2tzIHZpc2libGUgZnJvbSB0aGlzIHB1Y2sgKi8KCXJlcGVhdGVkIGludDMyIHZpc2libGVzMiA9IDc7IAoJcmVwZWF0ZWQgaW50MzIgdmlzaWJsZXMzID0gODsKfQoKLy8KLy8gQWxsIHB1Y2tzIGluIGEgbW9kZWwuIFB1Y2tzIGFyZSBzdG9yZWQgaW4gc2Nhbm5pbmcgb3JkZXIuCi8vCm1lc3NhZ2UgTmF2aWdhdGlvbkluZm8gewoJcmVwZWF0ZWQgU3dlZXBMb2NhdGlvbiBzd2VlcExvY2F0aW9ucyA9IDE7Cn0='), decoderMesh() { var builderMesh = dcodeIO.ProtoBuf.loadProto(this.damPro); return builderMesh.build('binary_mesh'); }, decoderModeldata() { var builderModeldata = dcodeIO.ProtoBuf.loadProto(this.visionmodeldataPro); return builderModeldata.build('NavigationInfo'); }, decompressMesh(content) { var data = null; try { data = this.decoderMesh().decode(content); } catch (k) { logger$1.error('failed parsing proto for .dam'); return null; } return data; }, decompressModeldata(content) { var data = null; try { data = this.decoderModeldata().decode(content); } catch (k) { logger$1.error('failed parsing proto for .modeldata'); return null; } return data; } }; function _createSuper$G(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$G(); 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 _isNativeReflectConstruct$G() { 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; } } /* meshObject = { geometry: i, textureName: e.material_name, name: e.chunk_name, meshUrl: t } */ //模型会分成多个chunk var Chunk = /*#__PURE__*/function (_THREE$Mesh) { _inherits(Chunk, _THREE$Mesh); var _super = _createSuper$G(Chunk); function Chunk(meshObject) { var _this; _classCallCheck(this, Chunk); var materialInside = new ModelTextureMaterial({ side: THREE.DoubleSide }); _this = _super.call(this, meshObject.geometry, materialInside); _this.materialInside = materialInside; var uniform = THREE.UniformsUtils.clone(shaders.modelOutside.uniforms); _this.materialOutside = new THREE.RawShaderMaterial({ fragmentShader: shaders.modelOutside.fragmentShader, vertexShader: shaders.modelOutside.vertexShader, uniforms: uniform, side: THREE.FrontSide, name: 'chunkOut', transparent: true //只有设置了透明才能使用renderOrder 和 depthTest }); _this.materialOutside.extraValues = {}; //xzw add _this.name = meshObject.name || ''; _this.meshUrl = meshObject.meshUrl; _this.tileId = meshObject.tileId; if (meshObject.tileId) { _this.materialInside.defines['Is3dTiles'] = 1; _this.materialOutside.defines['Is3dTiles'] = 1; } if (meshObject.textureName) _this.textureName = meshObject.textureName;else _this.setTextureMap(meshObject.texture); _this.isChunk = true; return _this; } _createClass(Chunk, [{ key: "setTextureMap", value: function setTextureMap(texture) { this.materialInside.uniforms.map.value = texture; this.materialOutside.uniforms.map.value = texture; } }, { key: "setMode", value: function setMode(mode) { var modeTran = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '-'; //mode可能是transitioning /* let getExtValue = (name)=>{//因为opacity两个材质都有 ,在其他地方设置后会被这里覆盖 return material.extraValues && material.extraValues[name] != void 0 ? material.extraValues[name] : this.material.uniforms[name].value } */ modeTran.split('-')[0]; modeTran.split('-')[1]; var material = this.materialInside; if ((mode === Viewmode$1.DOLLHOUSE || mode === Viewmode$1.FLOORPLAN) && !(mode == 'transitioning' && modeTran.includes(Viewmode$1.PANORAMA))) { //xzw改:当dollhouse和floorplan转换时也用outside. 飞出飞入时都是materialInside material = this.materialOutside; } if (mode === Viewmode$1.PANORAMA) { material.side = THREE.DoubleSide; // material.side = THREE.BackSide } else { material.side = THREE.FrontSide; } if (ModelSide.side !== null) { material.side = ModelSide.side; } //material.transparent = this.material.transparent //material.uniforms.opacity.value = getExtValue('opacity') this.material = material; } }]); return Chunk; }(THREE.Mesh); /* * @Author: Rindy * @Date: 2021-05-13 17:27:29 * @LastEditors: Rindy * @LastEditTime: 2021-05-27 16:30:31 * @Description: Process */ var Process = { //读入dam文件后,需要进行处理才能转换成mesh,方法如下: //loaddata和e一样 convertProtobufToSceneObject: function convertProtobufToSceneObject(app, loaddata, prefixTexture) { // function getMaterial(imgUrl) { // imgUrl in materails || (materails[imgUrl] = new THREE.MeshBasicMaterial({ // map: THREE.ImageUtils.loadTexture(imgUrl) // })); // return materails[imgUrl]; // } function getMesh(chunk) { var geometry = new THREE.BufferGeometry(); geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(chunk.vertices.xyz, 0, 3), 3)); chunk.vertices.uv.length > 0 && geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(chunk.vertices.uv, 0, 2), 2)); geometry.setIndex(new THREE.BufferAttribute(new Uint32Array(chunk.faces.faces, 0, 1), 1)); geometry.applyMatrix4(matrix); geometry.computeBoundingBox(); var meshUrl = settings$3.job + settings$3.format; if (config$4.model.name) { meshUrl = config$4.model.name; } return new Chunk({ geometry: geometry, textureName: chunk.material_name, name: chunk.chunk_name, meshUrl: app.resource.getViewImagesURL(meshUrl) //app.resource.getViewImagesURL(settings.job + settings.format), }); // var mesh = new THREE.Mesh(geometry,getMaterial(prefixTexture + chunk.material_name)); // mesh.name = chunk.chunk_name; // logger.warn("No chunks in damfile..."); // return mesh; } if (0 == loaddata.chunk.length) { logger$1.warn('No chunks in damfile...'); return null; } var matrix = new THREE.Matrix4(); matrix.set(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1); //var materails = {}; return loaddata.chunk.map(getMesh); }, //vision.modeldata的数据不能直接用,需要转换,方法如下: visionModeldata: function visionModeldata(loaddata) { loaddata.sweepLocations.forEach(function (s) { //许钟文 add 将某些旧场景visibles3为[]的改成至少包含visibles的所有 s.visibles3 = s.visibles3 || []; s.visibles.forEach(function (v) { s.visibles3.indexOf(v) == -1 && s.visibles3.push(v); }); }); //------有的场景非4dkk拍摄、手动上传的,visibles2可能都是[],那么就转化为null,这样flying时才会有模型 by许钟文 var hasVisibles2; for (var len = loaddata.sweepLocations.length, ss = 0; ss < len; ss++) { var v = loaddata.sweepLocations[ss].visibles2 && loaddata.sweepLocations[ss].visibles2.length || 0; if (v > 0) { hasVisibles2 = true; break; } } if (!hasVisibles2) { loaddata.sweepLocations.forEach(function (s) { s.visibles2 = null; }); logger$1.info('检测到疑似没有noblock数据,应该是手动上传,block置空'); } //------------------- var modeldata = loaddata.sweepLocations.map(function (n, i) { return { uuid: n.uuid.toUTF8().replace(/-/g, ''), position: { x: n.pose.translation.x, y: n.pose.translation.y, z: n.pose.translation.z }, quaternion: { x: n.pose.rotation.x, y: n.pose.rotation.y, z: n.pose.rotation.z, w: n.pose.rotation.w }, puck: { x: n.puck.x, y: n.puck.y, z: n.puck.z }, //floor: n.group, alignmentType: n.alignment_type, neighbours: n.visibles3 || n.visibles, noBlocks: n.visibles2, // 过渡时出模型的点 seeMarkers: n.visibles, //可以看见marker及热点的点 group: n.group, subgroup: n.subgroup, index: i //add }; }.bind(this)).map(function (n) { n.position = this.convertVisionVector(n.position); n.quaternion = this.convertVisionQuaternion(n.quaternion); n.puck = this.convertVisionVector(n.puck); return n; }.bind(this)); // modeldata.forEach(function (n) { // n.neighbours = n.neighbours.filter((o) => o >= 0 ) // n.seeMarkers = n.seeMarkers.filter((o) => o >= 0 ) // }) modeldata.forEach(function (n) { n.neighbours = n.neighbours.filter(function (o) { return modeldata[o]; }).map(function (o) { return modeldata[o].uuid; }); }); modeldata.forEach(function (t) { //xzw if (t.noBlocks) t.noBlocks = t.noBlocks.map(function (t) { return modeldata[t].uuid; }); }); modeldata.forEach(function (t) { //xzw if (t.seeMarkers) t.seeMarkers = t.seeMarkers.filter(function (t) { return modeldata[t]; }).map(function (t) { return modeldata[t].uuid; }); }); return modeldata; //def.resolve(m); }, panos: function panos($app, modeldata, metadata) { var panoramaCollection = $app.core.get('Player').model.panos; var panoVideoRenderer = $app.core.get('PanoVideoRenderer'); var panoVideos = panoVideoRenderer.videosInfo.videos; if ($app.config.view) { // 展示页仅加载可视点位球幕视频 var visiblePanoVideos = new Map(); panoramaCollection.extend(modeldata.map(function (modeldataitem) { if (modeldataitem.neighbours.length) { var video = panoVideos.get(modeldataitem.uuid); video && visiblePanoVideos.set(modeldataitem.uuid, video); return new Panorama($app, modeldataitem.uuid, modeldataitem, video); } else { return new Panorama($app, modeldataitem.uuid, modeldataitem, null); } }.bind(this)), 'id'); panoVideoRenderer.initVideoPlayer($app.dom, visiblePanoVideos); } else { // 编辑页加载所有点位球幕视频 panoramaCollection.extend(modeldata.map(function (modeldataitem) { return new Panorama($app, modeldataitem.uuid, modeldataitem, panoVideos.get(modeldataitem.uuid)); }.bind(this)), 'id'); panoVideoRenderer.initVideoPlayer($app.dom, panoVideos); } //forEach是PanoramaCollection的函数 //listItem是Panorama的一个对象 panoramaCollection.forEach(function (listItem) { if (listItem.neighbourUUIDs) { listItem.neighbourUUIDs.forEach(function (uuid) { //get是PanoramaCollection的函数 var pano = panoramaCollection.get(uuid); pano && panoramaCollection.setNeighbour(listItem, pano, !0); }); // 点位隐藏时neighbourPanos为undefined,会被赋默认值,导致点位隐藏不可用,所以取空对象 listItem.neighbourPanos = panoramaCollection.getNeighbours(listItem) || {}; } }); if (0 === panoramaCollection.length) { logger$1.warn('Model has no panos, turning off inside mode'); } return panoramaCollection; }, panosAssist(modeldata, $app) { //xzw add return modeldata.map(function (data) { data.panoType = 'assistant'; //isAssist = true data.tiled = false; return new Panorama($app, data.uuid, data); }.bind(this)); }, //变换vision.modeldata里拍摄点的坐标 convertVisionVector: function convertVisionVector(position) { return new THREE.Vector3(position.x, position.z, -position.y); }, //变换vision.modeldata里拍摄点的旋转角度quaternion convertVisionQuaternion: function convertVisionQuaternion(quaternion) { return new THREE.Quaternion(quaternion.x, quaternion.z, -quaternion.y, quaternion.w).multiply(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(90))); }, //变换初始点的坐标 convertWorkshopVector: function convertWorkshopVector(position) { return new THREE.Vector3(-position.x, position.y, position.z); }, //变换初始点的quaternion convertWorkshopQuaternion: function convertWorkshopQuaternion(quaternion) { return new THREE.Quaternion(-quaternion.x, quaternion.y, quaternion.z, -quaternion.w).multiply(new THREE.Quaternion(Math.sqrt(2) / 2, Math.sqrt(2) / 2, 0, 0)); } }; var Chunks = { parseIdsFromChunkName(chunkName, floorRoomIds) { floorRoomIds.floorId = this.parseFloor(chunkName); floorRoomIds.roomId = this.parseRoom(chunkName); }, parseFloor(chunkName) { var floorInfo = chunkName.match(/_group([0-9]+)/); if (!floorInfo) return 0; try { return parseInt(floorInfo[1], 10); } catch (msg) { logger.warn('Non-int value "' + floorInfo[1] + '" for mesh group, defaulting to floor 0'); return 0; } }, parseRoom(chunkName) { var roomInfo = chunkName.match(/_sub([0-9]+)/); if (!roomInfo) return -1; try { return parseInt(roomInfo[1], 10); } catch (msg) { logger.warn('Non-int value "' + roomInfo[1] + '" for mesh subgroup, defaulting to subgroup 0'); return 0; } } }; var ModelTextureLoader = { load(model, textures, resource) { return new Promise(function (resolve) { function addTexture(flag, texture) { if (!flag) { textures.push(texture); p++; p === textureLen && resolve(); } } if (!model.chunks[0] || !model.chunks[0].meshUrl) { return resolve(); } var textureLen = common.countUnique(model.chunks.map(function (chunk) { return chunk.textureName; })); var modelVersion = ''; if (model.chunks[0].meshUrl.indexOf('_50k') !== -1) ; var textureType = 'low'; if (settings$3.minimalMemoryMode && 'high' === textureType) { if (browser$1.detectSamsungS6()) { logger$1.warn('Galaxy S6 cannot handle large textures, turning down quality.'); textureType = 'low'; } else if (textureLen > settings$3.maxMobileTextures) { logger$1.warn('Model probably too large for mobile, turning down quality.'); textureType = 'low'; } } var p = 0; var textureFoldName = model.data.job.uuid + modelVersion + '_50k_texture_jpg_' + 'high1' + '/'; if (config$4.model.name) { textureFoldName = config$4.model.name.replace('.dam', '_texture/'); } model.chunks.forEach(function (chunk) { if (!chunk.material.map && chunk.textureName) { var textureUrl = model.urls.get(textureFoldName + chunk.textureName); chunk.setTextureMap(texture.load(textureUrl, addTexture.bind(this, texture.isLoaded(textureUrl)))); } }); }); } }; function _defineProperty$1(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; } function _AwaitValue(value) { this.wrapped = value; } function _awaitAsyncGenerator(value) { return new _AwaitValue(value); } function AsyncGenerator(gen) { var front, back; function send(key, arg) { return new Promise(function (resolve, reject) { var request = { key: key, arg: arg, resolve: resolve, reject: reject, next: null }; if (back) { back = back.next = request; } else { front = back = request; resume(key, arg); } }); } function resume(key, arg) { try { var result = gen[key](arg); var value = result.value; var wrappedAwait = value instanceof _AwaitValue; Promise.resolve(wrappedAwait ? value.wrapped : value).then(function (arg) { if (wrappedAwait) { resume(key === "return" ? "return" : "next", arg); return; } settle(result.done ? "return" : "normal", arg); }, function (err) { resume("throw", err); }); } catch (err) { settle("throw", err); } } function settle(type, value) { switch (type) { case "return": front.resolve({ value: value, done: true }); break; case "throw": front.reject(value); break; default: front.resolve({ value: value, done: false }); break; } front = front.next; if (front) { resume(front.key, front.arg); } else { back = null; } } this._invoke = send; if (typeof gen["return"] !== "function") { this["return"] = undefined; } } AsyncGenerator.prototype[typeof Symbol === "function" && Symbol.asyncIterator || "@@asyncIterator"] = function () { return this; }; AsyncGenerator.prototype.next = function (arg) { return this._invoke("next", arg); }; AsyncGenerator.prototype["throw"] = function (arg) { return this._invoke("throw", arg); }; AsyncGenerator.prototype["return"] = function (arg) { return this._invoke("return", arg); }; function _wrapAsyncGenerator(fn) { return function () { return new AsyncGenerator(fn.apply(this, arguments)); }; } function _asyncIterator(iterable) { var method; if (typeof Symbol !== "undefined") { if (Symbol.asyncIterator) method = iterable[Symbol.asyncIterator]; if (method == null && Symbol.iterator) method = iterable[Symbol.iterator]; } if (method == null) method = iterable["@@asyncIterator"]; if (method == null) method = iterable["@@iterator"]; if (method == null) throw new TypeError("Object is not async iterable"); return method.call(iterable); } /** * @author Deepkolos / https://github.com/deepkolos */ var WorkerPool$1 = /*#__PURE__*/function () { function WorkerPool() { var pool = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 4; _classCallCheck(this, WorkerPool); this.pool = pool; this.queue = []; this.workers = []; this.workersResolve = []; this.workerStatus = 0; } _createClass(WorkerPool, [{ key: "_initWorker", value: function _initWorker(workerId) { if (!this.workers[workerId]) { var worker = this.workerCreator(); worker.addEventListener('message', this._onMessage.bind(this, workerId)); this.workers[workerId] = worker; } } }, { key: "_getIdleWorker", value: function _getIdleWorker() { for (var i = 0; i < this.pool; i++) { if (!(this.workerStatus & 1 << i)) return i; } return -1; } }, { key: "_onMessage", value: function _onMessage(workerId, msg) { var resolve = this.workersResolve[workerId]; resolve && resolve(msg); if (this.queue.length) { var _this$queue$shift = this.queue.shift(), _resolve = _this$queue$shift.resolve, _msg = _this$queue$shift.msg, transfer = _this$queue$shift.transfer; this.workersResolve[workerId] = _resolve; this.workers[workerId].postMessage(_msg, transfer); } else { this.workerStatus ^= 1 << workerId; } } }, { key: "setWorkerCreator", value: function setWorkerCreator(workerCreator) { this.workerCreator = workerCreator; } }, { key: "setWorkerLimit", value: function setWorkerLimit(pool) { this.pool = pool; } }, { key: "postMessage", value: function postMessage(msg, transfer) { var _this = this; return new Promise(function (resolve) { var workerId = _this._getIdleWorker(); if (workerId !== -1) { _this._initWorker(workerId); _this.workerStatus |= 1 << workerId; _this.workersResolve[workerId] = resolve; _this.workers[workerId].postMessage(msg, transfer); } else { _this.queue.push({ resolve, msg, transfer }); } }); } }, { key: "dispose", value: function dispose() { this.workers.forEach(function (worker) { return worker.terminate(); }); this.workersResolve.length = 0; this.workers.length = 0; this.queue.length = 0; this.workerStatus = 0; } }]); return WorkerPool; }(); var t = 0, n$2 = 2, p$1 = 1, x$1 = 2, nt = 0, ct = 9, gt = 15, yt = 16, dt = 22, Ot = 37, Ft = 43, $t = 76, se = 83, pe = 97, xe = 100, de = 103, Ae = 109; var Si = function Si() { _classCallCheck(this, Si); this.vkFormat = 0, this.typeSize = 1, this.pixelWidth = 0, this.pixelHeight = 0, this.pixelDepth = 0, this.layerCount = 0, this.faceCount = 1, this.supercompressionScheme = 0, this.levels = [], this.dataFormatDescriptor = [{ vendorId: 0, descriptorType: 0, descriptorBlockSize: 0, versionNumber: 2, colorModel: 0, colorPrimaries: 1, transferFunction: 2, flags: 0, texelBlockDimension: [0, 0, 0, 0], bytesPlane: [0, 0, 0, 0, 0, 0, 0, 0], samples: [] }], this.keyValue = {}, this.globalData = null; }; var Ii = /*#__PURE__*/function () { function Ii(t, e, n, i) { _classCallCheck(this, Ii); this._dataView = new DataView(t.buffer, t.byteOffset + e, n), this._littleEndian = i, this._offset = 0; } _createClass(Ii, [{ key: "_nextUint8", value: function _nextUint8() { var t = this._dataView.getUint8(this._offset); return this._offset += 1, t; } }, { key: "_nextUint16", value: function _nextUint16() { var t = this._dataView.getUint16(this._offset, this._littleEndian); return this._offset += 2, t; } }, { key: "_nextUint32", value: function _nextUint32() { var t = this._dataView.getUint32(this._offset, this._littleEndian); return this._offset += 4, t; } }, { key: "_nextUint64", value: function _nextUint64() { var t = this._dataView.getUint32(this._offset, this._littleEndian) + Math.pow(2, 32) * this._dataView.getUint32(this._offset + 4, this._littleEndian); return this._offset += 8, t; } }, { key: "_nextInt32", value: function _nextInt32() { var t = this._dataView.getInt32(this._offset, this._littleEndian); return this._offset += 4, t; } }, { key: "_skip", value: function _skip(t) { return this._offset += t, this; } }, { key: "_scan", value: function _scan(t) { var e = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var n = this._offset; var i = 0; for (; this._dataView.getUint8(this._offset) !== e && i < t;) { i++, this._offset++; } return i < t && this._offset++, new Uint8Array(this._dataView.buffer, this._dataView.byteOffset + n, i); } }]); return Ii; }(); var Ti = [171, 75, 84, 88, 32, 50, 48, 187, 13, 10, 26, 10]; function Ei(t) { return 'undefined' != typeof TextDecoder ? new TextDecoder().decode(t) : Buffer.from(t).toString('utf8'); } function Pi(t) { var e = new Uint8Array(t.buffer, t.byteOffset, Ti.length); if (e[0] !== Ti[0] || e[1] !== Ti[1] || e[2] !== Ti[2] || e[3] !== Ti[3] || e[4] !== Ti[4] || e[5] !== Ti[5] || e[6] !== Ti[6] || e[7] !== Ti[7] || e[8] !== Ti[8] || e[9] !== Ti[9] || e[10] !== Ti[10] || e[11] !== Ti[11]) throw new Error('Missing KTX 2.0 identifier.'); var n = new Si(), i = 17 * Uint32Array.BYTES_PER_ELEMENT, s = new Ii(t, Ti.length, i, !0); n.vkFormat = s._nextUint32(), n.typeSize = s._nextUint32(), n.pixelWidth = s._nextUint32(), n.pixelHeight = s._nextUint32(), n.pixelDepth = s._nextUint32(), n.layerCount = s._nextUint32(), n.faceCount = s._nextUint32(); var a = s._nextUint32(); n.supercompressionScheme = s._nextUint32(); var r = s._nextUint32(), o = s._nextUint32(), l = s._nextUint32(), f = s._nextUint32(), U = s._nextUint64(), c = s._nextUint64(), h = new Ii(t, Ti.length + i, 3 * a * 8, !0); for (var _e3 = 0; _e3 < a; _e3++) { n.levels.push({ levelData: new Uint8Array(t.buffer, t.byteOffset + h._nextUint64(), h._nextUint64()), uncompressedByteLength: h._nextUint64() }); } var _ = new Ii(t, r, o, !0), p = { vendorId: _._skip(4)._nextUint16(), descriptorType: _._nextUint16(), versionNumber: _._nextUint16(), descriptorBlockSize: _._nextUint16(), colorModel: _._nextUint8(), colorPrimaries: _._nextUint8(), transferFunction: _._nextUint8(), flags: _._nextUint8(), texelBlockDimension: [_._nextUint8(), _._nextUint8(), _._nextUint8(), _._nextUint8()], bytesPlane: [_._nextUint8(), _._nextUint8(), _._nextUint8(), _._nextUint8(), _._nextUint8(), _._nextUint8(), _._nextUint8(), _._nextUint8()], samples: [] }, g = (p.descriptorBlockSize / 4 - 6) / 4; for (var _t2 = 0; _t2 < g; _t2++) { var _e4 = { bitOffset: _._nextUint16(), bitLength: _._nextUint8(), channelType: _._nextUint8(), samplePosition: [_._nextUint8(), _._nextUint8(), _._nextUint8(), _._nextUint8()], sampleLower: -Infinity, sampleUpper: Infinity }; 64 & _e4.channelType ? (_e4.sampleLower = _._nextInt32(), _e4.sampleUpper = _._nextInt32()) : (_e4.sampleLower = _._nextUint32(), _e4.sampleUpper = _._nextUint32()), p.samples[_t2] = _e4; } n.dataFormatDescriptor.length = 0, n.dataFormatDescriptor.push(p); var y = new Ii(t, l, f, !0); for (; y._offset < f;) { var _t3 = y._nextUint32(), _e5 = y._scan(_t3), _i2 = Ei(_e5), _s = y._scan(_t3 - _e5.byteLength); n.keyValue[_i2] = _i2.match(/^ktx/i) ? Ei(_s) : _s, y._offset % 4 && y._skip(4 - y._offset % 4); } if (c <= 0) return n; var x = new Ii(t, U, c, !0), u = x._nextUint16(), b = x._nextUint16(), d = x._nextUint32(), m = x._nextUint32(), w = x._nextUint32(), D = x._nextUint32(), B = []; for (var _t4 = 0; _t4 < a; _t4++) { B.push({ imageFlags: x._nextUint32(), rgbSliceByteOffset: x._nextUint32(), rgbSliceByteLength: x._nextUint32(), alphaSliceByteOffset: x._nextUint32(), alphaSliceByteLength: x._nextUint32() }); } var L = U + x._offset, A = L + d, k = A + m, v = k + w, S = new Uint8Array(t.buffer, t.byteOffset + L, d), I = new Uint8Array(t.buffer, t.byteOffset + A, m), O = new Uint8Array(t.buffer, t.byteOffset + k, w), T = new Uint8Array(t.buffer, t.byteOffset + v, D); return n.globalData = { endpointCount: u, selectorCount: b, imageDescs: B, endpointsData: S, selectorsData: I, tablesData: O, extendedData: T }, n; } var A$1, I$1, B$1; var g$1 = { env: { emscripten_notify_memory_growth: function emscripten_notify_memory_growth(A) { B$1 = new Uint8Array(I$1.exports.memory.buffer); } } }; var Q = /*#__PURE__*/function () { function Q() { _classCallCheck(this, Q); } _createClass(Q, [{ key: "init", value: function init() { return A$1 || (A$1 = 'undefined' != typeof fetch ? fetch('data:application/wasm;base64,' + C).then(function (A) { return A.arrayBuffer(); }).then(function (A) { return WebAssembly.instantiate(A, g$1); }).then(this._init) : WebAssembly.instantiate(Buffer.from(C, 'base64'), g$1).then(this._init), A$1); } }, { key: "_init", value: function _init(A) { I$1 = A.instance, g$1.env.emscripten_notify_memory_growth(0); } }, { key: "decode", value: function decode(A) { var g = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (!I$1) throw new Error('ZSTDDecoder: Await .init() before decoding.'); var _Q = A.byteLength, C = I$1.exports.malloc(_Q); B$1.set(A, C), g = g || Number(I$1.exports.ZSTD_findDecompressedSize(C, _Q)); var E = I$1.exports.malloc(g), i = I$1.exports.ZSTD_decompress(E, g, C, _Q), D = B$1.slice(E, E + i); return I$1.exports.free(C), I$1.exports.free(E), D; } }]); return Q; }(); var C = 'AGFzbQEAAAABpQEVYAF/AX9gAn9/AGADf39/AX9gBX9/f39/AX9gAX8AYAJ/fwF/YAR/f39/AX9gA39/fwBgBn9/f39/fwF/YAd/f39/f39/AX9gAn9/AX5gAn5+AX5gAABgBX9/f39/AGAGf39/f39/AGAIf39/f39/f38AYAl/f39/f39/f38AYAABf2AIf39/f39/f38Bf2ANf39/f39/f39/f39/fwF/YAF/AX4CJwEDZW52H2Vtc2NyaXB0ZW5fbm90aWZ5X21lbW9yeV9ncm93dGgABANpaAEFAAAFAgEFCwACAQABAgIFBQcAAwABDgsBAQcAEhMHAAUBDAQEAAANBwQCAgYCBAgDAwMDBgEACQkHBgICAAYGAgQUBwYGAwIGAAMCAQgBBwUGCgoEEQAEBAEIAwgDBQgDEA8IAAcABAUBcAECAgUEAQCAAgYJAX8BQaCgwAILB2AHBm1lbW9yeQIABm1hbGxvYwAoBGZyZWUAJgxaU1REX2lzRXJyb3IAaBlaU1REX2ZpbmREZWNvbXByZXNzZWRTaXplAFQPWlNURF9kZWNvbXByZXNzAEoGX3N0YXJ0ACQJBwEAQQELASQKussBaA8AIAAgACgCBCABajYCBAsZACAAKAIAIAAoAgRBH3F0QQAgAWtBH3F2CwgAIABBiH9LC34BBH9BAyEBIAAoAgQiA0EgTQRAIAAoAggiASAAKAIQTwRAIAAQDQ8LIAAoAgwiAiABRgRAQQFBAiADQSBJGw8LIAAgASABIAJrIANBA3YiBCABIARrIAJJIgEbIgJrIgQ2AgggACADIAJBA3RrNgIEIAAgBCgAADYCAAsgAQsUAQF/IAAgARACIQIgACABEAEgAgv3AQECfyACRQRAIABCADcCACAAQQA2AhAgAEIANwIIQbh/DwsgACABNgIMIAAgAUEEajYCECACQQRPBEAgACABIAJqIgFBfGoiAzYCCCAAIAMoAAA2AgAgAUF/ai0AACIBBEAgAEEIIAEQFGs2AgQgAg8LIABBADYCBEF/DwsgACABNgIIIAAgAS0AACIDNgIAIAJBfmoiBEEBTQRAIARBAWtFBEAgACABLQACQRB0IANyIgM2AgALIAAgAS0AAUEIdCADajYCAAsgASACakF/ai0AACIBRQRAIABBADYCBEFsDwsgAEEoIAEQFCACQQN0ams2AgQgAgsWACAAIAEpAAA3AAAgACABKQAINwAICy8BAX8gAUECdEGgHWooAgAgACgCAEEgIAEgACgCBGprQR9xdnEhAiAAIAEQASACCyEAIAFCz9bTvtLHq9lCfiAAfEIfiUKHla+vmLbem55/fgsdAQF/IAAoAgggACgCDEYEfyAAKAIEQSBGBUEACwuCBAEDfyACQYDAAE8EQCAAIAEgAhBnIAAPCyAAIAJqIQMCQCAAIAFzQQNxRQRAAkAgAkEBSARAIAAhAgwBCyAAQQNxRQRAIAAhAgwBCyAAIQIDQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADTw0BIAJBA3ENAAsLAkAgA0F8cSIEQcAASQ0AIAIgBEFAaiIFSw0AA0AgAiABKAIANgIAIAIgASgCBDYCBCACIAEoAgg2AgggAiABKAIMNgIMIAIgASgCEDYCECACIAEoAhQ2AhQgAiABKAIYNgIYIAIgASgCHDYCHCACIAEoAiA2AiAgAiABKAIkNgIkIAIgASgCKDYCKCACIAEoAiw2AiwgAiABKAIwNgIwIAIgASgCNDYCNCACIAEoAjg2AjggAiABKAI8NgI8IAFBQGshASACQUBrIgIgBU0NAAsLIAIgBE8NAQNAIAIgASgCADYCACABQQRqIQEgAkEEaiICIARJDQALDAELIANBBEkEQCAAIQIMAQsgA0F8aiIEIABJBEAgACECDAELIAAhAgNAIAIgAS0AADoAACACIAEtAAE6AAEgAiABLQACOgACIAIgAS0AAzoAAyABQQRqIQEgAkEEaiICIARNDQALCyACIANJBEADQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADRw0ACwsgAAsMACAAIAEpAAA3AAALQQECfyAAKAIIIgEgACgCEEkEQEEDDwsgACAAKAIEIgJBB3E2AgQgACABIAJBA3ZrIgE2AgggACABKAAANgIAQQALDAAgACABKAIANgAAC/cCAQJ/AkAgACABRg0AAkAgASACaiAASwRAIAAgAmoiBCABSw0BCyAAIAEgAhALDwsgACABc0EDcSEDAkACQCAAIAFJBEAgAwRAIAAhAwwDCyAAQQNxRQRAIAAhAwwCCyAAIQMDQCACRQ0EIAMgAS0AADoAACABQQFqIQEgAkF/aiECIANBAWoiA0EDcQ0ACwwBCwJAIAMNACAEQQNxBEADQCACRQ0FIAAgAkF/aiICaiIDIAEgAmotAAA6AAAgA0EDcQ0ACwsgAkEDTQ0AA0AgACACQXxqIgJqIAEgAmooAgA2AgAgAkEDSw0ACwsgAkUNAgNAIAAgAkF/aiICaiABIAJqLQAAOgAAIAINAAsMAgsgAkEDTQ0AIAIhBANAIAMgASgCADYCACABQQRqIQEgA0EEaiEDIARBfGoiBEEDSw0ACyACQQNxIQILIAJFDQADQCADIAEtAAA6AAAgA0EBaiEDIAFBAWohASACQX9qIgINAAsLIAAL8wICAn8BfgJAIAJFDQAgACACaiIDQX9qIAE6AAAgACABOgAAIAJBA0kNACADQX5qIAE6AAAgACABOgABIANBfWogAToAACAAIAE6AAIgAkEHSQ0AIANBfGogAToAACAAIAE6AAMgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIEayICQSBJDQAgAa0iBUIghiAFhCEFIAMgBGohAQNAIAEgBTcDGCABIAU3AxAgASAFNwMIIAEgBTcDACABQSBqIQEgAkFgaiICQR9LDQALCyAACy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAIajYCACADCy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAFajYCACADCx8AIAAgASACKAIEEAg2AgAgARAEGiAAIAJBCGo2AgQLCAAgAGdBH3MLugUBDX8jAEEQayIKJAACfyAEQQNNBEAgCkEANgIMIApBDGogAyAEEAsaIAAgASACIApBDGpBBBAVIgBBbCAAEAMbIAAgACAESxsMAQsgAEEAIAEoAgBBAXRBAmoQECENQVQgAygAACIGQQ9xIgBBCksNABogAiAAQQVqNgIAIAMgBGoiAkF8aiEMIAJBeWohDiACQXtqIRAgAEEGaiELQQQhBSAGQQR2IQRBICAAdCIAQQFyIQkgASgCACEPQQAhAiADIQYCQANAIAlBAkggAiAPS3JFBEAgAiEHAkAgCARAA0AgBEH//wNxQf//A0YEQCAHQRhqIQcgBiAQSQR/IAZBAmoiBigAACAFdgUgBUEQaiEFIARBEHYLIQQMAQsLA0AgBEEDcSIIQQNGBEAgBUECaiEFIARBAnYhBCAHQQNqIQcMAQsLIAcgCGoiByAPSw0EIAVBAmohBQNAIAIgB0kEQCANIAJBAXRqQQA7AQAgAkEBaiECDAELCyAGIA5LQQAgBiAFQQN1aiIHIAxLG0UEQCAHKAAAIAVBB3EiBXYhBAwCCyAEQQJ2IQQLIAYhBwsCfyALQX9qIAQgAEF/anEiBiAAQQF0QX9qIgggCWsiEUkNABogBCAIcSIEQQAgESAEIABIG2shBiALCyEIIA0gAkEBdGogBkF/aiIEOwEAIAlBASAGayAEIAZBAUgbayEJA0AgCSAASARAIABBAXUhACALQX9qIQsMAQsLAn8gByAOS0EAIAcgBSAIaiIFQQN1aiIGIAxLG0UEQCAFQQdxDAELIAUgDCIGIAdrQQN0awshBSACQQFqIQIgBEUhCCAGKAAAIAVBH3F2IQQMAQsLQWwgCUEBRyAFQSBKcg0BGiABIAJBf2o2AgAgBiAFQQdqQQN1aiADawwBC0FQCyEAIApBEGokACAACwkAQQFBBSAAGwsMACAAIAEoAAA2AAALqgMBCn8jAEHwAGsiCiQAIAJBAWohDiAAQQhqIQtBgIAEIAVBf2p0QRB1IQxBACECQQEhBkEBIAV0IglBf2oiDyEIA0AgAiAORkUEQAJAIAEgAkEBdCINai8BACIHQf//A0YEQCALIAhBA3RqIAI2AgQgCEF/aiEIQQEhBwwBCyAGQQAgDCAHQRB0QRB1ShshBgsgCiANaiAHOwEAIAJBAWohAgwBCwsgACAFNgIEIAAgBjYCACAJQQN2IAlBAXZqQQNqIQxBACEAQQAhBkEAIQIDQCAGIA5GBEADQAJAIAAgCUYNACAKIAsgAEEDdGoiASgCBCIGQQF0aiICIAIvAQAiAkEBajsBACABIAUgAhAUayIIOgADIAEgAiAIQf8BcXQgCWs7AQAgASAEIAZBAnQiAmooAgA6AAIgASACIANqKAIANgIEIABBAWohAAwBCwsFIAEgBkEBdGouAQAhDUEAIQcDQCAHIA1ORQRAIAsgAkEDdGogBjYCBANAIAIgDGogD3EiAiAISw0ACyAHQQFqIQcMAQsLIAZBAWohBgwBCwsgCkHwAGokAAsjAEIAIAEQCSAAhUKHla+vmLbem55/fkLj3MqV/M7y9YV/fAsQACAAQn43AwggACABNgIACyQBAX8gAARAIAEoAgQiAgRAIAEoAgggACACEQEADwsgABAmCwsfACAAIAEgAi8BABAINgIAIAEQBBogACACQQRqNgIEC0oBAX9BoCAoAgAiASAAaiIAQX9MBEBBiCBBMDYCAEF/DwsCQCAAPwBBEHRNDQAgABBmDQBBiCBBMDYCAEF/DwtBoCAgADYCACABC9cBAQh/Qbp/IQoCQCACKAIEIgggAigCACIJaiIOIAEgAGtLDQBBbCEKIAkgBCADKAIAIgtrSw0AIAAgCWoiBCACKAIIIgxrIQ0gACABQWBqIg8gCyAJQQAQKSADIAkgC2o2AgACQAJAIAwgBCAFa00EQCANIQUMAQsgDCAEIAZrSw0CIAcgDSAFayIAaiIBIAhqIAdNBEAgBCABIAgQDxoMAgsgBCABQQAgAGsQDyEBIAIgACAIaiIINgIEIAEgAGshBAsgBCAPIAUgCEEBECkLIA4hCgsgCgubAgEBfyMAQYABayINJAAgDSADNgJ8AkAgAkEDSwRAQX8hCQwBCwJAAkACQAJAIAJBAWsOAwADAgELIAZFBEBBuH8hCQwEC0FsIQkgBS0AACICIANLDQMgACAHIAJBAnQiAmooAgAgAiAIaigCABA7IAEgADYCAEEBIQkMAwsgASAJNgIAQQAhCQwCCyAKRQRAQWwhCQwCC0EAIQkgC0UgDEEZSHINAUEIIAR0QQhqIQBBACECA0AgAiAATw0CIAJBQGshAgwAAAsAC0FsIQkgDSANQfwAaiANQfgAaiAFIAYQFSICEAMNACANKAJ4IgMgBEsNACAAIA0gDSgCfCAHIAggAxAYIAEgADYCACACIQkLIA1BgAFqJAAgCQsLACAAIAEgAhALGgsQACAALwAAIAAtAAJBEHRyCy8AAn9BuH8gAUEISQ0AGkFyIAAoAAQiAEF3Sw0AGkG4fyAAQQhqIgAgACABSxsLCwkAIAAgATsAAAsDAAELigYBBX8gACAAKAIAIgVBfnE2AgBBACAAIAVBAXZqQYQgKAIAIgQgAEYbIQECQAJAIAAoAgQiAkUNACACKAIAIgNBAXENACACQQhqIgUgA0EBdkF4aiIDQQggA0EISxtnQR9zQQJ0QYAfaiIDKAIARgRAIAMgAigCDDYCAAsgAigCCCIDBEAgAyACKAIMNgIECyACKAIMIgMEQCADIAIoAgg2AgALIAIgAigCACAAKAIAQX5xajYCAEGEICEAAkACQCABRQ0AIAEgAjYCBCABKAIAIgNBAXENASADQQF2QXhqIgNBCCADQQhLG2dBH3NBAnRBgB9qIgMoAgAgAUEIakYEQCADIAEoAgw2AgALIAEoAggiAwRAIAMgASgCDDYCBAsgASgCDCIDBEAgAyABKAIINgIAQYQgKAIAIQQLIAIgAigCACABKAIAQX5xajYCACABIARGDQAgASABKAIAQQF2akEEaiEACyAAIAI2AgALIAIoAgBBAXZBeGoiAEEIIABBCEsbZ0Efc0ECdEGAH2oiASgCACEAIAEgBTYCACACIAA2AgwgAkEANgIIIABFDQEgACAFNgIADwsCQCABRQ0AIAEoAgAiAkEBcQ0AIAJBAXZBeGoiAkEIIAJBCEsbZ0Efc0ECdEGAH2oiAigCACABQQhqRgRAIAIgASgCDDYCAAsgASgCCCICBEAgAiABKAIMNgIECyABKAIMIgIEQCACIAEoAgg2AgBBhCAoAgAhBAsgACAAKAIAIAEoAgBBfnFqIgI2AgACQCABIARHBEAgASABKAIAQQF2aiAANgIEIAAoAgAhAgwBC0GEICAANgIACyACQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgIoAgAhASACIABBCGoiAjYCACAAIAE2AgwgAEEANgIIIAFFDQEgASACNgIADwsgBUEBdkF4aiIBQQggAUEISxtnQR9zQQJ0QYAfaiICKAIAIQEgAiAAQQhqIgI2AgAgACABNgIMIABBADYCCCABRQ0AIAEgAjYCAAsLDgAgAARAIABBeGoQJQsLgAIBA38CQCAAQQ9qQXhxQYQgKAIAKAIAQQF2ayICEB1Bf0YNAAJAQYQgKAIAIgAoAgAiAUEBcQ0AIAFBAXZBeGoiAUEIIAFBCEsbZ0Efc0ECdEGAH2oiASgCACAAQQhqRgRAIAEgACgCDDYCAAsgACgCCCIBBEAgASAAKAIMNgIECyAAKAIMIgFFDQAgASAAKAIINgIAC0EBIQEgACAAKAIAIAJBAXRqIgI2AgAgAkEBcQ0AIAJBAXZBeGoiAkEIIAJBCEsbZ0Efc0ECdEGAH2oiAygCACECIAMgAEEIaiIDNgIAIAAgAjYCDCAAQQA2AgggAkUNACACIAM2AgALIAELtwIBA38CQAJAIABBASAAGyICEDgiAA0AAkACQEGEICgCACIARQ0AIAAoAgAiA0EBcQ0AIAAgA0EBcjYCACADQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgEoAgAgAEEIakYEQCABIAAoAgw2AgALIAAoAggiAQRAIAEgACgCDDYCBAsgACgCDCIBBEAgASAAKAIINgIACyACECchAkEAIQFBhCAoAgAhACACDQEgACAAKAIAQX5xNgIAQQAPCyACQQ9qQXhxIgMQHSICQX9GDQIgAkEHakF4cSIAIAJHBEAgACACaxAdQX9GDQMLAkBBhCAoAgAiAUUEQEGAICAANgIADAELIAAgATYCBAtBhCAgADYCACAAIANBAXRBAXI2AgAMAQsgAEUNAQsgAEEIaiEBCyABC7kDAQJ/IAAgA2ohBQJAIANBB0wEQANAIAAgBU8NAiAAIAItAAA6AAAgAEEBaiEAIAJBAWohAgwAAAsACyAEQQFGBEACQCAAIAJrIgZBB00EQCAAIAItAAA6AAAgACACLQABOgABIAAgAi0AAjoAAiAAIAItAAM6AAMgAEEEaiACIAZBAnQiBkHAHmooAgBqIgIQFyACIAZB4B5qKAIAayECDAELIAAgAhAMCyACQQhqIQIgAEEIaiEACwJAAkACQAJAIAUgAU0EQCAAIANqIQEgBEEBRyAAIAJrQQ9Kcg0BA0AgACACEAwgAkEIaiECIABBCGoiACABSQ0ACwwFCyAAIAFLBEAgACEBDAQLIARBAUcgACACa0EPSnINASAAIQMgAiEEA0AgAyAEEAwgBEEIaiEEIANBCGoiAyABSQ0ACwwCCwNAIAAgAhAHIAJBEGohAiAAQRBqIgAgAUkNAAsMAwsgACEDIAIhBANAIAMgBBAHIARBEGohBCADQRBqIgMgAUkNAAsLIAIgASAAa2ohAgsDQCABIAVPDQEgASACLQAAOgAAIAFBAWohASACQQFqIQIMAAALAAsLQQECfyAAIAAoArjgASIDNgLE4AEgACgCvOABIQQgACABNgK84AEgACABIAJqNgK44AEgACABIAQgA2tqNgLA4AELpgEBAX8gACAAKALs4QEQFjYCyOABIABCADcD+OABIABCADcDuOABIABBwOABakIANwMAIABBqNAAaiIBQYyAgOAANgIAIABBADYCmOIBIABCADcDiOEBIABCAzcDgOEBIABBrNABakHgEikCADcCACAAQbTQAWpB6BIoAgA2AgAgACABNgIMIAAgAEGYIGo2AgggACAAQaAwajYCBCAAIABBEGo2AgALYQEBf0G4fyEDAkAgAUEDSQ0AIAIgABAhIgFBA3YiADYCCCACIAFBAXE2AgQgAiABQQF2QQNxIgM2AgACQCADQX9qIgFBAksNAAJAIAFBAWsOAgEAAgtBbA8LIAAhAwsgAwsMACAAIAEgAkEAEC4LiAQCA38CfiADEBYhBCAAQQBBKBAQIQAgBCACSwRAIAQPCyABRQRAQX8PCwJAAkAgA0EBRg0AIAEoAAAiBkGo6r5pRg0AQXYhAyAGQXBxQdDUtMIBRw0BQQghAyACQQhJDQEgAEEAQSgQECEAIAEoAAQhASAAQQE2AhQgACABrTcDAEEADwsgASACIAMQLyIDIAJLDQAgACADNgIYQXIhAyABIARqIgVBf2otAAAiAkEIcQ0AIAJBIHEiBkUEQEFwIQMgBS0AACIFQacBSw0BIAVBB3GtQgEgBUEDdkEKaq2GIgdCA4h+IAd8IQggBEEBaiEECyACQQZ2IQMgAkECdiEFAkAgAkEDcUF/aiICQQJLBEBBACECDAELAkACQAJAIAJBAWsOAgECAAsgASAEai0AACECIARBAWohBAwCCyABIARqLwAAIQIgBEECaiEEDAELIAEgBGooAAAhAiAEQQRqIQQLIAVBAXEhBQJ+AkACQAJAIANBf2oiA0ECTQRAIANBAWsOAgIDAQtCfyAGRQ0DGiABIARqMQAADAMLIAEgBGovAACtQoACfAwCCyABIARqKAAArQwBCyABIARqKQAACyEHIAAgBTYCICAAIAI2AhwgACAHNwMAQQAhAyAAQQA2AhQgACAHIAggBhsiBzcDCCAAIAdCgIAIIAdCgIAIVBs+AhALIAMLWwEBf0G4fyEDIAIQFiICIAFNBH8gACACakF/ai0AACIAQQNxQQJ0QaAeaigCACACaiAAQQZ2IgFBAnRBsB5qKAIAaiAAQSBxIgBFaiABRSAAQQV2cWoFQbh/CwsdACAAKAKQ4gEQWiAAQQA2AqDiASAAQgA3A5DiAQu1AwEFfyMAQZACayIKJABBuH8hBgJAIAVFDQAgBCwAACIIQf8BcSEHAkAgCEF/TARAIAdBgn9qQQF2IgggBU8NAkFsIQYgB0GBf2oiBUGAAk8NAiAEQQFqIQdBACEGA0AgBiAFTwRAIAUhBiAIIQcMAwUgACAGaiAHIAZBAXZqIgQtAABBBHY6AAAgACAGQQFyaiAELQAAQQ9xOgAAIAZBAmohBgwBCwAACwALIAcgBU8NASAAIARBAWogByAKEFMiBhADDQELIAYhBEEAIQYgAUEAQTQQECEJQQAhBQNAIAQgBkcEQCAAIAZqIggtAAAiAUELSwRAQWwhBgwDBSAJIAFBAnRqIgEgASgCAEEBajYCACAGQQFqIQZBASAILQAAdEEBdSAFaiEFDAILAAsLQWwhBiAFRQ0AIAUQFEEBaiIBQQxLDQAgAyABNgIAQQFBASABdCAFayIDEBQiAXQgA0cNACAAIARqIAFBAWoiADoAACAJIABBAnRqIgAgACgCAEEBajYCACAJKAIEIgBBAkkgAEEBcXINACACIARBAWo2AgAgB0EBaiEGCyAKQZACaiQAIAYLxhEBDH8jAEHwAGsiBSQAQWwhCwJAIANBCkkNACACLwAAIQogAi8AAiEJIAIvAAQhByAFQQhqIAQQDgJAIAMgByAJIApqakEGaiIMSQ0AIAUtAAohCCAFQdgAaiACQQZqIgIgChAGIgsQAw0BIAVBQGsgAiAKaiICIAkQBiILEAMNASAFQShqIAIgCWoiAiAHEAYiCxADDQEgBUEQaiACIAdqIAMgDGsQBiILEAMNASAAIAFqIg9BfWohECAEQQRqIQZBASELIAAgAUEDakECdiIDaiIMIANqIgIgA2oiDiEDIAIhBCAMIQcDQCALIAMgEElxBEAgACAGIAVB2ABqIAgQAkECdGoiCS8BADsAACAFQdgAaiAJLQACEAEgCS0AAyELIAcgBiAFQUBrIAgQAkECdGoiCS8BADsAACAFQUBrIAktAAIQASAJLQADIQogBCAGIAVBKGogCBACQQJ0aiIJLwEAOwAAIAVBKGogCS0AAhABIAktAAMhCSADIAYgBUEQaiAIEAJBAnRqIg0vAQA7AAAgBUEQaiANLQACEAEgDS0AAyENIAAgC2oiCyAGIAVB2ABqIAgQAkECdGoiAC8BADsAACAFQdgAaiAALQACEAEgAC0AAyEAIAcgCmoiCiAGIAVBQGsgCBACQQJ0aiIHLwEAOwAAIAVBQGsgBy0AAhABIActAAMhByAEIAlqIgkgBiAFQShqIAgQAkECdGoiBC8BADsAACAFQShqIAQtAAIQASAELQADIQQgAyANaiIDIAYgBUEQaiAIEAJBAnRqIg0vAQA7AAAgBUEQaiANLQACEAEgACALaiEAIAcgCmohByAEIAlqIQQgAyANLQADaiEDIAVB2ABqEA0gBUFAaxANciAFQShqEA1yIAVBEGoQDXJFIQsMAQsLIAQgDksgByACS3INAEFsIQsgACAMSw0BIAxBfWohCQNAQQAgACAJSSAFQdgAahAEGwRAIAAgBiAFQdgAaiAIEAJBAnRqIgovAQA7AAAgBUHYAGogCi0AAhABIAAgCi0AA2oiACAGIAVB2ABqIAgQAkECdGoiCi8BADsAACAFQdgAaiAKLQACEAEgACAKLQADaiEADAEFIAxBfmohCgNAIAVB2ABqEAQgACAKS3JFBEAgACAGIAVB2ABqIAgQAkECdGoiCS8BADsAACAFQdgAaiAJLQACEAEgACAJLQADaiEADAELCwNAIAAgCk0EQCAAIAYgBUHYAGogCBACQQJ0aiIJLwEAOwAAIAVB2ABqIAktAAIQASAAIAktAANqIQAMAQsLAkAgACAMTw0AIAAgBiAFQdgAaiAIEAIiAEECdGoiDC0AADoAACAMLQADQQFGBEAgBUHYAGogDC0AAhABDAELIAUoAlxBH0sNACAFQdgAaiAGIABBAnRqLQACEAEgBSgCXEEhSQ0AIAVBIDYCXAsgAkF9aiEMA0BBACAHIAxJIAVBQGsQBBsEQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiIAIAYgBUFAayAIEAJBAnRqIgcvAQA7AAAgBUFAayAHLQACEAEgACAHLQADaiEHDAEFIAJBfmohDANAIAVBQGsQBCAHIAxLckUEQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiEHDAELCwNAIAcgDE0EQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiEHDAELCwJAIAcgAk8NACAHIAYgBUFAayAIEAIiAEECdGoiAi0AADoAACACLQADQQFGBEAgBUFAayACLQACEAEMAQsgBSgCREEfSw0AIAVBQGsgBiAAQQJ0ai0AAhABIAUoAkRBIUkNACAFQSA2AkQLIA5BfWohAgNAQQAgBCACSSAFQShqEAQbBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2oiACAGIAVBKGogCBACQQJ0aiIELwEAOwAAIAVBKGogBC0AAhABIAAgBC0AA2ohBAwBBSAOQX5qIQIDQCAFQShqEAQgBCACS3JFBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2ohBAwBCwsDQCAEIAJNBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2ohBAwBCwsCQCAEIA5PDQAgBCAGIAVBKGogCBACIgBBAnRqIgItAAA6AAAgAi0AA0EBRgRAIAVBKGogAi0AAhABDAELIAUoAixBH0sNACAFQShqIAYgAEECdGotAAIQASAFKAIsQSFJDQAgBUEgNgIsCwNAQQAgAyAQSSAFQRBqEAQbBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2oiACAGIAVBEGogCBACQQJ0aiICLwEAOwAAIAVBEGogAi0AAhABIAAgAi0AA2ohAwwBBSAPQX5qIQIDQCAFQRBqEAQgAyACS3JFBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2ohAwwBCwsDQCADIAJNBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2ohAwwBCwsCQCADIA9PDQAgAyAGIAVBEGogCBACIgBBAnRqIgItAAA6AAAgAi0AA0EBRgRAIAVBEGogAi0AAhABDAELIAUoAhRBH0sNACAFQRBqIAYgAEECdGotAAIQASAFKAIUQSFJDQAgBUEgNgIUCyABQWwgBUHYAGoQCiAFQUBrEApxIAVBKGoQCnEgBUEQahAKcRshCwwJCwAACwALAAALAAsAAAsACwAACwALQWwhCwsgBUHwAGokACALC7UEAQ5/IwBBEGsiBiQAIAZBBGogABAOQVQhBQJAIARB3AtJDQAgBi0ABCEHIANB8ARqQQBB7AAQECEIIAdBDEsNACADQdwJaiIJIAggBkEIaiAGQQxqIAEgAhAxIhAQA0UEQCAGKAIMIgQgB0sNASADQdwFaiEPIANBpAVqIREgAEEEaiESIANBqAVqIQEgBCEFA0AgBSICQX9qIQUgCCACQQJ0aigCAEUNAAsgAkEBaiEOQQEhBQNAIAUgDk9FBEAgCCAFQQJ0IgtqKAIAIQwgASALaiAKNgIAIAVBAWohBSAKIAxqIQoMAQsLIAEgCjYCAEEAIQUgBigCCCELA0AgBSALRkUEQCABIAUgCWotAAAiDEECdGoiDSANKAIAIg1BAWo2AgAgDyANQQF0aiINIAw6AAEgDSAFOgAAIAVBAWohBQwBCwtBACEBIANBADYCqAUgBEF/cyAHaiEJQQEhBQNAIAUgDk9FBEAgCCAFQQJ0IgtqKAIAIQwgAyALaiABNgIAIAwgBSAJanQgAWohASAFQQFqIQUMAQsLIAcgBEEBaiIBIAJrIgRrQQFqIQgDQEEBIQUgBCAIT0UEQANAIAUgDk9FBEAgBUECdCIJIAMgBEE0bGpqIAMgCWooAgAgBHY2AgAgBUEBaiEFDAELCyAEQQFqIQQMAQsLIBIgByAPIAogESADIAIgARBkIAZBAToABSAGIAc6AAYgACAGKAIENgIACyAQIQULIAZBEGokACAFC8ENAQt/IwBB8ABrIgUkAEFsIQkCQCADQQpJDQAgAi8AACEKIAIvAAIhDCACLwAEIQYgBUEIaiAEEA4CQCADIAYgCiAMampBBmoiDUkNACAFLQAKIQcgBUHYAGogAkEGaiICIAoQBiIJEAMNASAFQUBrIAIgCmoiAiAMEAYiCRADDQEgBUEoaiACIAxqIgIgBhAGIgkQAw0BIAVBEGogAiAGaiADIA1rEAYiCRADDQEgACABaiIOQX1qIQ8gBEEEaiEGQQEhCSAAIAFBA2pBAnYiAmoiCiACaiIMIAJqIg0hAyAMIQQgCiECA0AgCSADIA9JcQRAIAYgBUHYAGogBxACQQF0aiIILQAAIQsgBUHYAGogCC0AARABIAAgCzoAACAGIAVBQGsgBxACQQF0aiIILQAAIQsgBUFAayAILQABEAEgAiALOgAAIAYgBUEoaiAHEAJBAXRqIggtAAAhCyAFQShqIAgtAAEQASAEIAs6AAAgBiAFQRBqIAcQAkEBdGoiCC0AACELIAVBEGogCC0AARABIAMgCzoAACAGIAVB2ABqIAcQAkEBdGoiCC0AACELIAVB2ABqIAgtAAEQASAAIAs6AAEgBiAFQUBrIAcQAkEBdGoiCC0AACELIAVBQGsgCC0AARABIAIgCzoAASAGIAVBKGogBxACQQF0aiIILQAAIQsgBUEoaiAILQABEAEgBCALOgABIAYgBUEQaiAHEAJBAXRqIggtAAAhCyAFQRBqIAgtAAEQASADIAs6AAEgA0ECaiEDIARBAmohBCACQQJqIQIgAEECaiEAIAkgBUHYAGoQDUVxIAVBQGsQDUVxIAVBKGoQDUVxIAVBEGoQDUVxIQkMAQsLIAQgDUsgAiAMS3INAEFsIQkgACAKSw0BIApBfWohCQNAIAVB2ABqEAQgACAJT3JFBEAgBiAFQdgAaiAHEAJBAXRqIggtAAAhCyAFQdgAaiAILQABEAEgACALOgAAIAYgBUHYAGogBxACQQF0aiIILQAAIQsgBUHYAGogCC0AARABIAAgCzoAASAAQQJqIQAMAQsLA0AgBUHYAGoQBCAAIApPckUEQCAGIAVB2ABqIAcQAkEBdGoiCS0AACEIIAVB2ABqIAktAAEQASAAIAg6AAAgAEEBaiEADAELCwNAIAAgCkkEQCAGIAVB2ABqIAcQAkEBdGoiCS0AACEIIAVB2ABqIAktAAEQASAAIAg6AAAgAEEBaiEADAELCyAMQX1qIQADQCAFQUBrEAQgAiAAT3JFBEAgBiAFQUBrIAcQAkEBdGoiCi0AACEJIAVBQGsgCi0AARABIAIgCToAACAGIAVBQGsgBxACQQF0aiIKLQAAIQkgBUFAayAKLQABEAEgAiAJOgABIAJBAmohAgwBCwsDQCAFQUBrEAQgAiAMT3JFBEAgBiAFQUBrIAcQAkEBdGoiAC0AACEKIAVBQGsgAC0AARABIAIgCjoAACACQQFqIQIMAQsLA0AgAiAMSQRAIAYgBUFAayAHEAJBAXRqIgAtAAAhCiAFQUBrIAAtAAEQASACIAo6AAAgAkEBaiECDAELCyANQX1qIQADQCAFQShqEAQgBCAAT3JFBEAgBiAFQShqIAcQAkEBdGoiAi0AACEKIAVBKGogAi0AARABIAQgCjoAACAGIAVBKGogBxACQQF0aiICLQAAIQogBUEoaiACLQABEAEgBCAKOgABIARBAmohBAwBCwsDQCAFQShqEAQgBCANT3JFBEAgBiAFQShqIAcQAkEBdGoiAC0AACECIAVBKGogAC0AARABIAQgAjoAACAEQQFqIQQMAQsLA0AgBCANSQRAIAYgBUEoaiAHEAJBAXRqIgAtAAAhAiAFQShqIAAtAAEQASAEIAI6AAAgBEEBaiEEDAELCwNAIAVBEGoQBCADIA9PckUEQCAGIAVBEGogBxACQQF0aiIALQAAIQIgBUEQaiAALQABEAEgAyACOgAAIAYgBUEQaiAHEAJBAXRqIgAtAAAhAiAFQRBqIAAtAAEQASADIAI6AAEgA0ECaiEDDAELCwNAIAVBEGoQBCADIA5PckUEQCAGIAVBEGogBxACQQF0aiIALQAAIQIgBUEQaiAALQABEAEgAyACOgAAIANBAWohAwwBCwsDQCADIA5JBEAgBiAFQRBqIAcQAkEBdGoiAC0AACECIAVBEGogAC0AARABIAMgAjoAACADQQFqIQMMAQsLIAFBbCAFQdgAahAKIAVBQGsQCnEgBUEoahAKcSAFQRBqEApxGyEJDAELQWwhCQsgBUHwAGokACAJC8oCAQR/IwBBIGsiBSQAIAUgBBAOIAUtAAIhByAFQQhqIAIgAxAGIgIQA0UEQCAEQQRqIQIgACABaiIDQX1qIQQDQCAFQQhqEAQgACAET3JFBEAgAiAFQQhqIAcQAkEBdGoiBi0AACEIIAVBCGogBi0AARABIAAgCDoAACACIAVBCGogBxACQQF0aiIGLQAAIQggBUEIaiAGLQABEAEgACAIOgABIABBAmohAAwBCwsDQCAFQQhqEAQgACADT3JFBEAgAiAFQQhqIAcQAkEBdGoiBC0AACEGIAVBCGogBC0AARABIAAgBjoAACAAQQFqIQAMAQsLA0AgACADT0UEQCACIAVBCGogBxACQQF0aiIELQAAIQYgBUEIaiAELQABEAEgACAGOgAAIABBAWohAAwBCwsgAUFsIAVBCGoQChshAgsgBUEgaiQAIAILtgMBCX8jAEEQayIGJAAgBkEANgIMIAZBADYCCEFUIQQCQAJAIANBQGsiDCADIAZBCGogBkEMaiABIAIQMSICEAMNACAGQQRqIAAQDiAGKAIMIgcgBi0ABEEBaksNASAAQQRqIQogBkEAOgAFIAYgBzoABiAAIAYoAgQ2AgAgB0EBaiEJQQEhBANAIAQgCUkEQCADIARBAnRqIgEoAgAhACABIAU2AgAgACAEQX9qdCAFaiEFIARBAWohBAwBCwsgB0EBaiEHQQAhBSAGKAIIIQkDQCAFIAlGDQEgAyAFIAxqLQAAIgRBAnRqIgBBASAEdEEBdSILIAAoAgAiAWoiADYCACAHIARrIQhBACEEAkAgC0EDTQRAA0AgBCALRg0CIAogASAEakEBdGoiACAIOgABIAAgBToAACAEQQFqIQQMAAALAAsDQCABIABPDQEgCiABQQF0aiIEIAg6AAEgBCAFOgAAIAQgCDoAAyAEIAU6AAIgBCAIOgAFIAQgBToABCAEIAg6AAcgBCAFOgAGIAFBBGohAQwAAAsACyAFQQFqIQUMAAALAAsgAiEECyAGQRBqJAAgBAutAQECfwJAQYQgKAIAIABHIAAoAgBBAXYiAyABa0F4aiICQXhxQQhHcgR/IAIFIAMQJ0UNASACQQhqC0EQSQ0AIAAgACgCACICQQFxIAAgAWpBD2pBeHEiASAAa0EBdHI2AgAgASAANgIEIAEgASgCAEEBcSAAIAJBAXZqIAFrIgJBAXRyNgIAQYQgIAEgAkH/////B3FqQQRqQYQgKAIAIABGGyABNgIAIAEQJQsLygIBBX8CQAJAAkAgAEEIIABBCEsbZ0EfcyAAaUEBR2oiAUEESSAAIAF2cg0AIAFBAnRB/B5qKAIAIgJFDQADQCACQXhqIgMoAgBBAXZBeGoiBSAATwRAIAIgBUEIIAVBCEsbZ0Efc0ECdEGAH2oiASgCAEYEQCABIAIoAgQ2AgALDAMLIARBHksNASAEQQFqIQQgAigCBCICDQALC0EAIQMgAUEgTw0BA0AgAUECdEGAH2ooAgAiAkUEQCABQR5LIQIgAUEBaiEBIAJFDQEMAwsLIAIgAkF4aiIDKAIAQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgEoAgBGBEAgASACKAIENgIACwsgAigCACIBBEAgASACKAIENgIECyACKAIEIgEEQCABIAIoAgA2AgALIAMgAygCAEEBcjYCACADIAAQNwsgAwvhCwINfwV+IwBB8ABrIgckACAHIAAoAvDhASIINgJcIAEgAmohDSAIIAAoAoDiAWohDwJAAkAgBUUEQCABIQQMAQsgACgCxOABIRAgACgCwOABIREgACgCvOABIQ4gAEEBNgKM4QFBACEIA0AgCEEDRwRAIAcgCEECdCICaiAAIAJqQazQAWooAgA2AkQgCEEBaiEIDAELC0FsIQwgB0EYaiADIAQQBhADDQEgB0EsaiAHQRhqIAAoAgAQEyAHQTRqIAdBGGogACgCCBATIAdBPGogB0EYaiAAKAIEEBMgDUFgaiESIAEhBEEAIQwDQCAHKAIwIAcoAixBA3RqKQIAIhRCEIinQf8BcSEIIAcoAkAgBygCPEEDdGopAgAiFUIQiKdB/wFxIQsgBygCOCAHKAI0QQN0aikCACIWQiCIpyEJIBVCIIghFyAUQiCIpyECAkAgFkIQiKdB/wFxIgNBAk8EQAJAIAZFIANBGUlyRQRAIAkgB0EYaiADQSAgBygCHGsiCiAKIANLGyIKEAUgAyAKayIDdGohCSAHQRhqEAQaIANFDQEgB0EYaiADEAUgCWohCQwBCyAHQRhqIAMQBSAJaiEJIAdBGGoQBBoLIAcpAkQhGCAHIAk2AkQgByAYNwNIDAELAkAgA0UEQCACBEAgBygCRCEJDAMLIAcoAkghCQwBCwJAAkAgB0EYakEBEAUgCSACRWpqIgNBA0YEQCAHKAJEQX9qIgMgA0VqIQkMAQsgA0ECdCAHaigCRCIJIAlFaiEJIANBAUYNAQsgByAHKAJINgJMCwsgByAHKAJENgJIIAcgCTYCRAsgF6chAyALBEAgB0EYaiALEAUgA2ohAwsgCCALakEUTwRAIAdBGGoQBBoLIAgEQCAHQRhqIAgQBSACaiECCyAHQRhqEAQaIAcgB0EYaiAUQhiIp0H/AXEQCCAUp0H//wNxajYCLCAHIAdBGGogFUIYiKdB/wFxEAggFadB//8DcWo2AjwgB0EYahAEGiAHIAdBGGogFkIYiKdB/wFxEAggFqdB//8DcWo2AjQgByACNgJgIAcoAlwhCiAHIAk2AmggByADNgJkAkACQAJAIAQgAiADaiILaiASSw0AIAIgCmoiEyAPSw0AIA0gBGsgC0Egak8NAQsgByAHKQNoNwMQIAcgBykDYDcDCCAEIA0gB0EIaiAHQdwAaiAPIA4gESAQEB4hCwwBCyACIARqIQggBCAKEAcgAkERTwRAIARBEGohAgNAIAIgCkEQaiIKEAcgAkEQaiICIAhJDQALCyAIIAlrIQIgByATNgJcIAkgCCAOa0sEQCAJIAggEWtLBEBBbCELDAILIBAgAiAOayICaiIKIANqIBBNBEAgCCAKIAMQDxoMAgsgCCAKQQAgAmsQDyEIIAcgAiADaiIDNgJkIAggAmshCCAOIQILIAlBEE8EQCADIAhqIQMDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALDAELAkAgCUEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgCUECdCIDQcAeaigCAGoiAhAXIAIgA0HgHmooAgBrIQIgBygCZCEDDAELIAggAhAMCyADQQlJDQAgAyAIaiEDIAhBCGoiCCACQQhqIgJrQQ9MBEADQCAIIAIQDCACQQhqIQIgCEEIaiIIIANJDQAMAgALAAsDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALCyAHQRhqEAQaIAsgDCALEAMiAhshDCAEIAQgC2ogAhshBCAFQX9qIgUNAAsgDBADDQFBbCEMIAdBGGoQBEECSQ0BQQAhCANAIAhBA0cEQCAAIAhBAnQiAmpBrNABaiACIAdqKAJENgIAIAhBAWohCAwBCwsgBygCXCEIC0G6fyEMIA8gCGsiACANIARrSw0AIAQEfyAEIAggABALIABqBUEACyABayEMCyAHQfAAaiQAIAwLkRcCFn8FfiMAQdABayIHJAAgByAAKALw4QEiCDYCvAEgASACaiESIAggACgCgOIBaiETAkACQCAFRQRAIAEhAwwBCyAAKALE4AEhESAAKALA4AEhFSAAKAK84AEhDyAAQQE2AozhAUEAIQgDQCAIQQNHBEAgByAIQQJ0IgJqIAAgAmpBrNABaigCADYCVCAIQQFqIQgMAQsLIAcgETYCZCAHIA82AmAgByABIA9rNgJoQWwhECAHQShqIAMgBBAGEAMNASAFQQQgBUEESBshFyAHQTxqIAdBKGogACgCABATIAdBxABqIAdBKGogACgCCBATIAdBzABqIAdBKGogACgCBBATQQAhBCAHQeAAaiEMIAdB5ABqIQoDQCAHQShqEARBAksgBCAXTnJFBEAgBygCQCAHKAI8QQN0aikCACIdQhCIp0H/AXEhCyAHKAJQIAcoAkxBA3RqKQIAIh5CEIinQf8BcSEJIAcoAkggBygCREEDdGopAgAiH0IgiKchCCAeQiCIISAgHUIgiKchAgJAIB9CEIinQf8BcSIDQQJPBEACQCAGRSADQRlJckUEQCAIIAdBKGogA0EgIAcoAixrIg0gDSADSxsiDRAFIAMgDWsiA3RqIQggB0EoahAEGiADRQ0BIAdBKGogAxAFIAhqIQgMAQsgB0EoaiADEAUgCGohCCAHQShqEAQaCyAHKQJUISEgByAINgJUIAcgITcDWAwBCwJAIANFBEAgAgRAIAcoAlQhCAwDCyAHKAJYIQgMAQsCQAJAIAdBKGpBARAFIAggAkVqaiIDQQNGBEAgBygCVEF/aiIDIANFaiEIDAELIANBAnQgB2ooAlQiCCAIRWohCCADQQFGDQELIAcgBygCWDYCXAsLIAcgBygCVDYCWCAHIAg2AlQLICCnIQMgCQRAIAdBKGogCRAFIANqIQMLIAkgC2pBFE8EQCAHQShqEAQaCyALBEAgB0EoaiALEAUgAmohAgsgB0EoahAEGiAHIAcoAmggAmoiCSADajYCaCAKIAwgCCAJSxsoAgAhDSAHIAdBKGogHUIYiKdB/wFxEAggHadB//8DcWo2AjwgByAHQShqIB5CGIinQf8BcRAIIB6nQf//A3FqNgJMIAdBKGoQBBogB0EoaiAfQhiIp0H/AXEQCCEOIAdB8ABqIARBBHRqIgsgCSANaiAIazYCDCALIAg2AgggCyADNgIEIAsgAjYCACAHIA4gH6dB//8DcWo2AkQgBEEBaiEEDAELCyAEIBdIDQEgEkFgaiEYIAdB4ABqIRogB0HkAGohGyABIQMDQCAHQShqEARBAksgBCAFTnJFBEAgBygCQCAHKAI8QQN0aikCACIdQhCIp0H/AXEhCyAHKAJQIAcoAkxBA3RqKQIAIh5CEIinQf8BcSEIIAcoAkggBygCREEDdGopAgAiH0IgiKchCSAeQiCIISAgHUIgiKchDAJAIB9CEIinQf8BcSICQQJPBEACQCAGRSACQRlJckUEQCAJIAdBKGogAkEgIAcoAixrIgogCiACSxsiChAFIAIgCmsiAnRqIQkgB0EoahAEGiACRQ0BIAdBKGogAhAFIAlqIQkMAQsgB0EoaiACEAUgCWohCSAHQShqEAQaCyAHKQJUISEgByAJNgJUIAcgITcDWAwBCwJAIAJFBEAgDARAIAcoAlQhCQwDCyAHKAJYIQkMAQsCQAJAIAdBKGpBARAFIAkgDEVqaiICQQNGBEAgBygCVEF/aiICIAJFaiEJDAELIAJBAnQgB2ooAlQiCSAJRWohCSACQQFGDQELIAcgBygCWDYCXAsLIAcgBygCVDYCWCAHIAk2AlQLICCnIRQgCARAIAdBKGogCBAFIBRqIRQLIAggC2pBFE8EQCAHQShqEAQaCyALBEAgB0EoaiALEAUgDGohDAsgB0EoahAEGiAHIAcoAmggDGoiGSAUajYCaCAbIBogCSAZSxsoAgAhHCAHIAdBKGogHUIYiKdB/wFxEAggHadB//8DcWo2AjwgByAHQShqIB5CGIinQf8BcRAIIB6nQf//A3FqNgJMIAdBKGoQBBogByAHQShqIB9CGIinQf8BcRAIIB+nQf//A3FqNgJEIAcgB0HwAGogBEEDcUEEdGoiDSkDCCIdNwPIASAHIA0pAwAiHjcDwAECQAJAAkAgBygCvAEiDiAepyICaiIWIBNLDQAgAyAHKALEASIKIAJqIgtqIBhLDQAgEiADayALQSBqTw0BCyAHIAcpA8gBNwMQIAcgBykDwAE3AwggAyASIAdBCGogB0G8AWogEyAPIBUgERAeIQsMAQsgAiADaiEIIAMgDhAHIAJBEU8EQCADQRBqIQIDQCACIA5BEGoiDhAHIAJBEGoiAiAISQ0ACwsgCCAdpyIOayECIAcgFjYCvAEgDiAIIA9rSwRAIA4gCCAVa0sEQEFsIQsMAgsgESACIA9rIgJqIhYgCmogEU0EQCAIIBYgChAPGgwCCyAIIBZBACACaxAPIQggByACIApqIgo2AsQBIAggAmshCCAPIQILIA5BEE8EQCAIIApqIQoDQCAIIAIQByACQRBqIQIgCEEQaiIIIApJDQALDAELAkAgDkEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgDkECdCIKQcAeaigCAGoiAhAXIAIgCkHgHmooAgBrIQIgBygCxAEhCgwBCyAIIAIQDAsgCkEJSQ0AIAggCmohCiAIQQhqIgggAkEIaiICa0EPTARAA0AgCCACEAwgAkEIaiECIAhBCGoiCCAKSQ0ADAIACwALA0AgCCACEAcgAkEQaiECIAhBEGoiCCAKSQ0ACwsgCxADBEAgCyEQDAQFIA0gDDYCACANIBkgHGogCWs2AgwgDSAJNgIIIA0gFDYCBCAEQQFqIQQgAyALaiEDDAILAAsLIAQgBUgNASAEIBdrIQtBACEEA0AgCyAFSARAIAcgB0HwAGogC0EDcUEEdGoiAikDCCIdNwPIASAHIAIpAwAiHjcDwAECQAJAAkAgBygCvAEiDCAepyICaiIKIBNLDQAgAyAHKALEASIJIAJqIhBqIBhLDQAgEiADayAQQSBqTw0BCyAHIAcpA8gBNwMgIAcgBykDwAE3AxggAyASIAdBGGogB0G8AWogEyAPIBUgERAeIRAMAQsgAiADaiEIIAMgDBAHIAJBEU8EQCADQRBqIQIDQCACIAxBEGoiDBAHIAJBEGoiAiAISQ0ACwsgCCAdpyIGayECIAcgCjYCvAEgBiAIIA9rSwRAIAYgCCAVa0sEQEFsIRAMAgsgESACIA9rIgJqIgwgCWogEU0EQCAIIAwgCRAPGgwCCyAIIAxBACACaxAPIQggByACIAlqIgk2AsQBIAggAmshCCAPIQILIAZBEE8EQCAIIAlqIQYDQCAIIAIQByACQRBqIQIgCEEQaiIIIAZJDQALDAELAkAgBkEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgBkECdCIGQcAeaigCAGoiAhAXIAIgBkHgHmooAgBrIQIgBygCxAEhCQwBCyAIIAIQDAsgCUEJSQ0AIAggCWohBiAIQQhqIgggAkEIaiICa0EPTARAA0AgCCACEAwgAkEIaiECIAhBCGoiCCAGSQ0ADAIACwALA0AgCCACEAcgAkEQaiECIAhBEGoiCCAGSQ0ACwsgEBADDQMgC0EBaiELIAMgEGohAwwBCwsDQCAEQQNHBEAgACAEQQJ0IgJqQazQAWogAiAHaigCVDYCACAEQQFqIQQMAQsLIAcoArwBIQgLQbp/IRAgEyAIayIAIBIgA2tLDQAgAwR/IAMgCCAAEAsgAGoFQQALIAFrIRALIAdB0AFqJAAgEAslACAAQgA3AgAgAEEAOwEIIABBADoACyAAIAE2AgwgACACOgAKC7QFAQN/IwBBMGsiBCQAIABB/wFqIgVBfWohBgJAIAMvAQIEQCAEQRhqIAEgAhAGIgIQAw0BIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahASOgAAIAMgBEEIaiAEQRhqEBI6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0FIAEgBEEQaiAEQRhqEBI6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBSABIARBCGogBEEYahASOgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEjoAACABIAJqIABrIQIMAwsgAyAEQRBqIARBGGoQEjoAAiADIARBCGogBEEYahASOgADIANBBGohAwwAAAsACyAEQRhqIAEgAhAGIgIQAw0AIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahAROgAAIAMgBEEIaiAEQRhqEBE6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0EIAEgBEEQaiAEQRhqEBE6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBCABIARBCGogBEEYahAROgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEToAACABIAJqIABrIQIMAgsgAyAEQRBqIARBGGoQEToAAiADIARBCGogBEEYahAROgADIANBBGohAwwAAAsACyAEQTBqJAAgAgtpAQF/An8CQAJAIAJBB00NACABKAAAQbfIwuF+Rw0AIAAgASgABDYCmOIBQWIgAEEQaiABIAIQPiIDEAMNAhogAEKBgICAEDcDiOEBIAAgASADaiACIANrECoMAQsgACABIAIQKgtBAAsLrQMBBn8jAEGAAWsiAyQAQWIhCAJAIAJBCUkNACAAQZjQAGogAUEIaiIEIAJBeGogAEGY0AAQMyIFEAMiBg0AIANBHzYCfCADIANB/ABqIANB+ABqIAQgBCAFaiAGGyIEIAEgAmoiAiAEaxAVIgUQAw0AIAMoAnwiBkEfSw0AIAMoAngiB0EJTw0AIABBiCBqIAMgBkGAC0GADCAHEBggA0E0NgJ8IAMgA0H8AGogA0H4AGogBCAFaiIEIAIgBGsQFSIFEAMNACADKAJ8IgZBNEsNACADKAJ4IgdBCk8NACAAQZAwaiADIAZBgA1B4A4gBxAYIANBIzYCfCADIANB/ABqIANB+ABqIAQgBWoiBCACIARrEBUiBRADDQAgAygCfCIGQSNLDQAgAygCeCIHQQpPDQAgACADIAZBwBBB0BEgBxAYIAQgBWoiBEEMaiIFIAJLDQAgAiAFayEFQQAhAgNAIAJBA0cEQCAEKAAAIgZBf2ogBU8NAiAAIAJBAnRqQZzQAWogBjYCACACQQFqIQIgBEEEaiEEDAELCyAEIAFrIQgLIANBgAFqJAAgCAtGAQN/IABBCGohAyAAKAIEIQJBACEAA0AgACACdkUEQCABIAMgAEEDdGotAAJBFktqIQEgAEEBaiEADAELCyABQQggAmt0C4YDAQV/Qbh/IQcCQCADRQ0AIAItAAAiBEUEQCABQQA2AgBBAUG4fyADQQFGGw8LAn8gAkEBaiIFIARBGHRBGHUiBkF/Sg0AGiAGQX9GBEAgA0EDSA0CIAUvAABBgP4BaiEEIAJBA2oMAQsgA0ECSA0BIAItAAEgBEEIdHJBgIB+aiEEIAJBAmoLIQUgASAENgIAIAVBAWoiASACIANqIgNLDQBBbCEHIABBEGogACAFLQAAIgVBBnZBI0EJIAEgAyABa0HAEEHQEUHwEiAAKAKM4QEgACgCnOIBIAQQHyIGEAMiCA0AIABBmCBqIABBCGogBUEEdkEDcUEfQQggASABIAZqIAgbIgEgAyABa0GAC0GADEGAFyAAKAKM4QEgACgCnOIBIAQQHyIGEAMiCA0AIABBoDBqIABBBGogBUECdkEDcUE0QQkgASABIAZqIAgbIgEgAyABa0GADUHgDkGQGSAAKAKM4QEgACgCnOIBIAQQHyIAEAMNACAAIAFqIAJrIQcLIAcLrQMBCn8jAEGABGsiCCQAAn9BUiACQf8BSw0AGkFUIANBDEsNABogAkEBaiELIABBBGohCUGAgAQgA0F/anRBEHUhCkEAIQJBASEEQQEgA3QiB0F/aiIMIQUDQCACIAtGRQRAAkAgASACQQF0Ig1qLwEAIgZB//8DRgRAIAkgBUECdGogAjoAAiAFQX9qIQVBASEGDAELIARBACAKIAZBEHRBEHVKGyEECyAIIA1qIAY7AQAgAkEBaiECDAELCyAAIAQ7AQIgACADOwEAIAdBA3YgB0EBdmpBA2ohBkEAIQRBACECA0AgBCALRkUEQCABIARBAXRqLgEAIQpBACEAA0AgACAKTkUEQCAJIAJBAnRqIAQ6AAIDQCACIAZqIAxxIgIgBUsNAAsgAEEBaiEADAELCyAEQQFqIQQMAQsLQX8gAg0AGkEAIQIDfyACIAdGBH9BAAUgCCAJIAJBAnRqIgAtAAJBAXRqIgEgAS8BACIBQQFqOwEAIAAgAyABEBRrIgU6AAMgACABIAVB/wFxdCAHazsBACACQQFqIQIMAQsLCyEFIAhBgARqJAAgBQvjBgEIf0FsIQcCQCACQQNJDQACQAJAAkACQCABLQAAIgNBA3EiCUEBaw4DAwEAAgsgACgCiOEBDQBBYg8LIAJBBUkNAkEDIQYgASgAACEFAn8CQAJAIANBAnZBA3EiCEF+aiIEQQFNBEAgBEEBaw0BDAILIAVBDnZB/wdxIQQgBUEEdkH/B3EhAyAIRQwCCyAFQRJ2IQRBBCEGIAVBBHZB//8AcSEDQQAMAQsgBUEEdkH//w9xIgNBgIAISw0DIAEtAARBCnQgBUEWdnIhBEEFIQZBAAshBSAEIAZqIgogAksNAgJAIANBgQZJDQAgACgCnOIBRQ0AQQAhAgNAIAJBg4ABSw0BIAJBQGshAgwAAAsACwJ/IAlBA0YEQCABIAZqIQEgAEHw4gFqIQIgACgCDCEGIAUEQCACIAMgASAEIAYQXwwCCyACIAMgASAEIAYQXQwBCyAAQbjQAWohAiABIAZqIQEgAEHw4gFqIQYgAEGo0ABqIQggBQRAIAggBiADIAEgBCACEF4MAQsgCCAGIAMgASAEIAIQXAsQAw0CIAAgAzYCgOIBIABBATYCiOEBIAAgAEHw4gFqNgLw4QEgCUECRgRAIAAgAEGo0ABqNgIMCyAAIANqIgBBiOMBakIANwAAIABBgOMBakIANwAAIABB+OIBakIANwAAIABB8OIBakIANwAAIAoPCwJ/AkACQAJAIANBAnZBA3FBf2oiBEECSw0AIARBAWsOAgACAQtBASEEIANBA3YMAgtBAiEEIAEvAABBBHYMAQtBAyEEIAEQIUEEdgsiAyAEaiIFQSBqIAJLBEAgBSACSw0CIABB8OIBaiABIARqIAMQCyEBIAAgAzYCgOIBIAAgATYC8OEBIAEgA2oiAEIANwAYIABCADcAECAAQgA3AAggAEIANwAAIAUPCyAAIAM2AoDiASAAIAEgBGo2AvDhASAFDwsCfwJAAkACQCADQQJ2QQNxQX9qIgRBAksNACAEQQFrDgIAAgELQQEhByADQQN2DAILQQIhByABLwAAQQR2DAELIAJBBEkgARAhIgJBj4CAAUtyDQFBAyEHIAJBBHYLIQIgAEHw4gFqIAEgB2otAAAgAkEgahAQIQEgACACNgKA4gEgACABNgLw4QEgB0EBaiEHCyAHC0sAIABC+erQ0OfJoeThADcDICAAQgA3AxggAELP1tO+0ser2UI3AxAgAELW64Lu6v2J9eAANwMIIABCADcDACAAQShqQQBBKBAQGgviAgICfwV+IABBKGoiASAAKAJIaiECAn4gACkDACIDQiBaBEAgACkDECIEQgeJIAApAwgiBUIBiXwgACkDGCIGQgyJfCAAKQMgIgdCEol8IAUQGSAEEBkgBhAZIAcQGQwBCyAAKQMYQsXP2bLx5brqJ3wLIAN8IQMDQCABQQhqIgAgAk0EQEIAIAEpAAAQCSADhUIbiUKHla+vmLbem55/fkLj3MqV/M7y9YV/fCEDIAAhAQwBCwsCQCABQQRqIgAgAksEQCABIQAMAQsgASgAAK1Ch5Wvr5i23puef34gA4VCF4lCz9bTvtLHq9lCfkL5893xmfaZqxZ8IQMLA0AgACACSQRAIAAxAABCxc/ZsvHluuonfiADhUILiUKHla+vmLbem55/fiEDIABBAWohAAwBCwsgA0IhiCADhULP1tO+0ser2UJ+IgNCHYggA4VC+fPd8Zn2masWfiIDQiCIIAOFC+8CAgJ/BH4gACAAKQMAIAKtfDcDAAJAAkAgACgCSCIDIAJqIgRBH00EQCABRQ0BIAAgA2pBKGogASACECAgACgCSCACaiEEDAELIAEgAmohAgJ/IAMEQCAAQShqIgQgA2ogAUEgIANrECAgACAAKQMIIAQpAAAQCTcDCCAAIAApAxAgACkAMBAJNwMQIAAgACkDGCAAKQA4EAk3AxggACAAKQMgIABBQGspAAAQCTcDICAAKAJIIQMgAEEANgJIIAEgA2tBIGohAQsgAUEgaiACTQsEQCACQWBqIQMgACkDICEFIAApAxghBiAAKQMQIQcgACkDCCEIA0AgCCABKQAAEAkhCCAHIAEpAAgQCSEHIAYgASkAEBAJIQYgBSABKQAYEAkhBSABQSBqIgEgA00NAAsgACAFNwMgIAAgBjcDGCAAIAc3AxAgACAINwMICyABIAJPDQEgAEEoaiABIAIgAWsiBBAgCyAAIAQ2AkgLCy8BAX8gAEUEQEG2f0EAIAMbDwtBun8hBCADIAFNBH8gACACIAMQEBogAwVBun8LCy8BAX8gAEUEQEG2f0EAIAMbDwtBun8hBCADIAFNBH8gACACIAMQCxogAwVBun8LC6gCAQZ/IwBBEGsiByQAIABB2OABaikDAEKAgIAQViEIQbh/IQUCQCAEQf//B0sNACAAIAMgBBBCIgUQAyIGDQAgACgCnOIBIQkgACAHQQxqIAMgAyAFaiAGGyIKIARBACAFIAYbayIGEEAiAxADBEAgAyEFDAELIAcoAgwhBCABRQRAQbp/IQUgBEEASg0BCyAGIANrIQUgAyAKaiEDAkAgCQRAIABBADYCnOIBDAELAkACQAJAIARBBUgNACAAQdjgAWopAwBCgICACFgNAAwBCyAAQQA2ApziAQwBCyAAKAIIED8hBiAAQQA2ApziASAGQRRPDQELIAAgASACIAMgBSAEIAgQOSEFDAELIAAgASACIAMgBSAEIAgQOiEFCyAHQRBqJAAgBQtnACAAQdDgAWogASACIAAoAuzhARAuIgEQAwRAIAEPC0G4fyECAkAgAQ0AIABB7OABaigCACIBBEBBYCECIAAoApjiASABRw0BC0EAIQIgAEHw4AFqKAIARQ0AIABBkOEBahBDCyACCycBAX8QVyIERQRAQUAPCyAEIAAgASACIAMgBBBLEE8hACAEEFYgAAs/AQF/AkACQAJAIAAoAqDiAUEBaiIBQQJLDQAgAUEBaw4CAAECCyAAEDBBAA8LIABBADYCoOIBCyAAKAKU4gELvAMCB38BfiMAQRBrIgkkAEG4fyEGAkAgBCgCACIIQQVBCSAAKALs4QEiBRtJDQAgAygCACIHQQFBBSAFGyAFEC8iBRADBEAgBSEGDAELIAggBUEDakkNACAAIAcgBRBJIgYQAw0AIAEgAmohCiAAQZDhAWohCyAIIAVrIQIgBSAHaiEHIAEhBQNAIAcgAiAJECwiBhADDQEgAkF9aiICIAZJBEBBuH8hBgwCCyAJKAIAIghBAksEQEFsIQYMAgsgB0EDaiEHAn8CQAJAAkAgCEEBaw4CAgABCyAAIAUgCiAFayAHIAYQSAwCCyAFIAogBWsgByAGEEcMAQsgBSAKIAVrIActAAAgCSgCCBBGCyIIEAMEQCAIIQYMAgsgACgC8OABBEAgCyAFIAgQRQsgAiAGayECIAYgB2ohByAFIAhqIQUgCSgCBEUNAAsgACkD0OABIgxCf1IEQEFsIQYgDCAFIAFrrFINAQsgACgC8OABBEBBaiEGIAJBBEkNASALEEQhDCAHKAAAIAynRw0BIAdBBGohByACQXxqIQILIAMgBzYCACAEIAI2AgAgBSABayEGCyAJQRBqJAAgBgsuACAAECsCf0EAQQAQAw0AGiABRSACRXJFBEBBYiAAIAEgAhA9EAMNARoLQQALCzcAIAEEQCAAIAAoAsTgASABKAIEIAEoAghqRzYCnOIBCyAAECtBABADIAFFckUEQCAAIAEQWwsL0QIBB38jAEEQayIGJAAgBiAENgIIIAYgAzYCDCAFBEAgBSgCBCEKIAUoAgghCQsgASEIAkACQANAIAAoAuzhARAWIQsCQANAIAQgC0kNASADKAAAQXBxQdDUtMIBRgRAIAMgBBAiIgcQAw0EIAQgB2shBCADIAdqIQMMAQsLIAYgAzYCDCAGIAQ2AggCQCAFBEAgACAFEE5BACEHQQAQA0UNAQwFCyAAIAogCRBNIgcQAw0ECyAAIAgQUCAMQQFHQQAgACAIIAIgBkEMaiAGQQhqEEwiByIDa0EAIAMQAxtBCkdyRQRAQbh/IQcMBAsgBxADDQMgAiAHayECIAcgCGohCEEBIQwgBigCDCEDIAYoAgghBAwBCwsgBiADNgIMIAYgBDYCCEG4fyEHIAQNASAIIAFrIQcMAQsgBiADNgIMIAYgBDYCCAsgBkEQaiQAIAcLRgECfyABIAAoArjgASICRwRAIAAgAjYCxOABIAAgATYCuOABIAAoArzgASEDIAAgATYCvOABIAAgASADIAJrajYCwOABCwutAgIEfwF+IwBBQGoiBCQAAkACQCACQQhJDQAgASgAAEFwcUHQ1LTCAUcNACABIAIQIiEBIABCADcDCCAAQQA2AgQgACABNgIADAELIARBGGogASACEC0iAxADBEAgACADEBoMAQsgAwRAIABBuH8QGgwBCyACIAQoAjAiA2shAiABIANqIQMDQAJAIAAgAyACIARBCGoQLCIFEAMEfyAFBSACIAVBA2oiBU8NAUG4fwsQGgwCCyAGQQFqIQYgAiAFayECIAMgBWohAyAEKAIMRQ0ACyAEKAI4BEAgAkEDTQRAIABBuH8QGgwCCyADQQRqIQMLIAQoAighAiAEKQMYIQcgAEEANgIEIAAgAyABazYCACAAIAIgBmytIAcgB0J/URs3AwgLIARBQGskAAslAQF/IwBBEGsiAiQAIAIgACABEFEgAigCACEAIAJBEGokACAAC30BBH8jAEGQBGsiBCQAIARB/wE2AggCQCAEQRBqIARBCGogBEEMaiABIAIQFSIGEAMEQCAGIQUMAQtBVCEFIAQoAgwiB0EGSw0AIAMgBEEQaiAEKAIIIAcQQSIFEAMNACAAIAEgBmogAiAGayADEDwhBQsgBEGQBGokACAFC4cBAgJ/An5BABAWIQMCQANAIAEgA08EQAJAIAAoAABBcHFB0NS0wgFGBEAgACABECIiAhADRQ0BQn4PCyAAIAEQVSIEQn1WDQMgBCAFfCIFIARUIQJCfiEEIAINAyAAIAEQUiICEAMNAwsgASACayEBIAAgAmohAAwBCwtCfiAFIAEbIQQLIAQLPwIBfwF+IwBBMGsiAiQAAn5CfiACQQhqIAAgARAtDQAaQgAgAigCHEEBRg0AGiACKQMICyEDIAJBMGokACADC40BAQJ/IwBBMGsiASQAAkAgAEUNACAAKAKI4gENACABIABB/OEBaigCADYCKCABIAApAvThATcDICAAEDAgACgCqOIBIQIgASABKAIoNgIYIAEgASkDIDcDECACIAFBEGoQGyAAQQA2AqjiASABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALKgECfyMAQRBrIgAkACAAQQA2AgggAEIANwMAIAAQWCEBIABBEGokACABC4cBAQN/IwBBEGsiAiQAAkAgACgCAEUgACgCBEVzDQAgAiAAKAIINgIIIAIgACkCADcDAAJ/IAIoAgAiAQRAIAIoAghBqOMJIAERBQAMAQtBqOMJECgLIgFFDQAgASAAKQIANwL04QEgAUH84QFqIAAoAgg2AgAgARBZIAEhAwsgAkEQaiQAIAMLywEBAn8jAEEgayIBJAAgAEGBgIDAADYCtOIBIABBADYCiOIBIABBADYC7OEBIABCADcDkOIBIABBADYCpOMJIABBADYC3OIBIABCADcCzOIBIABBADYCvOIBIABBADYCxOABIABCADcCnOIBIABBpOIBakIANwIAIABBrOIBakEANgIAIAFCADcCECABQgA3AhggASABKQMYNwMIIAEgASkDEDcDACABKAIIQQh2QQFxIQIgAEEANgLg4gEgACACNgKM4gEgAUEgaiQAC3YBA38jAEEwayIBJAAgAARAIAEgAEHE0AFqIgIoAgA2AiggASAAKQK80AE3AyAgACgCACEDIAEgAigCADYCGCABIAApArzQATcDECADIAFBEGoQGyABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALzAEBAX8gACABKAK00AE2ApjiASAAIAEoAgQiAjYCwOABIAAgAjYCvOABIAAgAiABKAIIaiICNgK44AEgACACNgLE4AEgASgCuNABBEAgAEKBgICAEDcDiOEBIAAgAUGk0ABqNgIMIAAgAUGUIGo2AgggACABQZwwajYCBCAAIAFBDGo2AgAgAEGs0AFqIAFBqNABaigCADYCACAAQbDQAWogAUGs0AFqKAIANgIAIABBtNABaiABQbDQAWooAgA2AgAPCyAAQgA3A4jhAQs7ACACRQRAQbp/DwsgBEUEQEFsDwsgAiAEEGAEQCAAIAEgAiADIAQgBRBhDwsgACABIAIgAyAEIAUQZQtGAQF/IwBBEGsiBSQAIAVBCGogBBAOAn8gBS0ACQRAIAAgASACIAMgBBAyDAELIAAgASACIAMgBBA0CyEAIAVBEGokACAACzQAIAAgAyAEIAUQNiIFEAMEQCAFDwsgBSAESQR/IAEgAiADIAVqIAQgBWsgABA1BUG4fwsLRgEBfyMAQRBrIgUkACAFQQhqIAQQDgJ/IAUtAAkEQCAAIAEgAiADIAQQYgwBCyAAIAEgAiADIAQQNQshACAFQRBqJAAgAAtZAQF/QQ8hAiABIABJBEAgAUEEdCAAbiECCyAAQQh2IgEgAkEYbCIAQYwIaigCAGwgAEGICGooAgBqIgJBA3YgAmogAEGACGooAgAgAEGECGooAgAgAWxqSQs3ACAAIAMgBCAFQYAQEDMiBRADBEAgBQ8LIAUgBEkEfyABIAIgAyAFaiAEIAVrIAAQMgVBuH8LC78DAQN/IwBBIGsiBSQAIAVBCGogAiADEAYiAhADRQRAIAAgAWoiB0F9aiEGIAUgBBAOIARBBGohAiAFLQACIQMDQEEAIAAgBkkgBUEIahAEGwRAIAAgAiAFQQhqIAMQAkECdGoiBC8BADsAACAFQQhqIAQtAAIQASAAIAQtAANqIgQgAiAFQQhqIAMQAkECdGoiAC8BADsAACAFQQhqIAAtAAIQASAEIAAtAANqIQAMAQUgB0F+aiEEA0AgBUEIahAEIAAgBEtyRQRAIAAgAiAFQQhqIAMQAkECdGoiBi8BADsAACAFQQhqIAYtAAIQASAAIAYtAANqIQAMAQsLA0AgACAES0UEQCAAIAIgBUEIaiADEAJBAnRqIgYvAQA7AAAgBUEIaiAGLQACEAEgACAGLQADaiEADAELCwJAIAAgB08NACAAIAIgBUEIaiADEAIiA0ECdGoiAC0AADoAACAALQADQQFGBEAgBUEIaiAALQACEAEMAQsgBSgCDEEfSw0AIAVBCGogAiADQQJ0ai0AAhABIAUoAgxBIUkNACAFQSA2AgwLIAFBbCAFQQhqEAobIQILCwsgBUEgaiQAIAILkgIBBH8jAEFAaiIJJAAgCSADQTQQCyEDAkAgBEECSA0AIAMgBEECdGooAgAhCSADQTxqIAgQIyADQQE6AD8gAyACOgA+QQAhBCADKAI8IQoDQCAEIAlGDQEgACAEQQJ0aiAKNgEAIARBAWohBAwAAAsAC0EAIQkDQCAGIAlGRQRAIAMgBSAJQQF0aiIKLQABIgtBAnRqIgwoAgAhBCADQTxqIAotAABBCHQgCGpB//8DcRAjIANBAjoAPyADIAcgC2siCiACajoAPiAEQQEgASAKa3RqIQogAygCPCELA0AgACAEQQJ0aiALNgEAIARBAWoiBCAKSQ0ACyAMIAo2AgAgCUEBaiEJDAELCyADQUBrJAALowIBCX8jAEHQAGsiCSQAIAlBEGogBUE0EAsaIAcgBmshDyAHIAFrIRADQAJAIAMgCkcEQEEBIAEgByACIApBAXRqIgYtAAEiDGsiCGsiC3QhDSAGLQAAIQ4gCUEQaiAMQQJ0aiIMKAIAIQYgCyAPTwRAIAAgBkECdGogCyAIIAUgCEE0bGogCCAQaiIIQQEgCEEBShsiCCACIAQgCEECdGooAgAiCEEBdGogAyAIayAHIA4QYyAGIA1qIQgMAgsgCUEMaiAOECMgCUEBOgAPIAkgCDoADiAGIA1qIQggCSgCDCELA0AgBiAITw0CIAAgBkECdGogCzYBACAGQQFqIQYMAAALAAsgCUHQAGokAA8LIAwgCDYCACAKQQFqIQoMAAALAAs0ACAAIAMgBCAFEDYiBRADBEAgBQ8LIAUgBEkEfyABIAIgAyAFaiAEIAVrIAAQNAVBuH8LCyMAIAA/AEEQdGtB//8DakEQdkAAQX9GBEBBAA8LQQAQAEEBCzsBAX8gAgRAA0AgACABIAJBgCAgAkGAIEkbIgMQCyEAIAFBgCBqIQEgAEGAIGohACACIANrIgINAAsLCwYAIAAQAwsLqBUJAEGICAsNAQAAAAEAAAACAAAAAgBBoAgLswYBAAAAAQAAAAIAAAACAAAAJgAAAIIAAAAhBQAASgAAAGcIAAAmAAAAwAEAAIAAAABJBQAASgAAAL4IAAApAAAALAIAAIAAAABJBQAASgAAAL4IAAAvAAAAygIAAIAAAACKBQAASgAAAIQJAAA1AAAAcwMAAIAAAACdBQAASgAAAKAJAAA9AAAAgQMAAIAAAADrBQAASwAAAD4KAABEAAAAngMAAIAAAABNBgAASwAAAKoKAABLAAAAswMAAIAAAADBBgAATQAAAB8NAABNAAAAUwQAAIAAAAAjCAAAUQAAAKYPAABUAAAAmQQAAIAAAABLCQAAVwAAALESAABYAAAA2gQAAIAAAABvCQAAXQAAACMUAABUAAAARQUAAIAAAABUCgAAagAAAIwUAABqAAAArwUAAIAAAAB2CQAAfAAAAE4QAAB8AAAA0gIAAIAAAABjBwAAkQAAAJAHAACSAAAAAAAAAAEAAAABAAAABQAAAA0AAAAdAAAAPQAAAH0AAAD9AAAA/QEAAP0DAAD9BwAA/Q8AAP0fAAD9PwAA/X8AAP3/AAD9/wEA/f8DAP3/BwD9/w8A/f8fAP3/PwD9/38A/f//AP3//wH9//8D/f//B/3//w/9//8f/f//P/3//38AAAAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAeAAAAHwAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACUAAAAnAAAAKQAAACsAAAAvAAAAMwAAADsAAABDAAAAUwAAAGMAAACDAAAAAwEAAAMCAAADBAAAAwgAAAMQAAADIAAAA0AAAAOAAAADAAEAQeAPC1EBAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAQcQQC4sBAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABIAAAAUAAAAFgAAABgAAAAcAAAAIAAAACgAAAAwAAAAQAAAAIAAAAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAAAAQBBkBIL5gQBAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAAAEAAAAEAAAACAAAAAAAAAABAAEBBgAAAAAAAAQAAAAAEAAABAAAAAAgAAAFAQAAAAAAAAUDAAAAAAAABQQAAAAAAAAFBgAAAAAAAAUHAAAAAAAABQkAAAAAAAAFCgAAAAAAAAUMAAAAAAAABg4AAAAAAAEFEAAAAAAAAQUUAAAAAAABBRYAAAAAAAIFHAAAAAAAAwUgAAAAAAAEBTAAAAAgAAYFQAAAAAAABwWAAAAAAAAIBgABAAAAAAoGAAQAAAAADAYAEAAAIAAABAAAAAAAAAAEAQAAAAAAAAUCAAAAIAAABQQAAAAAAAAFBQAAACAAAAUHAAAAAAAABQgAAAAgAAAFCgAAAAAAAAULAAAAAAAABg0AAAAgAAEFEAAAAAAAAQUSAAAAIAABBRYAAAAAAAIFGAAAACAAAwUgAAAAAAADBSgAAAAAAAYEQAAAABAABgRAAAAAIAAHBYAAAAAAAAkGAAIAAAAACwYACAAAMAAABAAAAAAQAAAEAQAAACAAAAUCAAAAIAAABQMAAAAgAAAFBQAAACAAAAUGAAAAIAAABQgAAAAgAAAFCQAAACAAAAULAAAAIAAABQwAAAAAAAAGDwAAACAAAQUSAAAAIAABBRQAAAAgAAIFGAAAACAAAgUcAAAAIAADBSgAAAAgAAQFMAAAAAAAEAYAAAEAAAAPBgCAAAAAAA4GAEAAAAAADQYAIABBgBcLhwIBAAEBBQAAAAAAAAUAAAAAAAAGBD0AAAAAAAkF/QEAAAAADwX9fwAAAAAVBf3/HwAAAAMFBQAAAAAABwR9AAAAAAAMBf0PAAAAABIF/f8DAAAAFwX9/38AAAAFBR0AAAAAAAgE/QAAAAAADgX9PwAAAAAUBf3/DwAAAAIFAQAAABAABwR9AAAAAAALBf0HAAAAABEF/f8BAAAAFgX9/z8AAAAEBQ0AAAAQAAgE/QAAAAAADQX9HwAAAAATBf3/BwAAAAEFAQAAABAABgQ9AAAAAAAKBf0DAAAAABAF/f8AAAAAHAX9//8PAAAbBf3//wcAABoF/f//AwAAGQX9//8BAAAYBf3//wBBkBkLhgQBAAEBBgAAAAAAAAYDAAAAAAAABAQAAAAgAAAFBQAAAAAAAAUGAAAAAAAABQgAAAAAAAAFCQAAAAAAAAULAAAAAAAABg0AAAAAAAAGEAAAAAAAAAYTAAAAAAAABhYAAAAAAAAGGQAAAAAAAAYcAAAAAAAABh8AAAAAAAAGIgAAAAAAAQYlAAAAAAABBikAAAAAAAIGLwAAAAAAAwY7AAAAAAAEBlMAAAAAAAcGgwAAAAAACQYDAgAAEAAABAQAAAAAAAAEBQAAACAAAAUGAAAAAAAABQcAAAAgAAAFCQAAAAAAAAUKAAAAAAAABgwAAAAAAAAGDwAAAAAAAAYSAAAAAAAABhUAAAAAAAAGGAAAAAAAAAYbAAAAAAAABh4AAAAAAAAGIQAAAAAAAQYjAAAAAAABBicAAAAAAAIGKwAAAAAAAwYzAAAAAAAEBkMAAAAAAAUGYwAAAAAACAYDAQAAIAAABAQAAAAwAAAEBAAAABAAAAQFAAAAIAAABQcAAAAgAAAFCAAAACAAAAUKAAAAIAAABQsAAAAAAAAGDgAAAAAAAAYRAAAAAAAABhQAAAAAAAAGFwAAAAAAAAYaAAAAAAAABh0AAAAAAAAGIAAAAAAAEAYDAAEAAAAPBgOAAAAAAA4GA0AAAAAADQYDIAAAAAAMBgMQAAAAAAsGAwgAAAAACgYDBABBpB0L2QEBAAAAAwAAAAcAAAAPAAAAHwAAAD8AAAB/AAAA/wAAAP8BAAD/AwAA/wcAAP8PAAD/HwAA/z8AAP9/AAD//wAA//8BAP//AwD//wcA//8PAP//HwD//z8A//9/AP///wD///8B////A////wf///8P////H////z////9/AAAAAAEAAAACAAAABAAAAAAAAAACAAAABAAAAAgAAAAAAAAAAQAAAAIAAAABAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAcAAAAIAAAACQAAAAoAAAALAEGgIAsDwBBQ'; function _createSuper$F(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct$F(); 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 _isNativeReflectConstruct$F() { 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; } } var _taskCache = new WeakMap(); var _activeLoaders = 0; var _zstd; var KTX2Loader = /*#__PURE__*/function (_Loader) { _inherits(KTX2Loader, _Loader); var _super = _createSuper$F(KTX2Loader); function KTX2Loader(manager) { var _this; _classCallCheck(this, KTX2Loader); _this = _super.call(this, manager); _this.transcoderPath = ''; _this.transcoderBinary = null; _this.transcoderPending = null; _this.workerPool = new WorkerPool$1(); _this.workerSourceURL = ''; _this.workerConfig = null; if (typeof MSC_TRANSCODER !== 'undefined') { console.warn('THREE.KTX2Loader: Please update to latest "basis_transcoder".' + ' "msc_basis_transcoder" is no longer supported in three.js r125+.'); } return _this; } _createClass(KTX2Loader, [{ key: "setTranscoderPath", value: function setTranscoderPath(path) { this.transcoderPath = path; return this; } }, { key: "setWorkerLimit", value: function setWorkerLimit(num) { this.workerPool.setWorkerLimit(num); return this; } }, { key: "detectSupport", value: function detectSupport(renderer) { this.workerConfig = { astcSupported: renderer.extensions.has('WEBGL_compressed_texture_astc'), etc1Supported: renderer.extensions.has('WEBGL_compressed_texture_etc1'), etc2Supported: renderer.extensions.has('WEBGL_compressed_texture_etc'), dxtSupported: renderer.extensions.has('WEBGL_compressed_texture_s3tc'), bptcSupported: renderer.extensions.has('EXT_texture_compression_bptc'), pvrtcSupported: renderer.extensions.has('WEBGL_compressed_texture_pvrtc') || renderer.extensions.has('WEBKIT_WEBGL_compressed_texture_pvrtc') }; if (renderer.capabilities.isWebGL2) { // https://github.com/mrdoob/three.js/pull/22928 this.workerConfig.etc1Supported = false; } return this; } }, { key: "init", value: function init() { var _this2 = this; if (!this.transcoderPending) { // Load transcoder wrapper. var jsLoader = new THREE$1.FileLoader(this.manager); jsLoader.setPath(this.transcoderPath); jsLoader.setWithCredentials(this.withCredentials); var jsContent = jsLoader.loadAsync('basis_transcoder.js'); // Load transcoder WASM binary. var binaryLoader = new THREE$1.FileLoader(this.manager); binaryLoader.setPath(this.transcoderPath); binaryLoader.setResponseType('arraybuffer'); binaryLoader.setWithCredentials(this.withCredentials); var binaryContent = binaryLoader.loadAsync('basis_transcoder.wasm'); this.transcoderPending = Promise.all([jsContent, binaryContent]).then(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), jsContent = _ref2[0], binaryContent = _ref2[1]; var fn = KTX2Loader.BasisWorker.toString(); var body = ['/* constants */', 'let _EngineFormat = ' + JSON.stringify(KTX2Loader.EngineFormat), 'let _TranscoderFormat = ' + JSON.stringify(KTX2Loader.TranscoderFormat), 'let _BasisFormat = ' + JSON.stringify(KTX2Loader.BasisFormat), '/* basis_transcoder.js */', jsContent, '/* worker */', fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))].join('\n'); _this2.workerSourceURL = URL.createObjectURL(new Blob([body])); _this2.transcoderBinary = binaryContent; _this2.workerPool.setWorkerCreator(function () { var worker = new Worker(_this2.workerSourceURL); var transcoderBinary = _this2.transcoderBinary.slice(0); worker.postMessage({ type: 'init', config: _this2.workerConfig, transcoderBinary }, [transcoderBinary]); return worker; }); }); if (_activeLoaders > 0) { // Each instance loads a transcoder and allocates workers, increasing network and memory cost. console.warn('THREE.KTX2Loader: Multiple active KTX2 loaders may cause performance issues.' + ' Use a single KTX2Loader instance, or call .dispose() on old instances.'); } _activeLoaders++; } return this.transcoderPending; } }, { key: "load", value: function load(url, onLoad, onProgress, onError) { var _this3 = this; if (this.workerConfig === null) { throw new Error('THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.'); } var loader = new THREE$1.FileLoader(this.manager); loader.setResponseType('arraybuffer'); loader.setWithCredentials(this.withCredentials); loader.load(url, function (buffer) { // Check for an existing task using this buffer. A transferred buffer cannot be transferred // again from this thread. if (_taskCache.has(buffer)) { var cachedTask = _taskCache.get(buffer); return cachedTask.promise.then(onLoad).catch(onError); } _this3._createTexture(buffer).then(function (texture) { return onLoad ? onLoad(texture) : null; }).catch(onError); }, onProgress, onError); } }, { key: "_createTextureFrom", value: function _createTextureFrom(transcodeResult) { var mipmaps = transcodeResult.mipmaps, width = transcodeResult.width, height = transcodeResult.height, format = transcodeResult.format, type = transcodeResult.type, error = transcodeResult.error, dfdTransferFn = transcodeResult.dfdTransferFn, dfdFlags = transcodeResult.dfdFlags; if (type === 'error') return Promise.reject(error); var texture = new THREE$1.CompressedTexture(mipmaps, width, height, format, THREE$1.UnsignedByteType); texture.minFilter = mipmaps.length === 1 ? THREE$1.LinearFilter : THREE$1.LinearMipmapLinearFilter; texture.magFilter = THREE$1.LinearFilter; texture.generateMipmaps = false; texture.needsUpdate = true; texture.encoding = dfdTransferFn === x$1 ? THREE$1.sRGBEncoding : THREE$1.LinearEncoding; texture.premultiplyAlpha = !!(dfdFlags & p$1); return texture; } /** * @param {ArrayBuffer} buffer * @param {object?} config * @return {Promise} */ }, { key: "_createTexture", value: function _createTexture(buffer) { var _this4 = this; var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var container = Pi(new Uint8Array(buffer)); if (container.vkFormat !== nt) { return createDataTexture(container); } // var taskConfig = config; var texturePending = this.init().then(function () { return _this4.workerPool.postMessage({ type: 'transcode', buffer, taskConfig: taskConfig }, [buffer]); }).then(function (e) { return _this4._createTextureFrom(e.data); }); // Cache the task result. _taskCache.set(buffer, { promise: texturePending }); return texturePending; } }, { key: "dispose", value: function dispose() { this.workerPool.dispose(); if (this.workerSourceURL) URL.revokeObjectURL(this.workerSourceURL); _activeLoaders--; return this; } }]); return KTX2Loader; }(THREE$1.Loader); /* CONSTANTS */ KTX2Loader.BasisFormat = { ETC1S: 0, UASTC_4x4: 1 }; KTX2Loader.TranscoderFormat = { ETC1: 0, ETC2: 1, BC1: 2, BC3: 3, BC4: 4, BC5: 5, BC7_M6_OPAQUE_ONLY: 6, BC7_M5: 7, PVRTC1_4_RGB: 8, PVRTC1_4_RGBA: 9, ASTC_4x4: 10, ATC_RGB: 11, ATC_RGBA_INTERPOLATED_ALPHA: 12, RGBA32: 13, RGB565: 14, BGR565: 15, RGBA4444: 16 }; KTX2Loader.EngineFormat = { RGBAFormat: THREE$1.RGBAFormat, RGBA_ASTC_4x4_Format: THREE$1.RGBA_ASTC_4x4_Format, RGBA_BPTC_Format: THREE$1.RGBA_BPTC_Format, RGBA_ETC2_EAC_Format: THREE$1.RGBA_ETC2_EAC_Format, RGBA_PVRTC_4BPPV1_Format: THREE$1.RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format: THREE$1.RGBA_S3TC_DXT5_Format, RGB_ETC1_Format: THREE$1.RGB_ETC1_Format, RGB_ETC2_Format: THREE$1.RGB_ETC2_Format, RGB_PVRTC_4BPPV1_Format: THREE$1.RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format: THREE$1.RGB_S3TC_DXT1_Format }; /* WEB WORKER */ KTX2Loader.BasisWorker = function () { var config; var transcoderPending; var BasisModule; var EngineFormat = _EngineFormat; // eslint-disable-line no-undef var TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef var BasisFormat = _BasisFormat; // eslint-disable-line no-undef self.addEventListener('message', function (e) { var message = e.data; switch (message.type) { case 'init': config = message.config; init(message.transcoderBinary); break; case 'transcode': transcoderPending.then(function () { try { var _transcode = transcode(message.buffer), width = _transcode.width, height = _transcode.height, hasAlpha = _transcode.hasAlpha, mipmaps = _transcode.mipmaps, format = _transcode.format, dfdTransferFn = _transcode.dfdTransferFn, dfdFlags = _transcode.dfdFlags; var buffers = []; for (var i = 0; i < mipmaps.length; ++i) { buffers.push(mipmaps[i].data.buffer); } self.postMessage({ type: 'transcode', id: message.id, width, height, hasAlpha, mipmaps, format, dfdTransferFn, dfdFlags }, buffers); } catch (error) { console.error(error); self.postMessage({ type: 'error', id: message.id, error: error.message }); } }); break; } }); function init(wasmBinary) { transcoderPending = new Promise(function (resolve) { BasisModule = { wasmBinary, onRuntimeInitialized: resolve }; BASIS(BasisModule); // eslint-disable-line no-undef }).then(function () { BasisModule.initializeBasis(); if (BasisModule.KTX2File === undefined) { console.warn('THREE.KTX2Loader: Please update Basis Universal transcoder.'); } }); } function transcode(buffer) { var ktx2File = new BasisModule.KTX2File(new Uint8Array(buffer)); function cleanup() { ktx2File.close(); ktx2File.delete(); } if (!ktx2File.isValid()) { cleanup(); throw new Error('THREE.KTX2Loader: Invalid or unsupported .ktx2 file'); } var basisFormat = ktx2File.isUASTC() ? BasisFormat.UASTC_4x4 : BasisFormat.ETC1S; var width = ktx2File.getWidth(); var height = ktx2File.getHeight(); var levels = ktx2File.getLevels(); var hasAlpha = ktx2File.getHasAlpha(); var dfdTransferFn = ktx2File.getDFDTransferFunc(); var dfdFlags = ktx2File.getDFDFlags(); var _getTranscoderFormat = getTranscoderFormat(basisFormat, width, height, hasAlpha), transcoderFormat = _getTranscoderFormat.transcoderFormat, engineFormat = _getTranscoderFormat.engineFormat; if (!width || !height || !levels) { cleanup(); throw new Error('THREE.KTX2Loader: Invalid texture'); } if (!ktx2File.startTranscoding()) { cleanup(); throw new Error('THREE.KTX2Loader: .startTranscoding failed'); } var mipmaps = []; for (var mip = 0; mip < levels; mip++) { var levelInfo = ktx2File.getImageLevelInfo(mip, 0, 0); var mipWidth = levelInfo.origWidth; var mipHeight = levelInfo.origHeight; var dst = new Uint8Array(ktx2File.getImageTranscodedSizeInBytes(mip, 0, 0, transcoderFormat)); var status = ktx2File.transcodeImage(dst, mip, 0, 0, transcoderFormat, 0, -1, -1); if (!status) { cleanup(); throw new Error('THREE.KTX2Loader: .transcodeImage failed.'); } mipmaps.push({ data: dst, width: mipWidth, height: mipHeight }); } cleanup(); return { width, height, hasAlpha, mipmaps, format: engineFormat, dfdTransferFn, dfdFlags }; } // // Optimal choice of a transcoder target format depends on the Basis format (ETC1S or UASTC), // device capabilities, and texture dimensions. The list below ranks the formats separately // for ETC1S and UASTC. // // In some cases, transcoding UASTC to RGBA32 might be preferred for higher quality (at // significant memory cost) compared to ETC1/2, BC1/3, and PVRTC. The transcoder currently // chooses RGBA32 only as a last resort and does not expose that option to the caller. var FORMAT_OPTIONS = [{ if: 'astcSupported', basisFormat: [BasisFormat.UASTC_4x4], transcoderFormat: [TranscoderFormat.ASTC_4x4, TranscoderFormat.ASTC_4x4], engineFormat: [EngineFormat.RGBA_ASTC_4x4_Format, EngineFormat.RGBA_ASTC_4x4_Format], priorityETC1S: Infinity, priorityUASTC: 1, needsPowerOfTwo: false }, { if: 'bptcSupported', basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4], transcoderFormat: [TranscoderFormat.BC7_M5, TranscoderFormat.BC7_M5], engineFormat: [EngineFormat.RGBA_BPTC_Format, EngineFormat.RGBA_BPTC_Format], priorityETC1S: 3, priorityUASTC: 2, needsPowerOfTwo: false }, { if: 'dxtSupported', basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4], transcoderFormat: [TranscoderFormat.BC1, TranscoderFormat.BC3], engineFormat: [EngineFormat.RGB_S3TC_DXT1_Format, EngineFormat.RGBA_S3TC_DXT5_Format], priorityETC1S: 4, priorityUASTC: 5, needsPowerOfTwo: false }, { if: 'etc2Supported', basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4], transcoderFormat: [TranscoderFormat.ETC1, TranscoderFormat.ETC2], engineFormat: [EngineFormat.RGB_ETC2_Format, EngineFormat.RGBA_ETC2_EAC_Format], priorityETC1S: 1, priorityUASTC: 3, needsPowerOfTwo: false }, { if: 'etc1Supported', basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4], transcoderFormat: [TranscoderFormat.ETC1], engineFormat: [EngineFormat.RGB_ETC1_Format], priorityETC1S: 2, priorityUASTC: 4, needsPowerOfTwo: false }, { if: 'pvrtcSupported', basisFormat: [BasisFormat.ETC1S, BasisFormat.UASTC_4x4], transcoderFormat: [TranscoderFormat.PVRTC1_4_RGB, TranscoderFormat.PVRTC1_4_RGBA], engineFormat: [EngineFormat.RGB_PVRTC_4BPPV1_Format, EngineFormat.RGBA_PVRTC_4BPPV1_Format], priorityETC1S: 5, priorityUASTC: 6, needsPowerOfTwo: true }]; var ETC1S_OPTIONS = FORMAT_OPTIONS.sort(function (a, b) { return a.priorityETC1S - b.priorityETC1S; }); var UASTC_OPTIONS = FORMAT_OPTIONS.sort(function (a, b) { return a.priorityUASTC - b.priorityUASTC; }); function getTranscoderFormat(basisFormat, width, height, hasAlpha) { var transcoderFormat; var engineFormat; var options = basisFormat === BasisFormat.ETC1S ? ETC1S_OPTIONS : UASTC_OPTIONS; for (var i = 0; i < options.length; i++) { var opt = options[i]; if (!config[opt.if]) continue; if (!opt.basisFormat.includes(basisFormat)) continue; if (hasAlpha && opt.transcoderFormat.length < 2) continue; if (opt.needsPowerOfTwo && !(isPowerOfTwo(width) && isPowerOfTwo(height))) continue; transcoderFormat = opt.transcoderFormat[hasAlpha ? 1 : 0]; engineFormat = opt.engineFormat[hasAlpha ? 1 : 0]; return { transcoderFormat, engineFormat }; } console.warn('THREE.KTX2Loader: No suitable compressed texture format found. Decoding to RGBA32.'); transcoderFormat = TranscoderFormat.RGBA32; engineFormat = EngineFormat.RGBAFormat; return { transcoderFormat, engineFormat }; } function isPowerOfTwo(value) { if (value <= 2) return true; return (value & value - 1) === 0 && value !== 0; } }; // // DataTexture and Data3DTexture parsing. var FORMAT_MAP = { [Ae]: THREE$1.RGBAFormat, [pe]: THREE$1.RGBAFormat, [Ot]: THREE$1.RGBAFormat, [Ft]: THREE$1.RGBAFormat, [de]: THREE$1.RGFormat, [se]: THREE$1.RGFormat, [yt]: THREE$1.RGFormat, [dt]: THREE$1.RGFormat, [xe]: THREE$1.RedFormat, [$t]: THREE$1.RedFormat, [gt]: THREE$1.RedFormat, [ct]: THREE$1.RedFormat }; var TYPE_MAP = { [Ae]: THREE$1.FloatType, [pe]: THREE$1.HalfFloatType, [Ot]: THREE$1.UnsignedByteType, [Ft]: THREE$1.UnsignedByteType, [de]: THREE$1.FloatType, [se]: THREE$1.HalfFloatType, [yt]: THREE$1.UnsignedByteType, [dt]: THREE$1.UnsignedByteType, [xe]: THREE$1.FloatType, [$t]: THREE$1.HalfFloatType, [gt]: THREE$1.UnsignedByteType, [ct]: THREE$1.UnsignedByteType }; var ENCODING_MAP = { [Ft]: THREE$1.sRGBEncoding, [dt]: THREE$1.sRGBEncoding, [gt]: THREE$1.sRGBEncoding }; function createDataTexture(_x) { return _createDataTexture.apply(this, arguments); } function _createDataTexture() { _createDataTexture = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2(container) { var vkFormat, pixelWidth, pixelHeight, pixelDepth, level, levelData, view, texture; return regenerator.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: vkFormat = container.vkFormat, pixelWidth = container.pixelWidth, pixelHeight = container.pixelHeight, pixelDepth = container.pixelDepth; if (!(FORMAT_MAP[vkFormat] === undefined)) { _context2.next = 3; break; } throw new Error('THREE.KTX2Loader: Unsupported vkFormat.'); case 3: // level = container.levels[0]; if (!(container.supercompressionScheme === t)) { _context2.next = 8; break; } levelData = level.levelData; _context2.next = 16; break; case 8: if (!(container.supercompressionScheme === n$2)) { _context2.next = 15; break; } if (!_zstd) { _zstd = new Promise( /*#__PURE__*/function () { var _ref3 = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(resolve) { var zstd; return regenerator.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: zstd = new Q(); _context.next = 3; return zstd.init(); case 3: resolve(zstd); case 4: case "end": return _context.stop(); } } }, _callee); })); return function (_x2) { return _ref3.apply(this, arguments); }; }()); } _context2.next = 12; return _zstd; case 12: levelData = _context2.sent.decode(level.levelData, level.uncompressedByteLength); _context2.next = 16; break; case 15: throw new Error('THREE.KTX2Loader: Unsupported supercompressionScheme.'); case 16: if (TYPE_MAP[vkFormat] === THREE$1.FloatType) { view = new Float32Array(levelData.buffer, levelData.byteOffset, levelData.byteLength / Float32Array.BYTES_PER_ELEMENT); } else if (TYPE_MAP[vkFormat] === THREE$1.HalfFloatType) { view = new Uint16Array(levelData.buffer, levelData.byteOffset, levelData.byteLength / Uint16Array.BYTES_PER_ELEMENT); } else { view = levelData; } // texture = pixelDepth === 0 ? new THREE$1.DataTexture(view, pixelWidth, pixelHeight) : new THREE$1.Data3DTexture(view, pixelWidth, pixelHeight, pixelDepth); texture.type = TYPE_MAP[vkFormat]; texture.format = FORMAT_MAP[vkFormat]; texture.encoding = ENCODING_MAP[vkFormat] || THREE$1.LinearEncoding; texture.needsUpdate = true; // return _context2.abrupt("return", Promise.resolve(texture)); case 23: case "end": return _context2.stop(); } } }, _callee2); })); return _createDataTexture.apply(this, arguments); } function _createSuper$E(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct$E();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 _isNativeReflectConstruct$E(){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;}}var _marked=/*#__PURE__*/regenerator.mark(makeStringIterator),_marked2=/*#__PURE__*/regenerator.mark(makeArrayBufferIterator),_marked3=/*#__PURE__*/regenerator.mark(makeMeshPrimitiveIterator);function _createForOfIteratorHelper$3(o,allowArrayLike){var it=typeof Symbol!=="undefined"&&o[Symbol.iterator]||o["@@iterator"];if(!it){if(Array.isArray(o)||(it=_unsupportedIterableToArray$3(o))||allowArrayLike&&o&&typeof o.length==="number"){if(it)o=it;var i=0;var F=function F(){};return {s:F,n:function n(){if(i>=o.length)return {done:true};return {done:false,value:o[i++]};},e:function e(_e){throw _e;},f:F};}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}var normalCompletion=true,didErr=false,err;return {s:function s(){it=it.call(o);},n:function n(){var step=it.next();normalCompletion=step.done;return step;},e:function e(_e2){didErr=true;err=_e2;},f:function f(){try{if(!normalCompletion&&it.return!=null)it.return();}finally{if(didErr)throw err;}}};}function _unsupportedIterableToArray$3(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray$3(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray$3(o,minLen);}function _arrayLikeToArray$3(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i1&&arguments[1]!==undefined?arguments[1]:true;var transfers=arguments.length>2?arguments[2]:undefined;var transfersSet=transfers||new Set();if(!object);else if(isTransferable(object)){transfersSet.add(object);}else if(isTransferable(object.buffer)){transfersSet.add(object.buffer);}else if(ArrayBuffer.isView(object));else if(recursive&&typeof object==='object'){for(var key in object){getTransferList(object[key],recursive,transfersSet);}}return transfers===undefined?Array.from(transfersSet):[];}function isTransferable(object){if(!object){return false;}if(object instanceof ArrayBuffer){return true;}if(typeof MessagePort!=='undefined'&&object instanceof MessagePort){return true;}if(typeof ImageBitmap!=='undefined'&&object instanceof ImageBitmap){return true;}if(typeof OffscreenCanvas!=='undefined'&&object instanceof OffscreenCanvas){return true;}return false;}var NOOP=function NOOP(){};var WorkerThread=/*#__PURE__*/function(){function WorkerThread(props){_classCallCheck(this,WorkerThread);_defineProperty(this,'name',void 0);_defineProperty(this,'source',void 0);_defineProperty(this,'url',void 0);_defineProperty(this,'terminated',false);_defineProperty(this,'worker',void 0);_defineProperty(this,'onMessage',void 0);_defineProperty(this,'onError',void 0);_defineProperty(this,'_loadableURL','');var name=props.name,source=props.source,url=props.url;assert$6(source||url);this.name=name;this.source=source;this.url=url;this.onMessage=NOOP;this.onError=function(error){return console.log(error);};this.worker=this._createBrowserWorker();}_createClass(WorkerThread,[{key:"destroy",value:function destroy(){this.onMessage=NOOP;this.onError=NOOP;this.worker.terminate();this.terminated=true;}},{key:"isRunning",get:function get(){return Boolean(this.onMessage);}},{key:"postMessage",value:function postMessage(data,transferList){transferList=transferList||getTransferList(data);this.worker.postMessage(data,transferList);}},{key:"_getErrorFromErrorEvent",value:function _getErrorFromErrorEvent(event){var message='Failed to load ';message+='worker '.concat(this.name,' from ').concat(this.url,'. ');if(event.message){message+=''.concat(event.message,' in ');}if(event.lineno){message+=':'.concat(event.lineno,':').concat(event.colno);}return new Error(message);}},{key:"_createBrowserWorker",value:function _createBrowserWorker(){var _this2=this;this._loadableURL=getLoadableWorkerURL({source:this.source,url:this.url});var worker=new Worker(this._loadableURL,{name:this.name});worker.onmessage=function(event){if(!event.data){_this2.onError(new Error('No data received'));}else {_this2.onMessage(event.data);}};worker.onerror=function(error){_this2.onError(_this2._getErrorFromErrorEvent(error));_this2.terminated=true;};worker.onmessageerror=function(event){return console.error(event);};return worker;}}],[{key:"isSupported",value:function isSupported(){return typeof Worker!=='undefined';}}]);return WorkerThread;}();var WorkerPool=/*#__PURE__*/function(){function WorkerPool(props){_classCallCheck(this,WorkerPool);_defineProperty(this,'name','unnamed');_defineProperty(this,'source',void 0);_defineProperty(this,'url',void 0);_defineProperty(this,'maxConcurrency',1);_defineProperty(this,'maxMobileConcurrency',1);_defineProperty(this,'onDebug',function(){});_defineProperty(this,'reuseWorkers',true);_defineProperty(this,'props',{});_defineProperty(this,'jobQueue',[]);_defineProperty(this,'idleQueue',[]);_defineProperty(this,'count',0);_defineProperty(this,'isDestroyed',false);this.source=props.source;this.url=props.url;this.setProps(props);}_createClass(WorkerPool,[{key:"destroy",value:function destroy(){this.idleQueue.forEach(function(worker){return worker.destroy();});this.isDestroyed=true;}},{key:"setProps",value:function setProps(props){this.props=_objectSpread$3(_objectSpread$3({},this.props),props);if(props.name!==undefined){this.name=props.name;}if(props.maxConcurrency!==undefined){this.maxConcurrency=props.maxConcurrency;}if(props.maxMobileConcurrency!==undefined){this.maxMobileConcurrency=props.maxMobileConcurrency;}if(props.reuseWorkers!==undefined){this.reuseWorkers=props.reuseWorkers;}if(props.onDebug!==undefined){this.onDebug=props.onDebug;}}},{key:"startJob",value:function(){var _startJob=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee(name){var _this3=this;var onMessage,onError,startPromise,_args2=arguments;return regenerator.wrap(function _callee$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:onMessage=_args2.length>1&&_args2[1]!==undefined?_args2[1]:function(job,type,data){return job.done(data);};onError=_args2.length>2&&_args2[2]!==undefined?_args2[2]:function(job,error){return job.error(error);};startPromise=new Promise(function(onStart){_this3.jobQueue.push({name,onMessage,onError,onStart});return _this3;});this._startQueuedJob();_context2.next=6;return startPromise;case 6:return _context2.abrupt("return",_context2.sent);case 7:case"end":return _context2.stop();}}},_callee,this);}));function startJob(_x7){return _startJob.apply(this,arguments);}return startJob;}()},{key:"_startQueuedJob",value:function(){var _startQueuedJob2=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee2(){var workerThread,queuedJob,job;return regenerator.wrap(function _callee2$(_context3){while(1){switch(_context3.prev=_context3.next){case 0:if(this.jobQueue.length){_context3.next=2;break;}return _context3.abrupt("return");case 2:workerThread=this._getAvailableWorker();if(workerThread){_context3.next=5;break;}return _context3.abrupt("return");case 5:queuedJob=this.jobQueue.shift();if(!queuedJob){_context3.next=18;break;}this.onDebug({message:'Starting job',name:queuedJob.name,workerThread,backlog:this.jobQueue.length});job=new WorkerJob(queuedJob.name,workerThread);workerThread.onMessage=function(data){return queuedJob.onMessage(job,data.type,data.payload);};workerThread.onError=function(error){return queuedJob.onError(job,error);};queuedJob.onStart(job);_context3.prev=12;_context3.next=15;return job.result;case 15:_context3.prev=15;this.returnWorkerToQueue(workerThread);return _context3.finish(15);case 18:case"end":return _context3.stop();}}},_callee2,this,[[12,,15,18]]);}));function _startQueuedJob(){return _startQueuedJob2.apply(this,arguments);}return _startQueuedJob;}()},{key:"returnWorkerToQueue",value:function returnWorkerToQueue(worker){var shouldDestroyWorker=this.isDestroyed||!this.reuseWorkers||this.count>this._getMaxConcurrency();if(shouldDestroyWorker){worker.destroy();this.count--;}else {this.idleQueue.push(worker);}if(!this.isDestroyed){this._startQueuedJob();}}},{key:"_getAvailableWorker",value:function _getAvailableWorker(){if(this.idleQueue.length>0){return this.idleQueue.shift()||null;}if(this.count0&&arguments[0]!==undefined?arguments[0]:{};WorkerFarm._workerFarm=WorkerFarm._workerFarm||new WorkerFarm({});WorkerFarm._workerFarm.setProps(props);return WorkerFarm._workerFarm;}}]);return WorkerFarm;}();_defineProperty(WorkerFarm,'_workerFarm',void 0);var NPM_TAG='latest';function getWorkerURL(worker){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var workerOptions=options[worker.id]||{};var workerFile=''.concat(worker.id,'-worker.js');var url=workerOptions.workerUrl;if(!url&&worker.id==='compression'){url=options.workerUrl;}if(options._workerType==='test'){url='modules/'.concat(worker.module,'/dist/').concat(workerFile);}if(!url){var version=worker.version;if(version==='latest'){version=NPM_TAG;}var versionTag=version?'@'.concat(version):'';url='https://unpkg.com/@loaders.gl/'.concat(worker.module).concat(versionTag,'/dist/').concat(workerFile);}assert$6(url);return url;}function validateWorkerVersion(worker){var coreVersion=arguments.length>1&&arguments[1]!==undefined?arguments[1]:VERSION$8;assert$6(worker,'no worker provided');var workerVersion=worker.version;if(!coreVersion||!workerVersion){return false;}return true;}var ChildProcessProxy={};var node=/*#__PURE__*/Object.freeze(/*#__PURE__*/Object.assign(/*#__PURE__*/Object.create(null),ChildProcessProxy,{default:ChildProcessProxy}));var VERSION$7='3.1.4';var loadLibraryPromises={};function loadLibrary(_x8){return _loadLibrary.apply(this,arguments);}function _loadLibrary(){_loadLibrary=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee14(libraryUrl){var moduleName,options,_args18=arguments;return regenerator.wrap(function _callee14$(_context18){while(1){switch(_context18.prev=_context18.next){case 0:moduleName=_args18.length>1&&_args18[1]!==undefined?_args18[1]:null;options=_args18.length>2&&_args18[2]!==undefined?_args18[2]:{};if(moduleName){libraryUrl=getLibraryUrl(libraryUrl,moduleName,options);}loadLibraryPromises[libraryUrl]=loadLibraryPromises[libraryUrl]||loadLibraryFromFile(libraryUrl);_context18.next=6;return loadLibraryPromises[libraryUrl];case 6:return _context18.abrupt("return",_context18.sent);case 7:case"end":return _context18.stop();}}},_callee14);}));return _loadLibrary.apply(this,arguments);}function getLibraryUrl(library,moduleName,options){if(library.startsWith('http')){return library;}var modules=options.modules||{};if(modules[library]){return modules[library];}if(!isBrowser$1){return 'modules/'.concat(moduleName,'/dist/libs/').concat(library);}if(options.CDN){assert$6(options.CDN.startsWith('http'));return ''.concat(options.CDN,'/').concat(moduleName,'@').concat(VERSION$7,'/dist/libs/').concat(library);}if(isWorker){return '../src/libs/'.concat(library);}return 'modules/'.concat(moduleName,'/src/libs/').concat(library);}function loadLibraryFromFile(_x9){return _loadLibraryFromFile.apply(this,arguments);}function _loadLibraryFromFile(){_loadLibraryFromFile=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee15(libraryUrl){var _response,response,scriptSource;return regenerator.wrap(function _callee15$(_context19){while(1){switch(_context19.prev=_context19.next){case 0:if(!libraryUrl.endsWith('wasm')){_context19.next=7;break;}_context19.next=3;return fetch(libraryUrl);case 3:_response=_context19.sent;_context19.next=6;return _response.arrayBuffer();case 6:return _context19.abrupt("return",_context19.sent);case 7:if(isBrowser$1){_context19.next=20;break;}_context19.prev=8;_context19.t0=node&&ChildProcessProxy.requireFromFile;if(!_context19.t0){_context19.next=14;break;}_context19.next=13;return ChildProcessProxy.requireFromFile(libraryUrl);case 13:_context19.t0=_context19.sent;case 14:return _context19.abrupt("return",_context19.t0);case 17:_context19.prev=17;_context19.t1=_context19["catch"](8);return _context19.abrupt("return",null);case 20:if(!isWorker){_context19.next=22;break;}return _context19.abrupt("return",importScripts(libraryUrl));case 22:_context19.next=24;return fetch(libraryUrl);case 24:response=_context19.sent;_context19.next=27;return response.text();case 27:scriptSource=_context19.sent;return _context19.abrupt("return",loadLibraryFromString(scriptSource,libraryUrl));case 29:case"end":return _context19.stop();}}},_callee15,null,[[8,17]]);}));return _loadLibraryFromFile.apply(this,arguments);}function loadLibraryFromString(scriptSource,id){if(!isBrowser$1){return ChildProcessProxy.requireFromString&&ChildProcessProxy.requireFromString(scriptSource,id);}if(isWorker){eval.call(global_,scriptSource);return null;}var script=document.createElement('script');script.id=id;try{script.appendChild(document.createTextNode(scriptSource));}catch(e){script.text=scriptSource;}document.body.appendChild(script);return null;}function canParseWithWorker(loader,options){if(!WorkerFarm.isSupported()){return false;}return loader.worker&&(options===null||options===void 0?void 0:options.worker);}function parseWithWorker(_x10,_x11,_x12,_x13,_x14){return _parseWithWorker.apply(this,arguments);}function _parseWithWorker(){_parseWithWorker=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee16(loader,data,options,context,parseOnMainThread){var name,url,workerFarm,workerPool,job,result;return regenerator.wrap(function _callee16$(_context20){while(1){switch(_context20.prev=_context20.next){case 0:name=loader.id;url=getWorkerURL(loader,options);workerFarm=WorkerFarm.getWorkerFarm(options);workerPool=workerFarm.getWorkerPool({name,url});options=JSON.parse(JSON.stringify(options));_context20.next=7;return workerPool.startJob('process-on-worker',onMessage.bind(null,parseOnMainThread));case 7:job=_context20.sent;job.postMessage('process',{input:data,options});_context20.next=11;return job.result;case 11:result=_context20.sent;_context20.next=14;return result.result;case 14:return _context20.abrupt("return",_context20.sent);case 15:case"end":return _context20.stop();}}},_callee16);}));return _parseWithWorker.apply(this,arguments);}function onMessage(_x15,_x16,_x17,_x18){return _onMessage.apply(this,arguments);}function _onMessage(){_onMessage=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee17(parseOnMainThread,job,type,payload){var id,input,_options,result,message;return regenerator.wrap(function _callee17$(_context21){while(1){switch(_context21.prev=_context21.next){case 0:_context21.t0=type;_context21.next=_context21.t0==='done'?3:_context21.t0==='error'?5:_context21.t0==='process'?7:20;break;case 3:job.done(payload);return _context21.abrupt("break",21);case 5:job.error(new Error(payload.error));return _context21.abrupt("break",21);case 7:id=payload.id,input=payload.input,_options=payload.options;_context21.prev=8;_context21.next=11;return parseOnMainThread(input,_options);case 11:result=_context21.sent;job.postMessage('done',{id,result});_context21.next=19;break;case 15:_context21.prev=15;_context21.t1=_context21["catch"](8);message=_context21.t1 instanceof Error?_context21.t1.message:'unknown error';job.postMessage('error',{id,error:message});case 19:return _context21.abrupt("break",21);case 20:console.warn('parse-with-worker unknown message '.concat(type));case 21:case"end":return _context21.stop();}}},_callee17,null,[[8,15]]);}));return _onMessage.apply(this,arguments);}function getFirstCharacters$1(data){var length=arguments.length>1&&arguments[1]!==undefined?arguments[1]:5;if(typeof data==='string'){return data.slice(0,length);}else if(ArrayBuffer.isView(data)){return getMagicString$3(data.buffer,data.byteOffset,length);}else if(data instanceof ArrayBuffer){var byteOffset=0;return getMagicString$3(data,byteOffset,length);}return '';}function getMagicString$3(arrayBuffer,byteOffset,length){if(arrayBuffer.byteLength<=byteOffset+length){return '';}var dataView=new DataView(arrayBuffer);var magic='';for(var _i=0;_i=0);assert$7(padding>0);return byteLength+(padding-1)&~(padding-1);}function copyToArray(source,target,targetOffset){var sourceArray;if(source instanceof ArrayBuffer){sourceArray=new Uint8Array(source);}else {var srcByteOffset=source.byteOffset;var srcByteLength=source.byteLength;sourceArray=new Uint8Array(source.buffer||source.arrayBuffer,srcByteOffset,srcByteLength);}target.set(sourceArray,targetOffset);return targetOffset+padToNBytes(sourceArray.byteLength,4);}function concatenateArrayBuffersAsync(asyncIterator){var arrayBuffers,_iteratorAbruptCompletion,_didIteratorError,_iteratorError,_iterator,_step,chunk;return regenerator.async(function concatenateArrayBuffersAsync$(_context){while(1){switch(_context.prev=_context.next){case 0:arrayBuffers=[];_iteratorAbruptCompletion=false;_didIteratorError=false;_context.prev=3;_iterator=_asyncIterator(asyncIterator);case 5:_context.next=7;return regenerator.awrap(_iterator.next());case 7:if(!(_iteratorAbruptCompletion=!(_step=_context.sent).done)){_context.next=13;break;}chunk=_step.value;arrayBuffers.push(chunk);case 10:_iteratorAbruptCompletion=false;_context.next=5;break;case 13:_context.next=19;break;case 15:_context.prev=15;_context.t0=_context["catch"](3);_didIteratorError=true;_iteratorError=_context.t0;case 19:_context.prev=19;_context.prev=20;if(!(_iteratorAbruptCompletion&&_iterator.return!=null)){_context.next=24;break;}_context.next=24;return regenerator.awrap(_iterator.return());case 24:_context.prev=24;if(!_didIteratorError){_context.next=27;break;}throw _iteratorError;case 27:return _context.finish(24);case 28:return _context.finish(19);case 29:return _context.abrupt("return",concatenateArrayBuffers.apply(void 0,arrayBuffers));case 30:case"end":return _context.stop();}}},null,null,[[3,15,19,29],[20,,24,28]],Promise);}function getHiResTimestamp$1(){var timestamp;if(typeof window!=='undefined'&&window.performance){timestamp=window.performance.now();}else if(typeof process!=='undefined'&&process.hrtime){var timeParts=process.hrtime();timestamp=timeParts[0]*1000+timeParts[1]/1e6;}else {timestamp=Date.now();}return timestamp;}var Stat=/*#__PURE__*/function(){function Stat(name,type){_classCallCheck(this,Stat);_defineProperty(this,'name',void 0);_defineProperty(this,'type',void 0);_defineProperty(this,'sampleSize',1);_defineProperty(this,'time',void 0);_defineProperty(this,'count',void 0);_defineProperty(this,'samples',void 0);_defineProperty(this,'lastTiming',void 0);_defineProperty(this,'lastSampleTime',void 0);_defineProperty(this,'lastSampleCount',void 0);_defineProperty(this,'_count',0);_defineProperty(this,'_time',0);_defineProperty(this,'_samples',0);_defineProperty(this,'_startTime',0);_defineProperty(this,'_timerPending',false);this.name=name;this.type=type;this.reset();}_createClass(Stat,[{key:"setSampleSize",value:function setSampleSize(samples){this.sampleSize=samples;return this;}},{key:"incrementCount",value:function incrementCount(){this.addCount(1);return this;}},{key:"decrementCount",value:function decrementCount(){this.subtractCount(1);return this;}},{key:"addCount",value:function addCount(value){this._count+=value;this._samples++;this._checkSampling();return this;}},{key:"subtractCount",value:function subtractCount(value){this._count-=value;this._samples++;this._checkSampling();return this;}},{key:"addTime",value:function addTime(time){this._time+=time;this.lastTiming=time;this._samples++;this._checkSampling();return this;}},{key:"timeStart",value:function timeStart(){this._startTime=getHiResTimestamp$1();this._timerPending=true;return this;}},{key:"timeEnd",value:function timeEnd(){if(!this._timerPending){return this;}this.addTime(getHiResTimestamp$1()-this._startTime);this._timerPending=false;this._checkSampling();return this;}},{key:"getSampleAverageCount",value:function getSampleAverageCount(){return this.sampleSize>0?this.lastSampleCount/this.sampleSize:0;}},{key:"getSampleAverageTime",value:function getSampleAverageTime(){return this.sampleSize>0?this.lastSampleTime/this.sampleSize:0;}},{key:"getSampleHz",value:function getSampleHz(){return this.lastSampleTime>0?this.sampleSize/(this.lastSampleTime/1000):0;}},{key:"getAverageCount",value:function getAverageCount(){return this.samples>0?this.count/this.samples:0;}},{key:"getAverageTime",value:function getAverageTime(){return this.samples>0?this.time/this.samples:0;}},{key:"getHz",value:function getHz(){return this.time>0?this.samples/(this.time/1000):0;}},{key:"reset",value:function reset(){this.time=0;this.count=0;this.samples=0;this.lastTiming=0;this.lastSampleTime=0;this.lastSampleCount=0;this._count=0;this._time=0;this._samples=0;this._startTime=0;this._timerPending=false;return this;}},{key:"_checkSampling",value:function _checkSampling(){if(this._samples===this.sampleSize){this.lastSampleTime=this._time;this.lastSampleCount=this._count;this.count+=this._count;this.time+=this._time;this.samples+=this._samples;this._time=0;this._count=0;this._samples=0;}}}]);return Stat;}();var Stats=/*#__PURE__*/function(){function Stats(options){_classCallCheck(this,Stats);_defineProperty(this,'id',void 0);_defineProperty(this,'stats',{});this.id=options.id;this.stats={};this._initializeStats(options.stats);Object.seal(this);}_createClass(Stats,[{key:"get",value:function get(name){var type=arguments.length>1&&arguments[1]!==undefined?arguments[1]:'count';return this._getOrCreate({name,type});}},{key:"size",get:function get(){return Object.keys(this.stats).length;}},{key:"reset",value:function reset(){for(var key in this.stats){this.stats[key].reset();}return this;}},{key:"forEach",value:function forEach(fn){for(var key in this.stats){fn(this.stats[key]);}}},{key:"getTable",value:function getTable(){var table={};this.forEach(function(stat){table[stat.name]={time:stat.time||0,count:stat.count||0,average:stat.getAverageTime()||0,hz:stat.getHz()||0};});return table;}},{key:"_initializeStats",value:function _initializeStats(){var _this4=this;var stats=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];stats.forEach(function(stat){return _this4._getOrCreate(stat);});}},{key:"_getOrCreate",value:function _getOrCreate(stat){if(!stat||!stat.name){return null;}var name=stat.name,type=stat.type;if(!this.stats[name]){if(stat instanceof Stat){this.stats[name]=stat;}else {this.stats[name]=new Stat(name,type);}}return this.stats[name];}}]);return Stats;}();var STAT_QUEUED_REQUESTS='Queued Requests';var STAT_ACTIVE_REQUESTS='Active Requests';var STAT_CANCELLED_REQUESTS='Cancelled Requests';var STAT_QUEUED_REQUESTS_EVER='Queued Requests Ever';var STAT_ACTIVE_REQUESTS_EVER='Active Requests Ever';var DEFAULT_PROPS$2={id:'request-scheduler',throttleRequests:true,maxRequests:6};var RequestScheduler=/*#__PURE__*/function(){function RequestScheduler(){var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};_classCallCheck(this,RequestScheduler);_defineProperty(this,'props',void 0);_defineProperty(this,'stats',void 0);_defineProperty(this,'activeRequestCount',0);_defineProperty(this,'requestQueue',[]);_defineProperty(this,'requestMap',new Map());_defineProperty(this,'deferredUpdate',null);this.props=_objectSpread$3(_objectSpread$3({},DEFAULT_PROPS$2),props);this.stats=new Stats({id:this.props.id});this.stats.get(STAT_QUEUED_REQUESTS);this.stats.get(STAT_ACTIVE_REQUESTS);this.stats.get(STAT_CANCELLED_REQUESTS);this.stats.get(STAT_QUEUED_REQUESTS_EVER);this.stats.get(STAT_ACTIVE_REQUESTS_EVER);}_createClass(RequestScheduler,[{key:"scheduleRequest",value:function scheduleRequest(handle){var getPriority=arguments.length>1&&arguments[1]!==undefined?arguments[1]:function(){return 0;};if(!this.props.throttleRequests){return Promise.resolve({done:function done(){}});}if(this.requestMap.has(handle)){return this.requestMap.get(handle);}var request={handle,priority:0,getPriority};var promise=new Promise(function(resolve){request.resolve=resolve;return request;});this.requestQueue.push(request);this.requestMap.set(handle,promise);this._issueNewRequests();return promise;}},{key:"_issueRequest",value:function _issueRequest(request){var _this5=this;var handle=request.handle,resolve=request.resolve;var isDone=false;var done=function done(){if(!isDone){isDone=true;_this5.requestMap.delete(handle);_this5.activeRequestCount--;_this5._issueNewRequests();}};this.activeRequestCount++;return resolve?resolve({done}):Promise.resolve({done});}},{key:"_issueNewRequests",value:function _issueNewRequests(){var _this6=this;if(!this.deferredUpdate){this.deferredUpdate=setTimeout(function(){return _this6._issueNewRequestsAsync();},0);}}},{key:"_issueNewRequestsAsync",value:function _issueNewRequestsAsync(){this.deferredUpdate=null;var freeSlots=Math.max(this.props.maxRequests-this.activeRequestCount,0);if(freeSlots===0){return;}this._updateAllRequests();for(var _i3=0;_i3=0?url.substr(slashIndex+1):'';}function dirname(url){var slashIndex=url&&url.lastIndexOf('/');return slashIndex>=0?url.substr(0,slashIndex):'';}var isBoolean=function isBoolean(x){return typeof x==='boolean';};var isFunction=function isFunction(x){return typeof x==='function';};var isObject$2=function isObject(x){return x!==null&&typeof x==='object';};var isPureObject=function isPureObject(x){return isObject$2(x)&&x.constructor==={}.constructor;};var isIterable=function isIterable(x){return x&&typeof x[Symbol.iterator]==='function';};var isAsyncIterable=function isAsyncIterable(x){return x&&typeof x[Symbol.asyncIterator]==='function';};var isResponse=function isResponse(x){return typeof Response!=='undefined'&&x instanceof Response||x&&x.arrayBuffer&&x.text&&x.json;};var isBlob=function isBlob(x){return typeof Blob!=='undefined'&&x instanceof Blob;};var isBuffer=function isBuffer(x){return x&&typeof x==='object'&&x.isBuffer;};var isReadableDOMStream=function isReadableDOMStream(x){return typeof ReadableStream!=='undefined'&&x instanceof ReadableStream||isObject$2(x)&&isFunction(x.tee)&&isFunction(x.cancel)&&isFunction(x.getReader);};var isReadableNodeStream=function isReadableNodeStream(x){return isObject$2(x)&&isFunction(x.read)&&isFunction(x.pipe)&&isBoolean(x.readable);};var isReadableStream=function isReadableStream(x){return isReadableDOMStream(x)||isReadableNodeStream(x);};var DATA_URL_PATTERN=/^data:([-\w.]+\/[-\w.+]+)(;|,)/;var MIME_TYPE_PATTERN=/^([-\w.]+\/[-\w.+]+)/;function parseMIMEType(mimeString){var matches=MIME_TYPE_PATTERN.exec(mimeString);if(matches){return matches[1];}return mimeString;}function parseMIMETypeFromURL(url){var matches=DATA_URL_PATTERN.exec(url);if(matches){return matches[1];}return '';}var QUERY_STRING_PATTERN=/\?.*/;function getResourceUrlAndType(resource){if(isResponse(resource)){var url=stripQueryString(resource.url||'');var contentTypeHeader=resource.headers.get('content-type')||'';return {url,type:parseMIMEType(contentTypeHeader)||parseMIMETypeFromURL(url)};}if(isBlob(resource)){return {url:stripQueryString(resource.name||''),type:resource.type||''};}if(typeof resource==='string'){return {url:stripQueryString(resource),type:parseMIMETypeFromURL(resource)};}return {url:'',type:''};}function getResourceContentLength(resource){if(isResponse(resource)){return resource.headers['content-length']||-1;}if(isBlob(resource)){return resource.size;}if(typeof resource==='string'){return resource.length;}if(resource instanceof ArrayBuffer){return resource.byteLength;}if(ArrayBuffer.isView(resource)){return resource.byteLength;}return -1;}function stripQueryString(url){return url.replace(QUERY_STRING_PATTERN,'');}function makeResponse(_x19){return _makeResponse.apply(this,arguments);}function _makeResponse(){_makeResponse=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee18(resource){var headers,contentLength,_getResourceUrlAndTyp3,url,type,initialDataUrl,response;return regenerator.wrap(function _callee18$(_context22){while(1){switch(_context22.prev=_context22.next){case 0:if(!isResponse(resource)){_context22.next=2;break;}return _context22.abrupt("return",resource);case 2:headers={};contentLength=getResourceContentLength(resource);if(contentLength>=0){headers['content-length']=String(contentLength);}_getResourceUrlAndTyp3=getResourceUrlAndType(resource),url=_getResourceUrlAndTyp3.url,type=_getResourceUrlAndTyp3.type;if(type){headers['content-type']=type;}_context22.next=9;return getInitialDataUrl(resource);case 9:initialDataUrl=_context22.sent;if(initialDataUrl){headers['x-first-bytes']=initialDataUrl;}if(typeof resource==='string'){resource=new TextEncoder().encode(resource);}response=new Response(resource,{headers});Object.defineProperty(response,'url',{value:url});return _context22.abrupt("return",response);case 15:case"end":return _context22.stop();}}},_callee18);}));return _makeResponse.apply(this,arguments);}function checkResponse(_x20){return _checkResponse.apply(this,arguments);}function _checkResponse(){_checkResponse=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee19(response){var message;return regenerator.wrap(function _callee19$(_context23){while(1){switch(_context23.prev=_context23.next){case 0:if(response.ok){_context23.next=5;break;}_context23.next=3;return getResponseError(response);case 3:message=_context23.sent;throw new Error(message);case 5:case"end":return _context23.stop();}}},_callee19);}));return _checkResponse.apply(this,arguments);}function getResponseError(_x21){return _getResponseError.apply(this,arguments);}function _getResponseError(){_getResponseError=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee20(response){var message,contentType,text;return regenerator.wrap(function _callee20$(_context24){while(1){switch(_context24.prev=_context24.next){case 0:message='Failed to fetch resource '.concat(response.url,' (').concat(response.status,'): ');_context24.prev=1;contentType=response.headers.get('Content-Type');text=response.statusText;if(!contentType.includes('application/json')){_context24.next=11;break;}_context24.t0=text;_context24.t1=' ';_context24.next=9;return response.text();case 9:_context24.t2=_context24.sent;text=_context24.t0+=_context24.t1.concat.call(_context24.t1,_context24.t2);case 11:message+=text;message=message.length>60?''.concat(message.slice(60),'...'):message;_context24.next=17;break;case 15:_context24.prev=15;_context24.t3=_context24["catch"](1);case 17:return _context24.abrupt("return",message);case 18:case"end":return _context24.stop();}}},_callee20,null,[[1,15]]);}));return _getResponseError.apply(this,arguments);}function getInitialDataUrl(_x22){return _getInitialDataUrl.apply(this,arguments);}function _getInitialDataUrl(){_getInitialDataUrl=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee21(resource){var INITIAL_DATA_LENGTH,blobSlice,slice,base64;return regenerator.wrap(function _callee21$(_context25){while(1){switch(_context25.prev=_context25.next){case 0:INITIAL_DATA_LENGTH=5;if(!(typeof resource==='string')){_context25.next=3;break;}return _context25.abrupt("return",'data:,'.concat(resource.slice(0,INITIAL_DATA_LENGTH)));case 3:if(!(resource instanceof Blob)){_context25.next=8;break;}blobSlice=resource.slice(0,5);_context25.next=7;return new Promise(function(resolve){var reader=new FileReader();reader.onload=function(event){var _event$target;return resolve(event===null||event===void 0?void 0:(_event$target=event.target)===null||_event$target===void 0?void 0:_event$target.result);};reader.readAsDataURL(blobSlice);});case 7:return _context25.abrupt("return",_context25.sent);case 8:if(!(resource instanceof ArrayBuffer)){_context25.next=12;break;}slice=resource.slice(0,INITIAL_DATA_LENGTH);base64=arrayBufferToBase64(slice);return _context25.abrupt("return",'data:base64,'.concat(base64));case 12:return _context25.abrupt("return",null);case 13:case"end":return _context25.stop();}}},_callee21);}));return _getInitialDataUrl.apply(this,arguments);}function arrayBufferToBase64(buffer){var binary='';var bytes=new Uint8Array(buffer);for(var _i5=0;_i5=0){return true;}return false;}function isBrowser(){var isNode=typeof process==='object'&&String(process)==='[object process]'&&!process.browser;return !isNode||isElectron();}var globals={self:typeof self!=='undefined'&&self,window:typeof window!=='undefined'&&window,global:typeof global!=='undefined'&&global,document:typeof document!=='undefined'&&document,process:typeof process==='object'&&process};var window_=globals.window||globals.self||globals.global;var process_=globals.process||{};var VERSION$6="4.12.0-alpha.26";isBrowser();function getStorage(type){try{var storage=window[type];var x='__storage_test__';storage.setItem(x,x);storage.removeItem(x);return storage;}catch(e){return null;}}var LocalStorage=/*#__PURE__*/function(){function LocalStorage(id){_classCallCheck(this,LocalStorage);var defaultSettings=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var type=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'sessionStorage';_defineProperty(this,'storage',void 0);_defineProperty(this,'id',void 0);_defineProperty(this,'config',{});this.storage=getStorage(type);this.id=id;this.config={};Object.assign(this.config,defaultSettings);this._loadConfiguration();}_createClass(LocalStorage,[{key:"getConfiguration",value:function getConfiguration(){return this.config;}},{key:"setConfiguration",value:function setConfiguration(configuration){this.config={};return this.updateConfiguration(configuration);}},{key:"updateConfiguration",value:function updateConfiguration(configuration){Object.assign(this.config,configuration);if(this.storage){var serialized=JSON.stringify(this.config);this.storage.setItem(this.id,serialized);}return this;}},{key:"_loadConfiguration",value:function _loadConfiguration(){var configuration={};if(this.storage){var serializedConfiguration=this.storage.getItem(this.id);configuration=serializedConfiguration?JSON.parse(serializedConfiguration):{};}Object.assign(this.config,configuration);return this;}}]);return LocalStorage;}();function formatTime(ms){var formatted;if(ms<10){formatted=''.concat(ms.toFixed(2),'ms');}else if(ms<100){formatted=''.concat(ms.toFixed(1),'ms');}else if(ms<1000){formatted=''.concat(ms.toFixed(0),'ms');}else {formatted=''.concat((ms/1000).toFixed(2),'s');}return formatted;}function leftPad(string){var length=arguments.length>1&&arguments[1]!==undefined?arguments[1]:8;var padLength=Math.max(length-string.length,0);return ''.concat(' '.repeat(padLength)).concat(string);}function formatImage(image,message,scale){var maxWidth=arguments.length>3&&arguments[3]!==undefined?arguments[3]:600;var imageUrl=image.src.replace(/\(/g,'%28').replace(/\)/g,'%29');if(image.width>maxWidth){scale=Math.min(scale,maxWidth/image.width);}var width=image.width*scale;var height=image.height*scale;var style=['font-size:1px;','padding:'.concat(Math.floor(height/2),'px ').concat(Math.floor(width/2),'px;'),'line-height:'.concat(height,'px;'),'background:url('.concat(imageUrl,');'),'background-size:'.concat(width,'px ').concat(height,'px;'),'color:transparent;'].join('');return [''.concat(message,' %c+'),style];}var COLOR;(function(COLOR){COLOR[COLOR['BLACK']=30]='BLACK';COLOR[COLOR['RED']=31]='RED';COLOR[COLOR['GREEN']=32]='GREEN';COLOR[COLOR['YELLOW']=33]='YELLOW';COLOR[COLOR['BLUE']=34]='BLUE';COLOR[COLOR['MAGENTA']=35]='MAGENTA';COLOR[COLOR['CYAN']=36]='CYAN';COLOR[COLOR['WHITE']=37]='WHITE';COLOR[COLOR['BRIGHT_BLACK']=90]='BRIGHT_BLACK';COLOR[COLOR['BRIGHT_RED']=91]='BRIGHT_RED';COLOR[COLOR['BRIGHT_GREEN']=92]='BRIGHT_GREEN';COLOR[COLOR['BRIGHT_YELLOW']=93]='BRIGHT_YELLOW';COLOR[COLOR['BRIGHT_BLUE']=94]='BRIGHT_BLUE';COLOR[COLOR['BRIGHT_MAGENTA']=95]='BRIGHT_MAGENTA';COLOR[COLOR['BRIGHT_CYAN']=96]='BRIGHT_CYAN';COLOR[COLOR['BRIGHT_WHITE']=97]='BRIGHT_WHITE';})(COLOR||(COLOR={}));function getColor(color){return typeof color==='string'?COLOR[color.toUpperCase()]||COLOR.WHITE:color;}function addColor(string,color,background){if(!isBrowser&&typeof string==='string'){if(color){color=getColor(color);string='\x1B['.concat(color,'m').concat(string,'\x1B[39m');}if(background){color=getColor(background);string='\x1B['.concat(background+10,'m').concat(string,'\x1B[49m');}}return string;}function autobind(obj){var predefined=arguments.length>1&&arguments[1]!==undefined?arguments[1]:['constructor'];var proto=Object.getPrototypeOf(obj);var propNames=Object.getOwnPropertyNames(proto);var _iterator6=_createForOfIteratorHelper$3(propNames),_step6;try{var _loop=function _loop(){var key=_step6.value;if(typeof obj[key]==='function'){if(!predefined.find(function(name){return key===name;})){obj[key]=obj[key].bind(obj);}}};for(_iterator6.s();!(_step6=_iterator6.n()).done;){_loop();}}catch(err){_iterator6.e(err);}finally{_iterator6.f();}}function assert$5(condition,message){if(!condition){throw new Error(message||'Assertion failed');}}function getHiResTimestamp(){var timestamp;if(isBrowser&&'performance'in window_){var _window$performance,_window$performance$n;timestamp=window_===null||window_===void 0?void 0:(_window$performance=window_.performance)===null||_window$performance===void 0?void 0:(_window$performance$n=_window$performance.now)===null||_window$performance$n===void 0?void 0:_window$performance$n.call(_window$performance);}else if('hrtime'in process_){var _process$hrtime;var timeParts=process_===null||process_===void 0?void 0:(_process$hrtime=process_.hrtime)===null||_process$hrtime===void 0?void 0:_process$hrtime.call(process_);timestamp=timeParts[0]*1000+timeParts[1]/1e6;}else {timestamp=Date.now();}return timestamp;}var originalConsole={debug:isBrowser?console.debug||console.log:console.log,log:console.log,info:console.info,warn:console.warn,error:console.error};var DEFAULT_SETTINGS={enabled:true,level:0};function noop$1(){}var cache={};var ONCE={once:true};var Log=/*#__PURE__*/function(){function Log(){_classCallCheck(this,Log);var _ref4=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{id:''},id=_ref4.id;_defineProperty(this,'id',void 0);_defineProperty(this,'VERSION',VERSION$6);_defineProperty(this,'_startTs',getHiResTimestamp());_defineProperty(this,'_deltaTs',getHiResTimestamp());_defineProperty(this,'_storage',void 0);_defineProperty(this,'userData',{});_defineProperty(this,'LOG_THROTTLE_TIMEOUT',0);this.id=id;this._storage=new LocalStorage('__probe-'.concat(this.id,'__'),DEFAULT_SETTINGS);this.userData={};this.timeStamp(''.concat(this.id,' started'));autobind(this);Object.seal(this);}_createClass(Log,[{key:"level",get:function get(){return this.getLevel();},set:function set(newLevel){this.setLevel(newLevel);}},{key:"isEnabled",value:function isEnabled(){return this._storage.config.enabled;}},{key:"getLevel",value:function getLevel(){return this._storage.config.level;}},{key:"getTotal",value:function getTotal(){return Number((getHiResTimestamp()-this._startTs).toPrecision(10));}},{key:"getDelta",value:function getDelta(){return Number((getHiResTimestamp()-this._deltaTs).toPrecision(10));}},{key:"priority",get:function get(){return this.level;},set:function set(newPriority){this.level=newPriority;}},{key:"getPriority",value:function getPriority(){return this.level;}},{key:"enable",value:function enable(){var enabled=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;this._storage.updateConfiguration({enabled});return this;}},{key:"setLevel",value:function setLevel(level){this._storage.updateConfiguration({level});return this;}},{key:"get",value:function get(setting){return this._storage.config[setting];}},{key:"set",value:function set(setting,value){this._storage.updateConfiguration({[setting]:value});}},{key:"settings",value:function settings(){if(console.table){console.table(this._storage.config);}else {console.log(this._storage.config);}}},{key:"assert",value:function assert(condition,message){assert$5(condition,message);}},{key:"warn",value:function warn(message){return this._getLogFunction(0,message,originalConsole.warn,arguments,ONCE);}},{key:"error",value:function error(message){return this._getLogFunction(0,message,originalConsole.error,arguments);}},{key:"deprecated",value:function deprecated(oldUsage,newUsage){return this.warn('`'.concat(oldUsage,'` is deprecated and will be removed in a later version. Use `').concat(newUsage,'` instead'));}},{key:"removed",value:function removed(oldUsage,newUsage){return this.error('`'.concat(oldUsage,'` has been removed. Use `').concat(newUsage,'` instead'));}},{key:"probe",value:function probe(logLevel,message){return this._getLogFunction(logLevel,message,originalConsole.log,arguments,{time:true,once:true});}},{key:"log",value:function log(logLevel,message){return this._getLogFunction(logLevel,message,originalConsole.debug,arguments);}},{key:"info",value:function info(logLevel,message){return this._getLogFunction(logLevel,message,console.info,arguments);}},{key:"once",value:function once(logLevel,message){for(var _len=arguments.length,args=new Array(_len>2?_len-2:0),_key=2;_key<_len;_key++){args[_key-2]=arguments[_key];}return this._getLogFunction(logLevel,message,originalConsole.debug||originalConsole.info,arguments,ONCE);}},{key:"table",value:function table(logLevel,_table,columns){if(_table){return this._getLogFunction(logLevel,_table,console.table||noop$1,columns&&[columns],{tag:getTableHeader(_table)});}return noop$1;}},{key:"image",value:function image(_ref){var logLevel=_ref.logLevel,priority=_ref.priority,image=_ref.image,_ref$message=_ref.message,message=_ref$message===void 0?'':_ref$message,_ref$scale=_ref.scale,scale=_ref$scale===void 0?1:_ref$scale;if(!this._shouldLog(logLevel||priority)){return noop$1;}return isBrowser?logImageInBrowser({image,message,scale}):logImageInNode({image,message,scale});}},{key:"time",value:function time(logLevel,message){return this._getLogFunction(logLevel,message,console.time?console.time:console.info);}},{key:"timeEnd",value:function timeEnd(logLevel,message){return this._getLogFunction(logLevel,message,console.timeEnd?console.timeEnd:console.info);}},{key:"timeStamp",value:function timeStamp(logLevel,message){return this._getLogFunction(logLevel,message,console.timeStamp||noop$1);}},{key:"group",value:function group(logLevel,message){var opts=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{collapsed:false};var options=normalizeArguments({logLevel,message,opts});var collapsed=opts.collapsed;options.method=(collapsed?console.groupCollapsed:console.group)||console.info;return this._getLogFunction(options);}},{key:"groupCollapsed",value:function groupCollapsed(logLevel,message){var opts=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};return this.group(logLevel,message,Object.assign({},opts,{collapsed:true}));}},{key:"groupEnd",value:function groupEnd(logLevel){return this._getLogFunction(logLevel,'',console.groupEnd||noop$1);}},{key:"withGroup",value:function withGroup(logLevel,message,func){this.group(logLevel,message)();try{func();}finally{this.groupEnd(logLevel)();}}},{key:"trace",value:function trace(){if(console.trace){console.trace();}}},{key:"_shouldLog",value:function _shouldLog(logLevel){return this.isEnabled()&&this.getLevel()>=normalizeLogLevel(logLevel);}},{key:"_getLogFunction",value:function _getLogFunction(logLevel,message,method,args,opts){if(this._shouldLog(logLevel)){var _method;opts=normalizeArguments({logLevel,message,args,opts});method=method||opts.method;assert$5(method);opts.total=this.getTotal();opts.delta=this.getDelta();this._deltaTs=getHiResTimestamp();var tag=opts.tag||opts.message;if(opts.once){if(!cache[tag]){cache[tag]=getHiResTimestamp();}else {return noop$1;}}message=decorateMessage(this.id,opts.message,opts);return (_method=method).bind.apply(_method,[console,message].concat(_toConsumableArray(opts.args)));}return noop$1;}}]);return Log;}();_defineProperty(Log,'VERSION',VERSION$6);function normalizeLogLevel(logLevel){if(!logLevel){return 0;}var resolvedLevel;switch(typeof logLevel){case'number':resolvedLevel=logLevel;break;case'object':resolvedLevel=logLevel.logLevel||logLevel.priority||0;break;default:return 0;}assert$5(Number.isFinite(resolvedLevel)&&resolvedLevel>=0);return resolvedLevel;}function normalizeArguments(opts){var logLevel=opts.logLevel,message=opts.message;opts.logLevel=normalizeLogLevel(logLevel);var args=opts.args?Array.from(opts.args):[];while(args.length&&args.shift()!==message){}switch(typeof logLevel){case'string':case'function':if(message!==undefined){args.unshift(message);}opts.message=logLevel;break;case'object':Object.assign(opts,logLevel);break;}if(typeof opts.message==='function'){opts.message=opts.message();}var messageType=typeof opts.message;assert$5(messageType==='string'||messageType==='object');return Object.assign(opts,{args},opts.opts);}function decorateMessage(id,message,opts){if(typeof message==='string'){var time=opts.time?leftPad(formatTime(opts.total)):'';message=opts.time?''.concat(id,': ').concat(time,' ').concat(message):''.concat(id,': ').concat(message);message=addColor(message,opts.color,opts.background);}return message;}function logImageInNode(_ref2){var image=_ref2.image;_ref2.message;var _ref2$scale=_ref2.scale,scale=_ref2$scale===void 0?1:_ref2$scale;var asciify=null;try{asciify=module.require('asciify-image');}catch(error){}if(asciify){return function(){return asciify(image,{fit:'box',width:''.concat(Math.round(80*scale),'%')}).then(function(data){return console.log(data);});};}return noop$1;}function logImageInBrowser(_ref3){var image=_ref3.image,_ref3$message=_ref3.message,message=_ref3$message===void 0?'':_ref3$message,_ref3$scale=_ref3.scale,scale=_ref3$scale===void 0?1:_ref3$scale;if(typeof image==='string'){var img=new Image();img.onload=function(){var _console;var args=formatImage(img,message,scale);(_console=console).log.apply(_console,_toConsumableArray(args));};img.src=image;return noop$1;}var element=image.nodeName||'';if(element.toLowerCase()==='img'){var _console2;(_console2=console).log.apply(_console2,_toConsumableArray(formatImage(image,message,scale)));return noop$1;}if(element.toLowerCase()==='canvas'){var _img=new Image();_img.onload=function(){var _console3;return (_console3=console).log.apply(_console3,_toConsumableArray(formatImage(_img,message,scale)));};_img.src=image.toDataURL();return noop$1;}return noop$1;}function getTableHeader(table){for(var key in table){for(var title in table[key]){return title||'untitled';}}return 'empty';}var probeLog=new Log({id:'loaders.gl'});var NullLog=/*#__PURE__*/function(){function NullLog(){_classCallCheck(this,NullLog);}_createClass(NullLog,[{key:"log",value:function log(){return function(){};}},{key:"info",value:function info(){return function(){};}},{key:"warn",value:function warn(){return function(){};}},{key:"error",value:function error(){return function(){};}}]);return NullLog;}();var ConsoleLog=/*#__PURE__*/function(){function ConsoleLog(){_classCallCheck(this,ConsoleLog);_defineProperty(this,'console',void 0);this.console=console;}_createClass(ConsoleLog,[{key:"log",value:function log(){var _this$console$log;for(var _len3=arguments.length,args=new Array(_len3),_key3=0;_key3<_len3;_key3++){args[_key3]=arguments[_key3];}return (_this$console$log=this.console.log).bind.apply(_this$console$log,[this.console].concat(args));}},{key:"info",value:function info(){var _this$console$info;for(var _len4=arguments.length,args=new Array(_len4),_key4=0;_key4<_len4;_key4++){args[_key4]=arguments[_key4];}return (_this$console$info=this.console.info).bind.apply(_this$console$info,[this.console].concat(args));}},{key:"warn",value:function warn(){var _this$console$warn;for(var _len5=arguments.length,args=new Array(_len5),_key5=0;_key5<_len5;_key5++){args[_key5]=arguments[_key5];}return (_this$console$warn=this.console.warn).bind.apply(_this$console$warn,[this.console].concat(args));}},{key:"error",value:function error(){var _this$console$error;for(var _len6=arguments.length,args=new Array(_len6),_key6=0;_key6<_len6;_key6++){args[_key6]=arguments[_key6];}return (_this$console$error=this.console.error).bind.apply(_this$console$error,[this.console].concat(args));}}]);return ConsoleLog;}();var DEFAULT_LOADER_OPTIONS={fetch:null,mimeType:undefined,nothrow:false,log:new ConsoleLog(),CDN:'https://unpkg.com/@loaders.gl',worker:true,maxConcurrency:3,maxMobileConcurrency:1,reuseWorkers:true,_workerType:'',limit:0,_limitMB:0,batchSize:'auto',batchDebounceMs:0,metadata:false,transforms:[]};var REMOVED_LOADER_OPTIONS={throws:'nothrow',dataType:'(no longer used)',uri:'baseUri',method:'fetch.method',headers:'fetch.headers',body:'fetch.body',mode:'fetch.mode',credentials:'fetch.credentials',cache:'fetch.cache',redirect:'fetch.redirect',referrer:'fetch.referrer',referrerPolicy:'fetch.referrerPolicy',integrity:'fetch.integrity',keepalive:'fetch.keepalive',signal:'fetch.signal'};function getGlobalLoaderState(){globalThis$1.loaders=globalThis$1.loaders||{};var loaders=globalThis$1.loaders;loaders._state=loaders._state||{};return loaders._state;}var getGlobalLoaderOptions=function getGlobalLoaderOptions(){var state=getGlobalLoaderState();state.globalOptions=state.globalOptions||_objectSpread$3({},DEFAULT_LOADER_OPTIONS);return state.globalOptions;};function normalizeOptions(options,loader,loaders,url){loaders=loaders||[];loaders=Array.isArray(loaders)?loaders:[loaders];validateOptions(options,loaders);return normalizeOptionsInternal(loader,options,url);}function getFetchFunction(options,context){var globalOptions=getGlobalLoaderOptions();var fetchOptions=options||globalOptions;if(typeof fetchOptions.fetch==='function'){return fetchOptions.fetch;}if(isObject$2(fetchOptions.fetch)){return function(url){return fetchFile(url,fetchOptions);};}if(context!==null&&context!==void 0&&context.fetch){return context===null||context===void 0?void 0:context.fetch;}return fetchFile;}function validateOptions(options,loaders){validateOptionsObject(options,null,DEFAULT_LOADER_OPTIONS,REMOVED_LOADER_OPTIONS,loaders);var _iterator7=_createForOfIteratorHelper$3(loaders),_step7;try{for(_iterator7.s();!(_step7=_iterator7.n()).done;){var loader=_step7.value;var idOptions=options&&options[loader.id]||{};var loaderOptions=loader.options&&loader.options[loader.id]||{};var deprecatedOptions=loader.deprecatedOptions&&loader.deprecatedOptions[loader.id]||{};validateOptionsObject(idOptions,loader.id,loaderOptions,deprecatedOptions,loaders);}}catch(err){_iterator7.e(err);}finally{_iterator7.f();}}function validateOptionsObject(options,id,defaultOptions,deprecatedOptions,loaders){var loaderName=id||'Top level';var prefix=id?''.concat(id,'.'):'';for(var key in options){var isSubOptions=!id&&isObject$2(options[key]);var isBaseUriOption=key==='baseUri'&&!id;var isWorkerUrlOption=key==='workerUrl'&&id;if(!(key in defaultOptions)&&!isBaseUriOption&&!isWorkerUrlOption){if(key in deprecatedOptions){probeLog.warn(''.concat(loaderName," loader option '").concat(prefix).concat(key,"' no longer supported, use '").concat(deprecatedOptions[key],"'"))();}else if(!isSubOptions){var suggestion=findSimilarOption(key,loaders);probeLog.warn(''.concat(loaderName," loader option '").concat(prefix).concat(key,"' not recognized. ").concat(suggestion))();}}}}function findSimilarOption(optionKey,loaders){var lowerCaseOptionKey=optionKey.toLowerCase();var bestSuggestion='';var _iterator8=_createForOfIteratorHelper$3(loaders),_step8;try{for(_iterator8.s();!(_step8=_iterator8.n()).done;){var loader=_step8.value;for(var key in loader.options){if(optionKey===key){return "Did you mean '".concat(loader.id,'.').concat(key,"'?");}var lowerCaseKey=key.toLowerCase();var isPartialMatch=lowerCaseOptionKey.startsWith(lowerCaseKey)||lowerCaseKey.startsWith(lowerCaseOptionKey);if(isPartialMatch){bestSuggestion=bestSuggestion||"Did you mean '".concat(loader.id,'.').concat(key,"'?");}}}}catch(err){_iterator8.e(err);}finally{_iterator8.f();}return bestSuggestion;}function normalizeOptionsInternal(loader,options,url){var loaderDefaultOptions=loader.options||{};var mergedOptions=_objectSpread$3({},loaderDefaultOptions);addUrlOptions(mergedOptions,url);if(mergedOptions.log===null){mergedOptions.log=new NullLog();}mergeNestedFields(mergedOptions,getGlobalLoaderOptions());mergeNestedFields(mergedOptions,options);return mergedOptions;}function mergeNestedFields(mergedOptions,options){for(var key in options){if(key in options){var value=options[key];if(isPureObject(value)&&isPureObject(mergedOptions[key])){mergedOptions[key]=_objectSpread$3(_objectSpread$3({},mergedOptions[key]),options[key]);}else {mergedOptions[key]=options[key];}}}}function addUrlOptions(options,url){if(url&&!('baseUri'in options)){options.baseUri=url;}}function isLoaderObject(loader){var _loader;if(!loader){return false;}if(Array.isArray(loader)){loader=loader[0];}var hasExtensions=Array.isArray((_loader=loader)===null||_loader===void 0?void 0:_loader.extensions);return hasExtensions;}function normalizeLoader(loader){var _loader2,_loader3;assert$7(loader,'null loader');assert$7(isLoaderObject(loader),'invalid loader');var options;if(Array.isArray(loader)){options=loader[1];loader=loader[0];loader=_objectSpread$3(_objectSpread$3({},loader),{},{options:_objectSpread$3(_objectSpread$3({},loader.options),options)});}if((_loader2=loader)!==null&&_loader2!==void 0&&_loader2.parseTextSync||(_loader3=loader)!==null&&_loader3!==void 0&&_loader3.parseText){loader.text=true;}if(!loader.text){loader.binary=true;}return loader;}var getGlobalLoaderRegistry=function getGlobalLoaderRegistry(){var state=getGlobalLoaderState();state.loaderRegistry=state.loaderRegistry||[];return state.loaderRegistry;};function getRegisteredLoaders(){return getGlobalLoaderRegistry();}var EXT_PATTERN=/\.([^.]+)$/;function selectLoader(_x25){return _selectLoader.apply(this,arguments);}function _selectLoader(){_selectLoader=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee23(data){var loaders,options,context,loader,_args27=arguments;return regenerator.wrap(function _callee23$(_context27){while(1){switch(_context27.prev=_context27.next){case 0:loaders=_args27.length>1&&_args27[1]!==undefined?_args27[1]:[];options=_args27.length>2?_args27[2]:undefined;context=_args27.length>3?_args27[3]:undefined;if(validHTTPResponse(data)){_context27.next=5;break;}return _context27.abrupt("return",null);case 5:loader=selectLoaderSync(data,loaders,_objectSpread$3(_objectSpread$3({},options),{},{nothrow:true}),context);if(!loader){_context27.next=8;break;}return _context27.abrupt("return",loader);case 8:if(!isBlob(data)){_context27.next=13;break;}_context27.next=11;return data.slice(0,10).arrayBuffer();case 11:data=_context27.sent;loader=selectLoaderSync(data,loaders,options,context);case 13:if(!(!loader&&!(options!==null&&options!==void 0&&options.nothrow))){_context27.next=15;break;}throw new Error(getNoValidLoaderMessage(data));case 15:return _context27.abrupt("return",loader);case 16:case"end":return _context27.stop();}}},_callee23);}));return _selectLoader.apply(this,arguments);}function selectLoaderSync(data){var loaders=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];var options=arguments.length>2?arguments[2]:undefined;var context=arguments.length>3?arguments[3]:undefined;if(!validHTTPResponse(data)){return null;}if(loaders&&!Array.isArray(loaders)){return normalizeLoader(loaders);}var candidateLoaders=[];if(loaders){candidateLoaders=candidateLoaders.concat(loaders);}if(!(options!==null&&options!==void 0&&options.ignoreRegisteredLoaders)){var _candidateLoaders;(_candidateLoaders=candidateLoaders).push.apply(_candidateLoaders,_toConsumableArray(getRegisteredLoaders()));}normalizeLoaders(candidateLoaders);var loader=selectLoaderInternal(data,candidateLoaders,options,context);if(!loader&&!(options!==null&&options!==void 0&&options.nothrow)){throw new Error(getNoValidLoaderMessage(data));}return loader;}function selectLoaderInternal(data,loaders,options,context){var _getResourceUrlAndTyp=getResourceUrlAndType(data),url=_getResourceUrlAndTyp.url,type=_getResourceUrlAndTyp.type;var testUrl=url||(context===null||context===void 0?void 0:context.url);var loader=null;if(options!==null&&options!==void 0&&options.mimeType){loader=findLoaderByMIMEType(loaders,options===null||options===void 0?void 0:options.mimeType);}loader=loader||findLoaderByUrl(loaders,testUrl);loader=loader||findLoaderByMIMEType(loaders,type);loader=loader||findLoaderByInitialBytes(loaders,data);loader=loader||findLoaderByMIMEType(loaders,options===null||options===void 0?void 0:options.fallbackMimeType);return loader;}function validHTTPResponse(data){if(data instanceof Response){if(data.status===204){return false;}}return true;}function getNoValidLoaderMessage(data){var _getResourceUrlAndTyp2=getResourceUrlAndType(data),url=_getResourceUrlAndTyp2.url,type=_getResourceUrlAndTyp2.type;var message='No valid loader found (';message+=url?''.concat(filename(url),', '):'no url provided, ';message+='MIME type: '.concat(type?'"'.concat(type,'"'):'not provided',', ');var firstCharacters=data?getFirstCharacters(data):'';message+=firstCharacters?' first bytes: "'.concat(firstCharacters,'"'):'first bytes: not available';message+=')';return message;}function normalizeLoaders(loaders){var _iterator9=_createForOfIteratorHelper$3(loaders),_step9;try{for(_iterator9.s();!(_step9=_iterator9.n()).done;){var loader=_step9.value;normalizeLoader(loader);}}catch(err){_iterator9.e(err);}finally{_iterator9.f();}}function findLoaderByUrl(loaders,url){var match=url&&EXT_PATTERN.exec(url);var extension=match&&match[1];return extension?findLoaderByExtension(loaders,extension):null;}function findLoaderByExtension(loaders,extension){extension=extension.toLowerCase();var _iterator10=_createForOfIteratorHelper$3(loaders),_step10;try{for(_iterator10.s();!(_step10=_iterator10.n()).done;){var loader=_step10.value;var _iterator11=_createForOfIteratorHelper$3(loader.extensions),_step11;try{for(_iterator11.s();!(_step11=_iterator11.n()).done;){var loaderExtension=_step11.value;if(loaderExtension.toLowerCase()===extension){return loader;}}}catch(err){_iterator11.e(err);}finally{_iterator11.f();}}}catch(err){_iterator10.e(err);}finally{_iterator10.f();}return null;}function findLoaderByMIMEType(loaders,mimeType){var _iterator12=_createForOfIteratorHelper$3(loaders),_step12;try{for(_iterator12.s();!(_step12=_iterator12.n()).done;){var loader=_step12.value;if(loader.mimeTypes&&loader.mimeTypes.includes(mimeType)){return loader;}if(mimeType==='application/x.'.concat(loader.id)){return loader;}}}catch(err){_iterator12.e(err);}finally{_iterator12.f();}return null;}function findLoaderByInitialBytes(loaders,data){if(!data){return null;}var _iterator13=_createForOfIteratorHelper$3(loaders),_step13;try{for(_iterator13.s();!(_step13=_iterator13.n()).done;){var loader=_step13.value;if(typeof data==='string'){if(testDataAgainstText(data,loader)){return loader;}}else if(ArrayBuffer.isView(data)){if(testDataAgainstBinary(data.buffer,data.byteOffset,loader)){return loader;}}else if(data instanceof ArrayBuffer){var byteOffset=0;if(testDataAgainstBinary(data,byteOffset,loader)){return loader;}}}}catch(err){_iterator13.e(err);}finally{_iterator13.f();}return null;}function testDataAgainstText(data,loader){if(loader.testText){return loader.testText(data);}var tests=Array.isArray(loader.tests)?loader.tests:[loader.tests];return tests.some(function(test){return data.startsWith(test);});}function testDataAgainstBinary(data,byteOffset,loader){var tests=Array.isArray(loader.tests)?loader.tests:[loader.tests];return tests.some(function(test){return testBinary(data,byteOffset,loader,test);});}function testBinary(data,byteOffset,loader,test){if(test instanceof ArrayBuffer){return compareArrayBuffers(test,data,test.byteLength);}switch(typeof test){case'function':return test(data,loader);case'string':var magic=getMagicString$2(data,byteOffset,test.length);return test===magic;default:return false;}}function getFirstCharacters(data){var length=arguments.length>1&&arguments[1]!==undefined?arguments[1]:5;if(typeof data==='string'){return data.slice(0,length);}else if(ArrayBuffer.isView(data)){return getMagicString$2(data.buffer,data.byteOffset,length);}else if(data instanceof ArrayBuffer){var byteOffset=0;return getMagicString$2(data,byteOffset,length);}return '';}function getMagicString$2(arrayBuffer,byteOffset,length){if(arrayBuffer.byteLength1&&_args5[1]!==undefined?_args5[1]:{};_options$chunkSize=options.chunkSize,chunkSize=_options$chunkSize===void 0?DEFAULT_CHUNK_SIZE$1:_options$chunkSize;byteOffset=0;case 3:if(!(byteOffset2&&arguments[2]!==undefined?arguments[2]:null;if(previousContext){return previousContext;}var resolvedContext=_objectSpread$3({fetch:getFetchFunction(options,context)},context);if(!Array.isArray(resolvedContext.loaders)){resolvedContext.loaders=null;}return resolvedContext;}function getLoadersFromContext(loaders,context){if(!context&&loaders&&!Array.isArray(loaders)){return loaders;}var candidateLoaders;if(loaders){candidateLoaders=Array.isArray(loaders)?loaders:[loaders];}if(context&&context.loaders){var contextLoaders=Array.isArray(context.loaders)?context.loaders:[context.loaders];candidateLoaders=candidateLoaders?[].concat(_toConsumableArray(candidateLoaders),_toConsumableArray(contextLoaders)):contextLoaders;}return candidateLoaders&&candidateLoaders.length?candidateLoaders:null;}function parse$3(_x29,_x30,_x31,_x32){return _parse$.apply(this,arguments);}function _parse$(){_parse$=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee25(data,loaders,options,context){var _getResourceUrlAndTyp4,url,typedLoaders,candidateLoaders,loader;return regenerator.wrap(function _callee25$(_context29){while(1){switch(_context29.prev=_context29.next){case 0:assert$6(!context||typeof context==='object');if(loaders&&!Array.isArray(loaders)&&!isLoaderObject(loaders)){context=undefined;options=loaders;loaders=undefined;}_context29.next=4;return data;case 4:data=_context29.sent;options=options||{};_getResourceUrlAndTyp4=getResourceUrlAndType(data),url=_getResourceUrlAndTyp4.url;typedLoaders=loaders;candidateLoaders=getLoadersFromContext(typedLoaders,context);_context29.next=11;return selectLoader(data,candidateLoaders,options);case 11:loader=_context29.sent;if(loader){_context29.next=14;break;}return _context29.abrupt("return",null);case 14:options=normalizeOptions(options,loader,candidateLoaders,url);context=getLoaderContext({url,parse:parse$3,loaders:candidateLoaders},options,context);_context29.next=18;return parseWithLoader(loader,data,options,context);case 18:return _context29.abrupt("return",_context29.sent);case 19:case"end":return _context29.stop();}}},_callee25);}));return _parse$.apply(this,arguments);}function parseWithLoader(_x33,_x34,_x35,_x36){return _parseWithLoader.apply(this,arguments);}function _parseWithLoader(){_parseWithLoader=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee26(loader,data,options,context){return regenerator.wrap(function _callee26$(_context30){while(1){switch(_context30.prev=_context30.next){case 0:validateWorkerVersion(loader);_context30.next=3;return getArrayBufferOrStringFromData(data,loader,options);case 3:data=_context30.sent;if(!(loader.parseTextSync&&typeof data==='string')){_context30.next=7;break;}options.dataType='text';return _context30.abrupt("return",loader.parseTextSync(data,options,context,loader));case 7:if(!canParseWithWorker(loader,options)){_context30.next=11;break;}_context30.next=10;return parseWithWorker(loader,data,options,context,parse$3);case 10:return _context30.abrupt("return",_context30.sent);case 11:if(!(loader.parseText&&typeof data==='string')){_context30.next=15;break;}_context30.next=14;return loader.parseText(data,options,context,loader);case 14:return _context30.abrupt("return",_context30.sent);case 15:if(!loader.parse){_context30.next=19;break;}_context30.next=18;return loader.parse(data,options,context,loader);case 18:return _context30.abrupt("return",_context30.sent);case 19:assert$6(!loader.parseSync);throw new Error(''.concat(loader.id,' loader - no parser found and worker is disabled'));case 21:case"end":return _context30.stop();}}},_callee26);}));return _parseWithLoader.apply(this,arguments);}function _load2(_x37,_x38,_x39,_x40){return _load.apply(this,arguments);}function _load(){_load=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee27(url,loaders,options,context){var fetch,data;return regenerator.wrap(function _callee27$(_context31){while(1){switch(_context31.prev=_context31.next){case 0:if(!Array.isArray(loaders)&&!isLoaderObject(loaders)){options=loaders;loaders=undefined;}fetch=getFetchFunction(options);data=url;if(!(typeof url==='string')){_context31.next=7;break;}_context31.next=6;return fetch(url);case 6:data=_context31.sent;case 7:if(!isBlob(url)){_context31.next=11;break;}_context31.next=10;return fetch(url);case 10:data=_context31.sent;case 11:_context31.next=13;return parse$3(data,loaders,options);case 13:return _context31.abrupt("return",_context31.sent);case 14:case"end":return _context31.stop();}}},_callee27);}));return _load.apply(this,arguments);}function assert$4(condition,message){if(!condition){throw new Error('math.gl assertion '.concat(message));}}var RADIANS_TO_DEGREES=1/Math.PI*180;var DEGREES_TO_RADIANS=1/180*Math.PI;var config$1={};config$1.EPSILON=1e-12;config$1.debug=false;config$1.precision=4;config$1.printTypes=false;config$1.printDegrees=false;config$1.printRowMajor=true;function round(value){return Math.round(value/config$1.EPSILON)*config$1.EPSILON;}function formatValue(value){var _ref5=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{},_ref5$precision=_ref5.precision,precision=_ref5$precision===void 0?config$1.precision||4:_ref5$precision;value=round(value);return ''.concat(parseFloat(value.toPrecision(precision)));}function isArray$2(value){return Array.isArray(value)||ArrayBuffer.isView(value)&&!(value instanceof DataView);}function duplicateArray(array){return array.clone?array.clone():new Array(array.length);}function map$1(value,func,result){if(isArray$2(value)){result=result||duplicateArray(value);for(var _i7=0;_i71&&arguments[1]!==undefined?arguments[1]:0;for(var _i9=0;_i90&&arguments[0]!==undefined?arguments[0]:[];var offset=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;for(var _i10=0;_i100?', ':'')+formatValue(this[_i11],opts);}return ''.concat(opts.printTypes?this.constructor.name:'','[').concat(string,']');}},{key:"equals",value:function equals(array){if(!array||this.length!==array.length){return false;}for(var _i12=0;_i122&&arguments[2]!==undefined?arguments[2]:'';if(config$1.debug&&!validateVector(v,length)){throw new Error('math.gl: '.concat(callerName," some fields set to invalid numbers'"));}return v;}var map={};function deprecated(method,version){if(!map[method]){map[method]=true;console.warn(''.concat(method,' has been removed in version ').concat(version,', see upgrade guide for more information'));}}var Vector=/*#__PURE__*/function(_MathArray){_inherits(Vector,_MathArray);var _super2=_createSuper$E(Vector);function Vector(){_classCallCheck(this,Vector);return _super2.apply(this,arguments);}_createClass(Vector,[{key:"ELEMENTS",get:function get(){assert$4(false);return 0;}},{key:"copy",value:function copy(vector){assert$4(false);return this;}},{key:"x",get:function get(){return this[0];},set:function set(value){this[0]=checkNumber(value);}},{key:"y",get:function get(){return this[1];},set:function set(value){this[1]=checkNumber(value);}},{key:"len",value:function len(){return Math.sqrt(this.lengthSquared());}},{key:"magnitude",value:function magnitude(){return this.len();}},{key:"lengthSquared",value:function lengthSquared(){var length=0;for(var _i30=0;_i30=0&&i=0&&i0&&arguments[0]!==undefined?arguments[0]:0;var y=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;_classCallCheck(this,Vector2);_this7=_super3.call(this,2);if(isArray$2(x)&&arguments.length===1){_this7.copy(x);}else {if(config$1.debug){checkNumber(x);checkNumber(y);}_this7[0]=x;_this7[1]=y;}return _this7;}_createClass(Vector2,[{key:"set",value:function set(x,y){this[0]=x;this[1]=y;return this.check();}},{key:"copy",value:function copy(array){this[0]=array[0];this[1]=array[1];return this.check();}},{key:"fromObject",value:function fromObject(object){if(config$1.debug){checkNumber(object.x);checkNumber(object.y);}this[0]=object.x;this[1]=object.y;return this.check();}},{key:"toObject",value:function toObject(object){object.x=this[0];object.y=this[1];return object;}},{key:"ELEMENTS",get:function get(){return 2;}},{key:"horizontalAngle",value:function horizontalAngle(){return Math.atan2(this.y,this.x);}},{key:"verticalAngle",value:function verticalAngle(){return Math.atan2(this.x,this.y);}},{key:"transform",value:function transform(matrix4){return this.transformAsPoint(matrix4);}},{key:"transformAsPoint",value:function transformAsPoint(matrix4){transformMat4$2(this,this,matrix4);return this.check();}},{key:"transformAsVector",value:function transformAsVector(matrix4){vec2_transformMat4AsVector(this,this,matrix4);return this.check();}},{key:"transformByMatrix3",value:function transformByMatrix3(matrix3){transformMat3$1(this,this,matrix3);return this.check();}},{key:"transformByMatrix2x3",value:function transformByMatrix2x3(matrix2x3){transformMat2d(this,this,matrix2x3);return this.check();}},{key:"transformByMatrix2",value:function transformByMatrix2(matrix2){transformMat2(this,this,matrix2);return this.check();}}]);return Vector2;}(Vector);/** * 3 Dimensional Vector * @module vec3 */ /** * Creates a new, empty vec3 * * @returns {vec3} a new 3D vector */function create$3(){var out=new ARRAY_TYPE(3);if(ARRAY_TYPE!=Float32Array){out[0]=0;out[1]=0;out[2]=0;}return out;}/** * Calculates the length of a vec3 * * @param {ReadonlyVec3} a vector to calculate length of * @returns {Number} length of a */function length$2(a){var x=a[0];var y=a[1];var z=a[2];return Math.hypot(x,y,z);}/** * Creates a new vec3 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @returns {vec3} a new 3D vector */function fromValues(x,y,z){var out=new ARRAY_TYPE(3);out[0]=x;out[1]=y;out[2]=z;return out;}/** * Normalize a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to normalize * @returns {vec3} out */function normalize$2(out,a){var x=a[0];var y=a[1];var z=a[2];var len=x*x+y*y+z*z;if(len>0){//TODO: evaluate use of glm_invsqrt here? len=1/Math.sqrt(len);}out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len;return out;}/** * Calculates the dot product of two vec3's * * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {Number} dot product of a and b */function dot$2(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];}/** * Computes the cross product of two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */function _cross(out,a,b){var ax=a[0],ay=a[1],az=a[2];var bx=b[0],by=b[1],bz=b[2];out[0]=ay*bz-az*by;out[1]=az*bx-ax*bz;out[2]=ax*by-ay*bx;return out;}/** * Transforms the vec3 with a mat4. * 4th vector component is implicitly '1' * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyMat4} m matrix to transform with * @returns {vec3} out */function transformMat4$1(out,a,m){var x=a[0],y=a[1],z=a[2];var w=m[3]*x+m[7]*y+m[11]*z+m[15];w=w||1.0;out[0]=(m[0]*x+m[4]*y+m[8]*z+m[12])/w;out[1]=(m[1]*x+m[5]*y+m[9]*z+m[13])/w;out[2]=(m[2]*x+m[6]*y+m[10]*z+m[14])/w;return out;}/** * Transforms the vec3 with a mat3. * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyMat3} m the 3x3 matrix to transform with * @returns {vec3} out */function transformMat3(out,a,m){var x=a[0],y=a[1],z=a[2];out[0]=x*m[0]+y*m[3]+z*m[6];out[1]=x*m[1]+y*m[4]+z*m[7];out[2]=x*m[2]+y*m[5]+z*m[8];return out;}/** * Transforms the vec3 with a quat * Can also be used for dual quaternions. (Multiply it with the real part) * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyQuat} q quaternion to transform with * @returns {vec3} out */function transformQuat$1(out,a,q){// benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed var qx=q[0],qy=q[1],qz=q[2],qw=q[3];var x=a[0],y=a[1],z=a[2];// var qvec = [qx, qy, qz]; // var uv = vec3.cross([], qvec, a); var uvx=qy*z-qz*y,uvy=qz*x-qx*z,uvz=qx*y-qy*x;// var uuv = vec3.cross([], qvec, uv); var uuvx=qy*uvz-qz*uvy,uuvy=qz*uvx-qx*uvz,uuvz=qx*uvy-qy*uvx;// vec3.scale(uv, uv, 2 * w); var w2=qw*2;uvx*=w2;uvy*=w2;uvz*=w2;// vec3.scale(uuv, uuv, 2); uuvx*=2;uuvy*=2;uuvz*=2;// return vec3.add(out, a, vec3.add(out, uv, uuv)); out[0]=x+uvx+uuvx;out[1]=y+uvy+uuvy;out[2]=z+uvz+uuvz;return out;}/** * Rotate a 3D vector around the x-axis * @param {vec3} out The receiving vec3 * @param {ReadonlyVec3} a The vec3 point to rotate * @param {ReadonlyVec3} b The origin of the rotation * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */function rotateX$2(out,a,b,rad){var p=[],r=[];//Translate point to the origin p[0]=a[0]-b[0];p[1]=a[1]-b[1];p[2]=a[2]-b[2];//perform rotation r[0]=p[0];r[1]=p[1]*Math.cos(rad)-p[2]*Math.sin(rad);r[2]=p[1]*Math.sin(rad)+p[2]*Math.cos(rad);//translate to correct position out[0]=r[0]+b[0];out[1]=r[1]+b[1];out[2]=r[2]+b[2];return out;}/** * Rotate a 3D vector around the y-axis * @param {vec3} out The receiving vec3 * @param {ReadonlyVec3} a The vec3 point to rotate * @param {ReadonlyVec3} b The origin of the rotation * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */function rotateY$2(out,a,b,rad){var p=[],r=[];//Translate point to the origin p[0]=a[0]-b[0];p[1]=a[1]-b[1];p[2]=a[2]-b[2];//perform rotation r[0]=p[2]*Math.sin(rad)+p[0]*Math.cos(rad);r[1]=p[1];r[2]=p[2]*Math.cos(rad)-p[0]*Math.sin(rad);//translate to correct position out[0]=r[0]+b[0];out[1]=r[1]+b[1];out[2]=r[2]+b[2];return out;}/** * Rotate a 3D vector around the z-axis * @param {vec3} out The receiving vec3 * @param {ReadonlyVec3} a The vec3 point to rotate * @param {ReadonlyVec3} b The origin of the rotation * @param {Number} rad The angle of rotation in radians * @returns {vec3} out */function rotateZ$2(out,a,b,rad){var p=[],r=[];//Translate point to the origin p[0]=a[0]-b[0];p[1]=a[1]-b[1];p[2]=a[2]-b[2];//perform rotation r[0]=p[0]*Math.cos(rad)-p[1]*Math.sin(rad);r[1]=p[0]*Math.sin(rad)+p[1]*Math.cos(rad);r[2]=p[2];//translate to correct position out[0]=r[0]+b[0];out[1]=r[1]+b[1];out[2]=r[2]+b[2];return out;}/** * Get the angle between two 3D vectors * @param {ReadonlyVec3} a The first operand * @param {ReadonlyVec3} b The second operand * @returns {Number} The angle in radians */function _angle(a,b){var ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2],mag1=Math.sqrt(ax*ax+ay*ay+az*az),mag2=Math.sqrt(bx*bx+by*by+bz*bz),mag=mag1*mag2,cosine=mag&&dot$2(a,b)/mag;return Math.acos(Math.min(Math.max(cosine,-1),1));}/** * Alias for {@link vec3.length} * @function */var len=length$2/** * Perform some operation over an array of vec3s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */;(function(){var vec=create$3();return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=3;}if(!offset){offset=0;}if(count){l=Math.min(count*stride+offset,a.length);}else {l=a.length;}for(i=offset;i0&&arguments[0]!==undefined?arguments[0]:0;var y=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;var z=arguments.length>2&&arguments[2]!==undefined?arguments[2]:0;_classCallCheck(this,Vector3);_this8=_super4.call(this,-0,-0,-0);if(arguments.length===1&&isArray$2(x)){_this8.copy(x);}else {if(config$1.debug){checkNumber(x);checkNumber(y);checkNumber(z);}_this8[0]=x;_this8[1]=y;_this8[2]=z;}return _this8;}_createClass(Vector3,[{key:"set",value:function set(x,y,z){this[0]=x;this[1]=y;this[2]=z;return this.check();}},{key:"copy",value:function copy(array){this[0]=array[0];this[1]=array[1];this[2]=array[2];return this.check();}},{key:"fromObject",value:function fromObject(object){if(config$1.debug){checkNumber(object.x);checkNumber(object.y);checkNumber(object.z);}this[0]=object.x;this[1]=object.y;this[2]=object.z;return this.check();}},{key:"toObject",value:function toObject(object){object.x=this[0];object.y=this[1];object.z=this[2];return object;}},{key:"ELEMENTS",get:function get(){return 3;}},{key:"z",get:function get(){return this[2];},set:function set(value){this[2]=checkNumber(value);}},{key:"angle",value:function angle(vector){return _angle(this,vector);}},{key:"cross",value:function cross(vector){_cross(this,this,vector);return this.check();}},{key:"rotateX",value:function rotateX(_ref6){var radians=_ref6.radians,_ref6$origin=_ref6.origin,origin=_ref6$origin===void 0?ORIGIN:_ref6$origin;rotateX$2(this,this,origin,radians);return this.check();}},{key:"rotateY",value:function rotateY(_ref7){var radians=_ref7.radians,_ref7$origin=_ref7.origin,origin=_ref7$origin===void 0?ORIGIN:_ref7$origin;rotateY$2(this,this,origin,radians);return this.check();}},{key:"rotateZ",value:function rotateZ(_ref8){var radians=_ref8.radians,_ref8$origin=_ref8.origin,origin=_ref8$origin===void 0?ORIGIN:_ref8$origin;rotateZ$2(this,this,origin,radians);return this.check();}},{key:"transform",value:function transform(matrix4){return this.transformAsPoint(matrix4);}},{key:"transformAsPoint",value:function transformAsPoint(matrix4){transformMat4$1(this,this,matrix4);return this.check();}},{key:"transformAsVector",value:function transformAsVector(matrix4){vec3_transformMat4AsVector(this,this,matrix4);return this.check();}},{key:"transformByMatrix3",value:function transformByMatrix3(matrix3){transformMat3(this,this,matrix3);return this.check();}},{key:"transformByMatrix2",value:function transformByMatrix2(matrix2){vec3_transformMat2(this,this,matrix2);return this.check();}},{key:"transformByQuaternion",value:function transformByQuaternion(quaternion){transformQuat$1(this,this,quaternion);return this.check();}}],[{key:"ZERO",get:function get(){return constants$2.ZERO=constants$2.ZERO||Object.freeze(new Vector3(0,0,0,0));}}]);return Vector3;}(Vector);var Matrix=/*#__PURE__*/function(_MathArray2){_inherits(Matrix,_MathArray2);var _super5=_createSuper$E(Matrix);function Matrix(){_classCallCheck(this,Matrix);return _super5.apply(this,arguments);}_createClass(Matrix,[{key:"ELEMENTS",get:function get(){assert$4(false);return 0;}},{key:"RANK",get:function get(){assert$4(false);return 0;}},{key:"toString",value:function toString(){var string='[';if(config$1.printRowMajor){string+='row-major:';for(var row=0;row1&&arguments[1]!==undefined?arguments[1]:new Array(this.RANK).fill(-0);var firstIndex=columnIndex*this.RANK;for(var _i39=0;_i390){len=1/Math.sqrt(len);}out[0]=x*len;out[1]=y*len;out[2]=z*len;out[3]=w*len;return out;}/** * Calculates the dot product of two vec4's * * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @returns {Number} dot product of a and b */function dot$1(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];}/** * Performs a linear interpolation between two vec4's * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the first operand * @param {ReadonlyVec4} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec4} out */function lerp$1(out,a,b,t){var ax=a[0];var ay=a[1];var az=a[2];var aw=a[3];out[0]=ax+t*(b[0]-ax);out[1]=ay+t*(b[1]-ay);out[2]=az+t*(b[2]-az);out[3]=aw+t*(b[3]-aw);return out;}/** * Transforms the vec4 with a mat4. * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the vector to transform * @param {ReadonlyMat4} m matrix to transform with * @returns {vec4} out */function transformMat4(out,a,m){var x=a[0],y=a[1],z=a[2],w=a[3];out[0]=m[0]*x+m[4]*y+m[8]*z+m[12]*w;out[1]=m[1]*x+m[5]*y+m[9]*z+m[13]*w;out[2]=m[2]*x+m[6]*y+m[10]*z+m[14]*w;out[3]=m[3]*x+m[7]*y+m[11]*z+m[15]*w;return out;}/** * Transforms the vec4 with a quat * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the vector to transform * @param {ReadonlyQuat} q quaternion to transform with * @returns {vec4} out */function transformQuat(out,a,q){var x=a[0],y=a[1],z=a[2];var qx=q[0],qy=q[1],qz=q[2],qw=q[3];// calculate quat * vec var ix=qw*x+qy*z-qz*y;var iy=qw*y+qz*x-qx*z;var iz=qw*z+qx*y-qy*x;var iw=-qx*x-qy*y-qz*z;// calculate result * inverse quat out[0]=ix*qw+iw*-qx+iy*-qz-iz*-qy;out[1]=iy*qw+iw*-qy+iz*-qx-ix*-qz;out[2]=iz*qw+iw*-qz+ix*-qy-iy*-qx;out[3]=a[3];return out;}(function(){var vec=create$1();return function(a,stride,offset,count,fn,arg){var i,l;if(!stride){stride=4;}if(!offset){offset=0;}if(count){l=Math.min(count*stride+offset,a.length);}else {l=a.length;}for(i=offset;iMath.PI*2){throw Error('radians');}var halfY=fovy/2;var top=focalDistance*Math.tan(halfY);var right=top*aspect;return new Matrix4().ortho({left:-right,right,bottom:-top,top,near,far});}},{key:"perspective",value:function perspective(){var _ref12=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{},_ref12$fovy=_ref12.fovy,fovy=_ref12$fovy===void 0?undefined:_ref12$fovy,_ref12$fov=_ref12.fov,fov=_ref12$fov===void 0?45*Math.PI/180:_ref12$fov,_ref12$aspect=_ref12.aspect,aspect=_ref12$aspect===void 0?1:_ref12$aspect,_ref12$near=_ref12.near,near=_ref12$near===void 0?0.1:_ref12$near,_ref12$far=_ref12.far,far=_ref12$far===void 0?500:_ref12$far;fovy=fovy||fov;if(fovy>Math.PI*2){throw Error('radians');}_perspective(this,fovy,aspect,near,far);return this.check();}},{key:"determinant",value:function determinant(){return _determinant(this);}},{key:"getScale",value:function getScale(){var result=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[-0,-0,-0];result[0]=Math.sqrt(this[0]*this[0]+this[1]*this[1]+this[2]*this[2]);result[1]=Math.sqrt(this[4]*this[4]+this[5]*this[5]+this[6]*this[6]);result[2]=Math.sqrt(this[8]*this[8]+this[9]*this[9]+this[10]*this[10]);return result;}},{key:"getTranslation",value:function getTranslation(){var result=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[-0,-0,-0];result[0]=this[12];result[1]=this[13];result[2]=this[14];return result;}},{key:"getRotation",value:function getRotation(){var result=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0];var scaleResult=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;var scale=this.getScale(scaleResult||[-0,-0,-0]);var inverseScale0=1/scale[0];var inverseScale1=1/scale[1];var inverseScale2=1/scale[2];result[0]=this[0]*inverseScale0;result[1]=this[1]*inverseScale1;result[2]=this[2]*inverseScale2;result[3]=0;result[4]=this[4]*inverseScale0;result[5]=this[5]*inverseScale1;result[6]=this[6]*inverseScale2;result[7]=0;result[8]=this[8]*inverseScale0;result[9]=this[9]*inverseScale1;result[10]=this[10]*inverseScale2;result[11]=0;result[12]=0;result[13]=0;result[14]=0;result[15]=1;return result;}},{key:"getRotationMatrix3",value:function getRotationMatrix3(){var result=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[-0,-0,-0,-0,-0,-0,-0,-0,-0];var scaleResult=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;var scale=this.getScale(scaleResult||[-0,-0,-0]);var inverseScale0=1/scale[0];var inverseScale1=1/scale[1];var inverseScale2=1/scale[2];result[0]=this[0]*inverseScale0;result[1]=this[1]*inverseScale1;result[2]=this[2]*inverseScale2;result[3]=this[4]*inverseScale0;result[4]=this[5]*inverseScale1;result[5]=this[6]*inverseScale2;result[6]=this[8]*inverseScale0;result[7]=this[9]*inverseScale1;result[8]=this[10]*inverseScale2;return result;}},{key:"transpose",value:function transpose(){_transpose(this,this);return this.check();}},{key:"invert",value:function invert(){invert$1(this,this);return this.check();}},{key:"multiplyLeft",value:function multiplyLeft(a){multiply$1(this,a,this);return this.check();}},{key:"multiplyRight",value:function multiplyRight(a){multiply$1(this,this,a);return this.check();}},{key:"rotateX",value:function rotateX(radians){rotateX$1(this,this,radians);return this.check();}},{key:"rotateY",value:function rotateY(radians){rotateY$1(this,this,radians);return this.check();}},{key:"rotateZ",value:function rotateZ(radians){rotateZ$1(this,this,radians);return this.check();}},{key:"rotateXYZ",value:function rotateXYZ(_ref13){var _ref14=_slicedToArray(_ref13,3),rx=_ref14[0],ry=_ref14[1],rz=_ref14[2];return this.rotateX(rx).rotateY(ry).rotateZ(rz);}},{key:"rotateAxis",value:function rotateAxis(radians,axis){rotate(this,this,radians,axis);return this.check();}},{key:"scale",value:function scale(factor){if(Array.isArray(factor)){scale$2(this,this,factor);}else {scale$2(this,this,[factor,factor,factor]);}return this.check();}},{key:"translate",value:function translate(vec){_translate(this,this,vec);return this.check();}},{key:"transform",value:function transform(vector,result){if(vector.length===4){result=transformMat4(result||[-0,-0,-0,-0],vector,this);checkVector(result,4);return result;}return this.transformAsPoint(vector,result);}},{key:"transformAsPoint",value:function transformAsPoint(vector,result){var length=vector.length;switch(length){case 2:result=transformMat4$2(result||[-0,-0],vector,this);break;case 3:result=transformMat4$1(result||[-0,-0,-0],vector,this);break;default:throw new Error('Illegal vector');}checkVector(result,vector.length);return result;}},{key:"transformAsVector",value:function transformAsVector(vector,result){switch(vector.length){case 2:result=vec2_transformMat4AsVector(result||[-0,-0],vector,this);break;case 3:result=vec3_transformMat4AsVector(result||[-0,-0,-0],vector,this);break;default:throw new Error('Illegal vector');}checkVector(result,vector.length);return result;}},{key:"makeRotationX",value:function makeRotationX(radians){return this.identity().rotateX(radians);}},{key:"makeTranslation",value:function makeTranslation(x,y,z){return this.identity().translate([x,y,z]);}},{key:"transformPoint",value:function transformPoint(vector,result){deprecated('Matrix4.transformPoint','3.0');return this.transformAsPoint(vector,result);}},{key:"transformVector",value:function transformVector(vector,result){deprecated('Matrix4.transformVector','3.0');return this.transformAsPoint(vector,result);}},{key:"transformDirection",value:function transformDirection(vector,result){deprecated('Matrix4.transformDirection','3.0');return this.transformAsVector(vector,result);}}],[{key:"IDENTITY",get:function get(){constants$3.IDENTITY=constants$3.IDENTITY||Object.freeze(new Matrix4(IDENTITY));return constants$3.IDENTITY;}},{key:"ZERO",get:function get(){constants$3.ZERO=constants$3.ZERO||Object.freeze(new Matrix4(ZERO));return constants$3.ZERO;}},{key:"_computeInfinitePerspectiveOffCenter",value:function _computeInfinitePerspectiveOffCenter(result,left,right,bottom,top,near){var column0Row0=2.0*near/(right-left);var column1Row1=2.0*near/(top-bottom);var column2Row0=(right+left)/(right-left);var column2Row1=(top+bottom)/(top-bottom);var column2Row2=-1.0;var column2Row3=-1.0;var column3Row2=-2.0*near;result[0]=column0Row0;result[1]=0.0;result[2]=0.0;result[3]=0.0;result[4]=0.0;result[5]=column1Row1;result[6]=0.0;result[7]=0.0;result[8]=column2Row0;result[9]=column2Row1;result[10]=column2Row2;result[11]=column2Row3;result[12]=0.0;result[13]=0.0;result[14]=column3Row2;result[15]=0.0;return result;}}]);return Matrix4;}(Matrix);/** * Quaternion * @module quat */ /** * Creates a new identity quat * * @returns {quat} a new quaternion */function create(){var out=new ARRAY_TYPE(4);if(ARRAY_TYPE!=Float32Array){out[0]=0;out[1]=0;out[2]=0;}out[3]=1;return out;}/** * Set a quat to the identity quaternion * * @param {quat} out the receiving quaternion * @returns {quat} out */function _identity(out){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out;}/** * Sets a quat from the given angle and rotation axis, * then returns it. * * @param {quat} out the receiving quaternion * @param {ReadonlyVec3} axis the axis around which to rotate * @param {Number} rad the angle in radians * @returns {quat} out **/function setAxisAngle(out,axis,rad){rad=rad*0.5;var s=Math.sin(rad);out[0]=s*axis[0];out[1]=s*axis[1];out[2]=s*axis[2];out[3]=Math.cos(rad);return out;}/** * Multiplies two quat's * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @returns {quat} out */function multiply(out,a,b){var ax=a[0],ay=a[1],az=a[2],aw=a[3];var bx=b[0],by=b[1],bz=b[2],bw=b[3];out[0]=ax*bw+aw*bx+ay*bz-az*by;out[1]=ay*bw+aw*by+az*bx-ax*bz;out[2]=az*bw+aw*bz+ax*by-ay*bx;out[3]=aw*bw-ax*bx-ay*by-az*bz;return out;}/** * Rotates a quaternion by the given angle about the X axis * * @param {quat} out quat receiving operation result * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */function _rotateX(out,a,rad){rad*=0.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3];var bx=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+aw*bx;out[1]=ay*bw+az*bx;out[2]=az*bw-ay*bx;out[3]=aw*bw-ax*bx;return out;}/** * Rotates a quaternion by the given angle about the Y axis * * @param {quat} out quat receiving operation result * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */function _rotateY(out,a,rad){rad*=0.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3];var by=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw-az*by;out[1]=ay*bw+aw*by;out[2]=az*bw+ax*by;out[3]=aw*bw-ay*by;return out;}/** * Rotates a quaternion by the given angle about the Z axis * * @param {quat} out quat receiving operation result * @param {ReadonlyQuat} a quat to rotate * @param {number} rad angle (in radians) to rotate * @returns {quat} out */function _rotateZ(out,a,rad){rad*=0.5;var ax=a[0],ay=a[1],az=a[2],aw=a[3];var bz=Math.sin(rad),bw=Math.cos(rad);out[0]=ax*bw+ay*bz;out[1]=ay*bw-ax*bz;out[2]=az*bw+aw*bz;out[3]=aw*bw-az*bz;return out;}/** * Calculates the W component of a quat from the X, Y, and Z components. * Assumes that quaternion is 1 unit in length. * Any existing W component will be ignored. * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate W component of * @returns {quat} out */function _calculateW(out,a){var x=a[0],y=a[1],z=a[2];out[0]=x;out[1]=y;out[2]=z;out[3]=Math.sqrt(Math.abs(1.0-x*x-y*y-z*z));return out;}/** * Performs a spherical linear interpolation between two quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */function _slerp(out,a,b,t){// benchmarks: // http://jsperf.com/quaternion-slerp-implementations var ax=a[0],ay=a[1],az=a[2],aw=a[3];var bx=b[0],by=b[1],bz=b[2],bw=b[3];var omega,cosom,sinom,scale0,scale1;// calc cosine cosom=ax*bx+ay*by+az*bz+aw*bw;// adjust signs (if necessary) if(cosom<0.0){cosom=-cosom;bx=-bx;by=-by;bz=-bz;bw=-bw;}// calculate coefficients if(1.0-cosom>EPSILON){// standard case (slerp) omega=Math.acos(cosom);sinom=Math.sin(omega);scale0=Math.sin((1.0-t)*omega)/sinom;scale1=Math.sin(t*omega)/sinom;}else {// "from" and "to" quaternions are very close // ... so we can do a linear interpolation scale0=1.0-t;scale1=t;}// calculate final values out[0]=scale0*ax+scale1*bx;out[1]=scale0*ay+scale1*by;out[2]=scale0*az+scale1*bz;out[3]=scale0*aw+scale1*bw;return out;}/** * Calculates the inverse of a quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate inverse of * @returns {quat} out */function _invert(out,a){var a0=a[0],a1=a[1],a2=a[2],a3=a[3];var dot=a0*a0+a1*a1+a2*a2+a3*a3;var invDot=dot?1.0/dot:0;// TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 out[0]=-a0*invDot;out[1]=-a1*invDot;out[2]=-a2*invDot;out[3]=a3*invDot;return out;}/** * Calculates the conjugate of a quat * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate conjugate of * @returns {quat} out */function _conjugate(out,a){out[0]=-a[0];out[1]=-a[1];out[2]=-a[2];out[3]=a[3];return out;}/** * Creates a quaternion from the given 3x3 rotation matrix. * * NOTE: The resultant quaternion is not normalized, so you should be sure * to renormalize the quaternion yourself where necessary. * * @param {quat} out the receiving quaternion * @param {ReadonlyMat3} m rotation matrix * @returns {quat} out * @function */function fromMat3(out,m){// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes // article "Quaternion Calculus and Fast Animation". var fTrace=m[0]+m[4]+m[8];var fRoot;if(fTrace>0.0){// |w| > 1/2, may as well choose w > 1/2 fRoot=Math.sqrt(fTrace+1.0);// 2w out[3]=0.5*fRoot;fRoot=0.5/fRoot;// 1/(4w) out[0]=(m[5]-m[7])*fRoot;out[1]=(m[6]-m[2])*fRoot;out[2]=(m[1]-m[3])*fRoot;}else {// |w| <= 1/2 var i=0;if(m[4]>m[0])i=1;if(m[8]>m[i*3+i])i=2;var j=(i+1)%3;var k=(i+2)%3;fRoot=Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k]+1.0);out[i]=0.5*fRoot;fRoot=0.5/fRoot;out[3]=(m[j*3+k]-m[k*3+j])*fRoot;out[j]=(m[j*3+i]+m[i*3+j])*fRoot;out[k]=(m[k*3+i]+m[i*3+k])*fRoot;}return out;}/** * Adds two quat's * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @returns {quat} out * @function */var _add=add$1;/** * Scales a quat by a scalar number * * @param {quat} out the receiving vector * @param {ReadonlyQuat} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {quat} out * @function */var _scale2=scale$1;/** * Calculates the dot product of two quat's * * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @returns {Number} dot product of a and b * @function */var _dot=dot$1;/** * Performs a linear interpolation between two quat's * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out * @function */var _lerp=lerp$1;/** * Calculates the length of a quat * * @param {ReadonlyQuat} a vector to calculate length of * @returns {Number} length of a */var length=length$1;/** * Calculates the squared length of a quat * * @param {ReadonlyQuat} a vector to calculate squared length of * @returns {Number} squared length of a * @function */var squaredLength=squaredLength$1;/** * Normalize a quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quaternion to normalize * @returns {quat} out * @function */var normalize=normalize$1;/** * Sets a quaternion to represent the shortest rotation from one * vector to another. * * Both vectors are assumed to be unit length. * * @param {quat} out the receiving quaternion. * @param {ReadonlyVec3} a the initial vector * @param {ReadonlyVec3} b the destination vector * @returns {quat} out */var _rotationTo=function(){var tmpvec3=create$3();var xUnitVec3=fromValues(1,0,0);var yUnitVec3=fromValues(0,1,0);return function(out,a,b){var dot=dot$2(a,b);if(dot<-0.999999){_cross(tmpvec3,xUnitVec3,a);if(len(tmpvec3)<0.000001)_cross(tmpvec3,yUnitVec3,a);normalize$2(tmpvec3,tmpvec3);setAxisAngle(out,tmpvec3,Math.PI);return out;}else if(dot>0.999999){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out;}else {_cross(tmpvec3,a,b);out[0]=tmpvec3[0];out[1]=tmpvec3[1];out[2]=tmpvec3[2];out[3]=1+dot;return normalize(out,out);}};}()/** * Performs a spherical linear interpolation with two control points * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {ReadonlyQuat} c the third operand * @param {ReadonlyQuat} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */;(function(){var temp1=create();var temp2=create();return function(out,a,b,c,d,t){_slerp(temp1,a,d,t);_slerp(temp2,b,c,t);_slerp(out,temp1,temp2,2*t*(1-t));return out;};})()/** * Sets the specified quaternion with values corresponding to the given * axes. Each axis is a vec3 and is expected to be unit length and * perpendicular to all other specified axes. * * @param {ReadonlyVec3} view the vector representing the viewing direction * @param {ReadonlyVec3} right the vector representing the local "right" direction * @param {ReadonlyVec3} up the vector representing the local "up" direction * @returns {quat} out */;(function(){var matr=create$2();return function(out,view,right,up){matr[0]=right[0];matr[3]=right[1];matr[6]=right[2];matr[1]=up[0];matr[4]=up[1];matr[7]=up[2];matr[2]=-view[0];matr[5]=-view[1];matr[8]=-view[2];return normalize(out,fromMat3(out,matr));};})();var IDENTITY_QUATERNION=[0,0,0,1];var Quaternion=/*#__PURE__*/function(_MathArray3){_inherits(Quaternion,_MathArray3);var _super8=_createSuper$E(Quaternion);function Quaternion(){var _this11;var x=arguments.length>0&&arguments[0]!==undefined?arguments[0]:0;var y=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;var z=arguments.length>2&&arguments[2]!==undefined?arguments[2]:0;var w=arguments.length>3&&arguments[3]!==undefined?arguments[3]:1;_classCallCheck(this,Quaternion);_this11=_super8.call(this,-0,-0,-0,-0);if(Array.isArray(x)&&arguments.length===1){_this11.copy(x);}else {_this11.set(x,y,z,w);}return _this11;}_createClass(Quaternion,[{key:"copy",value:function copy(array){this[0]=array[0];this[1]=array[1];this[2]=array[2];this[3]=array[3];return this.check();}},{key:"set",value:function set(x,y,z,w){this[0]=x;this[1]=y;this[2]=z;this[3]=w;return this.check();}},{key:"fromMatrix3",value:function fromMatrix3(m){fromMat3(this,m);return this.check();}},{key:"identity",value:function identity(){_identity(this);return this.check();}},{key:"fromAxisRotation",value:function fromAxisRotation(axis,rad){setAxisAngle(this,axis,rad);return this.check();}},{key:"setAxisAngle",value:function setAxisAngle(axis,rad){return this.fromAxisRotation(axis,rad);}},{key:"ELEMENTS",get:function get(){return 4;}},{key:"x",get:function get(){return this[0];},set:function set(value){this[0]=checkNumber(value);}},{key:"y",get:function get(){return this[1];},set:function set(value){this[1]=checkNumber(value);}},{key:"z",get:function get(){return this[2];},set:function set(value){this[2]=checkNumber(value);}},{key:"w",get:function get(){return this[3];},set:function set(value){this[3]=checkNumber(value);}},{key:"len",value:function len(){return length(this);}},{key:"lengthSquared",value:function lengthSquared(){return squaredLength(this);}},{key:"dot",value:function dot(a,b){if(b!==undefined){throw new Error('Quaternion.dot only takes one argument');}return _dot(this,a);}},{key:"rotationTo",value:function rotationTo(vectorA,vectorB){_rotationTo(this,vectorA,vectorB);return this.check();}},{key:"add",value:function add(a,b){if(b!==undefined){throw new Error('Quaternion.add only takes one argument');}_add(this,this,a);return this.check();}},{key:"calculateW",value:function calculateW(){_calculateW(this,this);return this.check();}},{key:"conjugate",value:function conjugate(){_conjugate(this,this);return this.check();}},{key:"invert",value:function invert(){_invert(this,this);return this.check();}},{key:"lerp",value:function lerp(a,b,t){_lerp(this,a,b,t);return this.check();}},{key:"multiplyRight",value:function multiplyRight(a,b){assert$4(!b);multiply(this,this,a);return this.check();}},{key:"multiplyLeft",value:function multiplyLeft(a,b){assert$4(!b);multiply(this,a,this);return this.check();}},{key:"normalize",value:function normalize(){var length=this.len();var l=length>0?1/length:0;this[0]=this[0]*l;this[1]=this[1]*l;this[2]=this[2]*l;this[3]=this[3]*l;if(length===0){this[3]=1;}return this.check();}},{key:"rotateX",value:function rotateX(rad){_rotateX(this,this,rad);return this.check();}},{key:"rotateY",value:function rotateY(rad){_rotateY(this,this,rad);return this.check();}},{key:"rotateZ",value:function rotateZ(rad){_rotateZ(this,this,rad);return this.check();}},{key:"scale",value:function scale(b){_scale2(this,this,b);return this.check();}},{key:"slerp",value:function slerp(start,target,ratio){switch(arguments.length){case 1:var _arguments$=arguments[0];var _arguments$$start=_arguments$.start;start=_arguments$$start===void 0?IDENTITY_QUATERNION:_arguments$$start;target=_arguments$.target;ratio=_arguments$.ratio;break;case 2:var _arguments2=Array.prototype.slice.call(arguments);target=_arguments2[0];ratio=_arguments2[1];start=this;break;}_slerp(this,start,target,ratio);return this.check();}},{key:"transformVector4",value:function transformVector4(vector){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:vector;transformQuat(result,vector,this);return checkVector(result,4);}},{key:"lengthSq",value:function lengthSq(){return this.lengthSquared();}},{key:"setFromAxisAngle",value:function setFromAxisAngle(axis,rad){return this.setAxisAngle(axis,rad);}},{key:"premultiply",value:function premultiply(a,b){return this.multiplyLeft(a,b);}},{key:"multiply",value:function multiply(a,b){return this.multiplyRight(a,b);}}]);return Quaternion;}(MathArray);var _MathUtils={EPSILON1:1e-1,EPSILON2:1e-2,EPSILON3:1e-3,EPSILON4:1e-4,EPSILON5:1e-5,EPSILON6:1e-6,EPSILON7:1e-7,EPSILON8:1e-8,EPSILON9:1e-9,EPSILON10:1e-10,EPSILON11:1e-11,EPSILON12:1e-12,EPSILON13:1e-13,EPSILON14:1e-14,EPSILON15:1e-15,EPSILON16:1e-16,EPSILON17:1e-17,EPSILON18:1e-18,EPSILON19:1e-19,EPSILON20:1e-20,PI_OVER_TWO:Math.PI/2,PI_OVER_FOUR:Math.PI/4,PI_OVER_SIX:Math.PI/6,TWO_PI:Math.PI*2};var WGS84_RADIUS_X$1=6378137.0;var WGS84_RADIUS_Y$1=6378137.0;var WGS84_RADIUS_Z$1=6356752.3142451793;var noop=function noop(x){return x;};var scratchVector$6=new Vector3$1();function fromCartographic(cartographic,result){var map=arguments.length>2&&arguments[2]!==undefined?arguments[2]:noop;if(isArray$2(cartographic)){result[0]=map(cartographic[0]);result[1]=map(cartographic[1]);result[2]=cartographic[2];}else if('longitude'in cartographic){result[0]=map(cartographic.longitude);result[1]=map(cartographic.latitude);result[2]=cartographic.height;}else {result[0]=map(cartographic.x);result[1]=map(cartographic.y);result[2]=cartographic.z;}return result;}function fromCartographicToRadians(cartographic){var vector=arguments.length>1&&arguments[1]!==undefined?arguments[1]:scratchVector$6;return fromCartographic(cartographic,vector,config$1._cartographicRadians?noop:toRadians);}function toCartographic(vector,cartographic){var map=arguments.length>2&&arguments[2]!==undefined?arguments[2]:noop;if(isArray$2(cartographic)){cartographic[0]=map(vector[0]);cartographic[1]=map(vector[1]);cartographic[2]=vector[2];}else if('longitude'in cartographic){cartographic.longitude=map(vector[0]);cartographic.latitude=map(vector[1]);cartographic.height=vector[2];}else {cartographic.x=map(vector[0]);cartographic.y=map(vector[1]);cartographic.z=vector[2];}return cartographic;}function toCartographicFromRadians(vector,cartographic){return toCartographic(vector,cartographic,config$1._cartographicRadians?noop:toDegrees);}var scratchVector$5=new Vector3$1();var scaleToGeodeticSurfaceIntersection=new Vector3$1();var scaleToGeodeticSurfaceGradient=new Vector3$1();function _scaleToGeodeticSurface(cartesian,ellipsoid){var result=arguments.length>2&&arguments[2]!==undefined?arguments[2]:new Vector3$1();var oneOverRadii=ellipsoid.oneOverRadii,oneOverRadiiSquared=ellipsoid.oneOverRadiiSquared,centerToleranceSquared=ellipsoid.centerToleranceSquared;scratchVector$5.from(cartesian);var positionX=cartesian.x;var positionY=cartesian.y;var positionZ=cartesian.z;var oneOverRadiiX=oneOverRadii.x;var oneOverRadiiY=oneOverRadii.y;var oneOverRadiiZ=oneOverRadii.z;var x2=positionX*positionX*oneOverRadiiX*oneOverRadiiX;var y2=positionY*positionY*oneOverRadiiY*oneOverRadiiY;var z2=positionZ*positionZ*oneOverRadiiZ*oneOverRadiiZ;var squaredNorm=x2+y2+z2;var ratio=Math.sqrt(1.0/squaredNorm);if(!Number.isFinite(ratio)){return undefined;}var intersection=scaleToGeodeticSurfaceIntersection;intersection.copy(cartesian).scale(ratio);if(squaredNorm_MathUtils.EPSILON12);return scratchVector$5.scale([xMultiplier,yMultiplier,zMultiplier]).to(result);}var EPSILON14=1e-14;var scratchOrigin=new Vector3$1();var VECTOR_PRODUCT_LOCAL_FRAME={up:{south:'east',north:'west',west:'south',east:'north'},down:{south:'west',north:'east',west:'north',east:'south'},south:{up:'west',down:'east',west:'down',east:'up'},north:{up:'east',down:'west',west:'up',east:'down'},west:{up:'north',down:'south',north:'down',south:'up'},east:{up:'south',down:'north',north:'up',south:'down'}};var degeneratePositionLocalFrame={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]};var scratchAxisVectors={east:new Vector3$1(),north:new Vector3$1(),up:new Vector3$1(),west:new Vector3$1(),south:new Vector3$1(),down:new Vector3$1()};var scratchVector1=new Vector3$1();var scratchVector2$1=new Vector3$1();var scratchVector3$1=new Vector3$1();function _localFrameToFixedFrame(ellipsoid,firstAxis,secondAxis,thirdAxis,cartesianOrigin,result){var thirdAxisInferred=VECTOR_PRODUCT_LOCAL_FRAME[firstAxis]&&VECTOR_PRODUCT_LOCAL_FRAME[firstAxis][secondAxis];assert$4(thirdAxisInferred&&(!thirdAxis||thirdAxis===thirdAxisInferred));var firstAxisVector;var secondAxisVector;var thirdAxisVector;var origin=scratchOrigin.copy(cartesianOrigin);var atPole=_equals(origin.x,0.0,EPSILON14)&&_equals(origin.y,0.0,EPSILON14);if(atPole){var sign=Math.sign(origin.z);firstAxisVector=scratchVector1.fromArray(degeneratePositionLocalFrame[firstAxis]);if(firstAxis!=='east'&&firstAxis!=='west'){firstAxisVector.scale(sign);}secondAxisVector=scratchVector2$1.fromArray(degeneratePositionLocalFrame[secondAxis]);if(secondAxis!=='east'&&secondAxis!=='west'){secondAxisVector.scale(sign);}thirdAxisVector=scratchVector3$1.fromArray(degeneratePositionLocalFrame[thirdAxis]);if(thirdAxis!=='east'&&thirdAxis!=='west'){thirdAxisVector.scale(sign);}}else {var up=scratchAxisVectors.up,east=scratchAxisVectors.east,north=scratchAxisVectors.north;east.set(-origin.y,origin.x,0.0).normalize();ellipsoid.geodeticSurfaceNormal(origin,up);north.copy(up).cross(east);var down=scratchAxisVectors.down,west=scratchAxisVectors.west,south=scratchAxisVectors.south;down.copy(up).scale(-1);west.copy(east).scale(-1);south.copy(north).scale(-1);firstAxisVector=scratchAxisVectors[firstAxis];secondAxisVector=scratchAxisVectors[secondAxis];thirdAxisVector=scratchAxisVectors[thirdAxis];}result[0]=firstAxisVector.x;result[1]=firstAxisVector.y;result[2]=firstAxisVector.z;result[3]=0.0;result[4]=secondAxisVector.x;result[5]=secondAxisVector.y;result[6]=secondAxisVector.z;result[7]=0.0;result[8]=thirdAxisVector.x;result[9]=thirdAxisVector.y;result[10]=thirdAxisVector.z;result[11]=0.0;result[12]=origin.x;result[13]=origin.y;result[14]=origin.z;result[15]=1.0;return result;}var scratchVector$4=new Vector3$1();var scratchNormal$2=new Vector3$1();var scratchK=new Vector3$1();var scratchPosition$2=new Vector3$1();var scratchHeight=new Vector3$1();var scratchCartesian=new Vector3$1();var wgs84;var Ellipsoid=/*#__PURE__*/function(){function Ellipsoid(){var x=arguments.length>0&&arguments[0]!==undefined?arguments[0]:0.0;var y=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0.0;var z=arguments.length>2&&arguments[2]!==undefined?arguments[2]:0.0;_classCallCheck(this,Ellipsoid);assert$4(x>=0.0);assert$4(y>=0.0);assert$4(z>=0.0);this.radii=new Vector3$1(x,y,z);this.radiiSquared=new Vector3$1(x*x,y*y,z*z);this.radiiToTheFourth=new Vector3$1(x*x*x*x,y*y*y*y,z*z*z*z);this.oneOverRadii=new Vector3$1(x===0.0?0.0:1.0/x,y===0.0?0.0:1.0/y,z===0.0?0.0:1.0/z);this.oneOverRadiiSquared=new Vector3$1(x===0.0?0.0:1.0/(x*x),y===0.0?0.0:1.0/(y*y),z===0.0?0.0:1.0/(z*z));this.minimumRadius=Math.min(x,y,z);this.maximumRadius=Math.max(x,y,z);this.centerToleranceSquared=_MathUtils.EPSILON1;if(this.radiiSquared.z!==0){this.squaredXOverSquaredZ=this.radiiSquared.x/this.radiiSquared.z;}Object.freeze(this);}_createClass(Ellipsoid,[{key:"equals",value:function equals(right){return this===right||Boolean(right&&this.radii.equals(right.radii));}},{key:"toString",value:function toString(){return this.radii.toString();}},{key:"cartographicToCartesian",value:function cartographicToCartesian(cartographic){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];var normal=scratchNormal$2;var k=scratchK;var _cartographic=_slicedToArray(cartographic,3),height=_cartographic[2];this.geodeticSurfaceNormalCartographic(cartographic,normal);k.copy(this.radiiSquared).scale(normal);var gamma=Math.sqrt(normal.dot(k));k.scale(1/gamma);normal.scale(height);k.add(normal);return k.to(result);}},{key:"cartesianToCartographic",value:function cartesianToCartographic(cartesian){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];scratchCartesian.from(cartesian);var point=this.scaleToGeodeticSurface(scratchCartesian,scratchPosition$2);if(!point){return undefined;}var normal=this.geodeticSurfaceNormal(point,scratchNormal$2);var h=scratchHeight;h.copy(scratchCartesian).subtract(point);var longitude=Math.atan2(normal.y,normal.x);var latitude=Math.asin(normal.z);var height=Math.sign(dot$2(h,scratchCartesian))*length$2(h);return toCartographicFromRadians([longitude,latitude,height],result);}},{key:"eastNorthUpToFixedFrame",value:function eastNorthUpToFixedFrame(origin){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:new Matrix4();return _localFrameToFixedFrame(this,'east','north','up',origin,result);}},{key:"localFrameToFixedFrame",value:function localFrameToFixedFrame(firstAxis,secondAxis,thirdAxis,origin){var result=arguments.length>4&&arguments[4]!==undefined?arguments[4]:new Matrix4();return _localFrameToFixedFrame(this,firstAxis,secondAxis,thirdAxis,origin,result);}},{key:"geocentricSurfaceNormal",value:function geocentricSurfaceNormal(cartesian){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];return scratchVector$4.from(cartesian).normalize().to(result);}},{key:"geodeticSurfaceNormalCartographic",value:function geodeticSurfaceNormalCartographic(cartographic){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];var cartographicVectorRadians=fromCartographicToRadians(cartographic);var longitude=cartographicVectorRadians[0];var latitude=cartographicVectorRadians[1];var cosLatitude=Math.cos(latitude);scratchVector$4.set(cosLatitude*Math.cos(longitude),cosLatitude*Math.sin(longitude),Math.sin(latitude)).normalize();return scratchVector$4.to(result);}},{key:"geodeticSurfaceNormal",value:function geodeticSurfaceNormal(cartesian){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];return scratchVector$4.from(cartesian).scale(this.oneOverRadiiSquared).normalize().to(result);}},{key:"scaleToGeodeticSurface",value:function scaleToGeodeticSurface(cartesian,result){return _scaleToGeodeticSurface(cartesian,this,result);}},{key:"scaleToGeocentricSurface",value:function scaleToGeocentricSurface(cartesian){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];scratchPosition$2.from(cartesian);var positionX=scratchPosition$2.x;var positionY=scratchPosition$2.y;var positionZ=scratchPosition$2.z;var oneOverRadiiSquared=this.oneOverRadiiSquared;var beta=1.0/Math.sqrt(positionX*positionX*oneOverRadiiSquared.x+positionY*positionY*oneOverRadiiSquared.y+positionZ*positionZ*oneOverRadiiSquared.z);return scratchPosition$2.multiplyScalar(beta).to(result);}},{key:"transformPositionToScaledSpace",value:function transformPositionToScaledSpace(position){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];return scratchPosition$2.from(position).scale(this.oneOverRadii).to(result);}},{key:"transformPositionFromScaledSpace",value:function transformPositionFromScaledSpace(position){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];return scratchPosition$2.from(position).scale(this.radii).to(result);}},{key:"getSurfaceNormalIntersectionWithZAxis",value:function getSurfaceNormalIntersectionWithZAxis(position){var buffer=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0.0;var result=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[0,0,0];assert$4(_equals(this.radii.x,this.radii.y,_MathUtils.EPSILON15));assert$4(this.radii.z>0);scratchPosition$2.from(position);var z=scratchPosition$2.z*(1-this.squaredXOverSquaredZ);if(Math.abs(z)>=this.radii.z-buffer){return undefined;}return scratchPosition$2.set(0.0,0.0,z).to(result);}}],[{key:"WGS84",get:function get(){wgs84=wgs84||new Ellipsoid(WGS84_RADIUS_X$1,WGS84_RADIUS_Y$1,WGS84_RADIUS_Z$1);return wgs84;}}]);return Ellipsoid;}();var DoublyLinkedListNode=function DoublyLinkedListNode(item,previous,next){_classCallCheck(this,DoublyLinkedListNode);_defineProperty(this,'item',void 0);_defineProperty(this,'previous',void 0);_defineProperty(this,'next',void 0);this.item=item;this.previous=previous;this.next=next;};var DoublyLinkedList=/*#__PURE__*/function(){function DoublyLinkedList(){_classCallCheck(this,DoublyLinkedList);_defineProperty(this,'head',null);_defineProperty(this,'tail',null);_defineProperty(this,'_length',0);}_createClass(DoublyLinkedList,[{key:"length",get:function get(){return this._length;}},{key:"add",value:function add(item){var node=new DoublyLinkedListNode(item,this.tail,null);if(this.tail){this.tail.next=node;this.tail=node;}else {this.head=node;this.tail=node;}++this._length;return node;}},{key:"remove",value:function remove(node){if(!node){return;}if(node.previous&&node.next){node.previous.next=node.next;node.next.previous=node.previous;}else if(node.previous){node.previous.next=null;this.tail=node.previous;}else if(node.next){node.next.previous=null;this.head=node.next;}else {this.head=null;this.tail=null;}node.next=null;node.previous=null;--this._length;}},{key:"splice",value:function splice(node,nextNode){if(node===nextNode){return;}this.remove(nextNode);this._insert(node,nextNode);}},{key:"_insert",value:function _insert(node,nextNode){var oldNodeNext=node.next;node.next=nextNode;if(this.tail===node){this.tail=nextNode;}else {oldNodeNext.previous=nextNode;}nextNode.next=oldNodeNext;nextNode.previous=node;++this._length;}}]);return DoublyLinkedList;}();function defined$5(x){return x!==undefined&&x!==null;}var TilesetCache=/*#__PURE__*/function(){function TilesetCache(){_classCallCheck(this,TilesetCache);_defineProperty(this,'_list',void 0);_defineProperty(this,'_sentinel',void 0);_defineProperty(this,'_trimTiles',void 0);this._list=new DoublyLinkedList();this._sentinel=this._list.add('sentinel');this._trimTiles=false;}_createClass(TilesetCache,[{key:"reset",value:function reset(){this._list.splice(this._list.tail,this._sentinel);}},{key:"touch",value:function touch(tile){var node=tile._cacheNode;if(defined$5(node)){this._list.splice(this._sentinel,node);}}},{key:"add",value:function add(tileset,tile,addCallback){if(!defined$5(tile._cacheNode)){tile._cacheNode=this._list.add(tile);if(addCallback){addCallback(tileset,tile);}}}},{key:"unloadTile",value:function unloadTile(tileset,tile,unloadCallback){var node=tile._cacheNode;if(!defined$5(node)){return;}this._list.remove(node);tile._cacheNode=undefined;if(unloadCallback){unloadCallback(tileset,tile);}}},{key:"unloadTiles",value:function unloadTiles(tileset,unloadCallback){var trimTiles=this._trimTiles;this._trimTiles=false;var list=this._list;var maximumMemoryUsageInBytes=tileset.maximumMemoryUsage*1024*1024;var sentinel=this._sentinel;var node=list.head;while(node!==sentinel&&(tileset.gpuMemoryUsageInBytes>maximumMemoryUsageInBytes||trimTiles)){var tile=node.item;node=node.next;this.unloadTile(tileset,tile,unloadCallback);}}},{key:"trim",value:function trim(){this._trimTiles=true;}}]);return TilesetCache;}();function calculateTransformProps(tileHeader,tile){assert$7(tileHeader);assert$7(tile);var rtcCenter=tile.rtcCenter,gltfUpAxis=tile.gltfUpAxis;var computedTransform=tileHeader.computedTransform,center=tileHeader.boundingVolume.center;var modelMatrix=new Matrix4(computedTransform);if(rtcCenter){modelMatrix.translate(rtcCenter);}switch(gltfUpAxis){case'Z':break;case'Y':var rotationY=new Matrix4().rotateX(Math.PI/2);modelMatrix=modelMatrix.multiplyRight(rotationY);break;case'X':var rotationX=new Matrix4().rotateY(-Math.PI/2);modelMatrix=modelMatrix.multiplyRight(rotationX);break;}if(tile.isQuantized){modelMatrix.translate(tile.quantizedVolumeOffset).scale(tile.quantizedVolumeScale);}var cartesianOrigin=new Vector3$1(center);tile.cartesianModelMatrix=modelMatrix;tile.cartesianOrigin=cartesianOrigin;var cartographicOrigin=Ellipsoid.WGS84.cartesianToCartographic(cartesianOrigin,new Vector3$1());var fromFixedFrameMatrix=Ellipsoid.WGS84.eastNorthUpToFixedFrame(cartesianOrigin);var toFixedFrameMatrix=fromFixedFrameMatrix.invert();tile.cartographicModelMatrix=toFixedFrameMatrix.multiplyRight(modelMatrix);tile.cartographicOrigin=cartographicOrigin;if(!tile.coordinateSystem){tile.modelMatrix=tile.cartographicModelMatrix;}}var INTERSECTION=Object.freeze({OUTSIDE:-1,INTERSECTING:0,INSIDE:1});new Vector3$1();new Vector3$1();var scratchVector$3=new Vector3$1();var scratchVector2=new Vector3$1();var BoundingSphere=/*#__PURE__*/function(){function BoundingSphere(){var center=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[0,0,0];var radius=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0.0;_classCallCheck(this,BoundingSphere);this.radius=-0;this.center=new Vector3$1();this.fromCenterRadius(center,radius);}_createClass(BoundingSphere,[{key:"fromCenterRadius",value:function fromCenterRadius(center,radius){this.center.from(center);this.radius=radius;return this;}},{key:"fromCornerPoints",value:function fromCornerPoints(corner,oppositeCorner){oppositeCorner=scratchVector$3.from(oppositeCorner);this.center=new Vector3$1().from(corner).add(oppositeCorner).scale(0.5);this.radius=this.center.distance(oppositeCorner);return this;}},{key:"equals",value:function equals(right){return this===right||Boolean(right)&&this.center.equals(right.center)&&this.radius===right.radius;}},{key:"clone",value:function clone(){return new BoundingSphere(this.center,this.radius);}},{key:"union",value:function union(boundingSphere){var leftCenter=this.center;var leftRadius=this.radius;var rightCenter=boundingSphere.center;var rightRadius=boundingSphere.radius;var toRightCenter=scratchVector$3.copy(rightCenter).subtract(leftCenter);var centerSeparation=toRightCenter.magnitude();if(leftRadius>=centerSeparation+rightRadius){return this.clone();}if(rightRadius>=centerSeparation+leftRadius){return boundingSphere.clone();}var halfDistanceBetweenTangentPoints=(leftRadius+centerSeparation+rightRadius)*0.5;scratchVector2.copy(toRightCenter).scale((-leftRadius+halfDistanceBetweenTangentPoints)/centerSeparation).add(leftCenter);this.center.copy(scratchVector2);this.radius=halfDistanceBetweenTangentPoints;return this;}},{key:"expand",value:function expand(point){point=scratchVector$3.from(point);var radius=point.subtract(this.center).magnitude();if(radius>this.radius){this.radius=radius;}return this;}},{key:"transform",value:function transform(_transform){this.center.transform(_transform);var scale=getScaling(scratchVector$3,_transform);this.radius=Math.max(scale[0],Math.max(scale[1],scale[2]))*this.radius;return this;}},{key:"distanceSquaredTo",value:function distanceSquaredTo(point){var d=this.distanceTo(point);return d*d;}},{key:"distanceTo",value:function distanceTo(point){point=scratchVector$3.from(point);var delta=point.subtract(this.center);return Math.max(0,delta.len()-this.radius);}},{key:"intersectPlane",value:function intersectPlane(plane){var center=this.center;var radius=this.radius;var normal=plane.normal;var distanceToPlane=normal.dot(center)+plane.distance;if(distanceToPlane<-radius){return INTERSECTION.OUTSIDE;}if(distanceToPlane0&&arguments[0]!==undefined?arguments[0]:[0,0,0];var halfAxes=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0,0,0,0,0,0,0];_classCallCheck(this,OrientedBoundingBox);this.center=new Vector3$1().from(center);this.halfAxes=new Matrix3(halfAxes);}_createClass(OrientedBoundingBox,[{key:"halfSize",get:function get(){var xAxis=this.halfAxes.getColumn(0);var yAxis=this.halfAxes.getColumn(1);var zAxis=this.halfAxes.getColumn(2);return [new Vector3$1(xAxis).len(),new Vector3$1(yAxis).len(),new Vector3$1(zAxis).len()];}},{key:"quaternion",get:function get(){var xAxis=this.halfAxes.getColumn(0);var yAxis=this.halfAxes.getColumn(1);var zAxis=this.halfAxes.getColumn(2);var normXAxis=new Vector3$1(xAxis).normalize();var normYAxis=new Vector3$1(yAxis).normalize();var normZAxis=new Vector3$1(zAxis).normalize();return new Quaternion().fromMatrix3(new Matrix3([].concat(_toConsumableArray(normXAxis),_toConsumableArray(normYAxis),_toConsumableArray(normZAxis))));}},{key:"fromCenterHalfSizeQuaternion",value:function fromCenterHalfSizeQuaternion(center,halfSize,quaternion){var quaternionObject=new Quaternion(quaternion);var directionsMatrix=new Matrix3().fromQuaternion(quaternionObject);directionsMatrix[0]=directionsMatrix[0]*halfSize[0];directionsMatrix[1]=directionsMatrix[1]*halfSize[0];directionsMatrix[2]=directionsMatrix[2]*halfSize[0];directionsMatrix[3]=directionsMatrix[3]*halfSize[1];directionsMatrix[4]=directionsMatrix[4]*halfSize[1];directionsMatrix[5]=directionsMatrix[5]*halfSize[1];directionsMatrix[6]=directionsMatrix[6]*halfSize[2];directionsMatrix[7]=directionsMatrix[7]*halfSize[2];directionsMatrix[8]=directionsMatrix[8]*halfSize[2];this.center=new Vector3$1().from(center);this.halfAxes=directionsMatrix;return this;}},{key:"clone",value:function clone(){return new OrientedBoundingBox(this.center,this.halfAxes);}},{key:"equals",value:function equals(right){return this===right||Boolean(right)&&this.center.equals(right.center)&&this.halfAxes.equals(right.halfAxes);}},{key:"getBoundingSphere",value:function getBoundingSphere(){var result=arguments.length>0&&arguments[0]!==undefined?arguments[0]:new BoundingSphere();var halfAxes=this.halfAxes;var u=halfAxes.getColumn(0,scratchVectorU);var v=halfAxes.getColumn(1,scratchVectorV);var w=halfAxes.getColumn(2,scratchVectorW);var cornerVector=scratchVector3.copy(u).add(v).add(w);result.center.copy(this.center);result.radius=cornerVector.magnitude();return result;}},{key:"intersectPlane",value:function intersectPlane(plane){var center=this.center;var normal=plane.normal;var halfAxes=this.halfAxes;var normalX=normal.x;var normalY=normal.y;var normalZ=normal.z;var radEffective=Math.abs(normalX*halfAxes[MATRIX3.COLUMN0ROW0]+normalY*halfAxes[MATRIX3.COLUMN0ROW1]+normalZ*halfAxes[MATRIX3.COLUMN0ROW2])+Math.abs(normalX*halfAxes[MATRIX3.COLUMN1ROW0]+normalY*halfAxes[MATRIX3.COLUMN1ROW1]+normalZ*halfAxes[MATRIX3.COLUMN1ROW2])+Math.abs(normalX*halfAxes[MATRIX3.COLUMN2ROW0]+normalY*halfAxes[MATRIX3.COLUMN2ROW1]+normalZ*halfAxes[MATRIX3.COLUMN2ROW2]);var distanceToPlane=normal.dot(center)+plane.distance;if(distanceToPlane<=-radEffective){return INTERSECTION.OUTSIDE;}else if(distanceToPlane>=radEffective){return INTERSECTION.INSIDE;}return INTERSECTION.INTERSECTING;}},{key:"distanceTo",value:function distanceTo(point){return Math.sqrt(this.distanceSquaredTo(point));}},{key:"distanceSquaredTo",value:function distanceSquaredTo(point){var offset=scratchOffset.from(point).subtract(this.center);var halfAxes=this.halfAxes;var u=halfAxes.getColumn(0,scratchVectorU);var v=halfAxes.getColumn(1,scratchVectorV);var w=halfAxes.getColumn(2,scratchVectorW);var uHalf=u.magnitude();var vHalf=v.magnitude();var wHalf=w.magnitude();u.normalize();v.normalize();w.normalize();var distanceSquared=0.0;var d;d=Math.abs(offset.dot(u))-uHalf;if(d>0){distanceSquared+=d*d;}d=Math.abs(offset.dot(v))-vHalf;if(d>0){distanceSquared+=d*d;}d=Math.abs(offset.dot(w))-wHalf;if(d>0){distanceSquared+=d*d;}return distanceSquared;}},{key:"computePlaneDistances",value:function computePlaneDistances(position,direction){var result=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[-0,-0];var minDist=Number.POSITIVE_INFINITY;var maxDist=Number.NEGATIVE_INFINITY;var center=this.center;var halfAxes=this.halfAxes;var u=halfAxes.getColumn(0,scratchVectorU);var v=halfAxes.getColumn(1,scratchVectorV);var w=halfAxes.getColumn(2,scratchVectorW);var corner=scratchCorner.copy(u).add(v).add(w).add(center);var toCenter=scratchToCenter.copy(corner).subtract(position);var mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);corner.copy(center).add(u).add(v).subtract(w);toCenter.copy(corner).subtract(position);mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);corner.copy(center).add(u).subtract(v).add(w);toCenter.copy(corner).subtract(position);mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);corner.copy(center).add(u).subtract(v).subtract(w);toCenter.copy(corner).subtract(position);mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);center.copy(corner).subtract(u).add(v).add(w);toCenter.copy(corner).subtract(position);mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);center.copy(corner).subtract(u).add(v).subtract(w);toCenter.copy(corner).subtract(position);mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);center.copy(corner).subtract(u).subtract(v).add(w);toCenter.copy(corner).subtract(position);mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);center.copy(corner).subtract(u).subtract(v).subtract(w);toCenter.copy(corner).subtract(position);mag=direction.dot(toCenter);minDist=Math.min(mag,minDist);maxDist=Math.max(mag,maxDist);result[0]=minDist;result[1]=maxDist;return result;}},{key:"transform",value:function transform(transformation){this.center.transformAsPoint(transformation);var xAxis=this.halfAxes.getColumn(0,scratchVectorU);xAxis.transformAsPoint(transformation);var yAxis=this.halfAxes.getColumn(1,scratchVectorV);yAxis.transformAsPoint(transformation);var zAxis=this.halfAxes.getColumn(2,scratchVectorW);zAxis.transformAsPoint(transformation);this.halfAxes=new Matrix3([].concat(_toConsumableArray(xAxis),_toConsumableArray(yAxis),_toConsumableArray(zAxis)));return this;}},{key:"getTransform",value:function getTransform(){throw new Error('not implemented');}}]);return OrientedBoundingBox;}();var scratchPosition$1=new Vector3$1();var scratchNormal$1=new Vector3$1();var Plane=/*#__PURE__*/function(){function Plane(){var normal=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[0,0,1];var distance=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;_classCallCheck(this,Plane);this.normal=new Vector3$1();this.distance=-0;this.fromNormalDistance(normal,distance);}_createClass(Plane,[{key:"fromNormalDistance",value:function fromNormalDistance(normal,distance){assert$4(Number.isFinite(distance));this.normal.from(normal).normalize();this.distance=distance;return this;}},{key:"fromPointNormal",value:function fromPointNormal(point,normal){point=scratchPosition$1.from(point);this.normal.from(normal).normalize();var distance=-this.normal.dot(point);this.distance=distance;return this;}},{key:"fromCoefficients",value:function fromCoefficients(a,b,c,d){this.normal.set(a,b,c);assert$4(_equals(this.normal.len(),1));this.distance=d;return this;}},{key:"clone",value:function clone(plane){return new Plane(this.normal,this.distance);}},{key:"equals",value:function equals(right){return _equals(this.distance,right.distance)&&_equals(this.normal,right.normal);}},{key:"getPointDistance",value:function getPointDistance(point){return this.normal.dot(point)+this.distance;}},{key:"transform",value:function transform(matrix4){var normal=scratchNormal$1.copy(this.normal).transformAsVector(matrix4).normalize();var point=this.normal.scale(-this.distance).transform(matrix4);return this.fromPointNormal(point,normal);}},{key:"projectPointOntoPlane",value:function projectPointOntoPlane(point){var result=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];point=scratchPosition$1.from(point);var pointDistance=this.getPointDistance(point);var scaledNormal=scratchNormal$1.copy(this.normal).scale(pointDistance);return point.subtract(scaledNormal).to(result);}}]);return Plane;}();var faces=[new Vector3$1([1,0,0]),new Vector3$1([0,1,0]),new Vector3$1([0,0,1])];var scratchPlaneCenter=new Vector3$1();var scratchPlaneNormal$1=new Vector3$1();new Plane(new Vector3$1(1.0,0.0,0.0),0.0);var CullingVolume=/*#__PURE__*/function(){function CullingVolume(){var planes=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];_classCallCheck(this,CullingVolume);this.planes=planes;assert$4(this.planes.every(function(plane){return plane instanceof Plane;}));}_createClass(CullingVolume,[{key:"fromBoundingSphere",value:function fromBoundingSphere(boundingSphere){this.planes.length=2*faces.length;var center=boundingSphere.center;var radius=boundingSphere.radius;var planeIndex=0;var _iterator14=_createForOfIteratorHelper$3(faces),_step14;try{for(_iterator14.s();!(_step14=_iterator14.n()).done;){var faceNormal=_step14.value;var plane0=this.planes[planeIndex];var plane1=this.planes[planeIndex+1];if(!plane0){plane0=this.planes[planeIndex]=new Plane();}if(!plane1){plane1=this.planes[planeIndex+1]=new Plane();}var plane0Center=scratchPlaneCenter.copy(faceNormal).scale(-radius).add(center);-faceNormal.dot(plane0Center);plane0.fromPointNormal(plane0Center,faceNormal);var plane1Center=scratchPlaneCenter.copy(faceNormal).scale(radius).add(center);var negatedFaceNormal=scratchPlaneNormal$1.copy(faceNormal).negate();-negatedFaceNormal.dot(plane1Center);plane1.fromPointNormal(plane1Center,negatedFaceNormal);planeIndex+=2;}}catch(err){_iterator14.e(err);}finally{_iterator14.f();}return this;}},{key:"computeVisibility",value:function computeVisibility(boundingVolume){assert$4(boundingVolume);var intersect=INTERSECTION.INSIDE;var _iterator15=_createForOfIteratorHelper$3(this.planes),_step15;try{for(_iterator15.s();!(_step15=_iterator15.n()).done;){var plane=_step15.value;var result=boundingVolume.intersectPlane(plane);switch(result){case INTERSECTION.OUTSIDE:return INTERSECTION.OUTSIDE;case INTERSECTION.INTERSECTING:intersect=INTERSECTION.INTERSECTING;break;}}}catch(err){_iterator15.e(err);}finally{_iterator15.f();}return intersect;}},{key:"computeVisibilityWithPlaneMask",value:function computeVisibilityWithPlaneMask(boundingVolume,parentPlaneMask){assert$4(boundingVolume,'boundingVolume is required.');assert$4(Number.isFinite(parentPlaneMask),'parentPlaneMask is required.');if(parentPlaneMask===CullingVolume.MASK_OUTSIDE||parentPlaneMask===CullingVolume.MASK_INSIDE){return parentPlaneMask;}var mask=CullingVolume.MASK_INSIDE;var planes=this.planes;for(var k=0;k0&&arguments[0]!==undefined?arguments[0]:{};_classCallCheck(this,PerspectiveOffCenterFrustum);options=_objectSpread$3({near:1.0,far:500000000.0},options);this.left=options.left;this._left=undefined;this.right=options.right;this._right=undefined;this.top=options.top;this._top=undefined;this.bottom=options.bottom;this._bottom=undefined;this.near=options.near;this._near=this.near;this.far=options.far;this._far=this.far;this._cullingVolume=new CullingVolume([new Plane(),new Plane(),new Plane(),new Plane(),new Plane(),new Plane()]);this._perspectiveMatrix=new Matrix4();this._infinitePerspective=new Matrix4();}_createClass(PerspectiveOffCenterFrustum,[{key:"clone",value:function clone(){return new PerspectiveOffCenterFrustum({right:this.right,left:this.left,top:this.top,bottom:this.bottom,near:this.near,far:this.far});}},{key:"equals",value:function equals(other){return other&&other instanceof PerspectiveOffCenterFrustum&&this.right===other.right&&this.left===other.left&&this.top===other.top&&this.bottom===other.bottom&&this.near===other.near&&this.far===other.far;}},{key:"projectionMatrix",get:function get(){update$1(this);return this._perspectiveMatrix;}},{key:"infiniteProjectionMatrix",get:function get(){update$1(this);return this._infinitePerspective;}},{key:"computeCullingVolume",value:function computeCullingVolume(position,direction,up){assert$4(position,'position is required.');assert$4(direction,'direction is required.');assert$4(up,'up is required.');var planes=this._cullingVolume.planes;up=scratchPlaneUpVector.copy(up).normalize();var right=scratchPlaneRightVector.copy(direction).cross(up).normalize();var nearCenter=scratchPlaneNearCenter.copy(direction).multiplyByScalar(this.near).add(position);var farCenter=scratchPlaneFarCenter.copy(direction).multiplyByScalar(this.far).add(position);var normal=scratchPlaneNormal;normal.copy(right).multiplyByScalar(this.left).add(nearCenter).subtract(position).cross(up);planes[0].fromPointNormal(position,normal);normal.copy(right).multiplyByScalar(this.right).add(nearCenter).subtract(position).cross(up).negate();planes[1].fromPointNormal(position,normal);normal.copy(up).multiplyByScalar(this.bottom).add(nearCenter).subtract(position).cross(right).negate();planes[2].fromPointNormal(position,normal);normal.copy(up).multiplyByScalar(this.top).add(nearCenter).subtract(position).cross(right);planes[3].fromPointNormal(position,normal);normal=new Vector3$1().copy(direction);planes[4].fromPointNormal(nearCenter,normal);normal.negate();planes[5].fromPointNormal(farCenter,normal);return this._cullingVolume;}},{key:"getPixelDimensions",value:function getPixelDimensions(drawingBufferWidth,drawingBufferHeight,distance,result){update$1(this);assert$4(Number.isFinite(drawingBufferWidth)&&Number.isFinite(drawingBufferHeight));assert$4(drawingBufferWidth>0);assert$4(drawingBufferHeight>0);assert$4(distance>0);assert$4(result);var inverseNear=1.0/this.near;var tanTheta=this.top*inverseNear;var pixelHeight=2.0*distance*tanTheta/drawingBufferHeight;tanTheta=this.right*inverseNear;var pixelWidth=2.0*distance*tanTheta/drawingBufferWidth;result.x=pixelWidth;result.y=pixelHeight;return result;}}]);return PerspectiveOffCenterFrustum;}();function update$1(frustum){assert$4(Number.isFinite(frustum.right)&&Number.isFinite(frustum.left)&&Number.isFinite(frustum.top)&&Number.isFinite(frustum.bottom)&&Number.isFinite(frustum.near)&&Number.isFinite(frustum.far));var top=frustum.top,bottom=frustum.bottom,right=frustum.right,left=frustum.left,near=frustum.near,far=frustum.far;if(top!==frustum._top||bottom!==frustum._bottom||left!==frustum._left||right!==frustum._right||near!==frustum._near||far!==frustum._far){assert$4(frustum.near>0&&frustum.near0&&arguments[0]!==undefined?arguments[0]:{};_classCallCheck(this,PerspectiveFrustum);options=_objectSpread$3({near:1.0,far:500000000.0,xOffset:0.0,yOffset:0.0},options);this.type=options.type;//add this._offCenterFrustum=new PerspectiveOffCenterFrustum();this.fov=options.fov;this._fov=undefined;this._fovy=undefined;this._sseDenominator=undefined;this.aspectRatio=options.aspectRatio;this._aspectRatio=undefined;this.near=options.near;this._near=this.near;this.far=options.far;this._far=this.far;this.xOffset=options.xOffset;this._xOffset=this.xOffset;this.yOffset=options.yOffset;this._yOffset=this.yOffset;}_createClass(PerspectiveFrustum,[{key:"clone",value:function clone(){return new PerspectiveFrustum({aspectRatio:this.aspectRatio,fov:this.fov,near:this.near,far:this.far});}},{key:"equals",value:function equals(other){if(!defined$4(other)||!(other instanceof PerspectiveFrustum)){return false;}update(this);update(other);return this.fov===other.fov&&this.aspectRatio===other.aspectRatio&&this.near===other.near&&this.far===other.far&&this._offCenterFrustum.equals(other._offCenterFrustum);}},{key:"projectionMatrix",get:function get(){update(this);return this._offCenterFrustum.projectionMatrix;}},{key:"infiniteProjectionMatrix",get:function get(){update(this);return this._offCenterFrustum.infiniteProjectionMatrix;}},{key:"fovy",get:function get(){update(this);return this._fovy;}},{key:"sseDenominator",get:function get(){update(this);return this._sseDenominator;}},{key:"computeCullingVolume",value:function computeCullingVolume(position,direction,up){update(this);return this._offCenterFrustum.computeCullingVolume(position,direction,up);}},{key:"getPixelDimensions",value:function getPixelDimensions(drawingBufferWidth,drawingBufferHeight,distance,result){update(this);return this._offCenterFrustum.getPixelDimensions(drawingBufferWidth,drawingBufferHeight,distance,result);}}]);return PerspectiveFrustum;}();function update(frustum){assert$4(Number.isFinite(frustum.fov)&&Number.isFinite(frustum.aspectRatio)&&Number.isFinite(frustum.near)&&Number.isFinite(frustum.far));var f=frustum._offCenterFrustum;if(frustum.fov!==frustum._fov||frustum.aspectRatio!==frustum._aspectRatio||frustum.near!==frustum._near||frustum.far!==frustum._far||frustum.xOffset!==frustum._xOffset||frustum.yOffset!==frustum._yOffset){assert$4(frustum.fov>=0&&frustum.fov0);assert$4(frustum.near>=0&&frustum.near0&&arguments[0]!==undefined?arguments[0]:0;_classCallCheck(this,ManagedArray);_defineProperty(this,'_map',new Map());_defineProperty(this,'_array',void 0);_defineProperty(this,'_length',void 0);this._array=new Array(length);this._length=length;}_createClass(ManagedArray,[{key:"length",get:function get(){return this._length;},set:function set(length){this._length=length;if(length>this._array.length){this._array.length=length;}}},{key:"values",get:function get(){return this._array;}},{key:"get",value:function get(index){assert$7(index=0);if(index>=this.length){this.length=index+1;}if(this._map.has(this._array[index])){this._map.delete(this._array[index]);}this._array[index]=element;this._map.set(element,index);}},{key:"delete",value:function _delete(element){var index=this._map.get(element);if(index>=0){this._array.splice(index,1);this._map.delete(element);this.length--;}}},{key:"peek",value:function peek(){return this._array[this._length-1];}},{key:"push",value:function push(element){if(!this._map.has(element)){var index=this.length++;this._array[index]=element;this._map.set(element,index);}}},{key:"pop",value:function pop(){var element=this._array[--this.length];this._map.delete(element);return element;}},{key:"reserve",value:function reserve(length){assert$7(length>=0);if(length>this._array.length){this._array.length=length;}}},{key:"resize",value:function resize(length){assert$7(length>=0);this.length=length;}},{key:"trim",value:function trim(length){if(length===null||length===undefined){length=this.length;}this._array.length=length;}},{key:"reset",value:function reset(){this._array=[];this._map=new Map();this._length=0;}},{key:"find",value:function find(target){return this._map.has(target);}}]);return ManagedArray;}();var DEFAULT_PROPS$1={loadSiblings:false,skipLevelOfDetail:false,maximumScreenSpaceError:2,updateTransforms:true,onTraversalEnd:function onTraversalEnd(){},viewportTraversersMap:{},basePath:''};var TilesetTraverser=/*#__PURE__*/function(){function TilesetTraverser(options){_classCallCheck(this,TilesetTraverser);_defineProperty(this,'options',void 0);_defineProperty(this,'root',void 0);_defineProperty(this,'requestedTiles',void 0);_defineProperty(this,'selectedTiles',void 0);_defineProperty(this,'emptyTiles',void 0);_defineProperty(this,'_traversalStack',void 0);_defineProperty(this,'_emptyTraversalStack',void 0);_defineProperty(this,'_frameNumber',void 0);this.options=_objectSpread$3(_objectSpread$3({},DEFAULT_PROPS$1),options);this._traversalStack=new ManagedArray();this._emptyTraversalStack=new ManagedArray();this._frameNumber=null;this.root=null;this.selectedTiles={};this.requestedTiles={};this.emptyTiles={};}// 每次tileload都会遍历一次root _createClass(TilesetTraverser,[{key:"traverse",value:function traverse(root,frameState,options){this.root=root;this.options=_objectSpread$3(_objectSpread$3({},this.options),options);this.reset();this.updateTile(root,frameState);this._frameNumber=frameState.frameNumber;this.executeTraversal(root,frameState);}},{key:"reset",value:function reset(){this.requestedTiles={};this.selectedTiles={};this.emptyTiles={};this._traversalStack.reset();this._emptyTraversalStack.reset();}// 遍历root },{key:"executeTraversal",value:function executeTraversal(root,frameState){var stack=this._traversalStack;root._selectionDepth=1;stack.push(root);while(stack.length>0){var tile=stack.pop();var shouldRefine=false;// !zeg改 判断tile所在floor是否隐藏,如果是,则只显示最低精度不细化(tile.floorIndex为void 0,即代表该tile没有glb模型) var isFloorShow=tile.tileset.options.currentFloorId=='all'||tile.floorIndex==void 0||tile.floorIndex==tile.tileset.options.currentFloorId;// 循环遍历子tile if(this.canTraverse(tile,frameState)&&isFloorShow){this.updateChildTiles(tile,frameState);// 根据isVisibleAndInRequestVolume判断是否select shouldRefine=this.updateAndPushChildren(tile,frameState,stack,tile.hasRenderContent?tile._selectionDepth+1:tile._selectionDepth);}var parent=tile.parent;var parentRefines=Boolean(!parent||parent._shouldRefine);var stoppedRefining=!shouldRefine;if(!tile.hasRenderContent){this.emptyTiles[tile.id]=tile;this.loadTile(tile,frameState);if(stoppedRefining){this.selectTile(tile,frameState);}}else if(tile.refine===TILE_REFINEMENT.ADD){this.loadTile(tile,frameState);this.selectTile(tile,frameState);}else if(tile.refine===TILE_REFINEMENT.REPLACE){this.loadTile(tile,frameState);if(stoppedRefining){this.selectTile(tile,frameState);}}this.touchTile(tile,frameState);tile._shouldRefine=shouldRefine&&parentRefines;}this.options.onTraversalEnd(frameState);}},{key:"updateChildTiles",value:function updateChildTiles(tile,frameState){var children=tile.children;var _iterator16=_createForOfIteratorHelper$3(children),_step16;try{for(_iterator16.s();!(_step16=_iterator16.n()).done;){var child=_step16.value;this.updateTile(child,frameState);}}catch(err){_iterator16.e(err);}finally{_iterator16.f();}return true;}},{key:"updateAndPushChildren",value:function updateAndPushChildren(tile,frameState,stack,depth){var _this$options=this.options,loadSiblings=_this$options.loadSiblings,skipLevelOfDetail=_this$options.skipLevelOfDetail;var children=tile.children;children.sort(this.compareDistanceToCamera.bind(this)).reverse();// !zeg改 从近到远加载tile var checkRefines=tile.refine===TILE_REFINEMENT.REPLACE&&tile.hasRenderContent&&!skipLevelOfDetail;var hasVisibleChild=false;var refines=true;var _iterator17=_createForOfIteratorHelper$3(children),_step17;try{for(_iterator17.s();!(_step17=_iterator17.n()).done;){var child=_step17.value;child._selectionDepth=depth;// !zeg改 全部显示子tile,isVisibleAndInRequestVolume只判断是否选中。如果在这里过滤视野外tile,模型会需要重新加载 if(stack.find(child)){stack.delete(child);}stack.push(child);// 如果hasVisibleChild全都不为true,则tile全在可视范围外,不会被selectTile if(child.isVisibleAndInRequestVolume){hasVisibleChild=true;}else if(checkRefines||loadSiblings){this.loadTile(child,frameState);this.touchTile(child,frameState);}if(checkRefines){var childRefines=void 0;if(!child._inRequestVolume){childRefines=false;}else if(!child.hasRenderContent){childRefines=this.executeEmptyTraversal(child,frameState);}else {childRefines=child.contentAvailable;}refines=refines&&childRefines;if(!refines){return false;}}}}catch(err){_iterator17.e(err);}finally{_iterator17.f();}if(!hasVisibleChild){refines=false;}return refines;}},{key:"updateTile",value:function updateTile(tile,frameState){this.updateTileVisibility(tile,frameState);}},{key:"selectTile",value:function selectTile(tile,frameState){if(this.shouldSelectTile(tile)){tile._selectedFrame=frameState.frameNumber;this.selectedTiles[tile.id]=tile;}}},{key:"loadTile",value:function loadTile(tile,frameState){if(this.shouldLoadTile(tile)){tile._requestedFrame=frameState.frameNumber;tile._priority=tile._getPriority();this.requestedTiles[tile.id]=tile;}}},{key:"touchTile",value:function touchTile(tile,frameState){tile.tileset._cache.touch(tile);tile._touchedFrame=frameState.frameNumber;}// 判断是否遍历(即判断是否更新更精细的模型) },{key:"canTraverse",value:function canTraverse(tile,frameState){var useParentMetric=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;if(!tile.hasChildren){return false;}// !zeg改 ios防崩 当模型体积大于10e5立方米时,不加载最精细那层tile(注意:如果当模型只有一层tile时,会加载不出模型,不过体积大于10e5一般不可能只有一层) var modelSize=tile.tileset.options.modelSize;if(browser$1.detectIOS()&&modelSize&&modelSize.x*modelSize.y*modelSize.z>10e5){if(!tile.children[0].hasChildren){return false;}}if(tile.hasTilesetContent){return !tile.contentExpired;}// !zeg改 不判断可视范围,否则把rootTile移出再移回屏幕后,所有tile都将重新加载 // // 如果tile不在可视范围内,则不加载更精细的模型 // if (!ignoreVisibility && !tile.isVisibleAndInRequestVolume) { // return false // } return this.shouldRefine(tile,frameState,useParentMetric);}},{key:"shouldLoadTile",value:function shouldLoadTile(tile){return tile.hasUnloadedContent||tile.contentExpired;}},{key:"shouldSelectTile",value:function shouldSelectTile(tile){return tile.contentAvailable&&!this.options.skipLevelOfDetail;}// 是否更新更精细的模型 },{key:"shouldRefine",value:function shouldRefine(tile,frameState,useParentMetric){if(tile.tileset.options.loadMaxLevelDirect){return true;//xzw add : 直接加载到最高清晰度,用于截图 }var screenSpaceError=tile._screenSpaceError;if(useParentMetric){screenSpaceError=tile.getScreenSpaceError(frameState,true);}// 距离越近,SSE越大 return screenSpaceError>this.options.maximumScreenSpaceError;}},{key:"updateTileVisibility",value:function updateTileVisibility(tile,frameState){var viewportIds=[];if(this.options.viewportTraversersMap){for(var key in this.options.viewportTraversersMap){var value=this.options.viewportTraversersMap[key];if(value===frameState.viewport.id){viewportIds.push(key);}}}else {viewportIds.push(frameState.viewport.id);}tile.updateVisibility(frameState,viewportIds);}},{key:"compareDistanceToCamera",value:function compareDistanceToCamera(b,a){return b._distanceToCamera-a._distanceToCamera;}// 检测tile是否有任意child可视 },{key:"anyChildrenVisible",value:function anyChildrenVisible(tile,frameState){var anyVisible=false;var _iterator18=_createForOfIteratorHelper$3(tile.children),_step18;try{for(_iterator18.s();!(_step18=_iterator18.n()).done;){var child=_step18.value;child.updateVisibility(frameState);anyVisible=anyVisible||child.isVisibleAndInRequestVolume;}}catch(err){_iterator18.e(err);}finally{_iterator18.f();}return anyVisible;}},{key:"executeEmptyTraversal",value:function executeEmptyTraversal(root,frameState){var allDescendantsLoaded=true;var stack=this._emptyTraversalStack;stack.push(root);while(stack.length>0&&allDescendantsLoaded){var tile=stack.pop();this.updateTile(tile,frameState);if(!tile.isVisibleAndInRequestVolume){this.loadTile(tile,frameState);}this.touchTile(tile,frameState);var traverse=!tile.hasRenderContent&&this.canTraverse(tile,frameState,false,true);if(traverse){var children=tile.children;var _iterator19=_createForOfIteratorHelper$3(children),_step19;try{for(_iterator19.s();!(_step19=_iterator19.n()).done;){var child=_step19.value;if(stack.find(child)){stack.delete(child);}stack.push(child);}}catch(err){_iterator19.e(err);}finally{_iterator19.f();}}else if(!tile.contentAvailable){allDescendantsLoaded=false;}}return allDescendantsLoaded;}}]);return TilesetTraverser;}();var scratchVector=new Vector3$1();function defined$2(x){return x!==undefined&&x!==null;}var TileHeader=/*#__PURE__*/function(){function TileHeader(tileset,header,parentHeader){var extendedId=arguments.length>3&&arguments[3]!==undefined?arguments[3]:'';_classCallCheck(this,TileHeader);_defineProperty(this,'tileset',void 0);_defineProperty(this,'header',void 0);_defineProperty(this,'id',void 0);_defineProperty(this,'url',void 0);_defineProperty(this,'parent',void 0);_defineProperty(this,'refine',void 0);_defineProperty(this,'type',void 0);_defineProperty(this,'contentUrl',void 0);_defineProperty(this,'lodMetricType',void 0);_defineProperty(this,'lodMetricValue',void 0);_defineProperty(this,'boundingVolume',void 0);_defineProperty(this,'content',void 0);_defineProperty(this,'contentState',void 0);_defineProperty(this,'gpuMemoryUsageInBytes',void 0);_defineProperty(this,'children',void 0);_defineProperty(this,'depth',void 0);_defineProperty(this,'viewportIds',void 0);_defineProperty(this,'transform',void 0);_defineProperty(this,'extensions',void 0);_defineProperty(this,'userData',void 0);_defineProperty(this,'computedTransform',void 0);_defineProperty(this,'hasEmptyContent',void 0);_defineProperty(this,'hasTilesetContent',void 0);_defineProperty(this,'traverser',void 0);_defineProperty(this,'_cacheNode',void 0);_defineProperty(this,'_frameNumber',void 0);_defineProperty(this,'_lodJudge',void 0);_defineProperty(this,'_expireDate',void 0);_defineProperty(this,'_expiredContent',void 0);_defineProperty(this,'_shouldRefine',void 0);_defineProperty(this,'_distanceToCamera',void 0);_defineProperty(this,'_centerZDepth',void 0);_defineProperty(this,'_screenSpaceError',void 0);_defineProperty(this,'_visibilityPlaneMask',void 0);_defineProperty(this,'_visible',void 0);_defineProperty(this,'_inRequestVolume',void 0);_defineProperty(this,'_stackLength',void 0);_defineProperty(this,'_selectionDepth',void 0);_defineProperty(this,'_touchedFrame',void 0);_defineProperty(this,'_visitedFrame',void 0);_defineProperty(this,'_selectedFrame',void 0);_defineProperty(this,'_requestedFrame',void 0);_defineProperty(this,'_priority',void 0);_defineProperty(this,'_contentBoundingVolume',void 0);_defineProperty(this,'_viewerRequestVolume',void 0);_defineProperty(this,'_initialTransform',void 0);_defineProperty(this,'floorIndex',void 0);// !zeg改 用于记录tile所在楼层 this.header=header;this.tileset=tileset;this.id=extendedId||header.id;this.url=header.url;this.parent=parentHeader;this.refine=this._getRefine(header.refine);this.type=header.type;this.contentUrl=header.contentUrl;this.lodMetricType='geometricError';this.lodMetricValue=0;this.boundingVolume=null;this.content=null;this.contentState=TILE_CONTENT_STATE.UNLOADED;this.gpuMemoryUsageInBytes=0;this.children=[];this.hasEmptyContent=false;this.hasTilesetContent=false;this.depth=0;this.viewportIds=[];this.userData={};this.extensions=null;this._priority=0;this._touchedFrame=0;this._visitedFrame=0;this._selectedFrame=0;this._requestedFrame=0;this._screenSpaceError=0;this._cacheNode=null;this._frameNumber=null;this._cacheNode=null;this.traverser=new TilesetTraverser({});this._shouldRefine=false;this._distanceToCamera=0;this._centerZDepth=0;this._visible=undefined;this._inRequestVolume=false;this._stackLength=0;this._selectionDepth=0;this._initialTransform=new Matrix4();this.transform=new Matrix4();this.controller=null;this._initializeLodMetric(header);this._initializeTransforms(header);this._initializeBoundingVolumes(header);this._initializeContent(header);this._initializeRenderingState(header);this._lodJudge=null;this._expireDate=null;this._expiredContent=null;Object.seal(this);}_createClass(TileHeader,[{key:"destroy",value:function destroy(){this.header=null;}},{key:"isDestroyed",value:function isDestroyed(){return this.header===null;}},{key:"selected",get:function get(){return this._selectedFrame===this.tileset._frameNumber;}},{key:"isVisible",get:function get(){return this._visible;}// 是否在可视范围内 },{key:"isVisibleAndInRequestVolume",get:function get(){return this._visible&&this._inRequestVolume;}},{key:"hasRenderContent",get:function get(){return !this.hasEmptyContent&&!this.hasTilesetContent;}},{key:"hasChildren",get:function get(){return this.children.length>0||this.header.children&&this.header.children.length>0;}},{key:"contentReady",get:function get(){return this.contentState===TILE_CONTENT_STATE.READY||this.hasEmptyContent;}},{key:"contentAvailable",get:function get(){return Boolean(this.contentReady&&this.hasRenderContent||this._expiredContent&&!this.contentFailed);}},{key:"hasUnloadedContent",get:function get(){return this.hasRenderContent&&this.contentUnloaded;}},{key:"contentUnloaded",get:function get(){return this.contentState===TILE_CONTENT_STATE.UNLOADED;}},{key:"contentExpired",get:function get(){return this.contentState===TILE_CONTENT_STATE.EXPIRED;}},{key:"contentFailed",get:function get(){return this.contentState===TILE_CONTENT_STATE.FAILED;}},{key:"getScreenSpaceError",value:function getScreenSpaceError(frameState,useParentLodMetric){switch(this.tileset.type){case TILESET_TYPE.I3S:return getProjectedRadius(this,frameState);case TILESET_TYPE.TILES3D:return getTiles3DScreenSpaceError(this,frameState,useParentLodMetric);default:throw new Error('Unsupported tileset type');}}},{key:"_getPriority",value:function _getPriority(){var traverser=this.tileset._traverser;var skipLevelOfDetail=traverser.options.skipLevelOfDetail;var maySkipTile=this.refine===TILE_REFINEMENT.ADD||skipLevelOfDetail;if(maySkipTile&&!this.isVisible&&this._visible!==undefined){return -1;}if(this.tileset._frameNumber-this._touchedFrame>=1){return -1;}if(this.contentState===TILE_CONTENT_STATE.UNLOADED){return -1;}var parent=this.parent;var useParentScreenSpaceError=parent&&(!maySkipTile||this._screenSpaceError===0.0||parent.hasTilesetContent);var screenSpaceError=useParentScreenSpaceError?parent._screenSpaceError:this._screenSpaceError;var rootScreenSpaceError=traverser.root?traverser.root._screenSpaceError:0.0;return Math.max(rootScreenSpaceError-screenSpaceError,0);}},{key:"loadContent",value:function(){var _loadContent=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee6(){var expired,requestToken,contentUrl,loader,options;return regenerator.wrap(function _callee6$(_context9){while(1){switch(_context9.prev=_context9.next){case 0:if(!this.hasEmptyContent){_context9.next=2;break;}return _context9.abrupt("return",false);case 2:if(!this.content){_context9.next=4;break;}return _context9.abrupt("return",true);case 4:expired=this.contentExpired;if(expired){this._expireDate=null;}this.contentState=TILE_CONTENT_STATE.LOADING;_context9.next=9;return this.tileset._requestScheduler.scheduleRequest(this.id,this._getPriority.bind(this));case 9:requestToken=_context9.sent;if(requestToken){_context9.next=13;break;}this.contentState=TILE_CONTENT_STATE.UNLOADED;return _context9.abrupt("return",false);case 13:_context9.prev=13;// !zeg改 使用AbortController中止tile的fetch请求 this.controller=new AbortController();contentUrl=this.tileset.getTileUrl(this.contentUrl)+"?_=".concat(this.tileset.options.imageVersion);// !zeg改 添加version后缀 loader=this.tileset.loader;options=_objectSpread$3(_objectSpread$3({},this.tileset.loadOptions),{},{fetch:{signal:this.controller.signal},[loader.id]:_objectSpread$3(_objectSpread$3({},this.tileset.loadOptions[loader.id]),{},{isTileset:this.type==='json'},this._getLoaderSpecificOptions(loader.id))});_context9.next=20;return _load2(contentUrl,loader,options);case 20:this.content=_context9.sent;// !zeg改 加载glb的byteLength if(this.content.type=='glTF'){this.content.byteLength=this.content.gltf.buffers[0].byteLength;}if(!this.tileset.options.contentLoader){_context9.next=25;break;}_context9.next=25;return this.tileset.options.contentLoader(this);case 25:if(this._isTileset()){this.tileset._initializeTileHeaders(this.content,this);}this.contentState=TILE_CONTENT_STATE.READY;this._onContentLoaded();return _context9.abrupt("return",true);case 31:_context9.prev=31;_context9.t0=_context9["catch"](13);if(!(_context9.t0.message.indexOf('The user aborted a request')>-1)){_context9.next=36;break;}this.contentState=TILE_CONTENT_STATE.UNLOADED;return _context9.abrupt("return",false);case 36:this.contentState=TILE_CONTENT_STATE.FAILED;throw _context9.t0;case 38:_context9.prev=38;requestToken.done();return _context9.finish(38);case 41:case"end":return _context9.stop();}}},_callee6,this,[[13,31,38,41]]);}));function loadContent(){return _loadContent.apply(this,arguments);}return loadContent;}()},{key:"unloadContent",value:function unloadContent(){if(this.content&&this.content.destroy){this.content.destroy();}this.content=null;if(this.header.content&&this.header.content.destroy){this.header.content.destroy();}this.header.content=null;this.contentState=TILE_CONTENT_STATE.UNLOADED;return true;}},{key:"updateVisibility",value:function updateVisibility(frameState,viewportIds){if(this._frameNumber===frameState.frameNumber){return;}var parent=this.parent;var parentVisibilityPlaneMask=parent?parent._visibilityPlaneMask:CullingVolume.MASK_INDETERMINATE;if(this.tileset._traverser.options.updateTransforms){var parentTransform=parent?parent.computedTransform:this.tileset.modelMatrix;this._updateTransform(parentTransform);}this._distanceToCamera=this.distanceToTile(frameState);this._screenSpaceError=this.getScreenSpaceError(frameState,false);this._visibilityPlaneMask=this.visibility(frameState,parentVisibilityPlaneMask);this._visible=this._visibilityPlaneMask!==CullingVolume.MASK_OUTSIDE;this._inRequestVolume=this.insideViewerRequestVolume(frameState);this._frameNumber=frameState.frameNumber;this.viewportIds=viewportIds;}},{key:"visibility",value:function visibility(frameState,parentVisibilityPlaneMask){var cullingVolume=frameState.cullingVolume;var boundingVolume=this.boundingVolume;return cullingVolume.computeVisibilityWithPlaneMask(boundingVolume,parentVisibilityPlaneMask);}},{key:"contentVisibility",value:function contentVisibility(){return true;}},{key:"distanceToTile",value:function distanceToTile(frameState){var boundingVolume=this.boundingVolume;return Math.sqrt(Math.max(boundingVolume.distanceSquaredTo(frameState.camera.position),0));}},{key:"cameraSpaceZDepth",value:function cameraSpaceZDepth(_ref15){var camera=_ref15.camera;var boundingVolume=this.boundingVolume;scratchVector.subVectors(boundingVolume.center,camera.position);return camera.direction.dot(scratchVector);}},{key:"insideViewerRequestVolume",value:function insideViewerRequestVolume(frameState){var viewerRequestVolume=this._viewerRequestVolume;return !viewerRequestVolume||viewerRequestVolume.distanceSquaredTo(frameState.camera.position)<=0;}},{key:"updateExpiration",value:function updateExpiration(){if(defined$2(this._expireDate)&&this.contentReady&&!this.hasEmptyContent){var now=Date.now();if(Date.lessThan(this._expireDate,now)){this.contentState=TILE_CONTENT_STATE.EXPIRED;this._expiredContent=this.content;}}}},{key:"extras",get:function get(){return this.header.extras;}},{key:"_initializeLodMetric",value:function _initializeLodMetric(header){if('lodMetricType'in header){this.lodMetricType=header.lodMetricType;}else {this.lodMetricType=this.parent&&this.parent.lodMetricType||this.tileset.lodMetricType;console.warn('3D Tile: Required prop lodMetricType is undefined. Using parent lodMetricType');}if('lodMetricValue'in header){this.lodMetricValue=header.lodMetricValue;}else {this.lodMetricValue=this.parent&&this.parent.lodMetricValue||this.tileset.lodMetricValue;console.warn('3D Tile: Required prop lodMetricValue is undefined. Using parent lodMetricValue');}}},{key:"_initializeTransforms",value:function _initializeTransforms(tileHeader){this.transform=tileHeader.transform?new Matrix4(tileHeader.transform):new Matrix4();var parent=this.parent;var tileset=this.tileset;var parentTransform=parent&&parent.computedTransform?parent.computedTransform.clone():tileset.modelMatrix.clone();this.computedTransform=new Matrix4(parentTransform).multiplyRight(this.transform);var parentInitialTransform=parent&&parent._initialTransform?parent._initialTransform.clone():new Matrix4();this._initialTransform=new Matrix4(parentInitialTransform).multiplyRight(this.transform);}},{key:"_initializeBoundingVolumes",value:function _initializeBoundingVolumes(tileHeader){this._contentBoundingVolume=null;this._viewerRequestVolume=null;this._updateBoundingVolume(tileHeader);}},{key:"_initializeContent",value:function _initializeContent(tileHeader){this.content={_tileset:this.tileset,_tile:this};this.hasEmptyContent=true;this.contentState=TILE_CONTENT_STATE.UNLOADED;this.hasTilesetContent=false;if(tileHeader.contentUrl){this.content=null;this.hasEmptyContent=false;}}},{key:"_initializeRenderingState",value:function _initializeRenderingState(header){this.depth=header.level||(this.parent?this.parent.depth+1:0);this._shouldRefine=false;this._distanceToCamera=0;this._centerZDepth=0;this._screenSpaceError=0;this._visibilityPlaneMask=CullingVolume.MASK_INDETERMINATE;this._visible=undefined;this._inRequestVolume=false;this._stackLength=0;this._selectionDepth=0;this._frameNumber=0;this._touchedFrame=0;this._visitedFrame=0;this._selectedFrame=0;this._requestedFrame=0;this._priority=0.0;}},{key:"_getRefine",value:function _getRefine(refine){return refine||this.parent&&this.parent.refine||TILE_REFINEMENT.REPLACE;}},{key:"_isTileset",value:function _isTileset(){return this.contentUrl.indexOf('.json')!==-1;}},{key:"_onContentLoaded",value:function _onContentLoaded(){switch(this.content&&this.content.type){case'vctr':case'geom':this.tileset._traverser.disableSkipLevelOfDetail=true;break;}if(this._isTileset()){this.hasTilesetContent=true;}}},{key:"_updateBoundingVolume",value:function _updateBoundingVolume(header){this.boundingVolume=createBoundingVolume(header.boundingVolume,this.computedTransform,this.boundingVolume);var content=header.content;if(!content){return;}if(content.boundingVolume){this._contentBoundingVolume=createBoundingVolume(content.boundingVolume,this.computedTransform,this._contentBoundingVolume);}if(header.viewerRequestVolume){this._viewerRequestVolume=createBoundingVolume(header.viewerRequestVolume,this.computedTransform,this._viewerRequestVolume);}}},{key:"_updateTransform",value:function _updateTransform(){var parentTransform=arguments.length>0&&arguments[0]!==undefined?arguments[0]:new Matrix4();var computedTransform=parentTransform.clone().multiplyRight(this.transform);var didTransformChange=!computedTransform.equals(this.computedTransform);if(!didTransformChange){return;}this.computedTransform=computedTransform;this._updateBoundingVolume(this.header);}},{key:"_getLoaderSpecificOptions",value:function _getLoaderSpecificOptions(loaderId){switch(loaderId){case'i3s':return _objectSpread$3(_objectSpread$3({},this.tileset.options.i3s),{},{tile:this.header,tileset:this.tileset.tileset,isTileHeader:false});case'3d-tiles':case'cesium-ion':default:return get3dTilesOptions(this.tileset.tileset);}}}]);return TileHeader;}();var Tileset3DTraverser=/*#__PURE__*/function(_TilesetTraverser){_inherits(Tileset3DTraverser,_TilesetTraverser);var _super9=_createSuper$E(Tileset3DTraverser);function Tileset3DTraverser(){_classCallCheck(this,Tileset3DTraverser);return _super9.apply(this,arguments);}_createClass(Tileset3DTraverser,[{key:"compareDistanceToCamera",value:function compareDistanceToCamera(a,b){return b._distanceToCamera===0&&a._distanceToCamera===0?b._centerZDepth-a._centerZDepth:b._distanceToCamera-a._distanceToCamera;}},{key:"updateTileVisibility",value:function updateTileVisibility(tile,frameState){_get(_getPrototypeOf(Tileset3DTraverser.prototype),"updateTileVisibility",this).call(this,tile,frameState);// !zeg改 强制显示所有tile if(this.options.ingoreVisibleCompute){tile._visible=true;return;}if(!tile.isVisibleAndInRequestVolume){return;}var hasChildren=tile.children.length>0;if(tile.hasTilesetContent&&hasChildren){var firstChild=tile.children[0];this.updateTileVisibility(firstChild,frameState);tile._visible=firstChild._visible;return;}if(this.meetsScreenSpaceErrorEarly(tile,frameState)){tile._visible=false;return;}var replace=tile.refine===TILE_REFINEMENT.REPLACE;var useOptimization=tile._optimChildrenWithinParent===TILE3D_OPTIMIZATION_HINT.USE_OPTIMIZATION;// 当没有child可视时,tile也不可视 if(replace&&useOptimization&&hasChildren){if(!this.anyChildrenVisible(tile,frameState)){tile._visible=false;return;}}}},{key:"meetsScreenSpaceErrorEarly",value:function meetsScreenSpaceErrorEarly(tile,frameState){var parent=tile.parent;if(!parent||parent.hasTilesetContent||parent.refine!==TILE_REFINEMENT.ADD){return false;}return !this.shouldRefine(tile,frameState,true);}}]);return Tileset3DTraverser;}(TilesetTraverser);var STATUS={REQUESTED:'REQUESTED',COMPLETED:'COMPLETED',ERROR:'ERROR'};var I3STileManager=/*#__PURE__*/function(){function I3STileManager(){_classCallCheck(this,I3STileManager);_defineProperty(this,'_statusMap',void 0);this._statusMap={};}_createClass(I3STileManager,[{key:"add",value:function add(request,key,callback,frameState){var _this12=this;if(!this._statusMap[key]){this._statusMap[key]={request,callback,key,frameState,status:STATUS.REQUESTED};request().then(function(data){_this12._statusMap[key].status=STATUS.COMPLETED;_this12._statusMap[key].callback(data,frameState);}).catch(function(error){_this12._statusMap[key].status=STATUS.ERROR;callback(error);});}}},{key:"update",value:function update(key,frameState){if(this._statusMap[key]){this._statusMap[key].frameState=frameState;}}},{key:"find",value:function find(key){return this._statusMap[key];}}]);return I3STileManager;}();var I3STilesetTraverser=/*#__PURE__*/function(_TilesetTraverser2){_inherits(I3STilesetTraverser,_TilesetTraverser2);var _super10=_createSuper$E(I3STilesetTraverser);function I3STilesetTraverser(options){var _this13;_classCallCheck(this,I3STilesetTraverser);_this13=_super10.call(this,options);_defineProperty(_assertThisInitialized(_this13),'_tileManager',void 0);_this13._tileManager=new I3STileManager();return _this13;}_createClass(I3STilesetTraverser,[{key:"shouldRefine",value:function shouldRefine(tile,frameState){tile._lodJudge=getLodStatus(tile,frameState);return tile._lodJudge==='DIG';}},{key:"updateChildTiles",value:function updateChildTiles(tile,frameState){var _this14=this;var children=tile.header.children||[];var childTiles=tile.children;var tileset=tile.tileset;var _iterator20=_createForOfIteratorHelper$3(children),_step20;try{var _loop2=function _loop2(){var child=_step20.value;var extendedId=''.concat(child.id,'-').concat(frameState.viewport.id);var childTile=childTiles&&childTiles.find(function(t){return t.id===extendedId;});if(!childTile){var request=function request(){return _this14._loadTile(child.id,tileset);};var cachedRequest=_this14._tileManager.find(extendedId);if(!cachedRequest){if(tileset.tileset.nodePages){request=function request(){return tileset.tileset.nodePagesTile.formTileFromNodePages(child.id);};}_this14._tileManager.add(request,extendedId,function(header){return _this14._onTileLoad(header,tile,extendedId);},frameState);}else {_this14._tileManager.update(extendedId,frameState);}}else if(childTile){_this14.updateTile(childTile,frameState);}};for(_iterator20.s();!(_step20=_iterator20.n()).done;){_loop2();}}catch(err){_iterator20.e(err);}finally{_iterator20.f();}return false;}},{key:"_loadTile",value:function(){var _loadTile2=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee7(nodeId,tileset){var loader,nodeUrl,options;return regenerator.wrap(function _callee7$(_context10){while(1){switch(_context10.prev=_context10.next){case 0:loader=tileset.loader;nodeUrl=tileset.getTileUrl(''.concat(tileset.url,'/nodes/').concat(nodeId));options=_objectSpread$3(_objectSpread$3({},tileset.loadOptions),{},{i3s:_objectSpread$3(_objectSpread$3({},tileset.loadOptions.i3s),{},{isTileHeader:true,loadContent:false})});_context10.next=5;return _load2(nodeUrl,loader,options);case 5:return _context10.abrupt("return",_context10.sent);case 6:case"end":return _context10.stop();}}},_callee7);}));function _loadTile(_x41,_x42){return _loadTile2.apply(this,arguments);}return _loadTile;}()},{key:"_onTileLoad",value:function _onTileLoad(header,tile,extendedId){var childTile=new TileHeader(tile.tileset,header,tile,extendedId);tile.children.push(childTile);var frameState=this._tileManager.find(childTile.id).frameState;this.updateTile(childTile,frameState);if(this._frameNumber===frameState.frameNumber){this.executeTraversal(childTile,frameState);}}}]);return I3STilesetTraverser;}(TilesetTraverser);var DEFAULT_PROPS={description:'',ellipsoid:Ellipsoid.WGS84,modelMatrix:new Matrix4(),throttleRequests:true,maxRequests:64,maximumMemoryUsage:32,onTileLoad:function onTileLoad(){},onTileUnload:function onTileUnload(){},onTileError:function onTileError(){},onTraversalComplete:function onTraversalComplete(selectedTiles){return selectedTiles;},contentLoader:undefined,viewDistanceScale:1.0,maximumScreenSpaceError:8,loadTiles:true,updateTransforms:true,viewportTraversersMap:null,loadOptions:{fetch:{}},attributions:[],basePath:'',i3s:{}};var TILES_TOTAL='Tiles In Tileset(s)';var TILES_IN_MEMORY='Tiles In Memory';var TILES_IN_VIEW='Tiles In View';var TILES_RENDERABLE='Tiles To Render';var TILES_LOADED='Tiles Loaded';var TILES_LOADING='Tiles Loading';var TILES_UNLOADED='Tiles Unloaded';var TILES_LOAD_FAILED='Failed Tile Loads';var POINTS_COUNT='Points';var TILES_GPU_MEMORY='Tile Memory Use';var Tileset3D=/*#__PURE__*/function(_Emiter){_inherits(Tileset3D,_Emiter);var _super11=_createSuper$E(Tileset3D);function Tileset3D(json,options){var _this15;_classCallCheck(this,Tileset3D);_this15=_super11.call(this);_defineProperty(_assertThisInitialized(_this15),'options',void 0);_defineProperty(_assertThisInitialized(_this15),'loadOptions',void 0);_defineProperty(_assertThisInitialized(_this15),'type',void 0);_defineProperty(_assertThisInitialized(_this15),'tileset',void 0);_defineProperty(_assertThisInitialized(_this15),'loader',void 0);_defineProperty(_assertThisInitialized(_this15),'url',void 0);_defineProperty(_assertThisInitialized(_this15),'basePath',void 0);_defineProperty(_assertThisInitialized(_this15),'modelMatrix',void 0);_defineProperty(_assertThisInitialized(_this15),'ellipsoid',void 0);_defineProperty(_assertThisInitialized(_this15),'lodMetricType',void 0);_defineProperty(_assertThisInitialized(_this15),'lodMetricValue',void 0);_defineProperty(_assertThisInitialized(_this15),'refine',void 0);_defineProperty(_assertThisInitialized(_this15),'root',void 0);_defineProperty(_assertThisInitialized(_this15),'roots',void 0);_defineProperty(_assertThisInitialized(_this15),'asset',void 0);_defineProperty(_assertThisInitialized(_this15),'description',void 0);_defineProperty(_assertThisInitialized(_this15),'properties',void 0);_defineProperty(_assertThisInitialized(_this15),'extras',void 0);_defineProperty(_assertThisInitialized(_this15),'attributions',void 0);_defineProperty(_assertThisInitialized(_this15),'credits',void 0);_defineProperty(_assertThisInitialized(_this15),'stats',void 0);_defineProperty(_assertThisInitialized(_this15),'traverseCounter',void 0);_defineProperty(_assertThisInitialized(_this15),'geometricError',void 0);_defineProperty(_assertThisInitialized(_this15),'selectedTiles',void 0);_defineProperty(_assertThisInitialized(_this15),'cartographicCenter',void 0);_defineProperty(_assertThisInitialized(_this15),'cartesianCenter',void 0);_defineProperty(_assertThisInitialized(_this15),'zoom',void 0);_defineProperty(_assertThisInitialized(_this15),'boundingVolume',void 0);_defineProperty(_assertThisInitialized(_this15),'gpuMemoryUsageInBytes',void 0);_defineProperty(_assertThisInitialized(_this15),'dynamicScreenSpaceErrorComputedDensity',void 0);_defineProperty(_assertThisInitialized(_this15),'_traverser',void 0);_defineProperty(_assertThisInitialized(_this15),'_cache',void 0);_defineProperty(_assertThisInitialized(_this15),'_requestScheduler',void 0);_defineProperty(_assertThisInitialized(_this15),'_frameNumber',void 0);_defineProperty(_assertThisInitialized(_this15),'_queryParamsString',void 0);_defineProperty(_assertThisInitialized(_this15),'_queryParams',void 0);_defineProperty(_assertThisInitialized(_this15),'_extensionsUsed',void 0);_defineProperty(_assertThisInitialized(_this15),'_tiles',void 0);_defineProperty(_assertThisInitialized(_this15),'_pendingCount',void 0);_defineProperty(_assertThisInitialized(_this15),'lastUpdatedVieports',void 0);_defineProperty(_assertThisInitialized(_this15),'_requestedTiles',void 0);_defineProperty(_assertThisInitialized(_this15),'_emptyTiles',void 0);_defineProperty(_assertThisInitialized(_this15),'frameStateData',void 0);_defineProperty(_assertThisInitialized(_this15),'maximumMemoryUsage',void 0);_defineProperty(_assertThisInitialized(_this15),'loadingTiles',void 0);// !zeg改 用于记录正在加载中的tile assert$7(json);_this15.options=_objectSpread$3(_objectSpread$3({},DEFAULT_PROPS),options);_this15.tileset=json;_this15.loader=json.loader;_this15.type=json.type;_this15.url=json.url;_this15.basePath=json.basePath||dirname(_this15.url);_this15.modelMatrix=_this15.options.modelMatrix;_this15.ellipsoid=_this15.options.ellipsoid;_this15.lodMetricType=json.lodMetricType;_this15.lodMetricValue=json.lodMetricValue;_this15.refine=json.root.refine;_this15.loadOptions=_this15.options.loadOptions||{};_this15.root=null;_this15.roots={};_this15.cartographicCenter=null;_this15.cartesianCenter=null;_this15.zoom=1;_this15.boundingVolume=null;_this15.traverseCounter=0;_this15.geometricError=0;_this15._traverser=_this15._initializeTraverser();_this15._cache=new TilesetCache();_this15._requestScheduler=new RequestScheduler({throttleRequests:_this15.options.throttleRequests,maxRequests:_this15.options.maxRequests});_this15._frameNumber=0;_this15._pendingCount=0;_this15._tiles={};_this15.selectedTiles=[];_this15._emptyTiles=[];_this15._requestedTiles=[];_this15.frameStateData={};_this15.lastUpdatedVieports=null;_this15._queryParams={};_this15._queryParamsString='';_this15.maximumMemoryUsage=_this15.options.maximumMemoryUsage||32;_this15.gpuMemoryUsageInBytes=0;_this15.stats=new Stats({id:_this15.url});_this15.loadingTiles=[];_this15._initializeStats();_this15._extensionsUsed=undefined;_this15.dynamicScreenSpaceErrorComputedDensity=0.0;_this15.extras=null;_this15.asset={};_this15.credits={};_this15.description=_this15.options.description||'';_this15._initializeTileSet(json);return _this15;}_createClass(Tileset3D,[{key:"destroy",value:function destroy(){this._destroy();}},{key:"isLoaded",value:function isLoaded(){return this._pendingCount===0&&this._frameNumber!==0;}},{key:"tiles",get:function get(){return Object.values(this._tiles);}},{key:"frameNumber",get:function get(){return this._frameNumber;}},{key:"queryParams",get:function get(){if(!this._queryParamsString){this._queryParamsString=getQueryParamString(this._queryParams);}return this._queryParamsString;}},{key:"setProps",value:function setProps(props){this.options=_objectSpread$3(_objectSpread$3({},this.options),props);}},{key:"setOptions",value:function setOptions(options){this.options=_objectSpread$3(_objectSpread$3({},this.options),options);}},{key:"getTileUrl",value:function getTileUrl(tilePath){var isDataUrl=tilePath.startsWith('data:');if(isDataUrl){return tilePath;}return ''.concat(tilePath).concat(this.queryParams);}},{key:"hasExtension",value:function hasExtension(extensionName){return Boolean(this._extensionsUsed&&this._extensionsUsed.indexOf(extensionName)>-1);}},{key:"update",value:function update(viewports){if('loadTiles'in this.options&&!this.options.loadTiles){return;}if(this.traverseCounter>0){return;}if(!viewports&&this.lastUpdatedVieports){viewports=this.lastUpdatedVieports;}else {this.lastUpdatedVieports=viewports;}if(!(viewports instanceof Array)){viewports=[viewports];}this._cache.reset();this._frameNumber++;this.traverseCounter=viewports.length;var viewportsToTraverse=[];var _iterator21=_createForOfIteratorHelper$3(viewports),_step21;try{for(_iterator21.s();!(_step21=_iterator21.n()).done;){var viewport=_step21.value;var id=viewport.id;if(this._needTraverse(id)){viewportsToTraverse.push(id);}else {this.traverseCounter--;}}}catch(err){_iterator21.e(err);}finally{_iterator21.f();}var _iterator22=_createForOfIteratorHelper$3(viewports),_step22;try{for(_iterator22.s();!(_step22=_iterator22.n()).done;){var _viewport=_step22.value;var _id=_viewport.id;if(!this.roots[_id]){this.roots[_id]=this._initializeTileHeaders(this.tileset,null);}if(!viewportsToTraverse.includes(_id)){continue;}var frameState=getFrameState(_viewport,this._frameNumber);this._traverser.traverse(this.roots[_id],frameState,this.options);}}catch(err){_iterator22.e(err);}finally{_iterator22.f();}}},{key:"_needTraverse",value:function _needTraverse(viewportId){var traverserId=viewportId;if(this.options.viewportTraversersMap){traverserId=this.options.viewportTraversersMap[viewportId];}if(traverserId!==viewportId){return false;}return true;}},{key:"_onTraversalEnd",value:function _onTraversalEnd(frameState){var id=frameState.viewport.id;if(!this.frameStateData[id]){this.frameStateData[id]={selectedTiles:[],_requestedTiles:[],_emptyTiles:[]};}var currentFrameStateData=this.frameStateData[id];var selectedTiles=Object.values(this._traverser.selectedTiles);currentFrameStateData.selectedTiles=selectedTiles;currentFrameStateData._requestedTiles=Object.values(this._traverser.requestedTiles);currentFrameStateData._emptyTiles=Object.values(this._traverser.emptyTiles);this.traverseCounter--;if(this.traverseCounter>0){return;}this._updateTiles();}},{key:"_updateTiles",value:function _updateTiles(){this.selectedTiles=[];this._requestedTiles=[];this._emptyTiles=[];for(var frameStateKey in this.frameStateData){var frameStateDataValue=this.frameStateData[frameStateKey];this.selectedTiles=this.selectedTiles.concat(frameStateDataValue.selectedTiles);this._requestedTiles=this._requestedTiles.concat(frameStateDataValue._requestedTiles);this._emptyTiles=this._emptyTiles.concat(frameStateDataValue._emptyTiles);}this.selectedTiles=this.options.onTraversalComplete(this.selectedTiles);var _iterator23=_createForOfIteratorHelper$3(this.selectedTiles),_step23;try{for(_iterator23.s();!(_step23=_iterator23.n()).done;){var tile=_step23.value;this._tiles[tile.id]=tile;}}catch(err){_iterator23.e(err);}finally{_iterator23.f();}this._loadTiles();this._unloadTiles();this._updateStats();}},{key:"_tilesChanged",value:function _tilesChanged(oldSelectedTiles,selectedTiles){if(oldSelectedTiles.length!==selectedTiles.length){return true;}var set1=new Set(oldSelectedTiles.map(function(t){return t.id;}));var set2=new Set(selectedTiles.map(function(t){return t.id;}));var changed=oldSelectedTiles.filter(function(x){return !set2.has(x.id);}).length>0;changed=changed||selectedTiles.filter(function(x){return !set1.has(x.id);}).length>0;return changed;}},{key:"_loadTiles",value:function _loadTiles(){var _iterator24=_createForOfIteratorHelper$3(this._requestedTiles),_step24;try{for(_iterator24.s();!(_step24=_iterator24.n()).done;){var tile=_step24.value;if(tile.contentUnloaded){this._loadTile(tile);}}}catch(err){_iterator24.e(err);}finally{_iterator24.f();}}},{key:"_unloadTiles",value:function _unloadTiles(){this._cache.unloadTiles(this,function(tileset,tile){return tileset._unloadTile(tile);});}},{key:"_updateStats",value:function _updateStats(){var tilesRenderable=0;var pointsRenderable=0;var _iterator25=_createForOfIteratorHelper$3(this.selectedTiles),_step25;try{for(_iterator25.s();!(_step25=_iterator25.n()).done;){var tile=_step25.value;if(tile.contentAvailable&&tile.content){tilesRenderable++;if(tile.content.pointCount){pointsRenderable+=tile.content.pointCount;}}}}catch(err){_iterator25.e(err);}finally{_iterator25.f();}this.stats.get(TILES_IN_VIEW).count=this.selectedTiles.length;this.stats.get(TILES_RENDERABLE).count=tilesRenderable;this.stats.get(POINTS_COUNT).count=pointsRenderable;}},{key:"_initializeTileSet",value:function _initializeTileSet(tilesetJson){this.root=this._initializeTileHeaders(tilesetJson,null);if(this.type===TILESET_TYPE.TILES3D){this._initializeCesiumTileset(tilesetJson);}if(this.type===TILESET_TYPE.I3S){this._initializeI3STileset();}this._calculateViewProps();}},{key:"_calculateViewProps",value:function _calculateViewProps(){var root=this.root;assert$7(root);var center=root.boundingVolume.center;if(!center){console.warn('center was not pre-calculated for the root tile');this.cartographicCenter=new Vector3$1();this.zoom=1;return;}this.cartographicCenter=Ellipsoid.WGS84.cartesianToCartographic(center,new Vector3$1());this.cartesianCenter=center;this.zoom=getZoomFromBoundingVolume(root.boundingVolume);}},{key:"_initializeStats",value:function _initializeStats(){this.stats.get(TILES_TOTAL);this.stats.get(TILES_LOADING);this.stats.get(TILES_IN_MEMORY);this.stats.get(TILES_IN_VIEW);this.stats.get(TILES_RENDERABLE);this.stats.get(TILES_LOADED);this.stats.get(TILES_UNLOADED);this.stats.get(TILES_LOAD_FAILED);this.stats.get(POINTS_COUNT,'memory');this.stats.get(TILES_GPU_MEMORY,'memory');}},{key:"_initializeTileHeaders",value:function _initializeTileHeaders(tilesetJson,parentTileHeader){var rootTile=new TileHeader(this,tilesetJson.root,parentTileHeader);if(parentTileHeader){parentTileHeader.children.push(rootTile);rootTile.depth=parentTileHeader.depth+1;}if(this.type===TILESET_TYPE.TILES3D){var _stack=[];_stack.push(rootTile);while(_stack.length>0){var tile=_stack.pop();this.stats.get(TILES_TOTAL).incrementCount();var children=tile.header.children||[];var _iterator26=_createForOfIteratorHelper$3(children),_step26;try{for(_iterator26.s();!(_step26=_iterator26.n()).done;){var childHeader=_step26.value;var childTile=new TileHeader(this,childHeader,tile);tile.children.push(childTile);childTile.depth=tile.depth+1;_stack.push(childTile);}}catch(err){_iterator26.e(err);}finally{_iterator26.f();}}}return rootTile;}},{key:"_initializeTraverser",value:function _initializeTraverser(){var TraverserClass;var type=this.type;switch(type){case TILESET_TYPE.TILES3D:TraverserClass=Tileset3DTraverser;break;case TILESET_TYPE.I3S:TraverserClass=I3STilesetTraverser;break;default:TraverserClass=TilesetTraverser;}return new TraverserClass({basePath:this.basePath,onTraversalEnd:this._onTraversalEnd.bind(this)});}},{key:"_destroyTileHeaders",value:function _destroyTileHeaders(parentTile){this._destroySubtree(parentTile);}},{key:"_loadTile",value:function(){var _loadTile3=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee8(tile){var loaded;return regenerator.wrap(function _callee8$(_context11){while(1){switch(_context11.prev=_context11.next){case 0:_context11.prev=0;this._onStartTileLoading(tile);_context11.next=4;return tile.loadContent();case 4:loaded=_context11.sent;_context11.next=10;break;case 7:_context11.prev=7;_context11.t0=_context11["catch"](0);this._onTileLoadError(tile,_context11.t0);case 10:_context11.prev=10;this._onEndTileLoading(tile);this._onTileLoad(tile,loaded);return _context11.finish(10);case 14:case"end":return _context11.stop();}}},_callee8,this,[[0,7,10,14]]);}));function _loadTile(_x43){return _loadTile3.apply(this,arguments);}return _loadTile;}()},{key:"_onTileLoadError",value:function _onTileLoadError(tile,error){this.stats.get(TILES_LOAD_FAILED).incrementCount();var message=error.message||error.toString();var url=tile.url;console.error('A 3D tile failed to load: '.concat(tile.url,' ').concat(message));this.options.onTileError(tile,message,url);}},{key:"_onTileLoad",value:function _onTileLoad(tile,loaded){if(!loaded){return;}if(tile&&tile.content){calculateTransformProps(tile,tile.content);}this._addTileToCache(tile);this.options.onTileLoad(tile);}},{key:"_onStartTileLoading",value:function _onStartTileLoading(tile){this.loadingTiles.push(tile);this._pendingCount++;this.stats.get(TILES_LOADING).incrementCount();}},{key:"_onEndTileLoading",value:function _onEndTileLoading(tile){this.loadingTiles=this.loadingTiles.filter(function(t){return t!=tile;});this._pendingCount--;this.stats.get(TILES_LOADING).decrementCount();this.emit('endTileLoading',{tile,loadingCount:this._pendingCount});// !zeg改 }},{key:"_addTileToCache",value:function _addTileToCache(tile){this._cache.add(this,tile,function(tileset){return tileset._updateCacheStats(tile);});}},{key:"_updateCacheStats",value:function _updateCacheStats(tile){this.stats.get(TILES_LOADED).incrementCount();this.stats.get(TILES_IN_MEMORY).incrementCount();this.gpuMemoryUsageInBytes+=tile.content.byteLength||0;this.stats.get(TILES_GPU_MEMORY).count=this.gpuMemoryUsageInBytes;}},{key:"_unloadTile",value:function _unloadTile(tile){this.gpuMemoryUsageInBytes-=tile.content&&tile.content.byteLength||0;this.stats.get(TILES_IN_MEMORY).decrementCount();this.stats.get(TILES_UNLOADED).incrementCount();this.stats.get(TILES_GPU_MEMORY).count=this.gpuMemoryUsageInBytes;this.options.onTileUnload(tile);tile.unloadContent();}},{key:"_destroy",value:function _destroy(){var stack=[];if(this.root){stack.push(this.root);}while(stack.length>0){var tile=stack.pop();var _iterator27=_createForOfIteratorHelper$3(tile.children),_step27;try{for(_iterator27.s();!(_step27=_iterator27.n()).done;){var child=_step27.value;stack.push(child);}}catch(err){_iterator27.e(err);}finally{_iterator27.f();}this._destroyTile(tile);}this.root=null;}},{key:"_destroySubtree",value:function _destroySubtree(tile){var root=tile;var stack=[];stack.push(root);while(stack.length>0){tile=stack.pop();var _iterator28=_createForOfIteratorHelper$3(tile.children),_step28;try{for(_iterator28.s();!(_step28=_iterator28.n()).done;){var child=_step28.value;stack.push(child);}}catch(err){_iterator28.e(err);}finally{_iterator28.f();}if(tile!==root){this._destroyTile(tile);}}root.children=[];}},{key:"_destroyTile",value:function _destroyTile(tile){this._cache.unloadTile(this,tile);this._unloadTile(tile);tile.destroy();}},{key:"_initializeCesiumTileset",value:function _initializeCesiumTileset(tilesetJson){this.asset=tilesetJson.asset;if(!this.asset){throw new Error('Tileset must have an asset property.');}if(this.asset.version!=='0.0'&&this.asset.version!=='1.0'){throw new Error('The tileset must be 3D Tiles version 0.0 or 1.0.');}if('tilesetVersion'in this.asset){this._queryParams.v=this.asset.tilesetVersion;}this.credits={attributions:this.options.attributions||[]};this.description=this.options.description||'';this.properties=tilesetJson.properties;this.geometricError=tilesetJson.geometricError;this._extensionsUsed=tilesetJson.extensionsUsed;this.extras=tilesetJson.extras;}},{key:"_initializeI3STileset",value:function _initializeI3STileset(){if(this.loadOptions.i3s&&'token'in this.loadOptions.i3s){this._queryParams.token=this.loadOptions.i3s.token;}}}]);return Tileset3D;}(tinyEmitter);function getQueryParamString(queryParams){var queryParamStrings=[];for(var _i41=0,_Object$keys=Object.keys(queryParams);_i41<_Object$keys.length;_i41++){var key=_Object$keys[_i41];queryParamStrings.push(''.concat(key,'=').concat(queryParams[key]));}switch(queryParamStrings.length){case 0:return '';case 1:return '?'.concat(queryParamStrings[0]);default:return '?'.concat(queryParamStrings.join('&'));}}var VERSION$5='3.1.4';var TILE3D_TYPE={COMPOSITE:'cmpt',POINT_CLOUD:'pnts',BATCHED_3D_MODEL:'b3dm',INSTANCED_3D_MODEL:'i3dm',GEOMETRY:'geom',VECTOR:'vect',GLTF:'glTF'};function getStringFromArrayBuffer(arrayBuffer,byteOffset,byteLength){assert$7(arrayBuffer instanceof ArrayBuffer);var textDecoder=new TextDecoder('utf8');var typedArray=new Uint8Array(arrayBuffer,byteOffset,byteLength);var string=textDecoder.decode(typedArray);return string;}function getMagicString$1(arrayBuffer){var byteOffset=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;var dataView=new DataView(arrayBuffer);return ''.concat(String.fromCharCode(dataView.getUint8(byteOffset+0))).concat(String.fromCharCode(dataView.getUint8(byteOffset+1))).concat(String.fromCharCode(dataView.getUint8(byteOffset+2))).concat(String.fromCharCode(dataView.getUint8(byteOffset+3)));}var VERSION$4='3.1.4';var DEFAULT_DRACO_OPTIONS={draco:{decoderType:typeof WebAssembly==='object'?'wasm':'js',libraryPath:'libs/',extraAttributes:{},attributeNameEntry:undefined}};var DracoLoader$1={name:'Draco',id:'draco',module:'draco',shapes:['mesh'],version:VERSION$4,worker:true,extensions:['drc'],mimeTypes:['application/octet-stream'],binary:true,tests:['DRACO'],options:DEFAULT_DRACO_OPTIONS};function getMeshBoundingBox(attributes){var minX=Infinity;var minY=Infinity;var minZ=Infinity;var maxX=-Infinity;var maxY=-Infinity;var maxZ=-Infinity;var positions=attributes.POSITION?attributes.POSITION.value:[];var len=positions&&positions.length;for(var _i42=0;_i42maxX?x:maxX;maxY=y>maxY?y:maxY;maxZ=z>maxZ?z:maxZ;}return [[minX,minY,minZ],[maxX,maxY,maxZ]];}function assert$3(condition,message){if(!condition){throw new Error(message||'loader assertion failed.');}}var Schema=/*#__PURE__*/function(){function Schema(fields,metadata){_classCallCheck(this,Schema);_defineProperty(this,'fields',void 0);_defineProperty(this,'metadata',void 0);assert$3(Array.isArray(fields));checkNames(fields);this.fields=fields;this.metadata=metadata||new Map();}_createClass(Schema,[{key:"compareTo",value:function compareTo(other){if(this.metadata!==other.metadata){return false;}if(this.fields.length!==other.fields.length){return false;}for(var _i43=0;_i432&&arguments[2]!==undefined?arguments[2]:false;var metadata=arguments.length>3&&arguments[3]!==undefined?arguments[3]:new Map();_classCallCheck(this,Field);_defineProperty(this,'name',void 0);_defineProperty(this,'type',void 0);_defineProperty(this,'nullable',void 0);_defineProperty(this,'metadata',void 0);this.name=name;this.type=type;this.nullable=nullable;this.metadata=metadata;}_createClass(Field,[{key:"typeId",get:function get(){return this.type&&this.type.typeId;}},{key:"clone",value:function clone(){return new Field(this.name,this.type,this.nullable,this.metadata);}},{key:"compareTo",value:function compareTo(other){return this.name===other.name&&this.type===other.type&&this.nullable===other.nullable&&this.metadata===other.metadata;}},{key:"toString",value:function toString(){return ''.concat(this.type).concat(this.nullable?', nullable':'').concat(this.metadata?', metadata: '.concat(this.metadata):'');}}]);return Field;}();var Type;(function(Type){Type[Type['NONE']=0]='NONE';Type[Type['Null']=1]='Null';Type[Type['Int']=2]='Int';Type[Type['Float']=3]='Float';Type[Type['Binary']=4]='Binary';Type[Type['Utf8']=5]='Utf8';Type[Type['Bool']=6]='Bool';Type[Type['Decimal']=7]='Decimal';Type[Type['Date']=8]='Date';Type[Type['Time']=9]='Time';Type[Type['Timestamp']=10]='Timestamp';Type[Type['Interval']=11]='Interval';Type[Type['List']=12]='List';Type[Type['Struct']=13]='Struct';Type[Type['Union']=14]='Union';Type[Type['FixedSizeBinary']=15]='FixedSizeBinary';Type[Type['FixedSizeList']=16]='FixedSizeList';Type[Type['Map']=17]='Map';Type[Type['Dictionary']=-1]='Dictionary';Type[Type['Int8']=-2]='Int8';Type[Type['Int16']=-3]='Int16';Type[Type['Int32']=-4]='Int32';Type[Type['Int64']=-5]='Int64';Type[Type['Uint8']=-6]='Uint8';Type[Type['Uint16']=-7]='Uint16';Type[Type['Uint32']=-8]='Uint32';Type[Type['Uint64']=-9]='Uint64';Type[Type['Float16']=-10]='Float16';Type[Type['Float32']=-11]='Float32';Type[Type['Float64']=-12]='Float64';Type[Type['DateDay']=-13]='DateDay';Type[Type['DateMillisecond']=-14]='DateMillisecond';Type[Type['TimestampSecond']=-15]='TimestampSecond';Type[Type['TimestampMillisecond']=-16]='TimestampMillisecond';Type[Type['TimestampMicrosecond']=-17]='TimestampMicrosecond';Type[Type['TimestampNanosecond']=-18]='TimestampNanosecond';Type[Type['TimeSecond']=-19]='TimeSecond';Type[Type['TimeMillisecond']=-20]='TimeMillisecond';Type[Type['TimeMicrosecond']=-21]='TimeMicrosecond';Type[Type['TimeNanosecond']=-22]='TimeNanosecond';Type[Type['DenseUnion']=-23]='DenseUnion';Type[Type['SparseUnion']=-24]='SparseUnion';Type[Type['IntervalDayTime']=-25]='IntervalDayTime';Type[Type['IntervalYearMonth']=-26]='IntervalYearMonth';})(Type||(Type={}));var _Symbol$toStringTag,_Symbol$toStringTag2,_Symbol$toStringTag7;var DataType=/*#__PURE__*/function(){function DataType(){_classCallCheck(this,DataType);}_createClass(DataType,[{key:"typeId",get:function get(){return Type.NONE;}},{key:"compareTo",value:function compareTo(other){return this===other;}}],[{key:"isNull",value:function isNull(x){return x&&x.typeId===Type.Null;}},{key:"isInt",value:function isInt(x){return x&&x.typeId===Type.Int;}},{key:"isFloat",value:function isFloat(x){return x&&x.typeId===Type.Float;}},{key:"isBinary",value:function isBinary(x){return x&&x.typeId===Type.Binary;}},{key:"isUtf8",value:function isUtf8(x){return x&&x.typeId===Type.Utf8;}},{key:"isBool",value:function isBool(x){return x&&x.typeId===Type.Bool;}},{key:"isDecimal",value:function isDecimal(x){return x&&x.typeId===Type.Decimal;}},{key:"isDate",value:function isDate(x){return x&&x.typeId===Type.Date;}},{key:"isTime",value:function isTime(x){return x&&x.typeId===Type.Time;}},{key:"isTimestamp",value:function isTimestamp(x){return x&&x.typeId===Type.Timestamp;}},{key:"isInterval",value:function isInterval(x){return x&&x.typeId===Type.Interval;}},{key:"isList",value:function isList(x){return x&&x.typeId===Type.List;}},{key:"isStruct",value:function isStruct(x){return x&&x.typeId===Type.Struct;}},{key:"isUnion",value:function isUnion(x){return x&&x.typeId===Type.Union;}},{key:"isFixedSizeBinary",value:function isFixedSizeBinary(x){return x&&x.typeId===Type.FixedSizeBinary;}},{key:"isFixedSizeList",value:function isFixedSizeList(x){return x&&x.typeId===Type.FixedSizeList;}},{key:"isMap",value:function isMap(x){return x&&x.typeId===Type.Map;}},{key:"isDictionary",value:function isDictionary(x){return x&&x.typeId===Type.Dictionary;}}]);return DataType;}();_Symbol$toStringTag=Symbol.toStringTag;var Int=/*#__PURE__*/function(_DataType,_Symbol$toStringTag3){_inherits(Int,_DataType);var _super12=_createSuper$E(Int);function Int(isSigned,bitWidth){var _this17;_classCallCheck(this,Int);_this17=_super12.call(this);_defineProperty(_assertThisInitialized(_this17),'isSigned',void 0);_defineProperty(_assertThisInitialized(_this17),'bitWidth',void 0);_this17.isSigned=isSigned;_this17.bitWidth=bitWidth;return _this17;}_createClass(Int,[{key:"typeId",get:function get(){return Type.Int;}},{key:_Symbol$toStringTag3,get:function get(){return 'Int';}},{key:"toString",value:function toString(){return ''.concat(this.isSigned?'I':'Ui','nt').concat(this.bitWidth);}}]);return Int;}(DataType,_Symbol$toStringTag);var Int8=/*#__PURE__*/function(_Int){_inherits(Int8,_Int);var _super13=_createSuper$E(Int8);function Int8(){_classCallCheck(this,Int8);return _super13.call(this,true,8);}return Int8;}(Int);var Int16=/*#__PURE__*/function(_Int2){_inherits(Int16,_Int2);var _super14=_createSuper$E(Int16);function Int16(){_classCallCheck(this,Int16);return _super14.call(this,true,16);}return Int16;}(Int);var Int32=/*#__PURE__*/function(_Int3){_inherits(Int32,_Int3);var _super15=_createSuper$E(Int32);function Int32(){_classCallCheck(this,Int32);return _super15.call(this,true,32);}return Int32;}(Int);var Uint8=/*#__PURE__*/function(_Int4){_inherits(Uint8,_Int4);var _super16=_createSuper$E(Uint8);function Uint8(){_classCallCheck(this,Uint8);return _super16.call(this,false,8);}return Uint8;}(Int);var Uint16=/*#__PURE__*/function(_Int5){_inherits(Uint16,_Int5);var _super17=_createSuper$E(Uint16);function Uint16(){_classCallCheck(this,Uint16);return _super17.call(this,false,16);}return Uint16;}(Int);var Uint32=/*#__PURE__*/function(_Int6){_inherits(Uint32,_Int6);var _super18=_createSuper$E(Uint32);function Uint32(){_classCallCheck(this,Uint32);return _super18.call(this,false,32);}return Uint32;}(Int);var Precision={HALF:16,SINGLE:32,DOUBLE:64};_Symbol$toStringTag2=Symbol.toStringTag;var Float=/*#__PURE__*/function(_DataType2,_Symbol$toStringTag4){_inherits(Float,_DataType2);var _super19=_createSuper$E(Float);function Float(precision){var _this18;_classCallCheck(this,Float);_this18=_super19.call(this);_defineProperty(_assertThisInitialized(_this18),'precision',void 0);_this18.precision=precision;return _this18;}_createClass(Float,[{key:"typeId",get:function get(){return Type.Float;}},{key:_Symbol$toStringTag4,get:function get(){return 'Float';}},{key:"toString",value:function toString(){return 'Float'.concat(this.precision);}}]);return Float;}(DataType,_Symbol$toStringTag2);var Float32=/*#__PURE__*/function(_Float){_inherits(Float32,_Float);var _super20=_createSuper$E(Float32);function Float32(){_classCallCheck(this,Float32);return _super20.call(this,Precision.SINGLE);}return Float32;}(Float);var Float64=/*#__PURE__*/function(_Float2){_inherits(Float64,_Float2);var _super21=_createSuper$E(Float64);function Float64(){_classCallCheck(this,Float64);return _super21.call(this,Precision.DOUBLE);}return Float64;}(Float);_Symbol$toStringTag7=Symbol.toStringTag;var FixedSizeList=/*#__PURE__*/function(_DataType3,_Symbol$toStringTag5){_inherits(FixedSizeList,_DataType3);var _super22=_createSuper$E(FixedSizeList);function FixedSizeList(listSize,child){var _this19;_classCallCheck(this,FixedSizeList);_this19=_super22.call(this);_defineProperty(_assertThisInitialized(_this19),'listSize',void 0);_defineProperty(_assertThisInitialized(_this19),'children',void 0);_this19.listSize=listSize;_this19.children=[child];return _this19;}_createClass(FixedSizeList,[{key:"typeId",get:function get(){return Type.FixedSizeList;}},{key:"valueType",get:function get(){return this.children[0].type;}},{key:"valueField",get:function get(){return this.children[0];}},{key:_Symbol$toStringTag5,get:function get(){return 'FixedSizeList';}},{key:"toString",value:function toString(){return 'FixedSizeList['.concat(this.listSize,']<').concat(this.valueType,'>');}}]);return FixedSizeList;}(DataType,_Symbol$toStringTag7);function getArrowTypeFromTypedArray(array){switch(array.constructor){case Int8Array:return new Int8();case Uint8Array:return new Uint8();case Int16Array:return new Int16();case Uint16Array:return new Uint16();case Int32Array:return new Int32();case Uint32Array:return new Uint32();case Float32Array:return new Float32();case Float64Array:return new Float64();default:throw new Error('array type not supported');}}function deduceMeshField(attributeName,attribute,optionalMetadata){var type=getArrowTypeFromTypedArray(attribute.value);var metadata=optionalMetadata?optionalMetadata:makeMeshAttributeMetadata(attribute);var field=new Field(attributeName,new FixedSizeList(attribute.size,new Field('value',type)),false,metadata);return field;}function makeMeshAttributeMetadata(attribute){var result=new Map();if('byteOffset'in attribute){result.set('byteOffset',attribute.byteOffset.toString(10));}if('byteStride'in attribute){result.set('byteStride',attribute.byteStride.toString(10));}if('normalized'in attribute){result.set('normalized',attribute.normalized.toString());}return result;}function getDracoSchema(attributes,loaderData,indices){var metadataMap=makeMetadata(loaderData.metadata);var fields=[];var namedLoaderDataAttributes=transformAttributesLoaderData(loaderData.attributes);for(var attributeName in attributes){var attribute=attributes[attributeName];var field=getArrowFieldFromAttribute(attributeName,attribute,namedLoaderDataAttributes[attributeName]);fields.push(field);}if(indices){var indicesField=getArrowFieldFromAttribute('indices',indices);fields.push(indicesField);}return new Schema(fields,metadataMap);}function transformAttributesLoaderData(loaderData){var result={};for(var key in loaderData){var dracoAttribute=loaderData[key];result[dracoAttribute.name||'undefined']=dracoAttribute;}return result;}function getArrowFieldFromAttribute(attributeName,attribute,loaderData){var metadataMap=loaderData?makeMetadata(loaderData.metadata):undefined;var field=deduceMeshField(attributeName,attribute,metadataMap);return field;}function makeMetadata(metadata){var metadataMap=new Map();for(var key in metadata){metadataMap.set(''.concat(key,'.string'),JSON.stringify(metadata[key]));}return metadataMap;}var DRACO_TO_GLTF_ATTRIBUTE_NAME_MAP={POSITION:'POSITION',NORMAL:'NORMAL',COLOR:'COLOR_0',TEX_COORD:'TEXCOORD_0'};var DRACO_DATA_TYPE_TO_TYPED_ARRAY_MAP={1:Int8Array,2:Uint8Array,3:Int16Array,4:Uint16Array,5:Int32Array,6:Uint32Array,9:Float32Array};var INDEX_ITEM_SIZE=4;var DracoParser=/*#__PURE__*/function(){function DracoParser(draco){_classCallCheck(this,DracoParser);_defineProperty(this,'draco',void 0);_defineProperty(this,'decoder',void 0);_defineProperty(this,'metadataQuerier',void 0);this.draco=draco;this.decoder=new this.draco.Decoder();this.metadataQuerier=new this.draco.MetadataQuerier();}_createClass(DracoParser,[{key:"destroy",value:function destroy(){this.draco.destroy(this.decoder);this.draco.destroy(this.metadataQuerier);}},{key:"parseSync",value:function parseSync(arrayBuffer){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var buffer=new this.draco.DecoderBuffer();buffer.Init(new Int8Array(arrayBuffer),arrayBuffer.byteLength);this._disableAttributeTransforms(options);var geometry_type=this.decoder.GetEncodedGeometryType(buffer);var dracoGeometry=geometry_type===this.draco.TRIANGULAR_MESH?new this.draco.Mesh():new this.draco.PointCloud();try{var dracoStatus;switch(geometry_type){case this.draco.TRIANGULAR_MESH:dracoStatus=this.decoder.DecodeBufferToMesh(buffer,dracoGeometry);break;case this.draco.POINT_CLOUD:dracoStatus=this.decoder.DecodeBufferToPointCloud(buffer,dracoGeometry);break;default:throw new Error('DRACO: Unknown geometry type.');}if(!dracoStatus.ok()||!dracoGeometry.ptr){var message='DRACO decompression failed: '.concat(dracoStatus.error_msg());throw new Error(message);}var loaderData=this._getDracoLoaderData(dracoGeometry,geometry_type,options);var geometry=this._getMeshData(dracoGeometry,loaderData,options);var boundingBox=getMeshBoundingBox(geometry.attributes);var schema=getDracoSchema(geometry.attributes,loaderData,geometry.indices);var data=_objectSpread$3(_objectSpread$3({loader:'draco',loaderData,header:{vertexCount:dracoGeometry.num_points(),boundingBox}},geometry),{},{schema});return data;}finally{this.draco.destroy(buffer);if(dracoGeometry){this.draco.destroy(dracoGeometry);}}}},{key:"_getDracoLoaderData",value:function _getDracoLoaderData(dracoGeometry,geometry_type,options){var metadata=this._getTopLevelMetadata(dracoGeometry);var attributes=this._getDracoAttributes(dracoGeometry,options);return {geometry_type,num_attributes:dracoGeometry.num_attributes(),num_points:dracoGeometry.num_points(),num_faces:dracoGeometry instanceof this.draco.Mesh?dracoGeometry.num_faces():0,metadata,attributes};}},{key:"_getDracoAttributes",value:function _getDracoAttributes(dracoGeometry,options){var dracoAttributes={};for(var attributeId=0;attributeId2&&arguments[2]!==undefined?arguments[2]:0;var length=arguments.length>3?arguments[3]:undefined;if(length===undefined){length=(buffer.byteLength-byteOffset)/GLType.getByteSize(glType);}var ArrayType=GLType.getArrayType(glType);return new ArrayType(buffer,byteOffset,length);}}]);return GLType;}();function assert$2(condition,message){if(!condition){throw new Error('math.gl assertion failed. '.concat(message));}}function decodeRGB565(rgb565){var target=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[0,0,0];var r5=rgb565>>11&31;var g6=rgb565>>5&63;var b5=rgb565&31;target[0]=r5<<3;target[1]=g6<<2;target[2]=b5<<3;return target;}new Vector2();new Vector3$1();new Vector2();new Vector2();function fromSNorm(value){var rangeMaximum=arguments.length>1&&arguments[1]!==undefined?arguments[1]:255;return clamp(value,0.0,rangeMaximum)/rangeMaximum*2.0-1.0;}function signNotZero(value){return value<0.0?-1.0:1.0;}function octDecodeInRange(x,y,rangeMax,result){assert$2(result);if(x<0||x>rangeMax||y<0||y>rangeMax){throw new Error('x and y must be unsigned normalized integers between 0 and '.concat(rangeMax));}result.x=fromSNorm(x,rangeMax);result.y=fromSNorm(y,rangeMax);result.z=1.0-(Math.abs(result.x)+Math.abs(result.y));if(result.z<0.0){var oldVX=result.x;result.x=(1.0-Math.abs(result.y))*signNotZero(oldVX);result.y=(1.0-Math.abs(oldVX))*signNotZero(result.y);}return result.normalize();}function octDecode(x,y,result){return octDecodeInRange(x,y,255,result);}var Tile3DFeatureTable=/*#__PURE__*/function(){function Tile3DFeatureTable(featureTableJson,featureTableBinary){_classCallCheck(this,Tile3DFeatureTable);_defineProperty(this,'json',void 0);_defineProperty(this,'buffer',void 0);_defineProperty(this,'featuresLength',0);_defineProperty(this,'_cachedTypedArrays',{});this.json=featureTableJson;this.buffer=featureTableBinary;}_createClass(Tile3DFeatureTable,[{key:"getExtension",value:function getExtension(extensionName){return this.json.extensions&&this.json.extensions[extensionName];}},{key:"hasProperty",value:function hasProperty(propertyName){return Boolean(this.json[propertyName]);}},{key:"getGlobalProperty",value:function getGlobalProperty(propertyName){var componentType=arguments.length>1&&arguments[1]!==undefined?arguments[1]:GL$1.UNSIGNED_INT;var componentLength=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1;var jsonValue=this.json[propertyName];if(jsonValue&&Number.isFinite(jsonValue.byteOffset)){return this._getTypedArrayFromBinary(propertyName,componentType,componentLength,1,jsonValue.byteOffset);}return jsonValue;}},{key:"getPropertyArray",value:function getPropertyArray(propertyName,componentType,componentLength){var jsonValue=this.json[propertyName];if(jsonValue&&Number.isFinite(jsonValue.byteOffset)){if('componentType'in jsonValue){componentType=GLType.fromName(jsonValue.componentType);}return this._getTypedArrayFromBinary(propertyName,componentType,componentLength,this.featuresLength,jsonValue.byteOffset);}return this._getTypedArrayFromArray(propertyName,componentType,jsonValue);}},{key:"getProperty",value:function getProperty(propertyName,componentType,componentLength,featureId,result){var jsonValue=this.json[propertyName];if(!jsonValue){return jsonValue;}var typedArray=this.getPropertyArray(propertyName,componentType,componentLength);if(componentLength===1){return typedArray[featureId];}for(var _i49=0;_i490){return traverseHierarchyMultipleParents(hierarchy,instanceIndex,endConditionCallback);}return traverseHierarchySingleParent(hierarchy,instanceIndex,endConditionCallback);}function traverseHierarchyMultipleParents(hierarchy,instanceIndex,endConditionCallback){var classIds=hierarchy.classIds;var parentCounts=hierarchy.parentCounts;var parentIds=hierarchy.parentIds;var parentIndexes=hierarchy.parentIndexes;var instancesLength=classIds.length;var visited=scratchVisited;visited.length=Math.max(visited.length,instancesLength);var visitedMarker=++marker;var stack=scratchStack;stack.length=0;stack.push(instanceIndex);while(stack.length>0){instanceIndex=stack.pop();if(visited[instanceIndex]===visitedMarker){continue;}visited[instanceIndex]=visitedMarker;var result=endConditionCallback(hierarchy,instanceIndex);if(defined$1(result)){return result;}var parentCount=parentCounts[instanceIndex];var parentIndex=parentIndexes[instanceIndex];for(var _i50=0;_i503&&arguments[3]!==undefined?arguments[3]:{};_classCallCheck(this,Tile3DBatchTableParser);var _this$json;_defineProperty(this,'json',void 0);_defineProperty(this,'binary',void 0);_defineProperty(this,'featureCount',void 0);_defineProperty(this,'_extensions',void 0);_defineProperty(this,'_properties',void 0);_defineProperty(this,'_binaryProperties',void 0);_defineProperty(this,'_hierarchy',void 0);assert$7(featureCount>=0);this.json=json||{};this.binary=binary;this.featureCount=featureCount;this._extensions=((_this$json=this.json)===null||_this$json===void 0?void 0:_this$json.extensions)||{};this._properties={};for(var propertyName in this.json){if(!IGNORED_PROPERTY_FIELDS[propertyName]){this._properties[propertyName]=this.json[propertyName];}}this._binaryProperties=this._initializeBinaryProperties();if(options['3DTILES_batch_table_hierarchy']){this._hierarchy=initializeHierarchy(this,this.json,this.binary);}}_createClass(Tile3DBatchTableParser,[{key:"getExtension",value:function getExtension(extensionName){return this.json&&this.json.extensions&&this.json.extensions[extensionName];}},{key:"memorySizeInBytes",value:function memorySizeInBytes(){return 0;}},{key:"isClass",value:function isClass(batchId,className){this._checkBatchId(batchId);assert$7(typeof className==='string',className);if(this._hierarchy){var result=traverseHierarchy(this._hierarchy,batchId,function(hierarchy,instanceIndex){var classId=hierarchy.classIds[instanceIndex];var instanceClass=hierarchy.classes[classId];return instanceClass.name===className;});return defined(result);}return false;}},{key:"isExactClass",value:function isExactClass(batchId,className){assert$7(typeof className==='string',className);return this.getExactClassName(batchId)===className;}},{key:"getExactClassName",value:function getExactClassName(batchId){this._checkBatchId(batchId);if(this._hierarchy){var classId=this._hierarchy.classIds[batchId];var instanceClass=this._hierarchy.classes[classId];return instanceClass.name;}return undefined;}},{key:"hasProperty",value:function hasProperty(batchId,name){this._checkBatchId(batchId);assert$7(typeof name==='string',name);return defined(this._properties[name])||this._hasPropertyInHierarchy(batchId,name);}},{key:"getPropertyNames",value:function getPropertyNames(batchId,results){var _results;this._checkBatchId(batchId);results=defined(results)?results:[];results.length=0;var propertyNames=Object.keys(this._properties);(_results=results).push.apply(_results,_toConsumableArray(propertyNames));if(this._hierarchy){this._getPropertyNamesInHierarchy(batchId,results);}return results;}},{key:"getProperty",value:function getProperty(batchId,name){this._checkBatchId(batchId);assert$7(typeof name==='string',name);if(this._binaryProperties){var binaryProperty=this._binaryProperties[name];if(defined(binaryProperty)){return this._getBinaryProperty(binaryProperty,batchId);}}var propertyValues=this._properties[name];if(defined(propertyValues)){return clone(propertyValues[batchId]);}if(this._hierarchy){var hierarchyProperty=this._getHierarchyProperty(batchId,name);if(defined(hierarchyProperty)){return hierarchyProperty;}}return undefined;}},{key:"setProperty",value:function setProperty(batchId,name,value){var featureCount=this.featureCount;this._checkBatchId(batchId);assert$7(typeof name==='string',name);if(this._binaryProperties){var binaryProperty=this._binaryProperties[name];if(binaryProperty){this._setBinaryProperty(binaryProperty,batchId,value);return;}}if(this._hierarchy){if(this._setHierarchyProperty(this,batchId,name,value)){return;}}var propertyValues=this._properties[name];if(!defined(propertyValues)){this._properties[name]=new Array(featureCount);propertyValues=this._properties[name];}propertyValues[batchId]=clone(value);}},{key:"_checkBatchId",value:function _checkBatchId(batchId){var valid=batchId>=0&&batchId2&&arguments[2]!==undefined?arguments[2]:0;var view=new DataView(arrayBuffer);tile.magic=view.getUint32(byteOffset,true);byteOffset+=SIZEOF_UINT32$1;tile.version=view.getUint32(byteOffset,true);byteOffset+=SIZEOF_UINT32$1;tile.byteLength=view.getUint32(byteOffset,true);byteOffset+=SIZEOF_UINT32$1;if(tile.version!==1){throw new Error('3D Tile Version '.concat(tile.version,' not supported'));}return byteOffset;}var SIZEOF_UINT32=4;var DEPRECATION_WARNING='b3dm tile in legacy format.';function parse3DTileTablesHeaderSync(tile,arrayBuffer,byteOffset){var view=new DataView(arrayBuffer);var batchLength;tile.header=tile.header||{};var featureTableJsonByteLength=view.getUint32(byteOffset,true);byteOffset+=SIZEOF_UINT32;var featureTableBinaryByteLength=view.getUint32(byteOffset,true);byteOffset+=SIZEOF_UINT32;var batchTableJsonByteLength=view.getUint32(byteOffset,true);byteOffset+=SIZEOF_UINT32;var batchTableBinaryByteLength=view.getUint32(byteOffset,true);byteOffset+=SIZEOF_UINT32;if(batchTableJsonByteLength>=570425344){byteOffset-=SIZEOF_UINT32*2;batchLength=featureTableJsonByteLength;batchTableJsonByteLength=featureTableBinaryByteLength;batchTableBinaryByteLength=0;featureTableJsonByteLength=0;featureTableBinaryByteLength=0;console.warn(DEPRECATION_WARNING);}else if(batchTableBinaryByteLength>=570425344){byteOffset-=SIZEOF_UINT32;batchLength=batchTableJsonByteLength;batchTableJsonByteLength=featureTableJsonByteLength;batchTableBinaryByteLength=featureTableBinaryByteLength;featureTableJsonByteLength=0;featureTableBinaryByteLength=0;console.warn(DEPRECATION_WARNING);}tile.header.featureTableJsonByteLength=featureTableJsonByteLength;tile.header.featureTableBinaryByteLength=featureTableBinaryByteLength;tile.header.batchTableJsonByteLength=batchTableJsonByteLength;tile.header.batchTableBinaryByteLength=batchTableBinaryByteLength;tile.header.batchLength=batchLength;return byteOffset;}function parse3DTileTablesSync(tile,arrayBuffer,byteOffset,options){byteOffset=parse3DTileFeatureTable(tile,arrayBuffer,byteOffset);byteOffset=parse3DTileBatchTable(tile,arrayBuffer,byteOffset);return byteOffset;}function parse3DTileFeatureTable(tile,arrayBuffer,byteOffset,options){var _tile$header=tile.header,featureTableJsonByteLength=_tile$header.featureTableJsonByteLength,featureTableBinaryByteLength=_tile$header.featureTableBinaryByteLength,batchLength=_tile$header.batchLength;tile.featureTableJson={BATCH_LENGTH:batchLength||0};if(featureTableJsonByteLength>0){var featureTableString=getStringFromArrayBuffer(arrayBuffer,byteOffset,featureTableJsonByteLength);tile.featureTableJson=JSON.parse(featureTableString);}byteOffset+=featureTableJsonByteLength;tile.featureTableBinary=new Uint8Array(arrayBuffer,byteOffset,featureTableBinaryByteLength);byteOffset+=featureTableBinaryByteLength;return byteOffset;}function parse3DTileBatchTable(tile,arrayBuffer,byteOffset,options){var _tile$header2=tile.header,batchTableJsonByteLength=_tile$header2.batchTableJsonByteLength,batchTableBinaryByteLength=_tile$header2.batchTableBinaryByteLength;if(batchTableJsonByteLength>0){var batchTableString=getStringFromArrayBuffer(arrayBuffer,byteOffset,batchTableJsonByteLength);tile.batchTableJson=JSON.parse(batchTableString);byteOffset+=batchTableJsonByteLength;if(batchTableBinaryByteLength>0){tile.batchTableBinary=new Uint8Array(arrayBuffer,byteOffset,batchTableBinaryByteLength);tile.batchTableBinary=new Uint8Array(tile.batchTableBinary);byteOffset+=batchTableBinaryByteLength;}}return byteOffset;}function normalize3DTileColorAttribute(tile,colors,batchTable){if(!colors&&(!tile||!tile.batchIds||!batchTable)){return null;}var batchIds=tile.batchIds,isRGB565=tile.isRGB565,pointCount=tile.pointCount;if(batchIds&&batchTable){var colorArray=new Uint8ClampedArray(pointCount*3);for(var _i53=0;_i531&&_args46[1]!==undefined?_args46[1]:null;if(isEmptyObject(imagebitmapOptions)||!imagebitmapOptionsSupported){imagebitmapOptions=null;}if(!imagebitmapOptions){_context46.next=13;break;}_context46.prev=3;_context46.next=6;return createImageBitmap(blob,imagebitmapOptions);case 6:return _context46.abrupt("return",_context46.sent);case 9:_context46.prev=9;_context46.t0=_context46["catch"](3);console.warn(_context46.t0);imagebitmapOptionsSupported=false;case 13:_context46.next=15;return createImageBitmap(blob);case 15:return _context46.abrupt("return",_context46.sent);case 16:case"end":return _context46.stop();}}},_callee42,null,[[3,9]]);}));return _safeCreateImageBitmap.apply(this,arguments);}function isEmptyObject(object){for(var key in object||EMPTY_OBJECT){return false;}return true;}var BIG_ENDIAN=false;var LITTLE_ENDIAN=true;function getBinaryImageMetadata(binaryData){var dataView=toDataView(binaryData);return getPngMetadata(dataView)||getJpegMetadata(dataView)||getGifMetadata(dataView)||getBmpMetadata(dataView);}function getPngMetadata(binaryData){var dataView=toDataView(binaryData);var isPng=dataView.byteLength>=24&&dataView.getUint32(0,BIG_ENDIAN)===0x89504e47;if(!isPng){return null;}return {mimeType:'image/png',width:dataView.getUint32(16,BIG_ENDIAN),height:dataView.getUint32(20,BIG_ENDIAN)};}function getGifMetadata(binaryData){var dataView=toDataView(binaryData);var isGif=dataView.byteLength>=10&&dataView.getUint32(0,BIG_ENDIAN)===0x47494638;if(!isGif){return null;}return {mimeType:'image/gif',width:dataView.getUint16(6,LITTLE_ENDIAN),height:dataView.getUint16(8,LITTLE_ENDIAN)};}function getBmpMetadata(binaryData){var dataView=toDataView(binaryData);var isBmp=dataView.byteLength>=14&&dataView.getUint16(0,BIG_ENDIAN)===0x424d&&dataView.getUint32(2,LITTLE_ENDIAN)===dataView.byteLength;if(!isBmp){return null;}return {mimeType:'image/bmp',width:dataView.getUint32(18,LITTLE_ENDIAN),height:dataView.getUint32(22,LITTLE_ENDIAN)};}function getJpegMetadata(binaryData){var dataView=toDataView(binaryData);var isJpeg=dataView.byteLength>=3&&dataView.getUint16(0,BIG_ENDIAN)===0xffd8&&dataView.getUint8(2)===0xff;if(!isJpeg){return null;}var _getJpegMarkers=getJpegMarkers(),tableMarkers=_getJpegMarkers.tableMarkers,sofMarkers=_getJpegMarkers.sofMarkers;var i=2;while(i+9=0&&byteLength<=bufferView.byteLength);return {ArrayType,length,byteLength};}var DEFAULT_GLTF_JSON={asset:{version:'2.0',generator:'loaders.gl'},buffers:[]};var GLTFScenegraph=/*#__PURE__*/function(){function GLTFScenegraph(gltf){_classCallCheck(this,GLTFScenegraph);_defineProperty(this,'gltf',void 0);_defineProperty(this,'sourceBuffers',void 0);_defineProperty(this,'byteLength',void 0);this.gltf=gltf||{json:_objectSpread$3({},DEFAULT_GLTF_JSON),buffers:[]};this.sourceBuffers=[];this.byteLength=0;if(this.gltf.buffers&&this.gltf.buffers[0]){this.byteLength=this.gltf.buffers[0].byteLength;this.sourceBuffers=[this.gltf.buffers[0]];}}_createClass(GLTFScenegraph,[{key:"json",get:function get(){return this.gltf.json;}},{key:"getApplicationData",value:function getApplicationData(key){var data=this.json[key];return data;}},{key:"getExtraData",value:function getExtraData(key){var extras=this.json.extras||{};return extras[key];}},{key:"getExtension",value:function getExtension(extensionName){var isExtension=this.getUsedExtensions().find(function(name){return name===extensionName;});var extensions=this.json.extensions||{};return isExtension?extensions[extensionName]||true:null;}},{key:"getRequiredExtension",value:function getRequiredExtension(extensionName){var isRequired=this.getRequiredExtensions().find(function(name){return name===extensionName;});return isRequired?this.getExtension(extensionName):null;}},{key:"getRequiredExtensions",value:function getRequiredExtensions(){return this.json.extensionsRequired||[];}},{key:"getUsedExtensions",value:function getUsedExtensions(){return this.json.extensionsUsed||[];}},{key:"getObjectExtension",value:function getObjectExtension(object,extensionName){var extensions=object.extensions||{};return extensions[extensionName];}},{key:"getScene",value:function getScene(index){return this.getObject('scenes',index);}},{key:"getNode",value:function getNode(index){return this.getObject('nodes',index);}},{key:"getSkin",value:function getSkin(index){return this.getObject('skins',index);}},{key:"getMesh",value:function getMesh(index){return this.getObject('meshes',index);}},{key:"getMaterial",value:function getMaterial(index){return this.getObject('materials',index);}},{key:"getAccessor",value:function getAccessor(index){return this.getObject('accessors',index);}},{key:"getTexture",value:function getTexture(index){return this.getObject('textures',index);}},{key:"getSampler",value:function getSampler(index){return this.getObject('samplers',index);}},{key:"getImage",value:function getImage(index){return this.getObject('images',index);}},{key:"getBufferView",value:function getBufferView(index){return this.getObject('bufferViews',index);}},{key:"getBuffer",value:function getBuffer(index){return this.getObject('buffers',index);}},{key:"getObject",value:function getObject(array,index){if(typeof index==='object'){return index;}var object=this.json[array]&&this.json[array][index];if(!object){throw new Error('glTF file error: Could not find '.concat(array,'[').concat(index,']'));}return object;}},{key:"getTypedArrayForBufferView",value:function getTypedArrayForBufferView(bufferView){bufferView=this.getBufferView(bufferView);var bufferIndex=bufferView.buffer;var binChunk=this.gltf.buffers[bufferIndex];assert$1(binChunk);var byteOffset=(bufferView.byteOffset||0)+binChunk.byteOffset;return new Uint8Array(binChunk.arrayBuffer,byteOffset,bufferView.byteLength);}},{key:"getTypedArrayForAccessor",value:function getTypedArrayForAccessor(accessor){accessor=this.getAccessor(accessor);var bufferView=this.getBufferView(accessor.bufferView);var buffer=this.getBuffer(bufferView.buffer);var arrayBuffer=buffer.data;var _getAccessorArrayType=getAccessorArrayTypeAndLength(accessor,bufferView),ArrayType=_getAccessorArrayType.ArrayType,length=_getAccessorArrayType.length;var byteOffset=bufferView.byteOffset+accessor.byteOffset;return new ArrayType(arrayBuffer,byteOffset,length);}},{key:"getTypedArrayForImageData",value:function getTypedArrayForImageData(image){image=this.getAccessor(image);var bufferView=this.getBufferView(image.bufferView);var buffer=this.getBuffer(bufferView.buffer);var arrayBuffer=buffer.data;var byteOffset=bufferView.byteOffset||0;return new Uint8Array(arrayBuffer,byteOffset,bufferView.byteLength);}},{key:"addApplicationData",value:function addApplicationData(key,data){this.json[key]=data;return this;}},{key:"addExtraData",value:function addExtraData(key,data){this.json.extras=this.json.extras||{};this.json.extras[key]=data;return this;}},{key:"addObjectExtension",value:function addObjectExtension(object,extensionName,data){object.extensions=object.extensions||{};object.extensions[extensionName]=data;this.registerUsedExtension(extensionName);return this;}},{key:"setObjectExtension",value:function setObjectExtension(object,extensionName,data){var extensions=object.extensions||{};extensions[extensionName]=data;}},{key:"removeObjectExtension",value:function removeObjectExtension(object,extensionName){var extensions=object.extensions||{};var extension=extensions[extensionName];delete extensions[extensionName];return extension;}},{key:"addExtension",value:function addExtension(extensionName){var extensionData=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};assert$1(extensionData);this.json.extensions=this.json.extensions||{};this.json.extensions[extensionName]=extensionData;this.registerUsedExtension(extensionName);return extensionData;}},{key:"addRequiredExtension",value:function addRequiredExtension(extensionName){var extensionData=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};assert$1(extensionData);this.addExtension(extensionName,extensionData);this.registerRequiredExtension(extensionName);return extensionData;}},{key:"registerUsedExtension",value:function registerUsedExtension(extensionName){this.json.extensionsUsed=this.json.extensionsUsed||[];if(!this.json.extensionsUsed.find(function(ext){return ext===extensionName;})){this.json.extensionsUsed.push(extensionName);}}},{key:"registerRequiredExtension",value:function registerRequiredExtension(extensionName){this.registerUsedExtension(extensionName);this.json.extensionsRequired=this.json.extensionsRequired||[];if(!this.json.extensionsRequired.find(function(ext){return ext===extensionName;})){this.json.extensionsRequired.push(extensionName);}}},{key:"removeExtension",value:function removeExtension(extensionName){if(this.json.extensionsRequired){this._removeStringFromArray(this.json.extensionsRequired,extensionName);}if(this.json.extensionsUsed){this._removeStringFromArray(this.json.extensionsUsed,extensionName);}if(this.json.extensions){delete this.json.extensions[extensionName];}}},{key:"setDefaultScene",value:function setDefaultScene(sceneIndex){this.json.scene=sceneIndex;}},{key:"addScene",value:function addScene(scene){var nodeIndices=scene.nodeIndices;this.json.scenes=this.json.scenes||[];this.json.scenes.push({nodes:nodeIndices});return this.json.scenes.length-1;}},{key:"addNode",value:function addNode(node){var meshIndex=node.meshIndex,matrix=node.matrix;this.json.nodes=this.json.nodes||[];var nodeData={mesh:meshIndex};if(matrix){nodeData.matrix=matrix;}this.json.nodes.push(nodeData);return this.json.nodes.length-1;}},{key:"addMesh",value:function addMesh(mesh){var attributes=mesh.attributes,indices=mesh.indices,material=mesh.material,_mesh$mode=mesh.mode,mode=_mesh$mode===void 0?4:_mesh$mode;var accessors=this._addAttributes(attributes);var glTFMesh={primitives:[{attributes:accessors,mode}]};if(indices){var indicesAccessor=this._addIndices(indices);glTFMesh.primitives[0].indices=indicesAccessor;}if(Number.isFinite(material)){glTFMesh.primitives[0].material=material;}this.json.meshes=this.json.meshes||[];this.json.meshes.push(glTFMesh);return this.json.meshes.length-1;}},{key:"addPointCloud",value:function addPointCloud(attributes){var accessorIndices=this._addAttributes(attributes);var glTFMesh={primitives:[{attributes:accessorIndices,mode:0}]};this.json.meshes=this.json.meshes||[];this.json.meshes.push(glTFMesh);return this.json.meshes.length-1;}},{key:"addImage",value:function addImage(imageData,mimeTypeOpt){var metadata=getBinaryImageMetadata(imageData);var mimeType=mimeTypeOpt||(metadata===null||metadata===void 0?void 0:metadata.mimeType);var bufferViewIndex=this.addBufferView(imageData);var glTFImage={bufferView:bufferViewIndex,mimeType};this.json.images=this.json.images||[];this.json.images.push(glTFImage);return this.json.images.length-1;}},{key:"addBufferView",value:function addBufferView(buffer){var byteLength=buffer.byteLength;assert$1(Number.isFinite(byteLength));this.sourceBuffers=this.sourceBuffers||[];this.sourceBuffers.push(buffer);var glTFBufferView={buffer:0,byteOffset:this.byteLength,byteLength};this.byteLength+=padToNBytes(byteLength,4);this.json.bufferViews=this.json.bufferViews||[];this.json.bufferViews.push(glTFBufferView);return this.json.bufferViews.length-1;}},{key:"addAccessor",value:function addAccessor(bufferViewIndex,accessor){var glTFAccessor={bufferView:bufferViewIndex,type:getAccessorTypeFromSize(accessor.size),componentType:accessor.componentType,count:accessor.count,max:accessor.max,min:accessor.min};this.json.accessors=this.json.accessors||[];this.json.accessors.push(glTFAccessor);return this.json.accessors.length-1;}},{key:"addBinaryBuffer",value:function addBinaryBuffer(sourceBuffer){var accessor=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{size:3};var bufferViewIndex=this.addBufferView(sourceBuffer);var minMax={min:accessor.min,max:accessor.max};if(!minMax.min||!minMax.max){minMax=this._getAccessorMinMax(sourceBuffer,accessor.size);}var accessorDefaults={size:accessor.size,componentType:getComponentTypeFromArray(sourceBuffer),count:Math.round(sourceBuffer.length/accessor.size),min:minMax.min,max:minMax.max};return this.addAccessor(bufferViewIndex,Object.assign(accessorDefaults,accessor));}},{key:"addTexture",value:function addTexture(texture){var imageIndex=texture.imageIndex;var glTFTexture={source:imageIndex};this.json.textures=this.json.textures||[];this.json.textures.push(glTFTexture);return this.json.textures.length-1;}},{key:"addMaterial",value:function addMaterial(pbrMaterialInfo){this.json.materials=this.json.materials||[];this.json.materials.push(pbrMaterialInfo);return this.json.materials.length-1;}},{key:"createBinaryChunk",value:function createBinaryChunk(){var _this$json,_this$json$buffers;this.gltf.buffers=[];var totalByteLength=this.byteLength;var arrayBuffer=new ArrayBuffer(totalByteLength);var targetArray=new Uint8Array(arrayBuffer);var dstByteOffset=0;var _iterator34=_createForOfIteratorHelper$3(this.sourceBuffers||[]),_step34;try{for(_iterator34.s();!(_step34=_iterator34.n()).done;){var sourceBuffer=_step34.value;dstByteOffset=copyToArray(sourceBuffer,targetArray,dstByteOffset);}}catch(err){_iterator34.e(err);}finally{_iterator34.f();}if((_this$json=this.json)!==null&&_this$json!==void 0&&(_this$json$buffers=_this$json.buffers)!==null&&_this$json$buffers!==void 0&&_this$json$buffers[0]){this.json.buffers[0].byteLength=totalByteLength;}else {this.json.buffers=[{byteLength:totalByteLength}];}this.gltf.binary=arrayBuffer;this.sourceBuffers=[arrayBuffer];}},{key:"_removeStringFromArray",value:function _removeStringFromArray(array,string){var found=true;while(found){var index=array.indexOf(string);if(index>-1){array.splice(index,1);}else {found=false;}}}},{key:"_addAttributes",value:function _addAttributes(){var attributes=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};var result={};for(var attributeKey in attributes){var attributeData=attributes[attributeKey];var attrName=this._getGltfAttributeName(attributeKey);var accessor=this.addBinaryBuffer(attributeData.value,attributeData);result[attrName]=accessor;}return result;}},{key:"_addIndices",value:function _addIndices(indices){return this.addBinaryBuffer(indices,{size:1});}},{key:"_getGltfAttributeName",value:function _getGltfAttributeName(attributeName){switch(attributeName.toLowerCase()){case'position':case'positions':case'vertices':return 'POSITION';case'normal':case'normals':return 'NORMAL';case'color':case'colors':return 'COLOR_0';case'texcoord':case'texcoords':return 'TEXCOORD_0';default:return attributeName;}}},{key:"_getAccessorMinMax",value:function _getAccessorMinMax(buffer,size){var result={min:null,max:null};if(buffer.length5&&_args49[5]!==undefined?_args49[5]:'NONE';_context49.next=3;return loadWasmInstance();case 3:instance=_context49.sent;decode$5(instance,instance.exports[DECODERS[mode]],target,count,size,source,instance.exports[FILTERS[filter||'NONE']]);case 5:case"end":return _context49.stop();}}},_callee45);}));return _meshoptDecodeGltfBuffer.apply(this,arguments);}var wasmPromise;function loadWasmInstance(){return _loadWasmInstance.apply(this,arguments);}function _loadWasmInstance(){_loadWasmInstance=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee46(){return regenerator.wrap(function _callee46$(_context50){while(1){switch(_context50.prev=_context50.next){case 0:if(!wasmPromise){wasmPromise=loadWasmModule();}return _context50.abrupt("return",wasmPromise);case 2:case"end":return _context50.stop();}}},_callee46);}));return _loadWasmInstance.apply(this,arguments);}function loadWasmModule(){return _loadWasmModule.apply(this,arguments);}function _loadWasmModule(){_loadWasmModule=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee47(){var wasm,result;return regenerator.wrap(function _callee47$(_context51){while(1){switch(_context51.prev=_context51.next){case 0:wasm=wasm_base;if(WebAssembly.validate(detector)){wasm=wasm_simd;console.log('Warning: meshopt_decoder is using experimental SIMD support');}_context51.next=4;return WebAssembly.instantiate(unpack(wasm),{});case 4:result=_context51.sent;_context51.next=7;return result.instance.exports.__wasm_call_ctors();case 7:return _context51.abrupt("return",result.instance);case 8:case"end":return _context51.stop();}}},_callee47);}));return _loadWasmModule.apply(this,arguments);}function unpack(data){var result=new Uint8Array(data.length);for(var _i58=0;_i5896?ch-71:ch>64?ch-65:ch>47?ch+4:ch>46?63:62;}var write=0;for(var _i59=0;_i592&&arguments[2]!==undefined?arguments[2]:false;if(!array){return null;}if(Array.isArray(array)){return new ArrayType(array);}if(convertTypedArrays&&!(array instanceof ArrayType)){return new ArrayType(array);}return array;}var KHR_DRACO_MESH_COMPRESSION='KHR_draco_mesh_compression';var name$3=KHR_DRACO_MESH_COMPRESSION;function preprocess$1(gltfData,options,context){var scenegraph=new GLTFScenegraph(gltfData);var _iterator38=_createForOfIteratorHelper$3(makeMeshPrimitiveIterator(scenegraph)),_step38;try{for(_iterator38.s();!(_step38=_iterator38.n()).done;){var primitive=_step38.value;if(scenegraph.getObjectExtension(primitive,KHR_DRACO_MESH_COMPRESSION));}}catch(err){_iterator38.e(err);}finally{_iterator38.f();}}function decode$3(_x91,_x92,_x93){return _decode$2.apply(this,arguments);}function _decode$2(){_decode$2=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee50(gltfData,options,context){var _options$gltf,scenegraph,promises,_iterator59,_step59,primitive;return regenerator.wrap(function _callee50$(_context54){while(1){switch(_context54.prev=_context54.next){case 0:if(options!==null&&options!==void 0&&(_options$gltf=options.gltf)!==null&&_options$gltf!==void 0&&_options$gltf.decompressMeshes){_context54.next=2;break;}return _context54.abrupt("return");case 2:scenegraph=new GLTFScenegraph(gltfData);promises=[];_iterator59=_createForOfIteratorHelper$3(makeMeshPrimitiveIterator(scenegraph));try{for(_iterator59.s();!(_step59=_iterator59.n()).done;){primitive=_step59.value;if(scenegraph.getObjectExtension(primitive,KHR_DRACO_MESH_COMPRESSION)){promises.push(decompressPrimitive(scenegraph,primitive,options,context));}}}catch(err){_iterator59.e(err);}finally{_iterator59.f();}_context54.next=8;return Promise.all(promises);case 8:scenegraph.removeExtension(KHR_DRACO_MESH_COMPRESSION);case 9:case"end":return _context54.stop();}}},_callee50);}));return _decode$2.apply(this,arguments);}function encode$3(gltfData){var scenegraph=new GLTFScenegraph(gltfData);var _iterator39=_createForOfIteratorHelper$3(scenegraph.json.meshes||[]),_step39;try{for(_iterator39.s();!(_step39=_iterator39.n()).done;){var mesh=_step39.value;compressMesh(mesh);scenegraph.addRequiredExtension(KHR_DRACO_MESH_COMPRESSION);}}catch(err){_iterator39.e(err);}finally{_iterator39.f();}}function decompressPrimitive(_x94,_x95,_x96,_x97){return _decompressPrimitive.apply(this,arguments);}function _decompressPrimitive(){_decompressPrimitive=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee51(scenegraph,primitive,options,context){var dracoExtension,buffer,bufferCopy,parse,dracoOptions,decodedData,decodedAttributes,_i67,_Object$entries2,_Object$entries2$_i,attributeName,decodedAttribute,accessorIndex,accessor;return regenerator.wrap(function _callee51$(_context55){while(1){switch(_context55.prev=_context55.next){case 0:dracoExtension=scenegraph.getObjectExtension(primitive,KHR_DRACO_MESH_COMPRESSION);if(dracoExtension){_context55.next=3;break;}return _context55.abrupt("return");case 3:buffer=scenegraph.getTypedArrayForBufferView(dracoExtension.bufferView);bufferCopy=sliceArrayBuffer(buffer.buffer,buffer.byteOffset);parse=context.parse;dracoOptions=_objectSpread$3({},options);delete dracoOptions['3d-tiles'];_context55.next=10;return parse(bufferCopy,DracoLoader,dracoOptions,context);case 10:decodedData=_context55.sent;decodedAttributes=getGLTFAccessors(decodedData.attributes);for(_i67=0,_Object$entries2=Object.entries(decodedAttributes);_i67<_Object$entries2.length;_i67++){_Object$entries2$_i=_slicedToArray(_Object$entries2[_i67],2),attributeName=_Object$entries2$_i[0],decodedAttribute=_Object$entries2$_i[1];if(attributeName in primitive.attributes){accessorIndex=primitive.attributes[attributeName];accessor=scenegraph.getAccessor(accessorIndex);if(accessor!==null&&accessor!==void 0&&accessor.min&&accessor!==null&&accessor!==void 0&&accessor.max){decodedAttribute.min=accessor.min;decodedAttribute.max=accessor.max;}}}primitive.attributes=decodedAttributes;if(decodedData.indices){primitive.indices=getGLTFAccessor(decodedData.indices);}checkPrimitive(primitive);case 16:case"end":return _context55.stop();}}},_callee51);}));return _decompressPrimitive.apply(this,arguments);}function compressMesh(attributes,indices){var mode=arguments.length>2&&arguments[2]!==undefined?arguments[2]:4;var options=arguments.length>3?arguments[3]:undefined;var context=arguments.length>4?arguments[4]:undefined;var _context$parseSync;if(!options.DracoWriter){throw new Error('options.gltf.DracoWriter not provided');}var compressedData=options.DracoWriter.encodeSync({attributes});var decodedData=context===null||context===void 0?void 0:(_context$parseSync=context.parseSync)===null||_context$parseSync===void 0?void 0:_context$parseSync.call(context,{attributes});var fauxAccessors=options._addFauxAttributes(decodedData.attributes);var bufferViewIndex=options.addBufferView(compressedData);var glTFMesh={primitives:[{attributes:fauxAccessors,mode,extensions:{[KHR_DRACO_MESH_COMPRESSION]:{bufferView:bufferViewIndex,attributes:fauxAccessors}}}]};return glTFMesh;}function checkPrimitive(primitive){if(!primitive.attributes&&Object.keys(primitive.attributes).length>0){throw new Error('glTF: Empty primitive detected: Draco decompression failure?');}}function makeMeshPrimitiveIterator(scenegraph){var _iterator40,_step40,mesh,_iterator41,_step41,primitive;return regenerator.wrap(function makeMeshPrimitiveIterator$(_context12){while(1){switch(_context12.prev=_context12.next){case 0:_iterator40=_createForOfIteratorHelper$3(scenegraph.json.meshes||[]);_context12.prev=1;_iterator40.s();case 3:if((_step40=_iterator40.n()).done){_context12.next=24;break;}mesh=_step40.value;_iterator41=_createForOfIteratorHelper$3(mesh.primitives);_context12.prev=6;_iterator41.s();case 8:if((_step41=_iterator41.n()).done){_context12.next=14;break;}primitive=_step41.value;_context12.next=12;return primitive;case 12:_context12.next=8;break;case 14:_context12.next=19;break;case 16:_context12.prev=16;_context12.t0=_context12["catch"](6);_iterator41.e(_context12.t0);case 19:_context12.prev=19;_iterator41.f();return _context12.finish(19);case 22:_context12.next=3;break;case 24:_context12.next=29;break;case 26:_context12.prev=26;_context12.t1=_context12["catch"](1);_iterator40.e(_context12.t1);case 29:_context12.prev=29;_iterator40.f();return _context12.finish(29);case 32:case"end":return _context12.stop();}}},_marked3,null,[[1,26,29,32],[6,16,19,22]]);}var KHR_draco_mesh_compression=/*#__PURE__*/Object.freeze({__proto__:null,name:name$3,preprocess:preprocess$1,decode:decode$3,encode:encode$3});var KHR_LIGHTS_PUNCTUAL='KHR_lights_punctual';var name$2=KHR_LIGHTS_PUNCTUAL;function decode$2(_x98){return _decode$3.apply(this,arguments);}function _decode$3(){_decode$3=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee52(gltfData){var gltfScenegraph,json,extension,_iterator60,_step60,_node3,nodeExtension;return regenerator.wrap(function _callee52$(_context56){while(1){switch(_context56.prev=_context56.next){case 0:gltfScenegraph=new GLTFScenegraph(gltfData);json=gltfScenegraph.json;extension=gltfScenegraph.getExtension(KHR_LIGHTS_PUNCTUAL);if(extension){gltfScenegraph.json.lights=extension.lights;gltfScenegraph.removeExtension(KHR_LIGHTS_PUNCTUAL);}_iterator60=_createForOfIteratorHelper$3(json.nodes||[]);try{for(_iterator60.s();!(_step60=_iterator60.n()).done;){_node3=_step60.value;nodeExtension=gltfScenegraph.getObjectExtension(_node3,KHR_LIGHTS_PUNCTUAL);if(nodeExtension){_node3.light=nodeExtension.light;}gltfScenegraph.removeObjectExtension(_node3,KHR_LIGHTS_PUNCTUAL);}}catch(err){_iterator60.e(err);}finally{_iterator60.f();}case 6:case"end":return _context56.stop();}}},_callee52);}));return _decode$3.apply(this,arguments);}function encode$2(_x99){return _encode$.apply(this,arguments);}function _encode$(){_encode$=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee53(gltfData){var gltfScenegraph,json,extension,_iterator61,_step61,light,_node4;return regenerator.wrap(function _callee53$(_context57){while(1){switch(_context57.prev=_context57.next){case 0:gltfScenegraph=new GLTFScenegraph(gltfData);json=gltfScenegraph.json;if(json.lights){extension=gltfScenegraph.addExtension(KHR_LIGHTS_PUNCTUAL);assert$1(!extension.lights);extension.lights=json.lights;delete json.lights;}if(gltfScenegraph.json.lights){_iterator61=_createForOfIteratorHelper$3(gltfScenegraph.json.lights);try{for(_iterator61.s();!(_step61=_iterator61.n()).done;){light=_step61.value;_node4=light.node;gltfScenegraph.addObjectExtension(_node4,KHR_LIGHTS_PUNCTUAL,light);}}catch(err){_iterator61.e(err);}finally{_iterator61.f();}delete gltfScenegraph.json.lights;}case 4:case"end":return _context57.stop();}}},_callee53);}));return _encode$.apply(this,arguments);}var KHR_lights_punctual=/*#__PURE__*/Object.freeze({__proto__:null,name:name$2,decode:decode$2,encode:encode$2});var KHR_MATERIALS_UNLIT='KHR_materials_unlit';var name$1=KHR_MATERIALS_UNLIT;function decode$1(_x100){return _decode$4.apply(this,arguments);}function _decode$4(){_decode$4=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee54(gltfData){var gltfScenegraph,json,_iterator62,_step62,material,extension;return regenerator.wrap(function _callee54$(_context58){while(1){switch(_context58.prev=_context58.next){case 0:gltfScenegraph=new GLTFScenegraph(gltfData);json=gltfScenegraph.json;gltfScenegraph.removeExtension(KHR_MATERIALS_UNLIT);_iterator62=_createForOfIteratorHelper$3(json.materials||[]);try{for(_iterator62.s();!(_step62=_iterator62.n()).done;){material=_step62.value;extension=material.extensions&&material.extensions.KHR_materials_unlit;if(extension){material.unlit=true;}gltfScenegraph.removeObjectExtension(material,KHR_MATERIALS_UNLIT);}}catch(err){_iterator62.e(err);}finally{_iterator62.f();}case 5:case"end":return _context58.stop();}}},_callee54);}));return _decode$4.apply(this,arguments);}function encode$1(gltfData){var gltfScenegraph=new GLTFScenegraph(gltfData);var json=gltfScenegraph.json;if(gltfScenegraph.materials){var _iterator42=_createForOfIteratorHelper$3(json.materials||[]),_step42;try{for(_iterator42.s();!(_step42=_iterator42.n()).done;){var material=_step42.value;if(material.unlit){delete material.unlit;gltfScenegraph.addObjectExtension(material,KHR_MATERIALS_UNLIT,{});gltfScenegraph.addExtension(KHR_MATERIALS_UNLIT);}}}catch(err){_iterator42.e(err);}finally{_iterator42.f();}}}var KHR_materials_unlit=/*#__PURE__*/Object.freeze({__proto__:null,name:name$1,decode:decode$1,encode:encode$1});var KHR_TECHNIQUES_WEBGL='KHR_techniques_webgl';var name=KHR_TECHNIQUES_WEBGL;function decode(_x101){return _decode.apply(this,arguments);}function _decode(){_decode=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee55(gltfData){var gltfScenegraph,json,extension,techniques,_iterator63,_step63,material,materialExtension;return regenerator.wrap(function _callee55$(_context59){while(1){switch(_context59.prev=_context59.next){case 0:gltfScenegraph=new GLTFScenegraph(gltfData);json=gltfScenegraph.json;extension=gltfScenegraph.getExtension(KHR_TECHNIQUES_WEBGL);if(extension){techniques=resolveTechniques(extension,gltfScenegraph);_iterator63=_createForOfIteratorHelper$3(json.materials||[]);try{for(_iterator63.s();!(_step63=_iterator63.n()).done;){material=_step63.value;materialExtension=gltfScenegraph.getObjectExtension(material,KHR_TECHNIQUES_WEBGL);if(materialExtension){material.technique=Object.assign({},materialExtension,techniques[materialExtension.technique]);material.technique.values=resolveValues(material.technique,gltfScenegraph);}gltfScenegraph.removeObjectExtension(material,KHR_TECHNIQUES_WEBGL);}}catch(err){_iterator63.e(err);}finally{_iterator63.f();}gltfScenegraph.removeExtension(KHR_TECHNIQUES_WEBGL);}case 4:case"end":return _context59.stop();}}},_callee55);}));return _decode.apply(this,arguments);}function encode(_x102,_x103){return _encode.apply(this,arguments);}function _encode(){_encode=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee56(gltfData,options){return regenerator.wrap(function _callee56$(_context60){while(1){switch(_context60.prev=_context60.next){case 0:case"end":return _context60.stop();}}},_callee56);}));return _encode.apply(this,arguments);}function resolveTechniques(techniquesExtension,gltfScenegraph){var _techniquesExtension$=techniquesExtension.programs,programs=_techniquesExtension$===void 0?[]:_techniquesExtension$,_techniquesExtension$2=techniquesExtension.shaders,shaders=_techniquesExtension$2===void 0?[]:_techniquesExtension$2,_techniquesExtension$3=techniquesExtension.techniques,techniques=_techniquesExtension$3===void 0?[]:_techniquesExtension$3;var textDecoder=new TextDecoder();shaders.forEach(function(shader){if(Number.isFinite(shader.bufferView)){shader.code=textDecoder.decode(gltfScenegraph.getTypedArrayForBufferView(shader.bufferView));}else {throw new Error('KHR_techniques_webgl: no shader code');}});programs.forEach(function(program){program.fragmentShader=shaders[program.fragmentShader];program.vertexShader=shaders[program.vertexShader];});techniques.forEach(function(technique){technique.program=programs[technique.program];});return techniques;}function resolveValues(technique,gltfScenegraph){var values=Object.assign({},technique.values);Object.keys(technique.uniforms||{}).forEach(function(uniform){if(technique.uniforms[uniform].value&&!(uniform in values)){values[uniform]=technique.uniforms[uniform].value;}});Object.keys(values).forEach(function(uniform){if(typeof values[uniform]==='object'&&values[uniform].index!==undefined){values[uniform].texture=gltfScenegraph.getTexture(values[uniform].index);}});return values;}var KHR_techniques_webgl=/*#__PURE__*/Object.freeze({__proto__:null,name:name,decode:decode,encode:encode});var EXTENSIONS=[EXT_meshopt_compression,EXT_texture_webp,KHR_texture_basisu,KHR_draco_mesh_compression,KHR_lights_punctual,KHR_materials_unlit,KHR_techniques_webgl];function preprocessExtensions(gltf){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var context=arguments.length>2?arguments[2]:undefined;var extensions=EXTENSIONS.filter(function(extension){return useExtension(extension.name,options);});var _iterator43=_createForOfIteratorHelper$3(extensions),_step43;try{for(_iterator43.s();!(_step43=_iterator43.n()).done;){var extension=_step43.value;var _extension$preprocess;(_extension$preprocess=extension.preprocess)===null||_extension$preprocess===void 0?void 0:_extension$preprocess.call(extension,gltf,options,context);}}catch(err){_iterator43.e(err);}finally{_iterator43.f();}}function decodeExtensions(_x104){return _decodeExtensions.apply(this,arguments);}function _decodeExtensions(){_decodeExtensions=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee57(gltf){var options,context,extensions,_iterator64,_step64,extension,_extension$decode,_args61=arguments;return regenerator.wrap(function _callee57$(_context61){while(1){switch(_context61.prev=_context61.next){case 0:options=_args61.length>1&&_args61[1]!==undefined?_args61[1]:{};context=_args61.length>2?_args61[2]:undefined;extensions=EXTENSIONS.filter(function(extension){return useExtension(extension.name,options);});_iterator64=_createForOfIteratorHelper$3(extensions);_context61.prev=4;_iterator64.s();case 6:if((_step64=_iterator64.n()).done){_context61.next=12;break;}extension=_step64.value;_context61.next=10;return (_extension$decode=extension.decode)===null||_extension$decode===void 0?void 0:_extension$decode.call(extension,gltf,options,context);case 10:_context61.next=6;break;case 12:_context61.next=17;break;case 14:_context61.prev=14;_context61.t0=_context61["catch"](4);_iterator64.e(_context61.t0);case 17:_context61.prev=17;_iterator64.f();return _context61.finish(17);case 20:case"end":return _context61.stop();}}},_callee57,null,[[4,14,17,20]]);}));return _decodeExtensions.apply(this,arguments);}function useExtension(extensionName,options){var _options$gltf;var excludes=(options===null||options===void 0?void 0:(_options$gltf=options.gltf)===null||_options$gltf===void 0?void 0:_options$gltf.excludeExtensions)||{};var exclude=extensionName in excludes&&!excludes[extensionName];return !exclude;}var KHR_BINARY_GLTF='KHR_binary_glTF';function preprocess(gltfData){var gltfScenegraph=new GLTFScenegraph(gltfData);var json=gltfScenegraph.json;var _iterator44=_createForOfIteratorHelper$3(json.images||[]),_step44;try{for(_iterator44.s();!(_step44=_iterator44.n()).done;){var image=_step44.value;var extension=gltfScenegraph.getObjectExtension(image,KHR_BINARY_GLTF);if(extension){Object.assign(image,extension);}gltfScenegraph.removeObjectExtension(image,KHR_BINARY_GLTF);}}catch(err){_iterator44.e(err);}finally{_iterator44.f();}if(json.buffers&&json.buffers[0]){delete json.buffers[0].uri;}gltfScenegraph.removeExtension(KHR_BINARY_GLTF);}var GLTF_ARRAYS={accessors:'accessor',animations:'animation',buffers:'buffer',bufferViews:'bufferView',images:'image',materials:'material',meshes:'mesh',nodes:'node',samplers:'sampler',scenes:'scene',skins:'skin',textures:'texture'};var GLTF_KEYS={accessor:'accessors',animations:'animation',buffer:'buffers',bufferView:'bufferViews',image:'images',material:'materials',mesh:'meshes',node:'nodes',sampler:'samplers',scene:'scenes',skin:'skins',texture:'textures'};var GLTFV1Normalizer=/*#__PURE__*/function(){function GLTFV1Normalizer(){_classCallCheck(this,GLTFV1Normalizer);_defineProperty(this,'idToIndexMap',{animations:{},accessors:{},buffers:{},bufferViews:{},images:{},materials:{},meshes:{},nodes:{},samplers:{},scenes:{},skins:{},textures:{}});_defineProperty(this,'json',void 0);}_createClass(GLTFV1Normalizer,[{key:"normalize",value:function normalize(gltf,options){this.json=gltf.json;var json=gltf.json;switch(json.asset&&json.asset.version){case'2.0':return;case undefined:case'1.0':break;default:console.warn('glTF: Unknown version '.concat(json.asset.version));return;}if(!options.normalize){throw new Error('glTF v1 is not supported.');}console.warn('Converting glTF v1 to glTF v2 format. This is experimental and may fail.');this._addAsset(json);this._convertTopLevelObjectsToArrays(json);preprocess(gltf);this._convertObjectIdsToArrayIndices(json);this._updateObjects(json);this._updateMaterial(json);}},{key:"_addAsset",value:function _addAsset(json){json.asset=json.asset||{};json.asset.version='2.0';json.asset.generator=json.asset.generator||'Normalized to glTF 2.0 by loaders.gl';}},{key:"_convertTopLevelObjectsToArrays",value:function _convertTopLevelObjectsToArrays(json){for(var arrayName in GLTF_ARRAYS){this._convertTopLevelObjectToArray(json,arrayName);}}},{key:"_convertTopLevelObjectToArray",value:function _convertTopLevelObjectToArray(json,mapName){var objectMap=json[mapName];if(!objectMap||Array.isArray(objectMap)){return;}json[mapName]=[];for(var id in objectMap){var object=objectMap[id];object.id=object.id||id;var index=json[mapName].length;json[mapName].push(object);this.idToIndexMap[mapName][id]=index;}}},{key:"_convertObjectIdsToArrayIndices",value:function _convertObjectIdsToArrayIndices(json){for(var arrayName in GLTF_ARRAYS){this._convertIdsToIndices(json,arrayName);}if('scene'in json){json.scene=this._convertIdToIndex(json.scene,'scene');}var _iterator45=_createForOfIteratorHelper$3(json.textures),_step45;try{for(_iterator45.s();!(_step45=_iterator45.n()).done;){var texture=_step45.value;this._convertTextureIds(texture);}}catch(err){_iterator45.e(err);}finally{_iterator45.f();}var _iterator46=_createForOfIteratorHelper$3(json.meshes),_step46;try{for(_iterator46.s();!(_step46=_iterator46.n()).done;){var mesh=_step46.value;this._convertMeshIds(mesh);}}catch(err){_iterator46.e(err);}finally{_iterator46.f();}var _iterator47=_createForOfIteratorHelper$3(json.nodes),_step47;try{for(_iterator47.s();!(_step47=_iterator47.n()).done;){var _node=_step47.value;this._convertNodeIds(_node);}}catch(err){_iterator47.e(err);}finally{_iterator47.f();}var _iterator48=_createForOfIteratorHelper$3(json.scenes),_step48;try{for(_iterator48.s();!(_step48=_iterator48.n()).done;){var _node2=_step48.value;this._convertSceneIds(_node2);}}catch(err){_iterator48.e(err);}finally{_iterator48.f();}}},{key:"_convertTextureIds",value:function _convertTextureIds(texture){if(texture.source){texture.source=this._convertIdToIndex(texture.source,'image');}}},{key:"_convertMeshIds",value:function _convertMeshIds(mesh){var _iterator49=_createForOfIteratorHelper$3(mesh.primitives),_step49;try{for(_iterator49.s();!(_step49=_iterator49.n()).done;){var primitive=_step49.value;var attributes=primitive.attributes,indices=primitive.indices,material=primitive.material;for(var attributeName in attributes){attributes[attributeName]=this._convertIdToIndex(attributes[attributeName],'accessor');}if(indices){primitive.indices=this._convertIdToIndex(indices,'accessor');}if(material){primitive.material=this._convertIdToIndex(material,'material');}}}catch(err){_iterator49.e(err);}finally{_iterator49.f();}}},{key:"_convertNodeIds",value:function _convertNodeIds(node){var _this24=this;if(node.children){node.children=node.children.map(function(child){return _this24._convertIdToIndex(child,'node');});}if(node.meshes){node.meshes=node.meshes.map(function(mesh){return _this24._convertIdToIndex(mesh,'mesh');});}}},{key:"_convertSceneIds",value:function _convertSceneIds(scene){var _this25=this;if(scene.nodes){scene.nodes=scene.nodes.map(function(node){return _this25._convertIdToIndex(node,'node');});}}},{key:"_convertIdsToIndices",value:function _convertIdsToIndices(json,topLevelArrayName){if(!json[topLevelArrayName]){console.warn("gltf v1: json doesn't contain attribute ".concat(topLevelArrayName));json[topLevelArrayName]=[];}var _iterator50=_createForOfIteratorHelper$3(json[topLevelArrayName]),_step50;try{for(_iterator50.s();!(_step50=_iterator50.n()).done;){var object=_step50.value;for(var key in object){var id=object[key];var index=this._convertIdToIndex(id,key);object[key]=index;}}}catch(err){_iterator50.e(err);}finally{_iterator50.f();}}},{key:"_convertIdToIndex",value:function _convertIdToIndex(id,key){var arrayName=GLTF_KEYS[key];if(arrayName in this.idToIndexMap){var index=this.idToIndexMap[arrayName][id];if(!Number.isFinite(index)){throw new Error('gltf v1: failed to resolve '.concat(key,' with id ').concat(id));}return index;}return id;}},{key:"_updateObjects",value:function _updateObjects(json){var _iterator51=_createForOfIteratorHelper$3(this.json.buffers),_step51;try{for(_iterator51.s();!(_step51=_iterator51.n()).done;){var buffer=_step51.value;delete buffer.type;}}catch(err){_iterator51.e(err);}finally{_iterator51.f();}}},{key:"_updateMaterial",value:function _updateMaterial(json){var _iterator52=_createForOfIteratorHelper$3(json.materials),_step52;try{var _loop3=function _loop3(){var material=_step52.value;material.pbrMetallicRoughness={baseColorFactor:[1,1,1,1],metallicFactor:1,roughnessFactor:1};var textureId=material.values&&material.values.tex;var textureIndex=json.textures.findIndex(function(texture){return texture.id===textureId;});if(textureIndex!==-1){material.pbrMetallicRoughness.baseColorTexture={index:textureIndex};}};for(_iterator52.s();!(_step52=_iterator52.n()).done;){_loop3();}}catch(err){_iterator52.e(err);}finally{_iterator52.f();}}}]);return GLTFV1Normalizer;}();function normalizeGLTFV1(gltf){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};return new GLTFV1Normalizer().normalize(gltf,options);}var COMPONENTS={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16};var BYTES={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4};var GL_SAMPLER={TEXTURE_MAG_FILTER:0x2800,TEXTURE_MIN_FILTER:0x2801,TEXTURE_WRAP_S:0x2802,TEXTURE_WRAP_T:0x2803,REPEAT:0x2901,LINEAR:0x2601,NEAREST_MIPMAP_LINEAR:0x2702};var SAMPLER_PARAMETER_GLTF_TO_GL={magFilter:GL_SAMPLER.TEXTURE_MAG_FILTER,minFilter:GL_SAMPLER.TEXTURE_MIN_FILTER,wrapS:GL_SAMPLER.TEXTURE_WRAP_S,wrapT:GL_SAMPLER.TEXTURE_WRAP_T};var DEFAULT_SAMPLER={[GL_SAMPLER.TEXTURE_MAG_FILTER]:GL_SAMPLER.LINEAR,[GL_SAMPLER.TEXTURE_MIN_FILTER]:GL_SAMPLER.NEAREST_MIPMAP_LINEAR,[GL_SAMPLER.TEXTURE_WRAP_S]:GL_SAMPLER.REPEAT,[GL_SAMPLER.TEXTURE_WRAP_T]:GL_SAMPLER.REPEAT};function getBytesFromComponentType(componentType){return BYTES[componentType];}function getSizeFromAccessorType(type){return COMPONENTS[type];}var GLTFPostProcessor=/*#__PURE__*/function(){function GLTFPostProcessor(){_classCallCheck(this,GLTFPostProcessor);_defineProperty(this,'baseUri','');_defineProperty(this,'json',{});_defineProperty(this,'buffers',[]);_defineProperty(this,'images',[]);}_createClass(GLTFPostProcessor,[{key:"postProcess",value:function postProcess(gltf){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var json=gltf.json,_gltf$buffers=gltf.buffers,buffers=_gltf$buffers===void 0?[]:_gltf$buffers,_gltf$images=gltf.images,images=_gltf$images===void 0?[]:_gltf$images,_gltf$baseUri=gltf.baseUri,baseUri=_gltf$baseUri===void 0?'':_gltf$baseUri;assert$1(json);this.baseUri=baseUri;this.json=json;this.buffers=buffers;this.images=images;this._resolveTree(this.json,options);return this.json;}},{key:"_resolveTree",value:function _resolveTree(json){var _this26=this;if(json.bufferViews){json.bufferViews=json.bufferViews.map(function(bufView,i){return _this26._resolveBufferView(bufView,i);});}if(json.images){json.images=json.images.map(function(image,i){return _this26._resolveImage(image,i);});}if(json.samplers){json.samplers=json.samplers.map(function(sampler,i){return _this26._resolveSampler(sampler,i);});}if(json.textures){json.textures=json.textures.map(function(texture,i){return _this26._resolveTexture(texture,i);});}if(json.accessors){json.accessors=json.accessors.map(function(accessor,i){return _this26._resolveAccessor(accessor,i);});}if(json.materials){json.materials=json.materials.map(function(material,i){return _this26._resolveMaterial(material,i);});}if(json.meshes){json.meshes=json.meshes.map(function(mesh,i){return _this26._resolveMesh(mesh,i);});}if(json.nodes){json.nodes=json.nodes.map(function(node,i){return _this26._resolveNode(node,i);});}if(json.skins){json.skins=json.skins.map(function(skin,i){return _this26._resolveSkin(skin,i);});}if(json.scenes){json.scenes=json.scenes.map(function(scene,i){return _this26._resolveScene(scene,i);});}if(json.scene!==undefined){json.scene=json.scenes[this.json.scene];}}},{key:"getScene",value:function getScene(index){return this._get('scenes',index);}},{key:"getNode",value:function getNode(index){return this._get('nodes',index);}},{key:"getSkin",value:function getSkin(index){return this._get('skins',index);}},{key:"getMesh",value:function getMesh(index){return this._get('meshes',index);}},{key:"getMaterial",value:function getMaterial(index){return this._get('materials',index);}},{key:"getAccessor",value:function getAccessor(index){return this._get('accessors',index);}},{key:"getCamera",value:function getCamera(index){return null;}},{key:"getTexture",value:function getTexture(index){return this._get('textures',index);}},{key:"getSampler",value:function getSampler(index){return this._get('samplers',index);}},{key:"getImage",value:function getImage(index){return this._get('images',index);}},{key:"getBufferView",value:function getBufferView(index){return this._get('bufferViews',index);}},{key:"getBuffer",value:function getBuffer(index){return this._get('buffers',index);}},{key:"_get",value:function _get(array,index){if(typeof index==='object'){return index;}var object=this.json[array]&&this.json[array][index];if(!object){console.warn('glTF file error: Could not find '.concat(array,'[').concat(index,']'));}return object;}},{key:"_resolveScene",value:function _resolveScene(scene,index){var _this27=this;scene.id=scene.id||'scene-'.concat(index);scene.nodes=(scene.nodes||[]).map(function(node){return _this27.getNode(node);});return scene;}},{key:"_resolveNode",value:function _resolveNode(node,index){var _this28=this;node.id=node.id||'node-'.concat(index);if(node.children){node.children=node.children.map(function(child){return _this28.getNode(child);});}if(node.mesh!==undefined){node.mesh=this.getMesh(node.mesh);}else if(node.meshes!==undefined&&node.meshes.length){node.mesh=node.meshes.reduce(function(accum,meshIndex){var mesh=_this28.getMesh(meshIndex);accum.id=mesh.id;accum.primitives=accum.primitives.concat(mesh.primitives);return accum;},{primitives:[]});}if(node.camera!==undefined){node.camera=this.getCamera(node.camera);}if(node.skin!==undefined){node.skin=this.getSkin(node.skin);}return node;}},{key:"_resolveSkin",value:function _resolveSkin(skin,index){skin.id=skin.id||'skin-'.concat(index);skin.inverseBindMatrices=this.getAccessor(skin.inverseBindMatrices);return skin;}},{key:"_resolveMesh",value:function _resolveMesh(mesh,index){var _this29=this;mesh.id=mesh.id||'mesh-'.concat(index);if(mesh.primitives){mesh.primitives=mesh.primitives.map(function(primitive){primitive=_objectSpread$3({},primitive);var attributes=primitive.attributes;primitive.attributes={};for(var attribute in attributes){primitive.attributes[attribute]=_this29.getAccessor(attributes[attribute]);}if(primitive.indices!==undefined){primitive.indices=_this29.getAccessor(primitive.indices);}if(primitive.material!==undefined){primitive.material=_this29.getMaterial(primitive.material);}return primitive;});}return mesh;}},{key:"_resolveMaterial",value:function _resolveMaterial(material,index){material.id=material.id||'material-'.concat(index);if(material.normalTexture){material.normalTexture=_objectSpread$3({},material.normalTexture);material.normalTexture.texture=this.getTexture(material.normalTexture.index);}if(material.occlusionTexture){material.occlustionTexture=_objectSpread$3({},material.occlustionTexture);material.occlusionTexture.texture=this.getTexture(material.occlusionTexture.index);}if(material.emissiveTexture){material.emmisiveTexture=_objectSpread$3({},material.emmisiveTexture);material.emissiveTexture.texture=this.getTexture(material.emissiveTexture.index);}if(!material.emissiveFactor){material.emissiveFactor=material.emmisiveTexture?[1,1,1]:[0,0,0];}if(material.pbrMetallicRoughness){material.pbrMetallicRoughness=_objectSpread$3({},material.pbrMetallicRoughness);var mr=material.pbrMetallicRoughness;if(mr.baseColorTexture){mr.baseColorTexture=_objectSpread$3({},mr.baseColorTexture);mr.baseColorTexture.texture=this.getTexture(mr.baseColorTexture.index);}if(mr.metallicRoughnessTexture){mr.metallicRoughnessTexture=_objectSpread$3({},mr.metallicRoughnessTexture);mr.metallicRoughnessTexture.texture=this.getTexture(mr.metallicRoughnessTexture.index);}}return material;}},{key:"_resolveAccessor",value:function _resolveAccessor(accessor,index){accessor.id=accessor.id||'accessor-'.concat(index);if(accessor.bufferView!==undefined){accessor.bufferView=this.getBufferView(accessor.bufferView);}accessor.bytesPerComponent=getBytesFromComponentType(accessor.componentType);accessor.components=getSizeFromAccessorType(accessor.type);accessor.bytesPerElement=accessor.bytesPerComponent*accessor.components;if(accessor.bufferView){var buffer=accessor.bufferView.buffer;var _getAccessorArrayType2=getAccessorArrayTypeAndLength(accessor,accessor.bufferView),ArrayType=_getAccessorArrayType2.ArrayType,byteLength=_getAccessorArrayType2.byteLength;var byteOffset=(accessor.bufferView.byteOffset||0)+(accessor.byteOffset||0)+buffer.byteOffset;var cutBuffer=buffer.arrayBuffer.slice(byteOffset,byteOffset+byteLength);if(accessor.bufferView.byteStride){cutBuffer=this._getValueFromInterleavedBuffer(buffer,byteOffset,accessor.bufferView.byteStride,accessor.bytesPerElement,accessor.count);}accessor.value=new ArrayType(cutBuffer);}return accessor;}},{key:"_getValueFromInterleavedBuffer",value:function _getValueFromInterleavedBuffer(buffer,byteOffset,byteStride,bytesPerElement,count){var result=new Uint8Array(count*bytesPerElement);for(var _i60=0;_i601&&arguments[1]!==undefined?arguments[1]:0;return ''.concat(String.fromCharCode(dataView.getUint8(byteOffset+0))).concat(String.fromCharCode(dataView.getUint8(byteOffset+1))).concat(String.fromCharCode(dataView.getUint8(byteOffset+2))).concat(String.fromCharCode(dataView.getUint8(byteOffset+3)));}function isGLB(arrayBuffer){var byteOffset=arguments.length>1&&arguments[1]!==undefined?arguments[1]:0;var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};var dataView=new DataView(arrayBuffer);var _options$magic=options.magic,magic=_options$magic===void 0?MAGIC_glTF:_options$magic;var magic1=dataView.getUint32(byteOffset,false);return magic1===magic||magic1===MAGIC_glTF;}function parseGLBSync(glb,arrayBuffer){var byteOffset=arguments.length>2&&arguments[2]!==undefined?arguments[2]:0;var dataView=new DataView(arrayBuffer);var type=getMagicString(dataView,byteOffset+0);var version=dataView.getUint32(byteOffset+4,LE);var byteLength=dataView.getUint32(byteOffset+8,LE);Object.assign(glb,{header:{byteOffset,byteLength,hasBinChunk:false},type,version,json:{},binChunks:[]});byteOffset+=GLB_FILE_HEADER_SIZE;switch(glb.version){case 1:return parseGLBV1(glb,dataView,byteOffset);case 2:return parseGLBV2(glb,dataView,byteOffset,{});default:throw new Error('Invalid GLB version '.concat(glb.version,'. Only supports v1 and v2.'));}}function parseGLBV1(glb,dataView,byteOffset){assert$7(glb.header.byteLength>GLB_FILE_HEADER_SIZE+GLB_CHUNK_HEADER_SIZE);var contentLength=dataView.getUint32(byteOffset+0,LE);var contentFormat=dataView.getUint32(byteOffset+4,LE);byteOffset+=GLB_CHUNK_HEADER_SIZE;assert$7(contentFormat===GLB_V1_CONTENT_FORMAT_JSON);parseJSONChunk(glb,dataView,byteOffset,contentLength);byteOffset+=contentLength;byteOffset+=parseBINChunk(glb,dataView,byteOffset,glb.header.byteLength);return byteOffset;}function parseGLBV2(glb,dataView,byteOffset,options){assert$7(glb.header.byteLength>GLB_FILE_HEADER_SIZE+GLB_CHUNK_HEADER_SIZE);parseGLBChunksSync(glb,dataView,byteOffset,options);return byteOffset+glb.header.byteLength;}function parseGLBChunksSync(glb,dataView,byteOffset,options){while(byteOffset+8<=glb.header.byteLength){var chunkLength=dataView.getUint32(byteOffset+0,LE);var chunkFormat=dataView.getUint32(byteOffset+4,LE);byteOffset+=GLB_CHUNK_HEADER_SIZE;switch(chunkFormat){case GLB_CHUNK_TYPE_JSON:parseJSONChunk(glb,dataView,byteOffset,chunkLength);break;case GLB_CHUNK_TYPE_BIN:parseBINChunk(glb,dataView,byteOffset,chunkLength);break;case GLB_CHUNK_TYPE_JSON_XVIZ_DEPRECATED:if(!options.strict){parseJSONChunk(glb,dataView,byteOffset,chunkLength);}break;case GLB_CHUNK_TYPE_BIX_XVIZ_DEPRECATED:if(!options.strict){parseBINChunk(glb,dataView,byteOffset,chunkLength);}break;}byteOffset+=padToNBytes(chunkLength,4);}return byteOffset;}function parseJSONChunk(glb,dataView,byteOffset,chunkLength){var jsonChunk=new Uint8Array(dataView.buffer,byteOffset,chunkLength);var textDecoder=new TextDecoder('utf8');var jsonText=textDecoder.decode(jsonChunk);glb.json=JSON.parse(jsonText);return padToNBytes(chunkLength,4);}function parseBINChunk(glb,dataView,byteOffset,chunkLength){glb.header.hasBinChunk=true;glb.binChunks.push({byteOffset,byteLength:chunkLength,arrayBuffer:dataView.buffer});return padToNBytes(chunkLength,4);}function parseGLTF(_x105,_x106){return _parseGLTF.apply(this,arguments);}function _parseGLTF(){_parseGLTF=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee58(gltf,arrayBufferOrString){var byteOffset,options,context,_options$gltf,_options$gltf2,_options$gltf3,_options$gltf4,promises,_promise,promise,_args62=arguments;return regenerator.wrap(function _callee58$(_context62){while(1){switch(_context62.prev=_context62.next){case 0:byteOffset=_args62.length>2&&_args62[2]!==undefined?_args62[2]:0;options=_args62.length>3?_args62[3]:undefined;context=_args62.length>4?_args62[4]:undefined;parseGLTFContainerSync(gltf,arrayBufferOrString,byteOffset,options);normalizeGLTFV1(gltf,{normalize:options===null||options===void 0?void 0:(_options$gltf=options.gltf)===null||_options$gltf===void 0?void 0:_options$gltf.normalize});preprocessExtensions(gltf,options,context);promises=[];if(!(options!==null&&options!==void 0&&(_options$gltf2=options.gltf)!==null&&_options$gltf2!==void 0&&_options$gltf2.loadBuffers&&gltf.json.buffers)){_context62.next=10;break;}_context62.next=10;return loadBuffers(gltf,options,context);case 10:if(options!==null&&options!==void 0&&(_options$gltf3=options.gltf)!==null&&_options$gltf3!==void 0&&_options$gltf3.loadImages){_promise=loadImages(gltf,options,context);promises.push(_promise);}promise=decodeExtensions(gltf,options,context);promises.push(promise);_context62.next=15;return Promise.all(promises);case 15:gltf.json.gltfArrayBuffer=arrayBufferOrString;// !zeg改 兼容gltf return _context62.abrupt("return",options!==null&&options!==void 0&&(_options$gltf4=options.gltf)!==null&&_options$gltf4!==void 0&&_options$gltf4.postProcess?postProcessGLTF(gltf,options):gltf);case 17:case"end":return _context62.stop();}}},_callee58);}));return _parseGLTF.apply(this,arguments);}function parseGLTFContainerSync(gltf,data,byteOffset,options){if(options.uri){gltf.baseUri=options.uri;}if(data instanceof ArrayBuffer&&!isGLB(data,byteOffset,options)){var textDecoder=new TextDecoder();data=textDecoder.decode(data);}if(typeof data==='string'){gltf.json=parseJSON(data);}else if(data instanceof ArrayBuffer){var glb={};byteOffset=parseGLBSync(glb,data,byteOffset,options.glb);assert$1(glb.type==='glTF','Invalid GLB magic string '.concat(glb.type));gltf._glb=glb;gltf.json=glb.json;}else {assert$1(false,'GLTF: must be ArrayBuffer or string');}var buffers=gltf.json.buffers||[];gltf.buffers=new Array(buffers.length).fill(null);if(gltf._glb&&gltf._glb.header.hasBinChunk){var binChunks=gltf._glb.binChunks;gltf.buffers[0]={arrayBuffer:binChunks[0].arrayBuffer,byteOffset:binChunks[0].byteOffset,byteLength:binChunks[0].byteLength};}var images=gltf.json.images||[];gltf.images=new Array(images.length).fill({});}function loadBuffers(_x107,_x108,_x109){return _loadBuffers.apply(this,arguments);}function _loadBuffers(){_loadBuffers=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee59(gltf,options,context){var buffers,_i68,buffer,_context$fetch,_response$arrayBuffer,_fetch,uri,response,arrayBuffer;return regenerator.wrap(function _callee59$(_context63){while(1){switch(_context63.prev=_context63.next){case 0:buffers=gltf.json.buffers||[];_i68=0;case 2:if(!(_i681&&_args66[1]!==undefined?_args66[1]:{};context=_args66.length>2?_args66[2]:undefined;options=_objectSpread$3(_objectSpread$3({},GLTFLoader.options),options);options.gltf=_objectSpread$3(_objectSpread$3({},GLTFLoader.options.gltf),options.gltf);_options2=options,_options2$byteOffset=_options2.byteOffset,byteOffset=_options2$byteOffset===void 0?0:_options2$byteOffset;gltf={};_context66.next=8;return parseGLTF(gltf,arrayBuffer,byteOffset,options,context);case 8:return _context66.abrupt("return",_context66.sent);case 9:case"end":return _context66.stop();}}},_callee62);}));return _parse$3.apply(this,arguments);}var GLTF_FORMAT={URI:0,EMBEDDED:1};function parse3DTileGLTFViewSync(tile,arrayBuffer,byteOffset,options){tile.rotateYtoZ=true;var gltfByteLength=tile.byteOffset+tile.byteLength-byteOffset;if(gltfByteLength===0){throw new Error('glTF byte length must be greater than 0.');}tile.gltfUpAxis=options['3d-tiles']&&options['3d-tiles'].assetGltfUpAxis?options['3d-tiles'].assetGltfUpAxis:'Y';tile.gltfArrayBuffer=sliceArrayBuffer(arrayBuffer,byteOffset,gltfByteLength);tile.gltfByteOffset=0;tile.gltfByteLength=gltfByteLength;if(byteOffset%4===0);else {console.warn(''.concat(tile.type,': embedded glb is not aligned to a 4-byte boundary.'));}return tile.byteOffset+tile.byteLength;}function extractGLTF(_x119,_x120,_x121,_x122){return _extractGLTF.apply(this,arguments);}function _extractGLTF(){_extractGLTF=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee63(tile,gltfFormat,options,context){var tile3DOptions,_parse3,_fetch2;return regenerator.wrap(function _callee63$(_context67){while(1){switch(_context67.prev=_context67.next){case 0:tile3DOptions=options['3d-tiles']||{};extractGLTFBufferOrURL(tile,gltfFormat);if(!tile3DOptions.loadGLTF){_context67.next=16;break;}_parse3=context.parse,_fetch2=context.fetch;if(!tile.gltfUrl){_context67.next=9;break;}_context67.next=7;return _fetch2(tile.gltfUrl,options);case 7:tile.gltfArrayBuffer=_context67.sent;tile.gltfByteOffset=0;case 9:if(!tile.gltfArrayBuffer){_context67.next=16;break;}_context67.next=12;return _parse3(tile.gltfArrayBuffer,GLTFLoader,options,context);case 12:tile.gltf=_context67.sent;delete tile.gltfArrayBuffer;delete tile.gltfByteOffset;delete tile.gltfByteLength;case 16:case"end":return _context67.stop();}}},_callee63);}));return _extractGLTF.apply(this,arguments);}function extractGLTFBufferOrURL(tile,gltfFormat,options){switch(gltfFormat){case GLTF_FORMAT.URI:var gltfUrlBytes=new Uint8Array(tile.gltfArrayBuffer,tile.gltfByteOffset);var textDecoder=new TextDecoder();var gltfUrl=textDecoder.decode(gltfUrlBytes);tile.gltfUrl=gltfUrl.replace(/[\s\0]+$/,'');delete tile.gltfArrayBuffer;delete tile.gltfByteOffset;delete tile.gltfByteLength;break;case GLTF_FORMAT.EMBEDDED:break;default:throw new Error('b3dm: Illegal glTF format field');}}function parseBatchedModel3DTile(_x123,_x124,_x125,_x126,_x127){return _parseBatchedModel3DTile.apply(this,arguments);}function _parseBatchedModel3DTile(){_parseBatchedModel3DTile=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee64(tile,arrayBuffer,byteOffset,options,context){var _tile$gltf,extensions;return regenerator.wrap(function _callee64$(_context68){while(1){switch(_context68.prev=_context68.next){case 0:byteOffset=parseBatchedModel(tile,arrayBuffer,byteOffset,options);_context68.next=3;return extractGLTF(tile,GLTF_FORMAT.EMBEDDED,options,context);case 3:extensions=tile===null||tile===void 0?void 0:(_tile$gltf=tile.gltf)===null||_tile$gltf===void 0?void 0:_tile$gltf.extensions;if(extensions&&extensions.CESIUM_RTC){tile.rtcCenter=extensions.CESIUM_RTC.center;}return _context68.abrupt("return",byteOffset);case 6:case"end":return _context68.stop();}}},_callee64);}));return _parseBatchedModel3DTile.apply(this,arguments);}function parseBatchedModel(tile,arrayBuffer,byteOffset,options,context){byteOffset=parse3DTileHeaderSync(tile,arrayBuffer,byteOffset);byteOffset=parse3DTileTablesHeaderSync(tile,arrayBuffer,byteOffset);byteOffset=parse3DTileTablesSync(tile,arrayBuffer,byteOffset);byteOffset=parse3DTileGLTFViewSync(tile,arrayBuffer,byteOffset,options);var featureTable=new Tile3DFeatureTable(tile.featureTableJson,tile.featureTableBinary);tile.rtcCenter=featureTable.getGlobalProperty('RTC_CENTER',GL$1.FLOAT,3);return byteOffset;}function parseInstancedModel3DTile(_x128,_x129,_x130,_x131,_x132){return _parseInstancedModel3DTile.apply(this,arguments);}function _parseInstancedModel3DTile(){_parseInstancedModel3DTile=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee65(tile,arrayBuffer,byteOffset,options,context){return regenerator.wrap(function _callee65$(_context69){while(1){switch(_context69.prev=_context69.next){case 0:byteOffset=parseInstancedModel(tile,arrayBuffer,byteOffset,options);_context69.next=3;return extractGLTF(tile,tile.gltfFormat,options,context);case 3:return _context69.abrupt("return",byteOffset);case 4:case"end":return _context69.stop();}}},_callee65);}));return _parseInstancedModel3DTile.apply(this,arguments);}function parseInstancedModel(tile,arrayBuffer,byteOffset,options,context){byteOffset=parse3DTileHeaderSync(tile,arrayBuffer,byteOffset);if(tile.version!==1){throw new Error('Instanced 3D Model version '.concat(tile.version,' is not supported'));}byteOffset=parse3DTileTablesHeaderSync(tile,arrayBuffer,byteOffset);var view=new DataView(arrayBuffer);tile.gltfFormat=view.getUint32(byteOffset,true);byteOffset+=4;byteOffset=parse3DTileTablesSync(tile,arrayBuffer,byteOffset);byteOffset=parse3DTileGLTFViewSync(tile,arrayBuffer,byteOffset,options);if(tile.featureTableJsonByteLength===0){throw new Error('i3dm parser: featureTableJsonByteLength is zero.');}var featureTable=new Tile3DFeatureTable(tile.featureTableJson,tile.featureTableBinary);var instancesLength=featureTable.getGlobalProperty('INSTANCES_LENGTH');featureTable.featuresLength=instancesLength;if(!Number.isFinite(instancesLength)){throw new Error('i3dm parser: INSTANCES_LENGTH must be defined');}tile.eastNorthUp=featureTable.getGlobalProperty('EAST_NORTH_UP');tile.rtcCenter=featureTable.getGlobalProperty('RTC_CENTER',GL$1.FLOAT,3);var batchTable=new Tile3DBatchTableParser(tile.batchTableJson,tile.batchTableBinary,instancesLength);extractInstancedAttributes(tile,featureTable,batchTable,instancesLength);return byteOffset;}function extractInstancedAttributes(tile,featureTable,batchTable,instancesLength){var collectionOptions={instances:new Array(instancesLength),batchTable:tile._batchTable,cull:false,url:undefined,gltf:undefined,basePath:undefined,incrementallyLoadTextures:false,forwardAxis:[1,0,0]};var instances=collectionOptions.instances;var instancePosition=new Vector3$1();new Vector3$1();new Vector3$1();new Vector3$1();var instanceRotation=new Matrix3();var instanceQuaternion=new Quaternion();var instanceScale=new Vector3$1();var instanceTranslationRotationScale={};var instanceTransform=new Matrix4();var scratch1=[];var scratch2=[];var scratchVector1=new Vector3$1();var scratchVector2=new Vector3$1();for(var _i61=0;_i6112)){_context70.next=13;break;}subtile={};tile.tiles.push(subtile);_context70.next=10;return parse3DTile(arrayBuffer,byteOffset,options,context,subtile);case 10:byteOffset=_context70.sent;_context70.next=5;break;case 13:return _context70.abrupt("return",byteOffset);case 14:case"end":return _context70.stop();}}},_callee66);}));return _parseComposite3DTile.apply(this,arguments);}function parseGltf3DTile(_x139,_x140,_x141,_x142){return _parseGltf3DTile.apply(this,arguments);}function _parseGltf3DTile(){_parseGltf3DTile=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee67(tile,arrayBuffer,options,context){var parse;return regenerator.wrap(function _callee67$(_context71){while(1){switch(_context71.prev=_context71.next){case 0:tile.rotateYtoZ=true;tile.gltfUpAxis=options['3d-tiles']&&options['3d-tiles'].assetGltfUpAxis?options['3d-tiles'].assetGltfUpAxis:'Y';parse=context.parse;_context71.next=5;return parse(arrayBuffer,GLTFLoader,options,context);case 5:tile.gltf=_context71.sent;case 6:case"end":return _context71.stop();}}},_callee67);}));return _parseGltf3DTile.apply(this,arguments);}function parse3DTile(_x143){return _parse3DTile.apply(this,arguments);}function _parse3DTile(){_parse3DTile=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee68(arrayBuffer){var byteOffset,options,context,tile,_args72=arguments;return regenerator.wrap(function _callee68$(_context72){while(1){switch(_context72.prev=_context72.next){case 0:byteOffset=_args72.length>1&&_args72[1]!==undefined?_args72[1]:0;options=_args72.length>2?_args72[2]:undefined;context=_args72.length>3?_args72[3]:undefined;tile=_args72.length>4&&_args72[4]!==undefined?_args72[4]:{};tile.byteOffset=byteOffset;tile.type=getMagicString$1(arrayBuffer,byteOffset);_context72.t0=tile.type;_context72.next=_context72.t0===TILE3D_TYPE.COMPOSITE?9:_context72.t0===TILE3D_TYPE.BATCHED_3D_MODEL?12:_context72.t0===TILE3D_TYPE.GLTF?15:_context72.t0===TILE3D_TYPE.INSTANCED_3D_MODEL?18:_context72.t0===TILE3D_TYPE.POINT_CLOUD?21:24;break;case 9:_context72.next=11;return parseComposite3DTile(tile,arrayBuffer,byteOffset,options,context,parse3DTile);case 11:return _context72.abrupt("return",_context72.sent);case 12:_context72.next=14;return parseBatchedModel3DTile(tile,arrayBuffer,byteOffset,options,context);case 14:return _context72.abrupt("return",_context72.sent);case 15:_context72.next=17;return parseGltf3DTile(tile,arrayBuffer,options,context);case 17:return _context72.abrupt("return",_context72.sent);case 18:_context72.next=20;return parseInstancedModel3DTile(tile,arrayBuffer,byteOffset,options,context);case 20:return _context72.abrupt("return",_context72.sent);case 21:_context72.next=23;return parsePointCloud3DTile(tile,arrayBuffer,byteOffset,options,context);case 23:return _context72.abrupt("return",_context72.sent);case 24:throw new Error('3DTileLoader: unknown type '.concat(tile.type));case 25:case"end":return _context72.stop();}}},_callee68);}));return _parse3DTile.apply(this,arguments);}var SUBTREE_FILE_MAGIC=0x74627573;var SUBTREE_FILE_VERSION=1;function parse3DTilesSubtree(_x144){return _parse3DTilesSubtree.apply(this,arguments);}function _parse3DTilesSubtree(){_parse3DTilesSubtree=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee69(data){var magic,version,jsonByteLength,stringAttribute,textDecoder,string,subtree,binaryByteLength,internalBinaryBuffer;return regenerator.wrap(function _callee69$(_context73){while(1){switch(_context73.prev=_context73.next){case 0:magic=new Uint32Array(data.slice(0,4));if(!(magic[0]!==SUBTREE_FILE_MAGIC)){_context73.next=3;break;}throw new Error('Wrong subtree file magic number');case 3:version=new Uint32Array(data.slice(4,8));if(!(version[0]!==SUBTREE_FILE_VERSION)){_context73.next=6;break;}throw new Error('Wrong subtree file verson, must be 1');case 6:jsonByteLength=parseUint64Value(data.slice(8,16));stringAttribute=new Uint8Array(data,24,jsonByteLength);textDecoder=new TextDecoder('utf8');string=textDecoder.decode(stringAttribute);subtree=JSON.parse(string);binaryByteLength=parseUint64Value(data.slice(16,24));internalBinaryBuffer=new ArrayBuffer(0);if(binaryByteLength){internalBinaryBuffer=data.slice(24+jsonByteLength);}if(!('bufferView'in subtree.tileAvailability)){_context73.next=18;break;}_context73.next=17;return getExplicitBitstream(subtree,'tileAvailability',internalBinaryBuffer);case 17:subtree.tileAvailability.explicitBitstream=_context73.sent;case 18:if(!('bufferView'in subtree.contentAvailability)){_context73.next=22;break;}_context73.next=21;return getExplicitBitstream(subtree,'contentAvailability',internalBinaryBuffer);case 21:subtree.contentAvailability.explicitBitstream=_context73.sent;case 22:if(!('bufferView'in subtree.childSubtreeAvailability)){_context73.next=26;break;}_context73.next=25;return getExplicitBitstream(subtree,'childSubtreeAvailability',internalBinaryBuffer);case 25:subtree.childSubtreeAvailability.explicitBitstream=_context73.sent;case 26:return _context73.abrupt("return",subtree);case 27:case"end":return _context73.stop();}}},_callee69);}));return _parse3DTilesSubtree.apply(this,arguments);}function getExplicitBitstream(_x145,_x146,_x147){return _getExplicitBitstream.apply(this,arguments);}function _getExplicitBitstream(){_getExplicitBitstream=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee70(subtree,name,internalBinaryBuffer){var bufferViewIndex,bufferView,buffer,response,data;return regenerator.wrap(function _callee70$(_context74){while(1){switch(_context74.prev=_context74.next){case 0:bufferViewIndex=subtree[name].bufferView;bufferView=subtree.bufferViews[bufferViewIndex];buffer=subtree.buffers[bufferView.buffer];if(!buffer.uri){_context74.next=11;break;}_context74.next=6;return fetchFile(buffer.uri);case 6:response=_context74.sent;_context74.next=9;return response.arrayBuffer();case 9:data=_context74.sent;return _context74.abrupt("return",new Uint8Array(data,bufferView.byteOffset,bufferView.byteLength));case 11:return _context74.abrupt("return",new Uint8Array(internalBinaryBuffer,bufferView.byteOffset,bufferView.byteLength));case 12:case"end":return _context74.stop();}}},_callee70);}));return _getExplicitBitstream.apply(this,arguments);}function parseUint64Value(buffer){var dataView=new DataView(buffer);var left=dataView.getUint32(0,true);var right=dataView.getUint32(4,true);return left+Math.pow(2,32)*right;}var Tile3DSubtreeLoader={id:'3d-tiles-subtree',name:'3D Tiles Subtree',module:'3d-tiles',version:VERSION$5,extensions:['subtree'],mimeTypes:['application/octet-stream'],tests:['subtree'],parse:parse3DTilesSubtree,options:{}};var QUADTREE_DEVISION_COUNT=4;var OCTREE_DEVISION_COUNT=8;var SUBDIVISION_COUNT_MAP={QUADTREE:QUADTREE_DEVISION_COUNT,OCTREE:OCTREE_DEVISION_COUNT};function parseImplicitTiles(_x148,_x149){return _parseImplicitTiles.apply(this,arguments);}function _parseImplicitTiles(){_parseImplicitTiles=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee71(subtree,options){var parentData,childIndex,level,globalData,subdivisionScheme,subtreeLevels,maximumLevel,contentUrlTemplate,subtreesUriTemplate,basePath,tile,childrenPerTile,childX,childY,childZ,levelOffset,childTileMortonIndex,tileAvailabilityIndex,childTileX,childTileY,childTileZ,isChildSubtreeAvailable,x,y,z,lev,subtreePath,childSubtreeUrl,childSubtree,isTileAvailable,isContentAvailable,childTileLevel,pData,index,currentTile,globalLevel,childCoordinates,formattedTile,_args75=arguments;return regenerator.wrap(function _callee71$(_context75){while(1){switch(_context75.prev=_context75.next){case 0:parentData=_args75.length>2&&_args75[2]!==undefined?_args75[2]:{mortonIndex:0,x:0,y:0,z:0};childIndex=_args75.length>3&&_args75[3]!==undefined?_args75[3]:0;level=_args75.length>4&&_args75[4]!==undefined?_args75[4]:0;globalData=_args75.length>5&&_args75[5]!==undefined?_args75[5]:{level:0,mortonIndex:0,x:0,y:0,z:0};subdivisionScheme=options.subdivisionScheme,subtreeLevels=options.subtreeLevels,maximumLevel=options.maximumLevel,contentUrlTemplate=options.contentUrlTemplate,subtreesUriTemplate=options.subtreesUriTemplate,basePath=options.basePath;tile={children:[],lodMetricValue:0,contentUrl:''};childrenPerTile=SUBDIVISION_COUNT_MAP[subdivisionScheme];childX=childIndex&0b01;childY=childIndex>>1&0b01;childZ=childIndex>>2&0b01;levelOffset=(Math.pow(childrenPerTile,level)-1)/(childrenPerTile-1);childTileMortonIndex=concatBits(parentData.mortonIndex,childIndex);tileAvailabilityIndex=levelOffset+childTileMortonIndex;childTileX=concatBits(parentData.x,childX);childTileY=concatBits(parentData.y,childY);childTileZ=concatBits(parentData.z,childZ);isChildSubtreeAvailable=false;if(level+1>subtreeLevels){isChildSubtreeAvailable=getAvailabilityResult(subtree.childSubtreeAvailability,childTileMortonIndex);}x=concatBits(globalData.x,childTileX);y=concatBits(globalData.y,childTileY);z=concatBits(globalData.z,childTileZ);lev=level+globalData.level;if(!isChildSubtreeAvailable){_context75.next=40;break;}subtreePath=''.concat(basePath,'/').concat(subtreesUriTemplate);childSubtreeUrl=replaceContentUrlTemplate(subtreePath,lev,x,y,z);_context75.next=27;return _load2(childSubtreeUrl,Tile3DSubtreeLoader);case 27:childSubtree=_context75.sent;subtree=childSubtree;globalData.mortonIndex=childTileMortonIndex;globalData.x=childTileX;globalData.y=childTileY;globalData.z=childTileZ;globalData.level=level;childTileMortonIndex=0;tileAvailabilityIndex=0;childTileX=0;childTileY=0;childTileZ=0;level=0;case 40:isTileAvailable=getAvailabilityResult(subtree.tileAvailability,tileAvailabilityIndex);if(!(!isTileAvailable||level>maximumLevel)){_context75.next=43;break;}return _context75.abrupt("return",tile);case 43:isContentAvailable=getAvailabilityResult(subtree.contentAvailability,tileAvailabilityIndex);if(isContentAvailable){tile.contentUrl=replaceContentUrlTemplate(contentUrlTemplate,lev,x,y,z);}childTileLevel=level+1;pData={mortonIndex:childTileMortonIndex,x:childTileX,y:childTileY,z:childTileZ};index=0;case 48:if(!(index>bitIndex&1;return bitValue===1;}function getTileType(tile){if(!tile.contentUrl){return TILE_TYPE.EMPTY;}var contentUrl=tile.contentUrl;var fileExtension=contentUrl.split('.').pop();switch(fileExtension){case'pnts':return TILE_TYPE.POINTCLOUD;case'i3dm':case'b3dm':case'glb':case'gltf':return TILE_TYPE.SCENEGRAPH;default:return fileExtension;}}function getRefine(refine){switch(refine){case'REPLACE':case'replace':return TILE_REFINEMENT.REPLACE;case'ADD':case'add':return TILE_REFINEMENT.ADD;default:return refine;}}function normalizeTileData(tile,options){if(!tile){return null;}if(tile.content){var contentUri=tile.content.uri||tile.content.url;tile.contentUrl=''.concat(options.basePath,'/').concat(contentUri);}tile.id=tile.contentUrl;tile.lodMetricType=LOD_METRIC_TYPE.GEOMETRIC_ERROR;tile.lodMetricValue=tile.geometricError;tile.transformMatrix=tile.transform;tile.type=getTileType(tile);tile.refine=getRefine(tile.refine);return tile;}function normalizeTileHeaders(tileset){var basePath=tileset.basePath;var root=normalizeTileData(tileset.root,tileset);var stack=[];stack.push(root);while(stack.length>0){var tile=stack.pop()||{};var children=tile.children||[];var _iterator54=_createForOfIteratorHelper$3(children),_step54;try{for(_iterator54.s();!(_step54=_iterator54.n()).done;){var childHeader=_step54.value;normalizeTileData(childHeader,{basePath});stack.push(childHeader);}}catch(err){_iterator54.e(err);}finally{_iterator54.f();}}return root;}function normalizeImplicitTileHeaders(_x150){return _normalizeImplicitTileHeaders.apply(this,arguments);}function _normalizeImplicitTileHeaders(){_normalizeImplicitTileHeaders=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee72(tileset){var basePath,implicitTilingExtension,subdivisionScheme,maximumLevel,subtreeLevels,subtreesUriTemplate,subtreeUrl,rootSubtreeUrl,rootSubtree,contentUrlTemplate,refine,rootLodMetricValue,rootBoundingVolume,options;return regenerator.wrap(function _callee72$(_context76){while(1){switch(_context76.prev=_context76.next){case 0:if(tileset.root){_context76.next=2;break;}return _context76.abrupt("return",null);case 2:basePath=tileset.basePath;implicitTilingExtension=tileset.root.extensions['3DTILES_implicit_tiling'];subdivisionScheme=implicitTilingExtension.subdivisionScheme,maximumLevel=implicitTilingExtension.maximumLevel,subtreeLevels=implicitTilingExtension.subtreeLevels,subtreesUriTemplate=implicitTilingExtension.subtrees.uri;subtreeUrl=replaceContentUrlTemplate(subtreesUriTemplate,0,0,0,0);rootSubtreeUrl=''.concat(basePath,'/').concat(subtreeUrl);_context76.next=9;return _load2(rootSubtreeUrl,Tile3DSubtreeLoader);case 9:rootSubtree=_context76.sent;contentUrlTemplate=''.concat(basePath,'/').concat(tileset.root.content.uri);refine=tileset.root.refine;rootLodMetricValue=tileset.root.geometricError;rootBoundingVolume=tileset.root.boundingVolume;options={contentUrlTemplate,subtreesUriTemplate,subdivisionScheme,subtreeLevels,maximumLevel,refine,basePath,lodMetricType:LOD_METRIC_TYPE.GEOMETRIC_ERROR,rootLodMetricValue,rootBoundingVolume,getTileType,getRefine};_context76.next=17;return normalizeImplicitTileData(tileset.root,rootSubtree,options);case 17:return _context76.abrupt("return",_context76.sent);case 18:case"end":return _context76.stop();}}},_callee72);}));return _normalizeImplicitTileHeaders.apply(this,arguments);}function normalizeImplicitTileData(_x151,_x152,_x153){return _normalizeImplicitTileData.apply(this,arguments);}function _normalizeImplicitTileData(){_normalizeImplicitTileData=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee73(tile,rootSubtree,options){var _yield$parseImplicitT,children,contentUrl;return regenerator.wrap(function _callee73$(_context77){while(1){switch(_context77.prev=_context77.next){case 0:if(tile){_context77.next=2;break;}return _context77.abrupt("return",null);case 2:tile.lodMetricType=LOD_METRIC_TYPE.GEOMETRIC_ERROR;tile.lodMetricValue=tile.geometricError;tile.transformMatrix=tile.transform;_context77.next=7;return parseImplicitTiles(rootSubtree,options);case 7:_yield$parseImplicitT=_context77.sent;children=_yield$parseImplicitT.children;contentUrl=_yield$parseImplicitT.contentUrl;if(contentUrl){tile.contentUrl=contentUrl;tile.content={uri:contentUrl.replace(''.concat(options.basePath,'/'),'')};}tile.refine=getRefine(tile.refine);tile.type=getTileType(tile);tile.children=children;tile.id=tile.contentUrl;return _context77.abrupt("return",tile);case 16:case"end":return _context77.stop();}}},_callee73);}));return _normalizeImplicitTileData.apply(this,arguments);}var IMPLICIT_TILING_EXTENSION_NAME='3DTILES_implicit_tiling';var Tiles3DLoader={id:'3d-tiles',name:'3D Tiles',module:'3d-tiles',version:VERSION$5,extensions:['cmpt','pnts','b3dm','i3dm'],mimeTypes:['application/octet-stream'],tests:['cmpt','pnts','b3dm','i3dm'],parse,options:{'3d-tiles':{loadGLTF:true,decodeQuantizedPositions:false,isTileset:'auto',assetGltfUpAxis:null}}};function getBaseUri(tileset){return dirname(tileset.url);}function parseTile(_x154,_x155,_x156){return _parseTile.apply(this,arguments);}function _parseTile(){_parseTile=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee74(arrayBuffer,options,context){var tile,byteOffset;return regenerator.wrap(function _callee74$(_context78){while(1){switch(_context78.prev=_context78.next){case 0:tile={content:{featureIds:null}};byteOffset=0;_context78.next=4;return parse3DTile(arrayBuffer,byteOffset,options,context,tile.content);case 4:return _context78.abrupt("return",tile.content);case 5:case"end":return _context78.stop();}}},_callee74);}));return _parseTile.apply(this,arguments);}function parseTileset(_x157,_x158,_x159){return _parseTileset.apply(this,arguments);}function _parseTileset(){_parseTileset=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee75(data,options,context){var _tilesetJson$root,tilesetJson;return regenerator.wrap(function _callee75$(_context79){while(1){switch(_context79.prev=_context79.next){case 0:tilesetJson=JSON.parse(new TextDecoder().decode(data));tilesetJson.loader=options.loader||Tiles3DLoader;tilesetJson.url=context.url;tilesetJson.basePath=getBaseUri(tilesetJson);if(!hasImplicitTilingExtension(tilesetJson)){_context79.next=10;break;}_context79.next=7;return normalizeImplicitTileHeaders(tilesetJson);case 7:_context79.t0=_context79.sent;_context79.next=11;break;case 10:_context79.t0=normalizeTileHeaders(tilesetJson);case 11:tilesetJson.root=_context79.t0;tilesetJson.type=TILESET_TYPE.TILES3D;tilesetJson.lodMetricType=LOD_METRIC_TYPE.GEOMETRIC_ERROR;tilesetJson.lodMetricValue=((_tilesetJson$root=tilesetJson.root)===null||_tilesetJson$root===void 0?void 0:_tilesetJson$root.lodMetricValue)||0;return _context79.abrupt("return",tilesetJson);case 16:case"end":return _context79.stop();}}},_callee75);}));return _parseTileset.apply(this,arguments);}function parse(_x160,_x161,_x162){return _parse.apply(this,arguments);}function _parse(){_parse=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee76(data,options,context){var loaderOptions,isTileset;return regenerator.wrap(function _callee76$(_context80){while(1){switch(_context80.prev=_context80.next){case 0:loaderOptions=options['3d-tiles']||{};if(loaderOptions.isTileset==='auto'){isTileset=context.url&&context.url.indexOf('.json')!==-1;}else {isTileset=loaderOptions.isTileset;}if(!isTileset){_context80.next=8;break;}_context80.next=5;return parseTileset(data,options,context);case 5:data=_context80.sent;_context80.next=11;break;case 8:_context80.next=10;return parseTile(data,options,context);case 10:data=_context80.sent;case 11:return _context80.abrupt("return",data);case 12:case"end":return _context80.stop();}}},_callee76);}));return _parse.apply(this,arguments);}function hasImplicitTilingExtension(tilesetJson){var _tilesetJson$extensio,_tilesetJson$extensio2;return (tilesetJson===null||tilesetJson===void 0?void 0:(_tilesetJson$extensio=tilesetJson.extensionsRequired)===null||_tilesetJson$extensio===void 0?void 0:_tilesetJson$extensio.includes(IMPLICIT_TILING_EXTENSION_NAME))&&(tilesetJson===null||tilesetJson===void 0?void 0:(_tilesetJson$extensio2=tilesetJson.extensionsUsed)===null||_tilesetJson$extensio2===void 0?void 0:_tilesetJson$extensio2.includes(IMPLICIT_TILING_EXTENSION_NAME));}var CESIUM_ION_URL='https://api.cesium.com/v1/assets';function getIonTilesetMetadata(_x163,_x164){return _getIonTilesetMetadata.apply(this,arguments);}function _getIonTilesetMetadata(){_getIonTilesetMetadata=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee77(accessToken,assetId){var assets,_iterator66,_step66,item,ionAssetMetadata,type,url;return regenerator.wrap(function _callee77$(_context81){while(1){switch(_context81.prev=_context81.next){case 0:if(assetId){_context81.next=6;break;}_context81.next=3;return getIonAssets(accessToken);case 3:assets=_context81.sent;_iterator66=_createForOfIteratorHelper$3(assets.items);try{for(_iterator66.s();!(_step66=_iterator66.n()).done;){item=_step66.value;if(item.type==='3DTILES'){assetId=item.id;}}}catch(err){_iterator66.e(err);}finally{_iterator66.f();}case 6:_context81.next=8;return getIonAssetMetadata(accessToken,assetId);case 8:ionAssetMetadata=_context81.sent;type=ionAssetMetadata.type,url=ionAssetMetadata.url;assert$7(type==='3DTILES'&&url);ionAssetMetadata.headers={Authorization:'Bearer '.concat(ionAssetMetadata.accessToken)};return _context81.abrupt("return",ionAssetMetadata);case 13:case"end":return _context81.stop();}}},_callee77);}));return _getIonTilesetMetadata.apply(this,arguments);}function getIonAssets(_x165){return _getIonAssets.apply(this,arguments);}function _getIonAssets(){_getIonAssets=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee78(accessToken){var url,headers,response;return regenerator.wrap(function _callee78$(_context82){while(1){switch(_context82.prev=_context82.next){case 0:assert$7(accessToken);url=CESIUM_ION_URL;headers={Authorization:'Bearer '.concat(accessToken)};_context82.next=5;return fetchFile(url,{fetch:{headers}});case 5:response=_context82.sent;if(response.ok){_context82.next=8;break;}throw new Error(response.statusText);case 8:_context82.next=10;return response.json();case 10:return _context82.abrupt("return",_context82.sent);case 11:case"end":return _context82.stop();}}},_callee78);}));return _getIonAssets.apply(this,arguments);}function getIonAssetMetadata(_x166,_x167){return _getIonAssetMetadata.apply(this,arguments);}function _getIonAssetMetadata(){_getIonAssetMetadata=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee79(accessToken,assetId){var headers,url,response,metadata,tilesetInfo;return regenerator.wrap(function _callee79$(_context83){while(1){switch(_context83.prev=_context83.next){case 0:assert$7(accessToken,assetId);headers={Authorization:'Bearer '.concat(accessToken)};url=''.concat(CESIUM_ION_URL,'/').concat(assetId);_context83.next=5;return fetchFile(''.concat(url),{fetch:{headers}});case 5:response=_context83.sent;if(response.ok){_context83.next=8;break;}throw new Error(response.statusText);case 8:_context83.next=10;return response.json();case 10:metadata=_context83.sent;_context83.next=13;return fetchFile(''.concat(url,'/endpoint'),{fetch:{headers}});case 13:response=_context83.sent;if(response.ok){_context83.next=16;break;}throw new Error(response.statusText);case 16:_context83.next=18;return response.json();case 18:tilesetInfo=_context83.sent;metadata=_objectSpread$3(_objectSpread$3({},metadata),tilesetInfo);return _context83.abrupt("return",metadata);case 21:case"end":return _context83.stop();}}},_callee79);}));return _getIonAssetMetadata.apply(this,arguments);}function preload(_x168){return _preload.apply(this,arguments);}function _preload(){_preload=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee80(url){var options,_options3,accessToken,assetId,matched,_args84=arguments;return regenerator.wrap(function _callee80$(_context84){while(1){switch(_context84.prev=_context84.next){case 0:options=_args84.length>1&&_args84[1]!==undefined?_args84[1]:{};options=options['cesium-ion']||{};_options3=options,accessToken=_options3.accessToken;assetId=options.assetId;if(!Number.isFinite(assetId)){matched=url.match(/\/([0-9]+)\/tileset.json/);assetId=matched&&matched[1];}return _context84.abrupt("return",getIonTilesetMetadata(accessToken,assetId));case 6:case"end":return _context84.stop();}}},_callee80);}));return _preload.apply(this,arguments);}var CesiumIonLoader=_objectSpread$3(_objectSpread$3({},Tiles3DLoader),{},{id:'cesium-ion',name:'Cesium Ion',preload,parse:function(){var _parse2=_asyncToGenerator(/*#__PURE__*/regenerator.mark(function _callee9(data,options,context){return regenerator.wrap(function _callee9$(_context13){while(1){switch(_context13.prev=_context13.next){case 0:options=_objectSpread$3({},options);options['3d-tiles']=options['cesium-ion'];options.loader=CesiumIonLoader;return _context13.abrupt("return",Tiles3DLoader.parse(data,options,context));case 4:case"end":return _context13.stop();}}},_callee9);}));function parse(_x169,_x170,_x171){return _parse2.apply(this,arguments);}return parse;}(),options:{'cesium-ion':_objectSpread$3(_objectSpread$3({},Tiles3DLoader.options['3d-tiles']),{},{accessToken:null})}});// From https://github.com/potree/potree/blob/master/src/materials/PointCloudMaterial.js function generateGradientTexture(gradient){var size=64;// create canvas var canvas=document.createElement('canvas');canvas.width=size;canvas.height=size;// get context var context=canvas.getContext('2d');// draw gradient context.rect(0,0,size,size);var ctxGradient=context.createLinearGradient(0,0,size,size);for(var _i62=0;_i62 1 ? (camera.right - camera.left) : (camera.top - camera.bottom) //越大越粗糙 }lastCameraAspect=camera.aspect;lastCameraTop=camera.top;//add lastCameraLeft=camera.left;//add if(options.debug){console.log('Updated sse denonimator:',sseDenominator);}}var frustum=_getCameraFrustum(camera);var planes=frustum.planes.map(function(plane){return new Plane(plane.normal.toArray(),plane.constant);});var cullingVolume=new CullingVolume(planes);var rendererSize=new THREE$1.Vector2();renderer.getSize(rendererSize);var frameState={camera:{position:options.isLowestDepth?[0,100,0]:lastCameraPosition.toArray(),// !zeg改 将相机坐标改成一个很远的位置,来加载lowestDepth type:camera.type,//xzw add left:camera.left,right:camera.right,top:camera.top,bottom:camera.bottom//xzw add },height:rendererSize.y,frameNumber:tileset._frameNumber,sseDenominator:sseDenominator,cullingVolume:cullingVolume,viewport:{id:0}};tileset.options.currentFloorId=root.currentFloorId===void 0?'all':root.currentFloorId;// !zeg改 用于停止隐藏楼层的tile更新 tileset._cache.reset();tileset._traverser.traverse(tileset.root,frameState,tileset.options);// 遍历更新 var _iterator55=_createForOfIteratorHelper$3(tileset.tiles),_step55;try{for(_iterator55.s();!(_step55=_iterator55.n()).done;){var _tile=_step55.value;if(_tile.selected){if(!renderMap[_tile.id]){console.error('TILE SELECTED BUT NOT LOADED!!',_tile.id);}else {// Make sure it's visible renderMap[_tile.id].visible=true;}}else {if(renderMap[_tile.id]){renderMap[_tile.id].visible=false;}}}}catch(err){_iterator55.e(err);}finally{_iterator55.f();}while(unloadQueue.length>0){var tile=unloadQueue.pop();if(renderMap[tile.id]&&tile.contentState==TILE_CONTENT_STATE.UNLOADED){if(options.type=='4dkk'){root.removeTile(renderMap[tile.id]);// !zeg改 removeTile }else {root.remove(renderMap[tile.id]);}disposeNode(renderMap[tile.id]);delete renderMap[tile.id];}if(boxMap[tile.id]){disposeNode(boxMap[tile.id]);tileBoxes.remove(boxMap[tile.id]);delete boxMap[tile.id];}}var tilesLoaded=tileset.stats.get('Tiles Loaded').count;var tilesLoading=tileset.stats.get('Tiles Loading').count;if(props.onProgress){props.onProgress(tilesLoaded,tilesLoaded+tilesLoading);}if(props.loadingManager&&!loadingEnded){if(tilesLoading==0&&(options.preloadTilesCount==null||tilesLoaded>=options.preloadTilesCount)){loadingEnded=true;props.loadingManager.itemEnd(props.url);}}return frameState;};updateResetTransform=function _updateResetTransform(){if(options.geoTransform!=GeoTransform.WGS84Cartesian){// Reset the current model matrix and apply our own transformation threeMat.copy(tileTrasnform).invert();threeMat.premultiply(lastRootTransform);threeMat.copy(lastRootTransform).multiply(new THREE$1.Matrix4().copy(tileTrasnform).invert());tileset.modelMatrix=new Matrix4(threeMat.toArray());}};detectOrientation=function _detectOrientation(tile){if(!tile.boundingVolume.halfAxes){return;}var halfAxes=tile.boundingVolume.halfAxes;var orientationMatrix=new THREE$1.Matrix4().extractRotation(getMatrix4FromHalfAxes(halfAxes)).premultiply(new THREE$1.Matrix4().extractRotation(rootTransformInverse));var rotation=new THREE$1.Euler().setFromRotationMatrix(orientationMatrix);if(!rotation.equals(new THREE$1.Euler())){orientationDetected=true;var pos=new THREE$1.Vector3(tileTrasnform.elements[12],tileTrasnform.elements[13],tileTrasnform.elements[14]);tileTrasnform.extractRotation(orientationMatrix);tileTrasnform.setPosition(pos);updateResetTransform();}};options=Object.assign(Object.assign({},defaultOptions),props.options);url=props.url;UPDATE_INTERVAL=options.updateInterval;MAX_DEPTH_FOR_ORIENTATION=2;loadersGLOptions={};if(!options.cesiumIONToken){_context16.next=14;break;}loadersGLOptions['cesium-ion']={accessToken:options.cesiumIONToken};_context16.next=12;return CesiumIonLoader.preload(url,loadersGLOptions);case 12:metadata=_context16.sent;loadersGLOptions['fetch']={headers:metadata.headers};case 14:if(props.loadingManager){props.loadingManager.itemStart(url);}_context16.next=17;return _load2(url,Tiles3DLoader,Object.assign({},loadersGLOptions));case 17:tilesetJson=_context16.sent;for(_i63=0,_arr=[0,1,2];_i63<_arr.length;_i63++){_i64=_arr[_i63];tilesetJson.root.boundingVolume.box[_i64]=0;}// !zeg改 root的坐标必须归0,否则会与原数据坐标以及collider对不上 renderMap={};boxMap={};unloadQueue=[];// !zeg改 使用4dkankan里传入的model root=props.model||new THREE$1.Group();tileBoxes=new THREE$1.Group();if(options.debug){root.add(tileBoxes);// 只在debug的时候才把tileBoxes添加进root }else {tileBoxes.visible=false;}pointcloudUniforms={pointSize:{type:'f',value:options.pointSize},gradient:{type:'t',value:gradientTexture},grayscale:{type:'t',value:grayscaleTexture},rootCenter:{type:'vec3',value:new THREE$1.Vector3()},rootNormal:{type:'vec3',value:new THREE$1.Vector3()},coloring:{type:'i',value:options.pointCloudColoring},hideGround:{type:'b',value:true},elevationRange:{type:'vec2',value:new THREE$1.Vector2(0,400)},maxIntensity:{type:'f',value:1.0},intensityContrast:{type:'f',value:1.0},alpha:{type:'f',value:1.0}};pointcloudMaterial=new THREE$1.ShaderMaterial({uniforms:pointcloudUniforms,vertexShader:PointCloudVS,fragmentShader:PointCloudFS,transparent:options.transparent,vertexColors:true});cameraReference=null;rendererReference=null;gltfLoader=new GLTFLoader$1();ktx2Loader=undefined;dracoLoader=undefined;if(options.basisTranscoderPath){ktx2Loader=new KTX2Loader();ktx2Loader.detectSupport(props.renderer);ktx2Loader.setTranscoderPath(options.basisTranscoderPath+'/');ktx2Loader.setWorkerLimit(2);gltfLoader.setKTX2Loader(ktx2Loader);}if(options.dracoDecoderPath){dracoLoader=new DRACOLoader();dracoLoader.setDecoderPath(options.dracoDecoderPath+'/');dracoLoader.setWorkerLimit(options.maxConcurrency);gltfLoader.setDRACOLoader(dracoLoader);}unlitMaterial=new THREE$1.MeshBasicMaterial({transparent:options.transparent});tileOptions={maximumMemoryUsage:options.maximumMemoryUsage,maximumScreenSpaceError:options.maximumScreenSpaceError,viewDistanceScale:options.viewDistanceScale,skipLevelOfDetail:options.skipLevelOfDetail,updateTransforms:options.updateTransforms,throttleRequests:options.throttleRequests,maxRequests:options.maxRequests,type:options.type,// !zeg改 用于兼容专属逻辑 imageVersion:options.imageVersion,// !zeg改 用于更新瓦片模型的version ingoreVisibleCompute:!!options.ingoreVisibleCompute,// !zeg改 禁用屏幕外瓦片计算 contentLoader:function contentLoader(tile){return __awaiter(_this30,void 0,void 0,/*#__PURE__*/regenerator.mark(function _callee10(){var tileContent,floorMatch,box;return regenerator.wrap(function _callee10$(_context14){while(1){switch(_context14.prev=_context14.next){case 0:tileContent=null;_context14.t0=tile.type;_context14.next=_context14.t0===TILE_TYPE.POINTCLOUD?4:_context14.t0===TILE_TYPE.SCENEGRAPH?6:_context14.t0===TILE_TYPE.MESH?6:10;break;case 4:tileContent=createPointNodes(tile,pointcloudMaterial,options,rootTransformInverse);return _context14.abrupt("break",10);case 6:_context14.next=8;return createGLTFNodes(gltfLoader,tile,unlitMaterial,options,rootTransformInverse);case 8:tileContent=_context14.sent;return _context14.abrupt("break",10);case 10:if(tileContent){tileContent.visible=false;tileContent.name='tileContent';renderMap[tile.id]=tileContent;if(options.type=='4dkk'){// !zeg改 addTile floorMatch=tile.contentUrl.match(/floor_([0-9]+)./);tile.floorIndex=floorMatch?parseInt(floorMatch[1]):0;root.addTile(tile.floorIndex,tileContent);}else {root.add(tileContent);}if(options.debug){box=loadersBoundingBoxToMesh(tile);tileBoxes.add(box);boxMap[tile.id]=box;}}case 11:case"end":return _context14.stop();}}},_callee10);}));},onTileLoad:function onTileLoad(tile){return __awaiter(_this30,void 0,void 0,/*#__PURE__*/regenerator.mark(function _callee11(){return regenerator.wrap(function _callee11$(_context15){while(1){switch(_context15.prev=_context15.next){case 0:if(tileset){if(!orientationDetected&&(tile===null||tile===void 0?void 0:tile.depth)<=MAX_DEPTH_FOR_ORIENTATION){detectOrientation(tile);}tileset._frameNumber++;tilesetUpdate(tileset,renderMap,rendererReference,cameraReference);}case 1:case"end":return _context15.stop();}}},_callee11);}));},onTileUnload:function onTileUnload(tile){unloadQueue.push(tile);},onTileError:function onTileError(tile,message){console.error('Tile error',tile.id,message);}};tileset=new Tileset3D(tilesetJson,Object.assign(Object.assign({},tileOptions),{loadOptions:Object.assign(Object.assign({},loadersGLOptions),{maxConcurrency:options.maxConcurrency,worker:options.worker,gltf:{loadImages:false},'3d-tiles':{loadGLTF:false}})}));// // transformations threeMat=new THREE$1.Matrix4();tileTrasnform=new THREE$1.Matrix4();rootCenter=new THREE$1.Vector3();orientationDetected=false;if(tileset.root.boundingVolume){if(tileset.root.header.boundingVolume.region){// TODO: Handle region type bounding volumes // https://github.com/visgl/loaders.gl/issues/1994 console.warn('Cannot apply a model matrix to bounding volumes of type region. Tileset stays in original geo-coordinates.');options.geoTransform=GeoTransform.WGS84Cartesian;}tileTrasnform.setPosition(tileset.root.boundingVolume.center[0],tileset.root.boundingVolume.center[1],tileset.root.boundingVolume.center[2]);}else {console.warn('Bounding volume not found, no transformations applied');}if(options.debug){box=loadersBoundingBoxToMesh(tileset.root);tileBoxes.add(box);boxMap[tileset.root.id]=box;}disposeFlag=false;loadingEnded=false;pointcloudUniforms.rootCenter.value.copy(rootCenter);pointcloudUniforms.rootNormal.value.copy(new THREE$1.Vector3(0,0,1).normalize());// Extra stats tileset.stats.get('Loader concurrency').count=options.maxConcurrency;tileset.stats.get('Maximum SSE').count=options.maximumScreenSpaceError;tileset.stats.get('Maximum mem usage').count=options.maximumMemoryUsage;timer=UPDATE_INTERVAL;// !zeg改 首次tilesetUpdate无需等待 //let lastCameraTransform = null lastCameraAspect=null,lastCameraTop=null,lastCameraLeft=null;lastCameraPosition=new THREE$1.Vector3(Infinity,Infinity,Infinity);sseDenominator=null;root.updateMatrixWorld(true);lastRootTransform=new THREE$1.Matrix4().copy(root.matrixWorld);rootTransformInverse=new THREE$1.Matrix4().copy(lastRootTransform).invert();detectOrientation(tileset.root);updateResetTransform();if(options.debug){boxMap[tileset.root.id].applyMatrix4(threeMat);tileBoxes.matrixWorld.copy(root.matrixWorld);}if(options.geoTransform==GeoTransform.Mercator){coords=datumsToSpherical(tileset.cartographicCenter[1],tileset.cartographicCenter[0]);rootCenter.set(coords.x,0,-coords.y);root.position.copy(rootCenter);root.rotation.set(-Math.PI/2,0,0);root.updateMatrixWorld(true);}else if(options.geoTransform==GeoTransform.WGS84Cartesian){root.applyMatrix4(tileTrasnform);root.updateMatrixWorld(true);rootCenter.copy(root.position);}return _context16.abrupt("return",{model:root,runtime:{getTileset:function getTileset(){return tileset;},getStats:function getStats(){return tileset.stats;},showTiles:function showTiles(visible){tileBoxes.visible=visible;},setWireframe:function setWireframe(wireframe){options.wireframe=wireframe;root.traverse(function(object){if(object instanceof THREE$1.Mesh){object.material.wireframe=wireframe;}});},setDebug:function setDebug(debug){options.debug=debug;tileBoxes.visible=debug;},setShading:function setShading(shading){options.shading=shading;},getTileBoxes:function getTileBoxes(){return tileBoxes;},setViewDistanceScale:function setViewDistanceScale(scale){tileset.options.viewDistanceScale=scale;tileset._frameNumber++;tilesetUpdate(tileset,renderMap,rendererReference,cameraReference);},setHideGround:function setHideGround(enabled){pointcloudUniforms.hideGround.value=enabled;},setPointCloudColoring:function setPointCloudColoring(selection){pointcloudUniforms.coloring.value=selection;},setElevationRange:function setElevationRange(range){pointcloudUniforms.elevationRange.value.set(range[0],range[1]);},setMaxIntensity:function setMaxIntensity(intensity){pointcloudUniforms.maxIntensity.value=intensity;},setIntensityContrast:function setIntensityContrast(contrast){pointcloudUniforms.intensityContrast.value=contrast;},setPointAlpha:function setPointAlpha(alpha){pointcloudUniforms.alpha.value=alpha;},getLatLongHeightFromPosition:function getLatLongHeightFromPosition(position){var cartographicPosition=tileset.ellipsoid.cartesianToCartographic(new THREE$1.Vector3().copy(position).applyMatrix4(new THREE$1.Matrix4().copy(threeMat).invert()).toArray());return {lat:cartographicPosition[1],long:cartographicPosition[0],height:cartographicPosition[2]};},getPositionFromLatLongHeight:function getPositionFromLatLongHeight(coord){var cartesianPosition=tileset.ellipsoid.cartographicToCartesian([coord.long,coord.lat,coord.height]);return _construct(THREE$1.Vector3,_toConsumableArray(cartesianPosition)).applyMatrix4(threeMat);},getCameraFrustum:function getCameraFrustum(camera){var frustum=_getCameraFrustum(camera);var meshes=frustum.planes.map(function(plane){return new Plane(plane.normal.toArray(),plane.constant);}).map(function(loadersPlane){return loadersPlaneToMesh(loadersPlane);});var model=new THREE$1.Group();var _iterator56=_createForOfIteratorHelper$3(meshes),_step56;try{for(_iterator56.s();!(_step56=_iterator56.n()).done;){var mesh=_step56.value;model.add(mesh);}}catch(err){_iterator56.e(err);}finally{_iterator56.f();}return model;},// !zeg改 isForse 强制tilesetUpdate update:function update(dt,renderer,camera,isForse){cameraReference=camera;rendererReference=renderer;timer+=isForse?9999:dt;if(tileset&&timer>=UPDATE_INTERVAL){if(!lastRootTransform.equals(root.matrixWorld)){timer=0;lastRootTransform.copy(root.matrixWorld);updateResetTransform();var _rootCenter=new THREE$1.Vector3().setFromMatrixPosition(lastRootTransform);pointcloudUniforms.rootCenter.value.copy(_rootCenter);pointcloudUniforms.rootNormal.value.copy(new THREE$1.Vector3(0,0,1).applyMatrix4(lastRootTransform).normalize());rootTransformInverse.copy(lastRootTransform).invert();if(options.debug){boxMap[tileset.root.id].matrixWorld.copy(threeMat);boxMap[tileset.root.id].applyMatrix4(lastRootTransform);}}//if (lastCameraTransform == null) { // lastCameraTransform = new Matrix4$1().copy(camera.matrixWorld) //} else { //const cameraChanged = !camera.matrixWorld.equals(lastCameraTransform) || !(camera.aspect == lastCameraAspect) //if (cameraChanged || isForse) { //if (lastCameraTransform == null) { // lastCameraTransform = new Matrix4$1().copy(camera.matrixWorld) //} else { //const cameraChanged = !camera.matrixWorld.equals(lastCameraTransform) || !(camera.aspect == lastCameraAspect) //if (cameraChanged || isForse) { timer=0;tileset._frameNumber++;camera.getWorldPosition(lastCameraPosition);//lastCameraTransform.copy(camera.matrixWorld) //lastCameraTransform.copy(camera.matrixWorld) tilesetUpdate(tileset,renderMap,renderer,camera);//} //} }},dispose:function dispose(){disposeFlag=true;tileset._destroy();while(root.children.length>0){var obj=root.children[0];disposeNode(obj);root.remove(obj);}while(tileBoxes.children.length>0){var _obj=tileBoxes.children[0];tileBoxes.remove(_obj);_obj.geometry.dispose();_obj.material.dispose();}if(ktx2Loader){ktx2Loader.dispose();}if(dracoLoader){dracoLoader.dispose();}},// !zeg改 // 显示并让所有tile按照相机位置细化,不受可视范围影响 ingoreVisibleCompute:function ingoreVisibleCompute(visi){tileset.options.ingoreVisibleCompute=visi;tileset._frameNumber++;tilesetUpdate(tileset,renderMap,rendererReference,cameraReference);},// 暂停tile更新,保持当前tile的显隐和depth pauseTilesetUpdate:function pauseTilesetUpdate(isPause){options.pauseTilesetUpdate=isPause;if(!isPause){tileset._frameNumber++;tilesetUpdate(tileset,renderMap,rendererReference,cameraReference);}},// 设置是否限制为最低精度tile深度 limit2lowestDepth:function limit2lowestDepth(isLowest){options.isLowestDepth=!!isLowest;if(cameraReference){tileset._frameNumber++;tilesetUpdate(tileset,renderMap,rendererReference,cameraReference);}},// 清空正在加载的tile clearLoadingTiles:function clearLoadingTiles(){tileset.loadingTiles.forEach(function(tile){return tile.controller&&tile.controller.abort();});},// 模型的总体积 setModelSize:function setModelSize(size){tileset.options.modelSize=size;console.error(size);},getRenderMap:function getRenderMap(){return renderMap;}}});case 62:case"end":return _context16.stop();}}},_callee12);}));}}]);return Loader3DTiles;}();function createGLTFNodes(gltfLoader,tile,unlitMaterial,options,rootTransformInverse){return __awaiter(this,void 0,void 0,/*#__PURE__*/regenerator.mark(function _callee13(){return regenerator.wrap(function _callee13$(_context17){while(1){switch(_context17.prev=_context17.next){case 0:return _context17.abrupt("return",new Promise(function(resolve,reject){var shouldRotate=tile.tileset.asset&&tile.tileset.asset.gltfUpAxis!=='Z';// The computed trasnform already contains the root's transform, so we have to invert it // The computed trasnform already contains the root's transform, so we have to invert it var contentTransform=new THREE$1.Matrix4().fromArray(tile.computedTransform).premultiply(rootTransformInverse);if(shouldRotate){var rotateX=new THREE$1.Matrix4().makeRotationAxis(new THREE$1.Vector3(1,0,0),Math.PI/2);contentTransform.multiply(rotateX);// convert from GLTF Y-up to Z-up }gltfLoader.parse(tile.content.type=='glTF'?tile.content.gltf.gltfArrayBuffer:tile.content.gltfArrayBuffer,tile.contentUrl?tile.contentUrl.substr(0,tile.contentUrl.lastIndexOf('/')+1):'',function(gltf){// !zeg改 Chunk // 模型加载成功 var tileContent=gltf.scenes[0];var meshes=[];tileContent.traverse(function(object){if(object.type=='Mesh'){meshes.push(object);// 提取tileContent里面的所有mesh }});tileContent.clear();// 清空tileContent // 清空tileContent meshes.forEach(function(mesh){var originalMaterial=mesh.material;var originalMap=originalMaterial.map;if(options.material){mesh.material=options.material.clone();originalMaterial.dispose();}else if(options.shading==Shading.FlatTexture){mesh.material=unlitMaterial.clone();originalMaterial.dispose();}if(options.shading!=Shading.ShadedNoTexture){if(mesh.material.type=='ShaderMaterial'){mesh.material.uniforms.map={value:originalMap};}else {mesh.material.map=originalMap;}}else {if(originalMap){originalMap.dispose();}mesh.material.map=null;}if(options.shaderCallback){mesh.onBeforeRender=options.shaderCallback;}mesh.material.wireframe=options.wireframe;if(options.computeNormals){mesh.geometry.computeVertexNormals();}mesh.geometry.applyMatrix4(contentTransform);if(tile.content.rtcCenter){// 有些b3dm模型会将坐标写在源码的rtcCenter里 mesh.geometry.translate(tile.content.rtcCenter[0],tile.content.rtcCenter[1],tile.content.rtcCenter[2]);}else {mesh.geometry.scale(1,1,-1);// 调整缩放,对应box也要进行变换(scaleZ对应box[2]) }if(tile.tileset.options.type=='4dkk'){// 将mesh转为chunk mesh.geometry.computeBoundingBox();mesh.material.dispose();var chunk=new Chunk({geometry:mesh.geometry,texture:mesh.material.map,name:mesh.name,meshUrl:tile.contentUrl,tileId:tile.id});tileContent.add(chunk);// 将chunk添加进tileContent }else {tileContent.add(mesh);}});resolve(tileContent);},function(e){reject(new Error("error parsing gltf in tile ".concat(tile.id,": ").concat(e)));});}));case 1:case"end":return _context17.stop();}}},_callee13);}));}function createPointNodes(tile,pointcloudMaterial,options,rootTransformInverse){var d={rtc_center:tile.content.rtcCenter,points:tile.content.attributes.positions,intensities:tile.content.attributes.intensity,classifications:tile.content.attributes.classification,rgb:null,rgba:null};var colors=tile.content.attributes.colors;if(colors&&colors.size===3){d.rgb=colors.value;}if(colors&&colors.size===4){d.rgba=colors.value;}var geometry=new THREE$1.BufferGeometry();geometry.setAttribute('position',new THREE$1.Float32BufferAttribute(d.points,3));var contentTransform=new THREE$1.Matrix4().fromArray(tile.computedTransform).premultiply(rootTransformInverse);if(d.rgba){geometry.setAttribute('color',new THREE$1.Float32BufferAttribute(d.rgba,4));}else if(d.rgb){geometry.setAttribute('color',new THREE$1.Uint8BufferAttribute(d.rgb,3,true));}if(d.intensities){geometry.setAttribute('intensity',// Handles both 16bit or 8bit intensity values new THREE$1.BufferAttribute(d.intensities,1,true));}if(d.classifications){geometry.setAttribute('classification',new THREE$1.Uint8BufferAttribute(d.classifications,1,false));}var tileContent=new THREE$1.Points(geometry,options.material||pointcloudMaterial);if(d.rtc_center){var c=d.rtc_center;contentTransform.multiply(new THREE$1.Matrix4().makeTranslation(c[0],c[1],c[2]));}tileContent.applyMatrix4(contentTransform);return tileContent;}function disposeMaterial(material){var _a,_b,_c,_d;if((_a=material===null||material===void 0?void 0:material.uniforms)===null||_a===void 0?void 0:_a.map){(_c=(_b=material===null||material===void 0?void 0:material.uniforms)===null||_b===void 0?void 0:_b.map.value)===null||_c===void 0?void 0:_c.dispose();}else if(material.map){(_d=material.map)===null||_d===void 0?void 0:_d.dispose();}material.dispose();}function disposeNode(node){node.traverse(function(object){if(object.isMesh){object.geometry.dispose();if(object.material.isMaterial){disposeMaterial(object.material);}else {// an array of materials var _iterator57=_createForOfIteratorHelper$3(object.material),_step57;try{for(_iterator57.s();!(_step57=_iterator57.n()).done;){var material=_step57.value;disposeMaterial(material);}}catch(err){_iterator57.e(err);}finally{_iterator57.f();}}}});for(var _i65=node.children.length-1;_i65>=0;_i65--){var obj=node.children[_i65];node.remove(obj);}} var baseURL = getScriptURL(); // 兼容V2 var compatiblev2 = function compatiblev2(data) { if (!data.floors) { data = { floors: [data] }; } data.floors.map(function (data) { data.column = data.column || []; data.window = data.window || []; data.door = data.door || []; data.groundCase = data.groundCase || []; data.bayCase = data.bayCase || []; data.slideDoor = data.slideDoor || []; data.tagging = data.tagging || []; data.furnColumn = data.furnColumn || []; data.furnFlue = data.furnFlue || []; if (data.rooms || data.room || data.points) { data.room = data.rooms || data.room || data.points; data.room.forEach(function (room) { if (!isNumber(room.top)) { room.top = isNumber(data.top) ? data.top : 1; } if (!isNumber(room.bottom)) { room.bottom = isNumber(data.bottom) ? data.bottom : 1; } if (!room.ground && room.points) { room.ground = room.points; } if (!room.hole) { room.hole = []; } room.close = true; }); } return data; }); return data; }; defineComponent('resource', function () { return /*#__PURE__*/function () { function Resource() { _classCallCheck(this, Resource); this.reload = false; this.version = Date.now(); this.nowTime = Date.now(); this.imageVersion = 0; this.linkVersion = 0; } _createClass(Resource, [{ key: "num", get: function get() { return this.$app.config.num; } }, { key: "mode", get: function get() { return this.$app.config.view ? 'view' : 'edit'; } }, { key: "time", get: function get() { if (this.reload || this.refresh) { if (this.reload) { this.reload = false; this.refresh = Date.now(); } return this.refresh; } return this.version; } }, { key: "base", value: function base(path) { return baseURL + path; } }, { key: "auth", value: function () { var _auth = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee() { var data; return regenerator.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!(this.mode != 'edit')) { _context.next = 2; break; } return _context.abrupt("return"); case 2: _context.prev = 2; _context.next = 5; return this.$app.remote_editor.getAuth({ num: this.num }); case 5: data = _context.sent; if (data.success) { this.$app.store.set('auth', data.data); } return _context.abrupt("return", data); case 10: _context.prev = 10; _context.t0 = _context["catch"](2); throw _context.t0; case 13: case "end": return _context.stop(); } } }, _callee, this, [[2, 10]]); })); function auth() { return _auth.apply(this, arguments); } return auth; }() }, { key: "metadata", value: function () { var _metadata = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() { var data, resp; return regenerator.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: logger$1.time("".concat(this.$app.config.num, "[load metadata]").concat(this.$app.uid)); data = null; resp = null; if (!this.$app.config.view) { _context2.next = 19; break; } if (!(this.$app.config.deploy == 'local' && !this.$app.config.server)) { _context2.next = 10; break; } _context2.next = 7; return http.get(this.getViewResourceURL("data/scene.json?_=".concat(this.time))); case 7: resp = _context2.sent; _context2.next = 17; break; case 10: if (!window.__KANKAN_DATA) { _context2.next = 14; break; } resp = window.__KANKAN_DATA; _context2.next = 17; break; case 14: _context2.next = 16; return http.get("/service/scene/getInfo?num=".concat(this.$app.config.num, "&_=").concat(this.time)); case 16: resp = _context2.sent; case 17: _context2.next = 22; break; case 19: _context2.next = 21; return http.get("/service/scene/edit/getInfo?num=".concat(this.$app.config.num, "&_=").concat(this.time)); case 21: resp = _context2.sent; case 22: if (!(resp.success != void 0)) { _context2.next = 30; break; } if (!resp.success) { _context2.next = 27; break; } data = resp.data; _context2.next = 28; break; case 27: return _context2.abrupt("return"); case 28: _context2.next = 31; break; case 30: data = resp; case 31: if (data.entry) { if (typeof data.entry === 'string') { data.entry = JSON.parse(data.entry); } } if (data.boxVideos) { if (typeof data.boxVideos === 'string') { data.boxVideos = JSON.parse(data.boxVideos); } } if (data.boxPhotos) { if (typeof data.boxPhotos === 'string') { data.boxPhotos = JSON.parse(data.boxPhotos); } } if (data.boxModels) { if (typeof data.boxModels === 'string') { data.boxModels = JSON.parse(data.boxModels); } } if (data.videos) { if (typeof data.videos === 'string') { data.videos = JSON.parse(data.videos); } } if (data.version) { this.version = data.version; this.imageVersion = data.imgVersion || 0; this.linkVersion = data.linkVersion || 0; } if (data.sns == void 0) { data.sns = {}; if (data.sns.share == void 0) { data.sns.share = {}; data.sns.share = { __init__: true, title: data.title, keywords: '', description: data.description, image: data.entry ? 'thumb-1k.jpg' : null }; } } logger$1.timeEnd("".concat(this.$app.config.num, "[load metadata]").concat(this.$app.uid)); this.$app.store.set('metadata', data); return _context2.abrupt("return", data); case 41: case "end": return _context2.stop(); } } }, _callee2, this); })); function metadata() { return _metadata.apply(this, arguments); } return metadata; }() /** * 加载漫游点 */ }, { key: "visions", value: function () { var _visions = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3() { var _this = this; var data, metadata, decompress; return regenerator.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: logger$1.time("".concat(this.$app.config.num, "[load visions]").concat(this.$app.uid)); _context3.next = 3; return http.getBueffer(this.getResourceURL("scene_view_data/{num}/images/vision.modeldata?_=".concat(this.version))); case 3: data = _context3.sent; _context3.next = 6; return this.$app.store.get('metadata'); case 6: metadata = _context3.sent; logger$1.timeEnd("".concat(this.$app.config.num, "[load visions]").concat(this.$app.uid)); decompress = function decompress(buffer) { logger$1.time("".concat(_this.$app.config.num, "[parse modeldata]").concat(_this.$app.uid)); var sweepLocations = Deompress.decompressModeldata(buffer); if (metadata.dataSync == 'ajk') { //同步漫游点数据(安居客需要) _this.$app.DataSYNC.use('DataAJK', { sweepLocations: sweepLocations }); } var modeldata = Process.visionModeldata(sweepLocations); logger$1.timeEnd("".concat(_this.$app.config.num, "[parse modeldata]").concat(_this.$app.uid)); // todo //将vision.modeldata数据进行处理,生成Panorama对象数组,以及设置邻居点, metadata用于检测球幕视频 _this.$app.core.get('Player').model.panos = Process.panos(_this.$app, modeldata, metadata); _this.$app.core.get('Player').model.dispatchEvent({ type: 'gotPanos' }); }; decompress(data); case 10: case "end": return _context3.stop(); } } }, _callee3, this); })); function visions() { return _visions.apply(this, arguments); } return visions; }() /** * 加载辅助点位 */ }, { key: "visions2", value: function () { var _visions2 = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee4() { var _this2 = this; var model, data, decompress; return regenerator.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: model = this.$app.core.get('Player').model; logger$1.time("".concat(this.$app.config.num, "[load visions2]").concat(this.$app.uid)); _context4.next = 4; return http.getBueffer(this.getResourceURL("scene_view_data/{num}/images/vision2.modeldata?_=".concat(this.version))); case 4: data = _context4.sent; logger$1.timeEnd("".concat(this.$app.config.num, "[load visions2]").concat(this.$app.uid)); decompress = function decompress(buffer) { logger$1.time("".concat(_this2.$app.config.num, "[parse modeldata2]").concat(_this2.$app.uid)); var sweepLocations = Deompress.decompressModeldata(buffer); var modeldata = Process.visionModeldata(sweepLocations); logger$1.timeEnd("".concat(_this2.$app.config.num, "[parse modeldata2]").concat(_this2.$app.uid)); var panos = Process.panosAssist(modeldata, _this2.$app); panos.forEach(function (pano) { model.panos.index[pano.id - 1].assistPano = pano; }); }; decompress(data); case 8: case "end": return _context4.stop(); } } }, _callee4, this); })); function visions2() { return _visions2.apply(this, arguments); } return visions2; }() /** * 加载模型 */ }, { key: "modelmesh3dTiles", value: function () { var _modelmesh3dTiles = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee5() { var _this3 = this; var player, sceneRenderer, result, runtime; return regenerator.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: logger$1.time("".concat(this.$app.config.num, "[load modelmesh]").concat(this.$app.uid)); player = this.$app.core.get('Player'); sceneRenderer = this.$app.core.get('SceneRenderer'); _context5.next = 5; return Loader3DTiles.load({ // url: texture.getImageURL('images/3dtiles/tileset.json'), // url: texture.getImageURL('images/3dtiles_tianranqi/tileset.json'), // url: 'https://4dkk.4dage.com/scene_view_data/SS-Ds19qsmuFA/images/3dtiles/tileset.json', // url: 'https://testgis.4dage.com/LVBADUI_qp/tileset.json', url: this.getResourceURL("scene_view_data/{num}/images/3dtiles/tileset.json?_=".concat(Date.now())), renderer: sceneRenderer.renderer, options: { dracoDecoderPath: texture.getImageURL('images/loaders/DRACOLoader/draco'), basisTranscoderPath: texture.getImageURL('images/loaders/KTX2Loader/basis'), maximumScreenSpaceError: browser$1.isMobile() ? 16 / 3 : 16, // 和geometryError的计算有关,值越小,瓦片细化所需距离越远 maxConcurrency: 2, isLowestDepth: true, // 限制为最低精度 // debug: true, // 显示tiles的boundingVolume线框 // updateInterval: 0.01, // update的频率(ms) ingoreVisibleCompute: true, // 禁用屏幕外瓦片计算,防止初始画面没有模型时不加载tiles maximumMemoryUsage: browser$1.detectIOS() ? 0.1 : 32, // 最大tiles缓存,默认32(ios防崩) imageVersion: this.imageVersion, // 用于更新瓦片模型的version type: '4dkk' // 用于兼容专属逻辑 }, model: player.model }); case 5: result = _context5.sent; runtime = result.runtime; player.model._3dTilesRuntime = runtime; sceneRenderer.autoUpdate3dTiles = true; // // 3dtiles调试面板 // // ---------------- stats-widget ------------------- // const statsParent = document.createElement('div') // statsParent.id = 'stats-widget' // statsParent.style.position = 'absolute' // statsParent.style.top = '20px' // statsParent.style.left = '100px' // statsParent.style.backgroundColor = 'rgb(255 255 255 / 83%)' // statsParent.style.padding = '10px' // statsParent.style.width = '300px' // statsParent.style.wordBreak = 'break-all' // statsParent.style.zIndex = '9999' // statsParent.style.fontSize = '18px' // document.querySelector('body').appendChild(statsParent) // player.model._3dTilesRuntime.stats = new StatsWidget(runtime.getStats(), { container: statsParent }) // // ------------------------------------------------- // 当瓦片都加载完时,继续加载其他场景数据 runtime.getTileset().on('endTileLoading', function (data) { if (data.loadingCount == 0 && !player.model.mesh3dTilesLoaded) { player.model.mesh3dTilesLoaded = true; player.model.floors.sort(); if (browser$1.detectIOS()) { // ios要计算模型体积,当体积过大时,不会加载最精细一层 var modelBox = new THREE.Box3(); player.model.floors.forEach(function (floor) { return modelBox.union(floor.boundingBox); }); player.model._3dTilesRuntime.setModelSize(modelBox.getSize(new THREE.Vector3())); } _this3.$app.Scene.emit('3dTilesLoaded'); player.model._3dTilesRuntime.pauseTilesetUpdate(false); // 先update一次 player.model._3dTilesRuntime.pauseTilesetUpdate(true); logger$1.timeEnd("".concat(_this3.$app.config.num, "[load modelmesh]").concat(_this3.$app.uid)); } }); case 10: case "end": return _context5.stop(); } } }, _callee5, this); })); function modelmesh3dTiles() { return _modelmesh3dTiles.apply(this, arguments); } return modelmesh3dTiles; }() }, { key: "modelmeshDam", value: function () { var _modelmeshDam = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee6() { var _this4 = this; var dam, data, addToModel, decompress; return regenerator.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: addToModel = function _addToModel(chunks, player) { if (0 === chunks.length) { logger$1.warn('No geometry found for model, loading faux geometry, disabling outside mode'); player.model.supportedModes[Viewmode$1.DOLLHOUSE] = !1; player.model.supportedModes[Viewmode$1.FLOORPLAN] = !1; var chunk = new Chunk({ geometry: new THREE.PlaneBufferGeometry(5, 5, 1, 1) }); chunk.material.visible = !1; chunk.rotateX(-Math.PI / 2); chunk.geometry.computeBoundingBox(); chunks = [chunk]; } chunks.forEach(function (mesh) { var floorIndex = 0; if (player.model.floorsEnabled) { floorIndex = Chunks.parseFloor(mesh.name); } player.model.addChunk(floorIndex, mesh); }); player.model.floors.sort(); //deferred.resolve(player.model); }; dam = settings$3.job + settings$3.format; //dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam if (this.$app.config.model.name) { dam = this.$app.config.model.name; } logger$1.time("".concat(this.$app.config.num, "[load modelmesh]").concat(this.$app.uid)); _context6.next = 6; return http.getBueffer(this.getResourceURL("scene_view_data/{num}/images/".concat(dam, "?_=").concat(this.imageVersion))); case 6: data = _context6.sent; logger$1.timeEnd("".concat(this.$app.config.num, "[load modelmesh]").concat(this.$app.uid)); decompress = function decompress(buffer) { logger$1.time("".concat(_this4.$app.config.num, "[parse dam]").concat(_this4.$app.uid)); var meshdata = Deompress.decompressMesh(buffer); var chunks = Process.convertProtobufToSceneObject(_this4.$app, meshdata); logger$1.timeEnd("".concat(_this4.$app.config.num, "[parse dam]").concat(_this4.$app.uid)); addToModel(chunks, _this4.$app.core.get('Player')); }; decompress(data); case 10: case "end": return _context6.stop(); } } }, _callee6, this); })); function modelmeshDam() { return _modelmeshDam.apply(this, arguments); } return modelmeshDam; }() }, { key: "textures", value: function () { var _textures = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee7() { return regenerator.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: logger$1.time("".concat(this.$app.config.num, "[load textures]").concat(this.$app.uid)); _context7.next = 3; return ModelTextureLoader.load(this.$app.core.get('Player').model, this.$app.core.get('Player').model.meshTextures, this); case 3: logger$1.timeEnd("".concat(this.$app.config.num, "[load textures]").concat(this.$app.uid)); this.$app.core.get('Player').model.meshTexturesLoaded = !0; case 5: case "end": return _context7.stop(); } } }, _callee7, this); })); function textures() { return _textures.apply(this, arguments); } return textures; }() /** * 原始算法楼层数据(数据同步使用) * @returns */ }, { key: "floor", value: function () { var _floor = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee8() { var data; return regenerator.wrap(function _callee8$(_context8) { while (1) { switch (_context8.prev = _context8.next) { case 0: data = null; _context8.prev = 1; logger$1.time("".concat(this.$app.config.num, "[load floor]").concat(this.$app.uid)); _context8.next = 5; return http.get(this.getResourceURL("scene_view_data/{num}/data/floor.json?_=".concat(this.time))); case 5: data = _context8.sent; logger$1.timeEnd("".concat(this.$app.config.num, "[load floor]").concat(this.$app.uid)); _context8.next = 12; break; case 9: _context8.prev = 9; _context8.t0 = _context8["catch"](1); logger$1.warn('loaded [floor] error'); case 12: return _context8.abrupt("return", data); case 13: case "end": return _context8.stop(); } } }, _callee8, this, [[1, 9]]); })); function floor() { return _floor.apply(this, arguments); } return floor; }() }, { key: "floorcad", value: function () { var _floorcad = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee9() { var data; return regenerator.wrap(function _callee9$(_context9) { while (1) { switch (_context9.prev = _context9.next) { case 0: data = null; _context9.prev = 1; logger$1.time("".concat(this.$app.config.num, "[load floorcad]").concat(this.$app.uid)); _context9.next = 5; return http.get(this.getResourceURL("scene_view_data/{num}/data/floorplan_cad.json?_=".concat(this.time))); case 5: data = _context9.sent; if (!data.floors) { data = compatiblev2(data); } if (data && data.floors) { data.floors = data.floors.filter(function (floor) { return floor.segment && floor.segment.length > 0; }); } logger$1.timeEnd("".concat(this.$app.config.num, "[load floorcad]").concat(this.$app.uid)); _context9.next = 14; break; case 11: _context9.prev = 11; _context9.t0 = _context9["catch"](1); logger$1.warn('loaded [floorcad] error'); case 14: this.$app.store.set('floorcad', data); return _context9.abrupt("return", data); case 16: case "end": return _context9.stop(); } } }, _callee9, this, [[1, 11]]); })); function floorcad() { return _floorcad.apply(this, arguments); } return floorcad; }() }, { key: "flooruser", value: function () { var _flooruser = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee10() { var data, meta; return regenerator.wrap(function _callee10$(_context10) { while (1) { switch (_context10.prev = _context10.next) { case 0: data = null; meta = this.$app.store.getValue('metadata'); _context10.prev = 2; logger$1.time("".concat(this.$app.config.num, "[load flooruser]").concat(this.$app.uid)); if (!meta.floorPlanUser) { _context10.next = 10; break; } _context10.next = 7; return http.get(this.getUserResourceURL("floorplan.json", this.reload)); case 7: data = _context10.sent; _context10.next = 13; break; case 10: _context10.next = 12; return http.get(this.getViewDataURL("floorplan.json")); case 12: data = _context10.sent; case 13: logger$1.timeEnd("".concat(this.$app.config.num, "[load flooruser]").concat(this.$app.uid)); _context10.next = 30; break; case 16: _context10.prev = 16; _context10.t0 = _context10["catch"](2); logger$1.warn('loaded [flooruser] error'); if (!meta.floorPlanUser) { _context10.next = 29; break; } _context10.prev = 20; _context10.next = 23; return http.get(this.getViewDataURL("floorplan.json")); case 23: data = _context10.sent; _context10.next = 29; break; case 26: _context10.prev = 26; _context10.t1 = _context10["catch"](20); logger$1.warn('loaded [flooruser] error'); case 29: if (!data) { data = { unit: 'm', floors: [{ walls: { Wall7: { important: false, geoType: 'Wall', children: [], start: 'Point3', vectorId: 'Wall7', width: 0.2, end: 'Point0', out: false }, Wall6: { important: false, geoType: 'Wall', children: [], start: 'Point2', vectorId: 'Wall6', width: 0.2, end: 'Point3', out: false }, Wall5: { important: false, geoType: 'Wall', children: [], start: 'Point1', vectorId: 'Wall5', width: 0.2, end: 'Point2', out: false }, Wall4: { important: false, geoType: 'Wall', children: [], start: 'Point0', vectorId: 'Wall4', width: 0.2, end: 'Point1', out: false } }, subgroup: 0, name: '1楼', id: 0, points: { Point1: { parent: { Wall5: 'start', Wall4: 'end' }, geoType: 'Point', vectorId: 'Point1', x: 5.531, y: 5.777 }, Point0: { parent: { Wall7: 'end', Wall4: 'start' }, geoType: 'Point', vectorId: 'Point0', x: 5.531, y: -6.046 }, Point3: { parent: { Wall7: 'start', Wall6: 'end' }, geoType: 'Point', vectorId: 'Point3', x: -2.663, y: -6.046 }, Point2: { parent: { Wall6: 'start', Wall5: 'end' }, geoType: 'Point', vectorId: 'Point2', x: -2.663, y: 5.777 } } }], currentId: 8, angle: 0, type: 'cad', version: 'v4.0' }; } case 30: this.$app.store.set('flooruser', data); return _context10.abrupt("return", data); case 32: case "end": return _context10.stop(); } } }, _callee10, this, [[2, 16], [20, 26]]); })); function flooruser() { return _flooruser.apply(this, arguments); } return flooruser; }() }, { key: "billboards", value: function () { var _billboards = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee11() { var _metadata2, data; return regenerator.wrap(function _callee11$(_context11) { while (1) { switch (_context11.prev = _context11.next) { case 0: _context11.prev = 0; _context11.next = 3; return this.$app.store.get('metadata'); case 3: _metadata2 = _context11.sent; data = null; if (!(this.mode === 'view')) { _context11.next = 14; break; } if (_metadata2.billboards) { _context11.next = 8; break; } return _context11.abrupt("return"); case 8: _context11.next = 10; return http.get(this.getUserResourceURL("billboards.json")); case 10: data = _context11.sent; this.$app.store.set('billboards', data); _context11.next = 18; break; case 14: _context11.next = 16; return this.$app.remote_editor.billboards_list({ num: this.num }); case 16: data = _context11.sent; this.$app.store.set('billboards', data.data); case 18: _context11.next = 23; break; case 20: _context11.prev = 20; _context11.t0 = _context11["catch"](0); logger$1.error('loaded [billboards] error', _context11.t0); case 23: case "end": return _context11.stop(); } } }, _callee11, this, [[0, 20]]); })); function billboards() { return _billboards.apply(this, arguments); } return billboards; }() }, { key: "cutModel", value: function () { var _cutModel = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee12() { var _metadata3, data; return regenerator.wrap(function _callee12$(_context12) { while (1) { switch (_context12.prev = _context12.next) { case 0: _context12.prev = 0; _context12.next = 3; return this.$app.store.get('metadata'); case 3: _metadata3 = _context12.sent; data = null; if (_metadata3.cutModel) { _context12.next = 7; break; } return _context12.abrupt("return"); case 7: if (!(this.mode === 'view')) { _context12.next = 14; break; } _context12.next = 10; return http.get(this.getUserResourceURL("cutModel.json")); case 10: data = _context12.sent; this.$app.store.set('cutModel', data); _context12.next = 18; break; case 14: _context12.next = 16; return this.$app.remote_editor.cutModel_list({ num: this.num }); case 16: data = _context12.sent; this.$app.store.set('cutModel', data.data); case 18: _context12.next = 23; break; case 20: _context12.prev = 20; _context12.t0 = _context12["catch"](0); logger$1.error('loaded [cutModel] error', _context12.t0); case 23: case "end": return _context12.stop(); } } }, _callee12, this, [[0, 20]]); })); function cutModel() { return _cutModel.apply(this, arguments); } return cutModel; }() }, { key: "tags", value: function () { var _tags = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee13(tagsURL) { var _this5 = this; var response, _metadata4; return regenerator.wrap(function _callee13$(_context13) { while (1) { switch (_context13.prev = _context13.next) { case 0: if (!(!this.$app.config.isLoadTags && !tagsURL)) { _context13.next = 2; break; } return _context13.abrupt("return"); case 2: response = { data: { icons: [], tags: [] } }; _context13.prev = 3; _context13.next = 6; return this.$app.store.get('metadata'); case 6: _metadata4 = _context13.sent; // if (metadata.tags) { logger$1.time("".concat(this.num, "[load tags]").concat(this.$app.uid)); if (!(this.mode == 'view')) { _context13.next = 24; break; } if (_metadata4.tags) { _context13.next = 11; break; } return _context13.abrupt("return"); case 11: response.success = true; if (!tagsURL) { _context13.next = 18; break; } _context13.next = 15; return http.get(tagsURL); case 15: _context13.t0 = _context13.sent; _context13.next = 21; break; case 18: _context13.next = 20; return http.get(this.getUserResourceURL("hot.json")); case 20: _context13.t0 = _context13.sent; case 21: response.data.tags = _context13.t0; _context13.next = 27; break; case 24: _context13.next = 26; return this.$app.remote_editor.tag_list({ num: this.num }); case 26: response = _context13.sent; case 27: if (response.success && response.data && response.data.tags) { response.data.tags.map(function (tag) { if (tag.position) { tag.position = new THREE.Vector3(tag.position.x, tag.position.y, tag.position.z); // visiblePanos不知为何在obj场景里会有重复id,保险起见初始化统一去重 tag.visiblePanos ? tag.visiblePanos = Array.from(new Set(tag.visiblePanos)).map(function (id) { return _this5.$app.core.get('Player').model.panos.index[id]; }) : tag.visiblePanos = _this5.$app.TagManager.getVisiblePano(tag.position, { maxDis: 5 }); } return tag; }); } logger$1.timeEnd("".concat(this.num, "[load tags]").concat(this.$app.uid)); // } _context13.next = 34; break; case 31: _context13.prev = 31; _context13.t1 = _context13["catch"](3); logger$1.error('loaded [tags] error', _context13.t1); case 34: this.$app.store.set('tags', response.data); return _context13.abrupt("return", response.data); case 36: case "end": return _context13.stop(); } } }, _callee13, this, [[3, 31]]); })); function tags(_x) { return _tags.apply(this, arguments); } return tags; }() }, { key: "tours", value: function () { var _tours = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee14() { var data, _metadata5; return regenerator.wrap(function _callee14$(_context14) { while (1) { switch (_context14.prev = _context14.next) { case 0: data = []; _context14.prev = 1; _context14.next = 4; return this.$app.store.get('metadata'); case 4: _metadata5 = _context14.sent; if (!_metadata5.tours) { _context14.next = 9; break; } _context14.next = 8; return http.get(this.getUserResourceURL("tour.json")); case 8: data = _context14.sent; case 9: _context14.next = 14; break; case 11: _context14.prev = 11; _context14.t0 = _context14["catch"](1); logger$1.error('loaded [tour] error', _context14.t0); case 14: this.$app.store.set('tours', data); return _context14.abrupt("return", data); case 16: case "end": return _context14.stop(); } } }, _callee14, this, [[1, 11]]); })); function tours() { return _tours.apply(this, arguments); } return tours; }() }, { key: "links", value: function () { var _links = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee15() { var _this6 = this; var _metadata6, data; return regenerator.wrap(function _callee15$(_context15) { while (1) { switch (_context15.prev = _context15.next) { case 0: _context15.prev = 0; _context15.next = 3; return this.$app.store.get('metadata'); case 3: _metadata6 = _context15.sent; data = null; if (!(this.mode === 'view')) { _context15.next = 15; break; } if (_metadata6.links) { _context15.next = 8; break; } return _context15.abrupt("return"); case 8: _context15.next = 10; return http.get(this.getUserResourceURL("links.json")); case 10: data = _context15.sent; data = data.filter(function (tag) { return _this6.$app.core.get('Player').model.panos.get(tag.nearestPano); }); // 过滤掉无效Pano this.$app.store.set('links', data); _context15.next = 20; break; case 15: _context15.next = 17; return this.$app.remote_editor.linkPan_list({ num: this.num }); case 17: data = _context15.sent; data.data.tags = data.data.tags.filter(function (tag) { return _this6.$app.core.get('Player').model.panos.get(tag.nearestPano); }); // 过滤掉无效Pano this.$app.store.set('links', data.data); case 20: _context15.next = 25; break; case 22: _context15.prev = 22; _context15.t0 = _context15["catch"](0); logger$1.error('loaded [tour] error', _context15.t0); case 25: case "end": return _context15.stop(); } } }, _callee15, this, [[0, 22]]); })); function links() { return _links.apply(this, arguments); } return links; }() }, { key: "cameras", value: function () { var _cameras = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee16() { var _metadata7, data; return regenerator.wrap(function _callee16$(_context16) { while (1) { switch (_context16.prev = _context16.next) { case 0: _context16.prev = 0; _context16.next = 3; return this.$app.store.get('metadata'); case 3: _metadata7 = _context16.sent; if (_metadata7.surveillances) { _context16.next = 6; break; } return _context16.abrupt("return"); case 6: data = null; if (!(this.mode === 'view')) { _context16.next = 14; break; } _context16.next = 10; return http.get(this.getUserResourceURL("surveillance.json")); case 10: data = _context16.sent; this.$app.store.set('cameras', data); _context16.next = 18; break; case 14: _context16.next = 16; return this.$app.remote_editor.surveillance_list({ num: this.num }); case 16: data = _context16.sent; this.$app.store.set('cameras', data.data); case 18: _context16.next = 23; break; case 20: _context16.prev = 20; _context16.t0 = _context16["catch"](0); logger$1.error('loaded [cameras] error', _context16.t0); case 23: case "end": return _context16.stop(); } } }, _callee16, this, [[0, 20]]); })); function cameras() { return _cameras.apply(this, arguments); } return cameras; }() }, { key: "sceneDraw", value: function () { var _sceneDraw = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee17() { var _metadata8, data; return regenerator.wrap(function _callee17$(_context17) { while (1) { switch (_context17.prev = _context17.next) { case 0: _context17.prev = 0; _context17.next = 3; return this.$app.store.get('metadata'); case 3: _metadata8 = _context17.sent; if (_metadata8.sceneDraw) { _context17.next = 6; break; } return _context17.abrupt("return"); case 6: data = null; if (!(this.mode === 'view')) { _context17.next = 14; break; } _context17.next = 10; return http.get(this.getUserResourceURL("sceneDraw.json")); case 10: data = _context17.sent; this.$app.store.set('sceneDraw', data); _context17.next = 18; break; case 14: _context17.next = 16; return this.$app.remote_editor.sceneDraw_list({ num: this.num }); case 16: data = _context17.sent; this.$app.store.set('sceneDraw', data.data); case 18: _context17.next = 23; break; case 20: _context17.prev = 20; _context17.t0 = _context17["catch"](0); logger$1.error('loaded [sceneDraw] error', _context17.t0); case 23: case "end": return _context17.stop(); } } }, _callee17, this, [[0, 20]]); })); function sceneDraw() { return _sceneDraw.apply(this, arguments); } return sceneDraw; }() }, { key: "mosaics", value: function () { var _mosaics = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee18() { var _metadata9, data; return regenerator.wrap(function _callee18$(_context18) { while (1) { switch (_context18.prev = _context18.next) { case 0: _context18.prev = 0; _context18.next = 3; return this.$app.store.get('metadata'); case 3: _metadata9 = _context18.sent; if (_metadata9.mosaic) { _context18.next = 6; break; } return _context18.abrupt("return"); case 6: data = null; if (!(this.mode === 'view')) { _context18.next = 14; break; } _context18.next = 10; return http.get(this.getUserResourceURL("mosaic.json")); case 10: data = _context18.sent; this.$app.store.set('mosaics', data); _context18.next = 18; break; case 14: _context18.next = 16; return this.$app.remote_editor.mosaics_list({ num: this.num }); case 16: data = _context18.sent; this.$app.store.set('mosaics', data.data); case 18: _context18.next = 23; break; case 20: _context18.prev = 20; _context18.t0 = _context18["catch"](0); logger$1.error('loaded [tour] error', _context18.t0); case 23: case "end": return _context18.stop(); } } }, _callee18, this, [[0, 20]]); })); function mosaics() { return _mosaics.apply(this, arguments); } return mosaics; }() }, { key: "filters", value: function () { var _filters = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee19() { var _metadata10, data; return regenerator.wrap(function _callee19$(_context19) { while (1) { switch (_context19.prev = _context19.next) { case 0: _context19.prev = 0; _context19.next = 3; return this.$app.store.get('metadata'); case 3: _metadata10 = _context19.sent; if (_metadata10.filters) { _context19.next = 6; break; } return _context19.abrupt("return"); case 6: data = null; if (!(this.mode === 'view')) { _context19.next = 14; break; } _context19.next = 10; return http.get(this.getUserResourceURL("filter.json")); case 10: data = _context19.sent; this.$app.store.set('filters', data); _context19.next = 18; break; case 14: _context19.next = 16; return this.$app.remote_editor.filter_list({ num: this.num }); case 16: data = _context19.sent; this.$app.store.set('filters', data.data); case 18: _context19.next = 23; break; case 20: _context19.prev = 20; _context19.t0 = _context19["catch"](0); logger$1.error('loaded [tour] error', _context19.t0); case 23: case "end": return _context19.stop(); } } }, _callee19, this, [[0, 20]]); })); function filters() { return _filters.apply(this, arguments); } return filters; }() /** * 获取场景相关的资源图片 * @param {*} path * @returns */ }, { key: "getImage", value: function () { var _getImage = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee20(path) { var data; return regenerator.wrap(function _callee20$(_context20) { while (1) { switch (_context20.prev = _context20.next) { case 0: _context20.next = 2; return http.getImage("".concat(this.$app.config.resource).concat(path)); case 2: data = _context20.sent; this.$app.store.set(path, data); return _context20.abrupt("return", data); case 5: case "end": return _context20.stop(); } } }, _callee20, this); })); function getImage(_x2) { return _getImage.apply(this, arguments); } return getImage; }() }, { key: "getUserImage", value: function () { var _getUserImage = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee21(path) { var data; return regenerator.wrap(function _callee21$(_context21) { while (1) { switch (_context21.prev = _context21.next) { case 0: data = http.getImage(this.getUserResourceURL(path)); this.$app.store.set(path, data); return _context21.abrupt("return", data); case 3: case "end": return _context21.stop(); } } }, _callee21, this); })); function getUserImage(_x3) { return _getUserImage.apply(this, arguments); } return getUserImage; }() /** * 获取SDK相关的资源图片 * @param {*} path * @returns */ }, { key: "getAppImage", value: function () { var _getAppImage = _asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee22(path) { var data; return regenerator.wrap(function _callee22$(_context22) { while (1) { switch (_context22.prev = _context22.next) { case 0: _context22.next = 2; return http.getImage(this.base(path)); case 2: data = _context22.sent; this.$app.store.set(path, data); return _context22.abrupt("return", data); case 5: case "end": return _context22.stop(); } } }, _callee22, this); })); function getAppImage(_x4) { return _getAppImage.apply(this, arguments); } return getAppImage; }() }, { key: "getAppURL", value: function getAppURL(url) { return this.base(url); } /** * 获取服务器资源 */ }, { key: "getServerURL", value: function getServerURL(url) { return this.$app.config.server + url; } /** * 获取场景资源地址 * @param {*} url * @returns */ }, { key: "getResourceURL", value: function getResourceURL(url) { return this.$app.config.resource + url.replace(/\{num\}/g, this.num); } /** * 获取用户资源地址 * @param {*} url * @returns */ }, { key: "getUserResourceURL", value: function getUserResourceURL(url, clearCache, now) { if (!url || !url.trim()) { return url; } if (url.indexOf('data:image') === 0 || url.indexOf('blob:') === 0 || url.indexOf('http') === 0 || url.indexOf('file') === 0) { return url; } if (clearCache) { this.reload = true; } var full; if (url.indexOf('?t=') != -1) { full = this.$app.config.resource + "scene_".concat(this.mode, "_data/").concat(this.num, "/user/").concat(url); } else { if (now) { //防止热点icon第一次查看抖动问题 full = this.$app.config.resource + "scene_".concat(this.mode, "_data/").concat(this.num, "/user/").concat(url, "?_=").concat(this.nowTime); } else { full = this.$app.config.resource + "scene_".concat(this.mode, "_data/").concat(this.num, "/user/").concat(url, "?_=").concat(this.time); } var search = url.split('?')[1]; if (search) { full += '&' + search; } } return full; } /** * 获取用户空间模型资源地址 * @param {*} url * @returns */ }, { key: "getUserModelResourceURL", value: function getUserModelResourceURL(url, clearCache) { if (!url || !url.trim()) { return url; } if (url.indexOf('blob:') === 0 || url.indexOf('http') === 0 || url.indexOf('file') === 0) { return url; } if (clearCache) { this.reload = true; } return this.$app.config.resource + "scene_".concat(this.mode, "_data/").concat(this.num, "/user/boxModels/").concat(url, "?_=").concat(this.time); } /** * 获取导览视频上传oss地址 * @param {*} url * @returns */ }, { key: "getTourVideoURL", value: function getTourVideoURL(url, clearCache) { if (clearCache) { this.reload = true; } return this.$app.config.resource + "".concat(url, "?_=").concat(this.time); } /** * 获取展示资源地址 * @param {*} url * @returns */ }, { key: "getViewResourceURL", value: function getViewResourceURL(url) { return this.$app.config.resource + "scene_view_data/".concat(this.num, "/").concat(url); } /** * 获取展示数据地址 * @param {*} url * @returns */ }, { key: "getViewDataURL", value: function getViewDataURL(url) { return this.$app.config.resource + "scene_view_data/".concat(this.num, "/data/").concat(url, "?_=").concat(this.version); } /** * 获取编辑数据地址 * @param {*} url * @returns */ }, { key: "getEditDataURL", value: function getEditDataURL(url) { return this.$app.config.resource + "scene_edit_data/".concat(this.num, "/data/").concat(url, "?_=").concat(this.version); } /** * 获取展示全景图地址 * @param {*} url * @returns */ }, { key: "getViewImagesURL", value: function getViewImagesURL(url) { if (url.indexOf('&_=') !== -1) { return url; } var version = url.indexOf('/panorama/') !== -1 ? this.linkVersion : this.imageVersion; if (url.indexOf('?') !== -1) { return this.$app.config.resource + "scene_view_data/".concat(this.num, "/images/").concat(url, "&_=").concat(version); } return this.$app.config.resource + "scene_view_data/".concat(this.num, "/images/").concat(url, "?_=").concat(version); } /** * 获取编辑页全景图地址 * @param {*} url * @returns */ }, { key: "getUserImagesURL", value: function getUserImagesURL(url) { var str; if (this.mode == 'view') { str = 'scene_view_data'; } else { str = 'scene_edit_data'; } if (url.indexOf('&_=') !== -1) { return url; } else if (url.indexOf('?') !== -1) { return this.$app.config.resource + "".concat(str, "/").concat(this.num, "/images/").concat(url, "&_=").concat(this.version); } return this.$app.config.resource + "".concat(str, "/").concat(this.num, "/images/").concat(url, "?_=").concat(this.version); } }]); return Resource; }(); }); /** * Make a map and return a function for checking if a key * is in that map. * IMPORTANT: all calls of this function must be prefixed with * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ function makeMap(str, expectsLowerCase) { var map = Object.create(null); var list = str.split(','); for (var i = 0; i < list.length; i++) { map[list[i]] = true; } return expectsLowerCase ? function (val) { return !!map[val.toLowerCase()]; } : function (val) { return !!map[val]; }; } Object.freeze({}) ; Object.freeze([]) ; var extend = Object.assign; var hasOwnProperty = Object.prototype.hasOwnProperty; var hasOwn = function hasOwn(val, key) { return hasOwnProperty.call(val, key); }; var isArray$1 = Array.isArray; var isMap = function isMap(val) { return toTypeString(val) === '[object Map]'; }; var isString$1 = function isString(val) { return typeof val === 'string'; }; var isSymbol = function isSymbol(val) { return typeof val === 'symbol'; }; var isObject$1 = function isObject(val) { return val !== null && typeof val === 'object'; }; var objectToString = Object.prototype.toString; var toTypeString = function toTypeString(value) { return objectToString.call(value); }; var toRawType = function toRawType(value) { // extract "RawType" from strings like "[object RawType]" return toTypeString(value).slice(8, -1); }; var isIntegerKey = function isIntegerKey(key) { return isString$1(key) && key !== 'NaN' && key[0] !== '-' && '' + parseInt(key, 10) === key; }; var cacheStringFunction$1 = function cacheStringFunction(fn) { var cache = Object.create(null); return function (str) { var hit = cache[str]; return hit || (cache[str] = fn(str)); }; }; /** * @private */ var capitalize = cacheStringFunction$1(function (str) { return str.charAt(0).toUpperCase() + str.slice(1); }); var hasChanged = function hasChanged(value, oldValue) { return !Object.is(value, oldValue); }; function _createForOfIteratorHelper$2(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$2(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$2(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$2(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$2(o, minLen); } function _arrayLikeToArray$2(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } var activeEffectScope; function recordEffectScope(effect) { var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : activeEffectScope; if (scope && scope.active) { scope.effects.push(effect); } } var createDep = function createDep(effects) { var dep = new Set(effects); dep.w = 0; dep.n = 0; return dep; }; var wasTracked = function wasTracked(dep) { return (dep.w & trackOpBit) > 0; }; var newTracked = function newTracked(dep) { return (dep.n & trackOpBit) > 0; }; var initDepMarkers = function initDepMarkers(_ref) { var deps = _ref.deps; if (deps.length) { for (var i = 0; i < deps.length; i++) { deps[i].w |= trackOpBit; // set was tracked } } }; var finalizeDepMarkers = function finalizeDepMarkers(effect) { var deps = effect.deps; if (deps.length) { var ptr = 0; for (var i = 0; i < deps.length; i++) { var dep = deps[i]; if (wasTracked(dep) && !newTracked(dep)) { dep.delete(effect); } else { deps[ptr++] = dep; } // clear bits dep.w &= ~trackOpBit; dep.n &= ~trackOpBit; } deps.length = ptr; } }; var targetMap = new WeakMap(); // The number of effects currently being tracked recursively. var effectTrackDepth = 0; var trackOpBit = 1; /** * The bitwise track markers support at most 30 levels of recursion. * This value is chosen to enable modern JS engines to use a SMI on all platforms. * When recursion depth is greater, fall back to using a full cleanup. */ var maxMarkerBits = 30; var activeEffect; var ITERATE_KEY = Symbol('iterate' ); var MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' ); var ReactiveEffect = /*#__PURE__*/function () { function ReactiveEffect(fn) { var scheduler = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var scope = arguments.length > 2 ? arguments[2] : undefined; _classCallCheck(this, ReactiveEffect); this.fn = fn; this.scheduler = scheduler; this.active = true; this.deps = []; this.parent = undefined; recordEffectScope(this, scope); } _createClass(ReactiveEffect, [{ key: "run", value: function run() { if (!this.active) { return this.fn(); } var parent = activeEffect; var lastShouldTrack = shouldTrack; while (parent) { if (parent === this) { return; } parent = parent.parent; } try { this.parent = activeEffect; activeEffect = this; shouldTrack = true; trackOpBit = 1 << ++effectTrackDepth; if (effectTrackDepth <= maxMarkerBits) { initDepMarkers(this); } else { cleanupEffect(this); } return this.fn(); } finally { if (effectTrackDepth <= maxMarkerBits) { finalizeDepMarkers(this); } trackOpBit = 1 << --effectTrackDepth; activeEffect = this.parent; shouldTrack = lastShouldTrack; this.parent = undefined; } } }, { key: "stop", value: function stop() { if (this.active) { cleanupEffect(this); if (this.onStop) { this.onStop(); } this.active = false; } } }]); return ReactiveEffect; }(); function cleanupEffect(effect) { var deps = effect.deps; if (deps.length) { for (var i = 0; i < deps.length; i++) { deps[i].delete(effect); } deps.length = 0; } } function effect$1(fn, options) { if (fn.effect) { fn = fn.effect.fn; } var _effect = new ReactiveEffect(fn); if (options) { extend(_effect, options); if (options.scope) recordEffectScope(_effect, options.scope); } if (!options || !options.lazy) { _effect.run(); } var runner = _effect.run.bind(_effect); runner.effect = _effect; return runner; } function stop(runner) { runner.effect.stop(); } var shouldTrack = true; var trackStack = []; function pauseTracking() { trackStack.push(shouldTrack); shouldTrack = false; } function resetTracking() { var last = trackStack.pop(); shouldTrack = last === undefined ? true : last; } function track(target, type, key) { if (shouldTrack && activeEffect) { var depsMap = targetMap.get(target); if (!depsMap) { targetMap.set(target, depsMap = new Map()); } var dep = depsMap.get(key); if (!dep) { depsMap.set(key, dep = createDep()); } var eventInfo = { effect: activeEffect, target, type, key } ; trackEffects(dep, eventInfo); } } function trackEffects(dep, debuggerEventExtraInfo) { var shouldTrack = false; if (effectTrackDepth <= maxMarkerBits) { if (!newTracked(dep)) { dep.n |= trackOpBit; // set newly tracked shouldTrack = !wasTracked(dep); } } else { // Full cleanup mode. shouldTrack = !dep.has(activeEffect); } if (shouldTrack) { dep.add(activeEffect); activeEffect.deps.push(dep); if (activeEffect.onTrack) { activeEffect.onTrack(Object.assign({ effect: activeEffect }, debuggerEventExtraInfo)); } } } function trigger$1(target, type, key, newValue, oldValue, oldTarget) { var depsMap = targetMap.get(target); if (!depsMap) { // never been tracked return; } var deps = []; if (type === "clear" /* CLEAR */ ) { // collection being cleared // trigger all effects for target deps = _toConsumableArray(depsMap.values()); } else if (key === 'length' && isArray$1(target)) { depsMap.forEach(function (dep, key) { if (key === 'length' || key >= newValue) { deps.push(dep); } }); } else { // schedule runs for SET | ADD | DELETE if (key !== void 0) { deps.push(depsMap.get(key)); } // also run for iteration key on ADD | DELETE | Map.SET switch (type) { case "add" /* ADD */ : if (!isArray$1(target)) { deps.push(depsMap.get(ITERATE_KEY)); if (isMap(target)) { deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); } } else if (isIntegerKey(key)) { // new index added to array -> length changes deps.push(depsMap.get('length')); } break; case "delete" /* DELETE */ : if (!isArray$1(target)) { deps.push(depsMap.get(ITERATE_KEY)); if (isMap(target)) { deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); } } break; case "set" /* SET */ : if (isMap(target)) { deps.push(depsMap.get(ITERATE_KEY)); } break; } } var eventInfo = { target, type, key, newValue, oldValue, oldTarget } ; if (deps.length === 1) { if (deps[0]) { { triggerEffects(deps[0], eventInfo); } } } else { var effects = []; var _iterator = _createForOfIteratorHelper$2(deps), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var dep = _step.value; if (dep) { effects.push.apply(effects, _toConsumableArray(dep)); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } { triggerEffects(createDep(effects), eventInfo); } } } function triggerEffects(dep, debuggerEventExtraInfo) { // spread into array for stabilization var _iterator2 = _createForOfIteratorHelper$2(isArray$1(dep) ? dep : _toConsumableArray(dep)), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var _effect2 = _step2.value; if (_effect2 !== activeEffect || _effect2.allowRecurse) { if ("development" !== 'production' && _effect2.onTrigger) { _effect2.onTrigger(extend({ effect: _effect2 }, debuggerEventExtraInfo)); } if (_effect2.scheduler) { _effect2.scheduler(); } else { _effect2.run(); } } } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } } var isNonTrackableKeys = /*#__PURE__*/makeMap("__proto__,__v_isRef,__isVue"); var builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol).map(function (key) { return Symbol[key]; }).filter(isSymbol)); var get = /*#__PURE__*/createGetter(); var readonlyGet = /*#__PURE__*/createGetter(true); var arrayInstrumentations = /*#__PURE__*/createArrayInstrumentations(); function createArrayInstrumentations() { var instrumentations = {}; ['includes', 'indexOf', 'lastIndexOf'].forEach(function (key) { instrumentations[key] = function () { var arr = toRaw(this); for (var i = 0, l = this.length; i < l; i++) { track(arr, "get" /* GET */ , i + ''); } // we run the method using the original args first (which may be reactive) for (var _len2 = arguments.length, args = new Array(_len2), _key3 = 0; _key3 < _len2; _key3++) { args[_key3] = arguments[_key3]; } var res = arr[key].apply(arr, args); if (res === -1 || res === false) { // if that didn't work, run it again using raw values. return arr[key].apply(arr, _toConsumableArray(args.map(toRaw))); } else { return res; } }; }); ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(function (key) { instrumentations[key] = function () { pauseTracking(); for (var _len3 = arguments.length, args = new Array(_len3), _key4 = 0; _key4 < _len3; _key4++) { args[_key4] = arguments[_key4]; } var res = toRaw(this)[key].apply(this, args); resetTracking(); return res; }; }); return instrumentations; } function createGetter() { var isReadonly = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var shallow = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; return function get(target, key, receiver) { if (key === "__v_isReactive" /* IS_REACTIVE */ ) { return !isReadonly; } else if (key === "__v_isReadonly" /* IS_READONLY */ ) { return isReadonly; } else if (key === "__v_isShallow" /* IS_SHALLOW */ ) { return shallow; } else if (key === "__v_raw" /* RAW */ && receiver === (isReadonly ? shallow ? shallowReadonlyMap : readonlyMap : shallow ? shallowReactiveMap : reactiveMap).get(target)) { return target; } var targetIsArray = isArray$1(target); if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) { return Reflect.get(arrayInstrumentations, key, receiver); } var res = Reflect.get(target, key, receiver); if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { return res; } if (!isReadonly) { track(target, "get" /* GET */ , key); } if (shallow) { return res; } if (isRef(res)) { // ref unwrapping - does not apply for Array + integer key. var shouldUnwrap = !targetIsArray || !isIntegerKey(key); return shouldUnwrap ? res.value : res; } if (isObject$1(res)) { // Convert returned value into a proxy as well. we do the isObject check // here to avoid invalid value warning. Also need to lazy access readonly // and reactive here to avoid circular dependency. return isReadonly ? readonly(res) : reactive(res); } return res; }; } var set = /*#__PURE__*/createSetter(); function createSetter() { var shallow = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; return function set(target, key, value, receiver) { var oldValue = target[key]; if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) { return false; } if (!shallow && !isReadonly(value)) { if (!isShallow(value)) { value = toRaw(value); oldValue = toRaw(oldValue); } if (!isArray$1(target) && isRef(oldValue) && !isRef(value)) { oldValue.value = value; return true; } } var hadKey = isArray$1(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key); var result = Reflect.set(target, key, value, receiver); // don't trigger if target is something up in the prototype chain of original if (target === toRaw(receiver)) { if (!hadKey) { trigger$1(target, "add" /* ADD */ , key, value); } else if (hasChanged(value, oldValue)) { trigger$1(target, "set" /* SET */ , key, value, oldValue); } } return result; }; } function deleteProperty(target, key) { var hadKey = hasOwn(target, key); var oldValue = target[key]; var result = Reflect.deleteProperty(target, key); if (result && hadKey) { trigger$1(target, "delete" /* DELETE */ , key, undefined, oldValue); } return result; } function has(target, key) { var result = Reflect.has(target, key); if (!isSymbol(key) || !builtInSymbols.has(key)) { track(target, "has" /* HAS */ , key); } return result; } function ownKeys$3(target) { track(target, "iterate" /* ITERATE */ , isArray$1(target) ? 'length' : ITERATE_KEY); return Reflect.ownKeys(target); } var mutableHandlers = { get, set, deleteProperty, has, ownKeys: ownKeys$3 }; var readonlyHandlers = { get: readonlyGet, set(target, key) { { console.warn("Set operation on key \"".concat(String(key), "\" failed: target is readonly."), target); } return true; }, deleteProperty(target, key) { { console.warn("Delete operation on key \"".concat(String(key), "\" failed: target is readonly."), target); } return true; } }; var toShallow = function toShallow(value) { return value; }; var getProto = function getProto(v) { return Reflect.getPrototypeOf(v); }; function get$1(target, key) { var isReadonly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var isShallow = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // #1772: readonly(reactive(Map)) should return readonly + reactive version // of the value target = target["__v_raw" /* RAW */ ]; var rawTarget = toRaw(target); var rawKey = toRaw(key); if (key !== rawKey) { !isReadonly && track(rawTarget, "get" /* GET */ , key); } !isReadonly && track(rawTarget, "get" /* GET */ , rawKey); var _getProto = getProto(rawTarget), has = _getProto.has; var wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; if (has.call(rawTarget, key)) { return wrap(target.get(key)); } else if (has.call(rawTarget, rawKey)) { return wrap(target.get(rawKey)); } else if (target !== rawTarget) { // #3602 readonly(reactive(Map)) // ensure that the nested reactive `Map` can do tracking for itself target.get(key); } } function has$1(key) { var isReadonly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var target = this["__v_raw" /* RAW */ ]; var rawTarget = toRaw(target); var rawKey = toRaw(key); if (key !== rawKey) { !isReadonly && track(rawTarget, "has" /* HAS */ , key); } !isReadonly && track(rawTarget, "has" /* HAS */ , rawKey); return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); } function size$2(target) { var isReadonly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; target = target["__v_raw" /* RAW */ ]; !isReadonly && track(toRaw(target), "iterate" /* ITERATE */ , ITERATE_KEY); return Reflect.get(target, 'size', target); } function add(value) { value = toRaw(value); var target = toRaw(this); var proto = getProto(target); var hadKey = proto.has.call(target, value); if (!hadKey) { target.add(value); trigger$1(target, "add" /* ADD */ , value, value); } return this; } function set$1(key, value) { value = toRaw(value); var target = toRaw(this); var _getProto2 = getProto(target), has = _getProto2.has, get = _getProto2.get; var hadKey = has.call(target, key); if (!hadKey) { key = toRaw(key); hadKey = has.call(target, key); } else { checkIdentityKeys(target, has, key); } var oldValue = get.call(target, key); target.set(key, value); if (!hadKey) { trigger$1(target, "add" /* ADD */ , key, value); } else if (hasChanged(value, oldValue)) { trigger$1(target, "set" /* SET */ , key, value, oldValue); } return this; } function deleteEntry(key) { var target = toRaw(this); var _getProto3 = getProto(target), has = _getProto3.has, get = _getProto3.get; var hadKey = has.call(target, key); if (!hadKey) { key = toRaw(key); hadKey = has.call(target, key); } else { checkIdentityKeys(target, has, key); } var oldValue = get ? get.call(target, key) : undefined; // forward the operation before queueing reactions var result = target.delete(key); if (hadKey) { trigger$1(target, "delete" /* DELETE */ , key, undefined, oldValue); } return result; } function clear() { var target = toRaw(this); var hadItems = target.size !== 0; var oldTarget = isMap(target) ? new Map(target) : new Set(target) ; // forward the operation before queueing reactions var result = target.clear(); if (hadItems) { trigger$1(target, "clear" /* CLEAR */ , undefined, undefined, oldTarget); } return result; } function createForEach(isReadonly, isShallow) { return function forEach(callback, thisArg) { var observed = this; var target = observed["__v_raw" /* RAW */ ]; var rawTarget = toRaw(target); var wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; !isReadonly && track(rawTarget, "iterate" /* ITERATE */ , ITERATE_KEY); return target.forEach(function (value, key) { // important: make sure the callback is // 1. invoked with the reactive map as `this` and 3rd arg // 2. the value received should be a corresponding reactive/readonly. return callback.call(thisArg, wrap(value), wrap(key), observed); }); }; } function createIterableMethod(method, isReadonly, isShallow) { return function () { var target = this["__v_raw" /* RAW */ ]; var rawTarget = toRaw(target); var targetIsMap = isMap(rawTarget); var isPair = method === 'entries' || method === Symbol.iterator && targetIsMap; var isKeyOnly = method === 'keys' && targetIsMap; var innerIterator = target[method].apply(target, arguments); var wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; !isReadonly && track(rawTarget, "iterate" /* ITERATE */ , isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); // return a wrapped iterator which returns observed versions of the // values emitted from the real iterator return { // iterator protocol next() { var _innerIterator$next = innerIterator.next(), value = _innerIterator$next.value, done = _innerIterator$next.done; return done ? { value, done } : { value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), done }; }, // iterable protocol [Symbol.iterator]() { return this; } }; }; } function createReadonlyMethod(type) { return function () { { var key = (arguments.length <= 0 ? undefined : arguments[0]) ? "on key \"".concat(arguments.length <= 0 ? undefined : arguments[0], "\" ") : ""; console.warn("".concat(capitalize(type), " operation ").concat(key, "failed: target is readonly."), toRaw(this)); } return type === "delete" /* DELETE */ ? false : this; }; } function createInstrumentations() { var mutableInstrumentations = { get(key) { return get$1(this, key); }, get size() { return size$2(this); }, has: has$1, add, set: set$1, delete: deleteEntry, clear, forEach: createForEach(false, false) }; var shallowInstrumentations = { get(key) { return get$1(this, key, false, true); }, get size() { return size$2(this); }, has: has$1, add, set: set$1, delete: deleteEntry, clear, forEach: createForEach(false, true) }; var readonlyInstrumentations = { get(key) { return get$1(this, key, true); }, get size() { return size$2(this, true); }, has(key) { return has$1.call(this, key, true); }, add: createReadonlyMethod("add" /* ADD */ ), set: createReadonlyMethod("set" /* SET */ ), delete: createReadonlyMethod("delete" /* DELETE */ ), clear: createReadonlyMethod("clear" /* CLEAR */ ), forEach: createForEach(true, false) }; var shallowReadonlyInstrumentations = { get(key) { return get$1(this, key, true, true); }, get size() { return size$2(this, true); }, has(key) { return has$1.call(this, key, true); }, add: createReadonlyMethod("add" /* ADD */ ), set: createReadonlyMethod("set" /* SET */ ), delete: createReadonlyMethod("delete" /* DELETE */ ), clear: createReadonlyMethod("clear" /* CLEAR */ ), forEach: createForEach(true, true) }; var iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; iteratorMethods.forEach(function (method) { mutableInstrumentations[method] = createIterableMethod(method, false, false); readonlyInstrumentations[method] = createIterableMethod(method, true, false); shallowInstrumentations[method] = createIterableMethod(method, false, true); shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true); }); return [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations]; } var _createInstrumentatio = /* #__PURE__*/createInstrumentations(), _createInstrumentatio2 = _slicedToArray(_createInstrumentatio, 4), mutableInstrumentations = _createInstrumentatio2[0], readonlyInstrumentations = _createInstrumentatio2[1], shallowInstrumentations = _createInstrumentatio2[2], shallowReadonlyInstrumentations = _createInstrumentatio2[3]; function createInstrumentationGetter(isReadonly, shallow) { var instrumentations = shallow ? isReadonly ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly ? readonlyInstrumentations : mutableInstrumentations; return function (target, key, receiver) { if (key === "__v_isReactive" /* IS_REACTIVE */ ) { return !isReadonly; } else if (key === "__v_isReadonly" /* IS_READONLY */ ) { return isReadonly; } else if (key === "__v_raw" /* RAW */ ) { return target; } return Reflect.get(hasOwn(instrumentations, key) && key in target ? instrumentations : target, key, receiver); }; } var mutableCollectionHandlers = { get: /*#__PURE__*/createInstrumentationGetter(false, false) }; var readonlyCollectionHandlers = { get: /*#__PURE__*/createInstrumentationGetter(true, false) }; function checkIdentityKeys(target, has, key) { var rawKey = toRaw(key); if (rawKey !== key && has.call(target, rawKey)) { var type = toRawType(target); console.warn("Reactive ".concat(type, " contains both the raw and reactive ") + "versions of the same object".concat(type === "Map" ? " as keys" : "", ", ") + "which can lead to inconsistencies. " + "Avoid differentiating between the raw and reactive versions " + "of an object and only use the reactive version if possible."); } } var reactiveMap = new WeakMap(); var shallowReactiveMap = new WeakMap(); var readonlyMap = new WeakMap(); var shallowReadonlyMap = new WeakMap(); function targetTypeMap(rawType) { switch (rawType) { case 'Object': case 'Array': return 1 /* COMMON */ ; case 'Map': case 'Set': case 'WeakMap': case 'WeakSet': return 2 /* COLLECTION */ ; default: return 0 /* INVALID */ ; } } function getTargetType(value) { return value["__v_skip" /* SKIP */ ] || !Object.isExtensible(value) ? 0 /* INVALID */ : targetTypeMap(toRawType(value)); } function reactive(target) { // if trying to observe a readonly proxy, return the readonly version. if (isReadonly(target)) { return target; } return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); } /** * Creates a readonly copy of the original object. Note the returned copy is not * made reactive, but `readonly` can be called on an already reactive object. */ function readonly(target) { return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); } function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) { if (!isObject$1(target)) { { console.warn("value cannot be made reactive: ".concat(String(target))); } return target; } // target is already a Proxy, return it. // exception: calling readonly() on a reactive object if (target["__v_raw" /* RAW */ ] && !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */ ])) { return target; } // target already has corresponding Proxy var existingProxy = proxyMap.get(target); if (existingProxy) { return existingProxy; } // only a whitelist of value types can be observed. var targetType = getTargetType(target); if (targetType === 0 /* INVALID */ ) { return target; } var proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers); proxyMap.set(target, proxy); return proxy; } function isReadonly(value) { return !!(value && value["__v_isReadonly" /* IS_READONLY */ ]); } function isShallow(value) { return !!(value && value["__v_isShallow" /* IS_SHALLOW */ ]); } function toRaw(observed) { var raw = observed && observed["__v_raw" /* RAW */ ]; return raw ? toRaw(raw) : observed; } var toReactive = function toReactive(value) { return isObject$1(value) ? reactive(value) : value; }; var toReadonly = function toReadonly(value) { return isObject$1(value) ? readonly(value) : value; }; function isRef(r) { return !!(r && r.__v_isRef === true); } Promise.resolve(); function _createForOfIteratorHelper$1(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); } function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } var queued = false; var queue = []; var p = Promise.resolve(); var nextTick = function nextTick(fn) { return p.then(fn); }; var queueJob = function queueJob(job) { if (!queue.includes(job)) queue.push(job); if (!queued) { queued = true; nextTick(flushJobs); } }; var flushJobs = function flushJobs() { var _iterator = _createForOfIteratorHelper$1(queue), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var job = _step.value; job(); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } queue.length = 0; queued = false; }; function normalizeStyle(value) { if (isArray(value)) { var res = {}; for (var i = 0; i < value.length; i++) { var item = value[i]; var normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item); if (normalized) { for (var key in normalized) { res[key] = normalized[key]; } } } return res; } else if (isString(value)) { return value; } else if (isObject(value)) { return value; } } var listDelimiterRE = /;(?![^(]*\))/g; var propertyDelimiterRE = /:(.+)/; function parseStringStyle(cssText) { var ret = {}; cssText.split(listDelimiterRE).forEach(function (item) { if (item) { var tmp = item.split(propertyDelimiterRE); tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); } }); return ret; } function normalizeClass(value) { var res = ''; if (isString(value)) { res = value; } else if (isArray(value)) { for (var i = 0; i < value.length; i++) { var normalized = normalizeClass(value[i]); if (normalized) { res += normalized + ' '; } } } else if (isObject(value)) { for (var name in value) { if (value[name]) { res += name + ' '; } } } return res.trim(); } function looseCompareArrays(a, b) { if (a.length !== b.length) return false; var equal = true; for (var i = 0; equal && i < a.length; i++) { equal = looseEqual(a[i], b[i]); } return equal; } function looseEqual(a, b) { if (a === b) return true; var aValidType = isDate(a); var bValidType = isDate(b); if (aValidType || bValidType) { return aValidType && bValidType ? a.getTime() === b.getTime() : false; } aValidType = isArray(a); bValidType = isArray(b); if (aValidType || bValidType) { return aValidType && bValidType ? looseCompareArrays(a, b) : false; } aValidType = isObject(a); bValidType = isObject(b); if (aValidType || bValidType) { /* istanbul ignore if: this if will probably never be called */ if (!aValidType || !bValidType) { return false; } var aKeysCount = Object.keys(a).length; var bKeysCount = Object.keys(b).length; if (aKeysCount !== bKeysCount) { return false; } for (var key in a) { var aHasKey = a.hasOwnProperty(key); var bHasKey = b.hasOwnProperty(key); if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) { return false; } } } return String(a) === String(b); } function looseIndexOf(arr, val) { return arr.findIndex(function (item) { return looseEqual(item, val); }); } Object.freeze({}) ; Object.freeze([]) ; var remove = function remove(arr, el) { var i = arr.indexOf(el); if (i > -1) { arr.splice(i, 1); } }; var isArray = Array.isArray; var isDate = function isDate(val) { return val instanceof Date; }; var isString = function isString(val) { return typeof val === 'string'; }; var isObject = function isObject(val) { return val !== null && typeof val === 'object'; }; var cacheStringFunction = function cacheStringFunction(fn) { var cache = Object.create(null); return function (str) { var hit = cache[str]; return hit || (cache[str] = fn(str)); }; }; var camelizeRE = /-(\w)/g; /** * @private */ var camelize = cacheStringFunction(function (str) { return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; }); }); var hyphenateRE = /\B([A-Z])/g; /** * @private */ var hyphenate = cacheStringFunction(function (str) { return str.replace(hyphenateRE, '-$1').toLowerCase(); }); var toNumber = function toNumber(val) { var n = parseFloat(val); return isNaN(n) ? val : n; }; var forceAttrRE = /^(spellcheck|draggable|form|list|type)$/; var bind = function bind(_ref) { var el = _ref.el, get = _ref.get, effect = _ref.effect, arg = _ref.arg, modifiers = _ref.modifiers; var prevValue; // record static class if (arg === 'class') { el._class = el.className; } effect(function () { var value = get(); if (arg) { if (modifiers === null || modifiers === void 0 ? void 0 : modifiers.camel) { arg = camelize(arg); } setProp(el, arg, value, prevValue); } else { for (var key in value) { setProp(el, key, value[key], prevValue && prevValue[key]); } for (var _key in prevValue) { if (!value || !(_key in value)) { setProp(el, _key, null); } } } prevValue = value; }); }; var setProp = function setProp(el, key, value, prevValue) { if (key === 'class') { el.setAttribute('class', normalizeClass(el._class ? [el._class, value] : value) || ''); } else if (key === 'style') { value = normalizeStyle(value); var style = el.style; if (!value) { el.removeAttribute('style'); } else if (isString(value)) { if (value !== prevValue) style.cssText = value; } else { for (var _key2 in value) { setStyle(style, _key2, value[_key2]); } if (prevValue && !isString(prevValue)) { for (var _key3 in prevValue) { if (value[_key3] == null) { setStyle(style, _key3, ''); } } } } } else if (!(el instanceof SVGElement) && key in el && !forceAttrRE.test(key)) { // @ts-ignore el[key] = value; if (key === 'value') { // @ts-ignore el._value = value; } } else { // special case for with // :true-value & :false-value // store value as dom properties since non-string values will be // stringified. if (key === 'true-value') { el._trueValue = value; } else if (key === 'false-value') { el._falseValue = value; } else if (value != null) { el.setAttribute(key, value); } else { el.removeAttribute(key); } } }; var importantRE = /\s*!important$/; var setStyle = function setStyle(style, name, val) { if (isArray(val)) { val.forEach(function (v) { return setStyle(style, name, v); }); } else { if (name.startsWith('--')) { // custom property definition style.setProperty(name, val); } else { if (importantRE.test(val)) { // !important style.setProperty(hyphenate(name), val.replace(importantRE, ''), 'important'); } else { style[name] = val; } } } }; var checkAttr = function checkAttr(el, name) { var val = el.getAttribute(name); if (val != null) el.removeAttribute(name); return val; }; var listen = function listen(el, event, handler, options) { el.addEventListener(event, handler, options); }; var simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/; var systemModifiers = ['ctrl', 'shift', 'alt', 'meta']; var modifierGuards = { stop: function stop(e) { return e.stopPropagation(); }, prevent: function prevent(e) { return e.preventDefault(); }, self: function self(e) { return e.target !== e.currentTarget; }, ctrl: function ctrl(e) { return !e.ctrlKey; }, shift: function shift(e) { return !e.shiftKey; }, alt: function alt(e) { return !e.altKey; }, meta: function meta(e) { return !e.metaKey; }, left: function left(e) { return 'button' in e && e.button !== 0; }, middle: function middle(e) { return 'button' in e && e.button !== 1; }, right: function right(e) { return 'button' in e && e.button !== 2; }, exact: function exact(e, modifiers) { return systemModifiers.some(function (m) { return e["".concat(m, "Key")] && !modifiers[m]; }); } }; var on = function on(_ref) { var el = _ref.el, get = _ref.get, exp = _ref.exp, arg = _ref.arg, modifiers = _ref.modifiers; if (!arg) { { console.error("v-on=\"obj\" syntax is not supported in petite-vue."); } return; } var handler = simplePathRE.test(exp) ? get("(e => ".concat(exp, "(e))")) : get("($event => { ".concat(exp, " })")); // special lifecycle events if ((arg === 'mounted' || arg === 'unmounted')) { console.error("mounted and unmounted hooks now need to be prefixed with vue: " + "- use @vue:".concat(arg, "=\"handler\" instead.")); } if (arg === 'vue:mounted') { nextTick(handler); return; } else if (arg === 'vue:unmounted') { return function () { return handler(); }; } if (modifiers) { // map modifiers if (arg === 'click') { if (modifiers.right) arg = 'contextmenu'; if (modifiers.middle) arg = 'mouseup'; } var raw = handler; handler = function handler(e) { if ('key' in e && !(hyphenate(e.key) in modifiers)) { return; } for (var key in modifiers) { var guard = modifierGuards[key]; if (guard && guard(e, modifiers)) { return; } } return raw(e); }; } listen(el, arg, handler, modifiers); }; var show = function show(_ref) { var el = _ref.el, get = _ref.get, effect = _ref.effect; var initialDisplay = el.style.display; effect(function () { el.style.display = get() ? initialDisplay : 'none'; }); }; var text = function text(_ref) { var el = _ref.el, get = _ref.get, effect = _ref.effect; effect(function () { el.textContent = toDisplayString(get()); }); }; var toDisplayString = function toDisplayString(value) { return value == null ? '' : isObject(value) ? JSON.stringify(value, null, 2) : String(value); }; var html = function html(_ref) { var el = _ref.el, get = _ref.get, effect = _ref.effect; effect(function () { el.innerHTML = get(); }); }; var model = function model(_ref) { var el = _ref.el, exp = _ref.exp, get = _ref.get, effect = _ref.effect, modifiers = _ref.modifiers; var type = el.type; var assign = get("(val) => { ".concat(exp, " = val }")); var _ref2 = modifiers || {}, trim = _ref2.trim, _ref2$number = _ref2.number, number = _ref2$number === void 0 ? type === 'number' : _ref2$number; if (el.tagName === 'SELECT') { var sel = el; listen(el, 'change', function () { var selectedVal = Array.prototype.filter.call(sel.options, function (o) { return o.selected; }).map(function (o) { return number ? toNumber(getValue(o)) : getValue(o); }); assign(sel.multiple ? selectedVal : selectedVal[0]); }); effect(function () { var value = get(); var isMultiple = sel.multiple; for (var i = 0, l = sel.options.length; i < l; i++) { var option = sel.options[i]; var optionValue = getValue(option); if (isMultiple) { if (isArray(value)) { option.selected = looseIndexOf(value, optionValue) > -1; } else { option.selected = value.has(optionValue); } } else { if (looseEqual(getValue(option), value)) { if (sel.selectedIndex !== i) sel.selectedIndex = i; return; } } } if (!isMultiple && sel.selectedIndex !== -1) { sel.selectedIndex = -1; } }); } else if (type === 'checkbox') { listen(el, 'change', function () { var modelValue = get(); var checked = el.checked; if (isArray(modelValue)) { var elementValue = getValue(el); var index = looseIndexOf(modelValue, elementValue); var found = index !== -1; if (checked && !found) { assign(modelValue.concat(elementValue)); } else if (!checked && found) { var filtered = _toConsumableArray(modelValue); filtered.splice(index, 1); assign(filtered); } } else { assign(getCheckboxValue(el, checked)); } }); var oldValue; effect(function () { var value = get(); if (isArray(value)) { el.checked = looseIndexOf(value, getValue(el)) > -1; } else if (value !== oldValue) { el.checked = looseEqual(value, getCheckboxValue(el, true)); } oldValue = value; }); } else if (type === 'radio') { listen(el, 'change', function () { assign(getValue(el)); }); var _oldValue; effect(function () { var value = get(); if (value !== _oldValue) { el.checked = looseEqual(value, getValue(el)); } }); } else { // text-like var resolveValue = function resolveValue(val) { if (trim) return val.trim(); if (number) return toNumber(val); return val; }; listen(el, 'compositionstart', onCompositionStart); listen(el, 'compositionend', onCompositionEnd); listen(el, (modifiers === null || modifiers === void 0 ? void 0 : modifiers.lazy) ? 'change' : 'input', function () { if (el.composing) return; assign(resolveValue(el.value)); }); if (trim) { listen(el, 'change', function () { el.value = el.value.trim(); }); } effect(function () { if (el.composing) { return; } var curVal = el.value; var newVal = get(); if (document.activeElement === el && resolveValue(curVal) === newVal) { return; } if (curVal !== newVal) { el.value = newVal; } }); } }; var getValue = function getValue(el) { return '_value' in el ? el._value : el.value; }; // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings var getCheckboxValue = function getCheckboxValue(el, checked) { var key = checked ? '_trueValue' : '_falseValue'; return key in el ? el[key] : checked; }; var onCompositionStart = function onCompositionStart(e) { e.target.composing = true; }; var onCompositionEnd = function onCompositionEnd(e) { var target = e.target; if (target.composing) { target.composing = false; trigger(target, 'input'); } }; var trigger = function trigger(el, type) { var e = document.createEvent('HTMLEvents'); e.initEvent(type, true, true); el.dispatchEvent(e); }; var evalCache = Object.create(null); var evaluate = function evaluate(scope, exp, el) { return execute(scope, "return(".concat(exp, ")"), el); }; var execute = function execute(scope, exp, el) { var fn = evalCache[exp] || (evalCache[exp] = toFunction(exp)); try { return fn(scope, el); } catch (e) { { console.warn("Error when evaluating expression \"".concat(exp, "\":")); } console.error(e); } }; var toFunction = function toFunction(exp) { try { return new Function("$data", "$el", "with($data){".concat(exp, "}")); } catch (e) { console.error("".concat(e.message, " in expression: ").concat(exp)); return function () {}; } }; var effect = function effect(_ref) { var el = _ref.el, ctx = _ref.ctx, exp = _ref.exp, effect = _ref.effect; nextTick(function () { return effect(function () { return execute(ctx.scope, exp, el); }); }); }; var builtInDirectives = { bind, on, show, text, html, model, effect }; var _if = function _if(el, exp, ctx) { if (!exp.trim()) { console.warn("v-if expression cannot be empty."); } var parent = el.parentElement; var anchor = new Comment('v-if'); parent.insertBefore(anchor, el); var branches = [{ exp, el }]; // locate else branch var elseEl; var elseExp; while (elseEl = el.nextElementSibling) { elseExp = null; if (checkAttr(elseEl, 'v-else') === '' || (elseExp = checkAttr(elseEl, 'v-else-if'))) { parent.removeChild(elseEl); branches.push({ exp: elseExp, el: elseEl }); } else { break; } } var nextNode = el.nextSibling; parent.removeChild(el); var block; var activeBranchIndex = -1; var removeActiveBlock = function removeActiveBlock() { if (block) { parent.insertBefore(anchor, block.el); block.remove(); block = undefined; } }; ctx.effect(function () { for (var i = 0; i < branches.length; i++) { var _branches$i = branches[i], _exp = _branches$i.exp, _el = _branches$i.el; if (!_exp || evaluate(ctx.scope, _exp)) { if (i !== activeBranchIndex) { removeActiveBlock(); block = new Block(_el, ctx); block.insert(parent, anchor); parent.removeChild(anchor); activeBranchIndex = i; } return; } } // no matched branch. activeBranchIndex = -1; removeActiveBlock(); }); return nextNode; }; var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/; var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/; var stripParensRE = /^\(|\)$/g; var destructureRE = /^[{[]\s*((?:[\w_$]+\s*,?\s*)+)[\]}]$/; var _for = function _for(el, exp, ctx) { var inMatch = exp.match(forAliasRE); if (!inMatch) { console.warn("invalid v-for expression: ".concat(exp)); return; } var nextNode = el.nextSibling; var parent = el.parentElement; var anchor = new Text(''); parent.insertBefore(anchor, el); parent.removeChild(el); var sourceExp = inMatch[2].trim(); var valueExp = inMatch[1].trim().replace(stripParensRE, '').trim(); var destructureBindings; var isArrayDestructure = false; var indexExp; var objIndexExp; var keyAttr = 'key'; var keyExp = el.getAttribute(keyAttr) || el.getAttribute(keyAttr = ':key') || el.getAttribute(keyAttr = 'v-bind:key'); if (keyExp) { el.removeAttribute(keyAttr); if (keyAttr === 'key') keyExp = JSON.stringify(keyExp); } var match; if (match = valueExp.match(forIteratorRE)) { valueExp = valueExp.replace(forIteratorRE, '').trim(); indexExp = match[1].trim(); if (match[2]) { objIndexExp = match[2].trim(); } } if (match = valueExp.match(destructureRE)) { destructureBindings = match[1].split(',').map(function (s) { return s.trim(); }); isArrayDestructure = valueExp[0] === '['; } var mounted = false; var blocks; var childCtxs; var keyToIndexMap; var createChildContexts = function createChildContexts(source) { var map = new Map(); var ctxs = []; if (isArray(source)) { for (var i = 0; i < source.length; i++) { ctxs.push(createChildContext(map, source[i], i)); } } else if (typeof source === 'number') { for (var _i = 0; _i < source; _i++) { ctxs.push(createChildContext(map, _i + 1, _i)); } } else if (isObject(source)) { var _i2 = 0; for (var key in source) { ctxs.push(createChildContext(map, source[key], _i2++, key)); } } return [ctxs, map]; }; var createChildContext = function createChildContext(map, value, index, objKey) { var data = {}; if (destructureBindings) { destructureBindings.forEach(function (b, i) { return data[b] = value[isArrayDestructure ? i : b]; }); } else { data[valueExp] = value; } if (objKey) { indexExp && (data[indexExp] = objKey); objIndexExp && (data[objIndexExp] = index); } else { indexExp && (data[indexExp] = index); } var childCtx = createScopedContext(ctx, data); var key = keyExp ? evaluate(childCtx.scope, keyExp) : index; map.set(key, index); childCtx.key = key; return childCtx; }; var mountBlock = function mountBlock(ctx, ref) { var block = new Block(el, ctx); block.key = ctx.key; block.insert(parent, ref); return block; }; ctx.effect(function () { var source = evaluate(ctx.scope, sourceExp); var prevKeyToIndexMap = keyToIndexMap; var _createChildContexts = createChildContexts(source); var _createChildContexts2 = _slicedToArray(_createChildContexts, 2); childCtxs = _createChildContexts2[0]; keyToIndexMap = _createChildContexts2[1]; if (!mounted) { blocks = childCtxs.map(function (s) { return mountBlock(s, anchor); }); mounted = true; } else { for (var _i3 = 0; _i3 < blocks.length; _i3++) { if (!keyToIndexMap.has(blocks[_i3].key)) { blocks[_i3].remove(); } } var nextBlocks = []; var i = childCtxs.length; var nextBlock; var prevMovedBlock; while (i--) { var childCtx = childCtxs[i]; var oldIndex = prevKeyToIndexMap.get(childCtx.key); var block = void 0; if (oldIndex == null) { // new block = mountBlock(childCtx, nextBlock ? nextBlock.el : anchor); } else { // update block = blocks[oldIndex]; Object.assign(block.ctx.scope, childCtx.scope); if (oldIndex !== i) { // moved if (blocks[oldIndex + 1] !== nextBlock || // If the next has moved, it must move too prevMovedBlock === nextBlock) { prevMovedBlock = block; block.insert(parent, nextBlock ? nextBlock.el : anchor); } } } nextBlocks.unshift(nextBlock = block); } blocks = nextBlocks; } }); return nextNode; }; var ref = function ref(_ref) { var el = _ref.el, $refs = _ref.ctx.scope.$refs, get = _ref.get, effect = _ref.effect; var prevRef; effect(function () { var ref = get(); $refs[ref] = el; if (prevRef && ref !== prevRef) { delete $refs[prevRef]; } prevRef = ref; }); return function () { prevRef && delete $refs[prevRef]; }; }; var dirRE = /^(?:v-|:|@)/; var modifierRE = /\.([\w-]+)/g; var inOnce = false; var walk = function walk(node, ctx) { var type = node.nodeType; if (type === 1) { // Element var el = node; if (el.hasAttribute('v-pre')) { return; } checkAttr(el, 'v-cloak'); var exp; // v-if if (exp = checkAttr(el, 'v-if')) { return _if(el, exp, ctx); } // v-for if (exp = checkAttr(el, 'v-for')) { return _for(el, exp, ctx); } // v-scope if ((exp = checkAttr(el, 'v-scope')) || exp === '') { var scope = exp ? evaluate(ctx.scope, exp) : {}; ctx = createScopedContext(ctx, scope); if (scope.$template) { resolveTemplate(el, scope.$template); } } // v-once var hasVOnce = checkAttr(el, 'v-once') != null; if (hasVOnce) { inOnce = true; } // ref if (exp = checkAttr(el, 'ref')) { applyDirective(el, ref, "\"".concat(exp, "\""), ctx); } // process children first before self attrs walkChildren(el, ctx); // other directives var deferred = []; for (var _i = 0, _arr = _toConsumableArray(el.attributes); _i < _arr.length; _i++) { var _arr$_i = _arr[_i], name = _arr$_i.name, value = _arr$_i.value; if (dirRE.test(name) && name !== 'v-cloak') { if (name === 'v-model') { // defer v-model since it relies on :value bindings to be processed // first, but also before v-on listeners (#73) deferred.unshift([name, value]); } else if (name[0] === '@' || /^v-on\b/.test(name)) { deferred.push([name, value]); } else { processDirective(el, name, value, ctx); } } } for (var _i2 = 0, _deferred = deferred; _i2 < _deferred.length; _i2++) { var _deferred$_i = _slicedToArray(_deferred[_i2], 2), _name = _deferred$_i[0], _value = _deferred$_i[1]; processDirective(el, _name, _value, ctx); } if (hasVOnce) { inOnce = false; } } else if (type === 3) { // Text var data = node.data; if (data.includes(ctx.delimiters[0])) { var segments = []; var lastIndex = 0; var match; while (match = ctx.delimitersRE.exec(data)) { var leading = data.slice(lastIndex, match.index); if (leading) segments.push(JSON.stringify(leading)); segments.push("$s(".concat(match[1], ")")); lastIndex = match.index + match[0].length; } if (lastIndex < data.length) { segments.push(JSON.stringify(data.slice(lastIndex))); } applyDirective(node, text, segments.join('+'), ctx); } } else if (type === 11) { walkChildren(node, ctx); } }; var walkChildren = function walkChildren(node, ctx) { var child = node.firstChild; while (child) { child = walk(child, ctx) || child.nextSibling; } }; var processDirective = function processDirective(el, raw, exp, ctx) { var dir; var arg; var modifiers; // modifiers raw = raw.replace(modifierRE, function (_, m) { (modifiers || (modifiers = {}))[m] = true; return ''; }); if (raw[0] === ':') { dir = bind; arg = raw.slice(1); } else if (raw[0] === '@') { dir = on; arg = raw.slice(1); } else { var argIndex = raw.indexOf(':'); var dirName = argIndex > 0 ? raw.slice(2, argIndex) : raw.slice(2); dir = builtInDirectives[dirName] || ctx.dirs[dirName]; arg = argIndex > 0 ? raw.slice(argIndex + 1) : undefined; } if (dir) { if (dir === bind && arg === 'ref') dir = ref; applyDirective(el, dir, exp, ctx, arg, modifiers); el.removeAttribute(raw); } else { console.error("unknown custom directive ".concat(raw, ".")); } }; var applyDirective = function applyDirective(el, dir, exp, ctx, arg, modifiers) { var get = function get() { var e = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : exp; return evaluate(ctx.scope, e, el); }; var cleanup = dir({ el, get, effect: ctx.effect, ctx, exp, arg, modifiers }); if (cleanup) { ctx.cleanups.push(cleanup); } }; var resolveTemplate = function resolveTemplate(el, template) { if (template[0] === '#') { var templateEl = document.querySelector(template); if (!templateEl) { console.error("template selector ".concat(template, " has no matching