@ridp/threejs 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/{readme.md → README.md} +228 -26
  2. package/dist/hooks.cjs +1 -1
  3. package/dist/hooks.js +12 -9
  4. package/dist/packages/threejs/package.json.cjs +1 -0
  5. package/dist/packages/threejs/package.json.js +4 -0
  6. package/dist/packages/threejs/src/hooks/useBatchGLTFLoader.cjs +1 -0
  7. package/dist/packages/threejs/src/hooks/useBatchGLTFLoader.js +83 -0
  8. package/dist/packages/threejs/src/hooks/useGLTFLoader.cjs +1 -0
  9. package/dist/packages/threejs/src/hooks/useGLTFLoader.js +292 -0
  10. package/dist/packages/threejs/src/hooks/useObb.cjs +1 -0
  11. package/dist/packages/threejs/src/hooks/useObb.js +41 -0
  12. package/dist/packages/threejs/src/hooks/useRaycaster.cjs +1 -0
  13. package/dist/packages/threejs/src/hooks/useRaycaster.js +35 -0
  14. package/dist/packages/threejs/src/hooks/useThreeJs.cjs +5 -0
  15. package/dist/packages/threejs/src/hooks/useThreeJs.js +153 -0
  16. package/dist/packages/threejs/src/instance/IDBCache.cjs +1 -0
  17. package/dist/packages/threejs/src/instance/IDBCache.js +142 -0
  18. package/dist/packages/threejs/src/instance/threeIns.cjs +3 -0
  19. package/dist/packages/threejs/src/instance/threeIns.js +393 -0
  20. package/dist/packages/threejs/src/utils/CacheMonitor.cjs +1 -0
  21. package/dist/packages/threejs/src/utils/CacheMonitor.js +125 -0
  22. package/dist/packages/threejs/src/utils/ImageLoader.cjs +1 -0
  23. package/dist/packages/threejs/src/utils/ImageLoader.js +33 -0
  24. package/dist/packages/threejs/src/utils/PredictiveLoader.cjs +1 -0
  25. package/dist/packages/threejs/src/utils/PredictiveLoader.js +155 -0
  26. package/dist/packages/threejs/src/utils/RetryHelper.cjs +1 -0
  27. package/dist/packages/threejs/src/utils/RetryHelper.js +108 -0
  28. package/dist/packages/threejs/src/utils/common.cjs +1 -0
  29. package/dist/packages/threejs/src/utils/common.js +15 -0
  30. package/dist/packages/threejs/src/utils/css3dHelper.cjs +15 -0
  31. package/dist/packages/threejs/src/utils/css3dHelper.js +42 -0
  32. package/dist/packages/threejs/src/utils/disposeObject.cjs +1 -0
  33. package/dist/packages/threejs/src/utils/disposeObject.js +13 -0
  34. package/dist/packages/threejs/src/utils/helper.cjs +1 -0
  35. package/dist/packages/threejs/src/utils/helper.js +47 -0
  36. package/dist/packages/threejs/src/utils/modelSerialize.cjs +1 -0
  37. package/dist/packages/threejs/src/utils/modelSerialize.js +225 -0
  38. package/dist/packages/threejs/src/utils/sceneRebuilder.cjs +1 -0
  39. package/dist/packages/threejs/src/utils/sceneRebuilder.js +138 -0
  40. package/dist/packages/threejs/src/workers/gltfParser.worker.cjs +1 -0
  41. package/dist/packages/threejs/src/workers/gltfParser.worker.js +11 -0
  42. package/dist/packages/threejs/src/workers/gltfParserOptimized.worker.cjs +1 -0
  43. package/dist/packages/threejs/src/workers/gltfParserOptimized.worker.js +11 -0
  44. package/dist/threejs.cjs +1 -3
  45. package/dist/threejs.js +58 -404
  46. package/dist/utils.cjs +1 -1
  47. package/dist/utils.js +40 -32
  48. package/package.json +1 -1
  49. package/dist/ImageLoader-Br_nvMOg.js +0 -1444
  50. package/dist/ImageLoader-DL32KyTh.cjs +0 -24
  51. package/dist/PredictiveLoader-CZfMSjv-.js +0 -3731
  52. package/dist/PredictiveLoader-DDxh7dDg.cjs +0 -2
  53. package/dist/useBatchGLTFLoader-B5EUagWI.js +0 -493
  54. package/dist/useBatchGLTFLoader-BjAvIpyB.cjs +0 -5
  55. /package/dist/{modelOptimizer-A0Cs6f9e.cjs → packages/threejs/src/utils/modelOptimizer.cjs} +0 -0
  56. /package/dist/{modelOptimizer-BRPnM2RH.js → packages/threejs/src/utils/modelOptimizer.js} +0 -0
@@ -0,0 +1,125 @@
1
+ class e {
2
+ constructor() {
3
+ this.stats = {
4
+ hits: 0,
5
+ // 缓存命中次数
6
+ misses: 0,
7
+ // 缓存未命中次数
8
+ totalLoadTime: 0,
9
+ // 总加载时间(ms)
10
+ cacheSaveTime: 0,
11
+ // 缓存保存时间(ms)
12
+ errors: 0
13
+ // 错误次数
14
+ }, this.loadHistory = [];
15
+ }
16
+ /**
17
+ * 记录缓存命中
18
+ * @param {number} loadTime - 加载耗时(ms)
19
+ */
20
+ recordHit(t) {
21
+ this.stats.hits++, this.stats.totalLoadTime += t, this._recordHistory("hit", t);
22
+ }
23
+ /**
24
+ * 记录缓存未命中
25
+ * @param {number} loadTime - 加载耗时(ms)
26
+ */
27
+ recordMiss(t) {
28
+ this.stats.misses++, this.stats.totalLoadTime += t, this._recordHistory("miss", t);
29
+ }
30
+ /**
31
+ * 记录缓存保存时间
32
+ * @param {number} saveTime - 保存耗时(ms)
33
+ */
34
+ recordCacheSave(t) {
35
+ this.stats.cacheSaveTime += t;
36
+ }
37
+ /**
38
+ * 记录错误
39
+ * @param {string} path - 模型路径
40
+ * @param {Error} error - 错误对象
41
+ */
42
+ recordError(t, s) {
43
+ this.stats.errors++, this._recordHistory("error", 0, { path: t, error: s.message });
44
+ }
45
+ /**
46
+ * 计算缓存命中率
47
+ * @returns {string} 命中率百分比字符串
48
+ */
49
+ getHitRate() {
50
+ const t = this.stats.hits + this.stats.misses;
51
+ return t > 0 ? (this.stats.hits / t * 100).toFixed(2) + "%" : "0%";
52
+ }
53
+ /**
54
+ * 计算平均加载时间
55
+ * @returns {string} 平均加载时间(含单位)
56
+ */
57
+ getAvgLoadTime() {
58
+ const t = this.stats.hits + this.stats.misses;
59
+ return t > 0 ? (this.stats.totalLoadTime / t).toFixed(2) + "ms" : "0ms";
60
+ }
61
+ /**
62
+ * 获取完整的统计数据
63
+ * @returns {Object} 统计数据对象
64
+ */
65
+ getStats() {
66
+ const t = this.stats.hits + this.stats.misses;
67
+ return {
68
+ 命中率: this.getHitRate(),
69
+ 平均加载时间: this.getAvgLoadTime(),
70
+ 缓存命中数: this.stats.hits,
71
+ 缓存未命中数: this.stats.misses,
72
+ 总加载次数: t,
73
+ 总加载时间: this.stats.totalLoadTime.toFixed(2) + "ms",
74
+ 缓存保存时间: this.stats.cacheSaveTime.toFixed(2) + "ms",
75
+ 错误次数: this.stats.errors
76
+ };
77
+ }
78
+ /**
79
+ * 获取最近N条加载历史
80
+ * @param {number} count - 获取条数,默认 10
81
+ * @returns {Array} 历史记录数组
82
+ */
83
+ getHistory(t = 10) {
84
+ return this.loadHistory.slice(-t);
85
+ }
86
+ /**
87
+ * 清空统计数据
88
+ */
89
+ reset() {
90
+ this.stats = {
91
+ hits: 0,
92
+ misses: 0,
93
+ totalLoadTime: 0,
94
+ cacheSaveTime: 0,
95
+ errors: 0
96
+ }, this.loadHistory = [];
97
+ }
98
+ /**
99
+ * 内部方法: 记录历史
100
+ * @private
101
+ */
102
+ _recordHistory(t, s, i = {}) {
103
+ this.loadHistory.push({
104
+ type: t,
105
+ duration: s,
106
+ timestamp: Date.now(),
107
+ ...i
108
+ }), this.loadHistory.length > 100 && this.loadHistory.shift();
109
+ }
110
+ /**
111
+ * 打印统计报告到控制台
112
+ */
113
+ logReport() {
114
+ console.group("📊 缓存性能报告");
115
+ const t = this.getStats();
116
+ Object.entries(t).forEach(([s, i]) => {
117
+ console.log(`${s}: ${i}`);
118
+ }), console.groupEnd();
119
+ }
120
+ }
121
+ const r = new e();
122
+ export {
123
+ e as CacheMonitor,
124
+ r as cacheMonitor
125
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("three"),d=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/loaders/EXRLoader.cjs"),u=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/loaders/RGBELoader.cjs"),i={};async function l(r,n){if(!n)return;if(i[n]){const e=i[n];r.environment=e;return}let o=t(n);return new Promise((e,a)=>{o.load(n,e,void 0,a)}).then(e=>{e.mapping=c.EquirectangularReflectionMapping,r.environment=e,i[n]=e}).catch(e=>{console.log(" =====> e:",e)})}async function s(r){let n=t(r);return new Promise((o,e)=>{n.load(r,o,void 0,e)})}function t(r){return r.split(".").pop()==="exr"?new d.EXRLoader:new u.RGBELoader}exports.ImageLoader=s;exports.initEnvImage=l;
@@ -0,0 +1,33 @@
1
+ import { EquirectangularReflectionMapping as c } from "three";
2
+ import { EXRLoader as d } from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/loaders/EXRLoader.js";
3
+ import { RGBELoader as m } from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/loaders/RGBELoader.js";
4
+ const i = {};
5
+ async function s(o, n) {
6
+ if (!n) return;
7
+ if (i[n]) {
8
+ const e = i[n];
9
+ o.environment = e;
10
+ return;
11
+ }
12
+ let r = t(n);
13
+ return new Promise((e, a) => {
14
+ r.load(n, e, void 0, a);
15
+ }).then((e) => {
16
+ e.mapping = c, o.environment = e, i[n] = e;
17
+ }).catch((e) => {
18
+ console.log(" =====> e:", e);
19
+ });
20
+ }
21
+ async function g(o) {
22
+ let n = t(o);
23
+ return new Promise((r, e) => {
24
+ n.load(o, r, void 0, e);
25
+ });
26
+ }
27
+ function t(o) {
28
+ return o.split(".").pop() === "exr" ? new d() : new m();
29
+ }
30
+ export {
31
+ g as ImageLoader,
32
+ s as initEnvImage
33
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("../hooks/useGLTFLoader.cjs");class c{constructor(e={}){this.options={maxPreloadCount:e.maxPreloadCount||5,preloadDelay:e.preloadDelay||1e3,enableLearning:e.enableLearning!==!1},this.loadHistory=new Map,this.loadSequence=[],this.associations=new Map,this.preloadQueue=new Set,this.isPreloading=!1,this.loader=null,this.getLoader=()=>(this.loader||(this.loader=d.useGLTFLoader()),this.loader)}recordLoad(e,s){const t=Date.now(),o=this.loadHistory.get(e)||{count:0,lastLoadTime:0,versions:new Set};o.count++,o.lastLoadTime=t,o.versions.add(s),this.loadHistory.set(e,o),this.loadSequence.push({path:e,timestamp:t}),this.loadSequence.length>100&&this.loadSequence.shift(),this.options.enableLearning&&this.loadSequence.length>=2&&this._learnAssociations(e),this._triggerPredictivePreload(e,s)}_learnAssociations(e){const t=this.loadSequence.length-1;for(let o=Math.max(0,t-10);o<t;o++){const{path:a}=this.loadSequence[o];if(this.loadSequence[t].timestamp-this.loadSequence[o].timestamp<5*60*1e3&&a!==e){this.associations.has(a)||this.associations.set(a,new Map);const i=this.associations.get(a),n=i.get(e)||0;i.set(e,n+1)}}}_triggerPredictivePreload(e,s){setTimeout(()=>{const t=this.predictNext(e);this.preload(t,s)},this.options.preloadDelay)}predictNext(e){const s=new Map,t=this.associations.get(e);t&&t.forEach((i,n)=>{s.set(n,(s.get(n)||0)+i*2)});const o=Array.from(this.loadHistory.values()).reduce((i,n)=>i+n.count,0)/(this.loadHistory.size||1);this.loadHistory.forEach((i,n)=>{if(n!==e){const l=i.count/o;s.set(n,(s.get(n)||0)+l)}});const a=this.loadSequence.slice(-10);return new Set(a.map(i=>i.path)).forEach(i=>{i!==e&&s.set(i,(s.get(i)||0)+.5)}),Array.from(s.entries()).sort((i,n)=>n[1]-i[1]).slice(0,this.options.maxPreloadCount).map(([i])=>i)}async preload(e,s="latest"){if(this.isPreloading)return;this.isPreloading=!0;const{asyncFetch:t}=this.getLoader(),o=e.filter(a=>!this.preloadQueue.has(a)).slice(0,this.options.maxPreloadCount).map(async a=>{this.preloadQueue.add(a);try{console.log(`[ 智能预加载 ] 开始预加载: ${a}`),await t(a,s),console.log(`[ 智能预加载 ] 完成: ${a}`)}catch(r){console.warn(`[ 智能预加载 ] 失败: ${a}`,r)}finally{this.preloadQueue.delete(a)}});await Promise.all(o),this.isPreloading=!1}addAssociation(e,s){this.associations.has(e)||this.associations.set(e,new Map);const t=this.associations.get(e);s.forEach(o=>{const a=t.get(o)||0;t.set(o,a+10)})}getStats(){const e=Array.from(this.loadHistory.entries()).sort((s,t)=>t[1].count-s[1].count).slice(0,10).map(([s,t])=>({path:s,loadCount:t.count,lastLoadTime:new Date(t.lastLoadTime).toLocaleString()}));return{totalModelsLoaded:this.loadHistory.size,totalAssociations:this.associations.size,topModels:e,preloadQueueSize:this.preloadQueue.size}}clearHistory(){this.loadHistory.clear(),this.loadSequence=[],this.associations.clear()}exportAssociations(){const e={};return this.associations.forEach((s,t)=>{e[t]=Array.from(s.entries())}),e}importAssociations(e){Object.entries(e).forEach(([s,t])=>{const o=new Map(t);this.associations.set(s,o)})}}const h=new c;exports.PredictiveLoader=c;exports.predictiveLoader=h;
@@ -0,0 +1,155 @@
1
+ import { useGLTFLoader as l } from "../hooks/useGLTFLoader.js";
2
+ class d {
3
+ constructor(e = {}) {
4
+ this.options = {
5
+ maxPreloadCount: e.maxPreloadCount || 5,
6
+ preloadDelay: e.preloadDelay || 1e3,
7
+ enableLearning: e.enableLearning !== !1
8
+ }, this.loadHistory = /* @__PURE__ */ new Map(), this.loadSequence = [], this.associations = /* @__PURE__ */ new Map(), this.preloadQueue = /* @__PURE__ */ new Set(), this.isPreloading = !1, this.loader = null, this.getLoader = () => (this.loader || (this.loader = l()), this.loader);
9
+ }
10
+ /**
11
+ * 记录模型加载
12
+ * @param {string} path - 模型路径
13
+ * @param {string} version - 模型版本
14
+ */
15
+ recordLoad(e, s) {
16
+ const t = Date.now(), o = this.loadHistory.get(e) || {
17
+ count: 0,
18
+ lastLoadTime: 0,
19
+ versions: /* @__PURE__ */ new Set()
20
+ };
21
+ o.count++, o.lastLoadTime = t, o.versions.add(s), this.loadHistory.set(e, o), this.loadSequence.push({ path: e, timestamp: t }), this.loadSequence.length > 100 && this.loadSequence.shift(), this.options.enableLearning && this.loadSequence.length >= 2 && this._learnAssociations(e), this._triggerPredictivePreload(e, s);
22
+ }
23
+ /**
24
+ * 学习模型关联规则
25
+ * @private
26
+ * @param {string} currentPath - 当前加载的模型
27
+ */
28
+ _learnAssociations(e) {
29
+ const t = this.loadSequence.length - 1;
30
+ for (let o = Math.max(0, t - 10); o < t; o++) {
31
+ const { path: a } = this.loadSequence[o];
32
+ if (this.loadSequence[t].timestamp - this.loadSequence[o].timestamp < 5 * 60 * 1e3 && a !== e) {
33
+ this.associations.has(a) || this.associations.set(a, /* @__PURE__ */ new Map());
34
+ const i = this.associations.get(a), n = i.get(e) || 0;
35
+ i.set(e, n + 1);
36
+ }
37
+ }
38
+ }
39
+ /**
40
+ * 触发预测性预加载
41
+ * @private
42
+ * @param {string} currentPath - 当前加载的模型
43
+ * @param {string} version - 模型版本
44
+ */
45
+ _triggerPredictivePreload(e, s) {
46
+ setTimeout(() => {
47
+ const t = this.predictNext(e);
48
+ this.preload(t, s);
49
+ }, this.options.preloadDelay);
50
+ }
51
+ /**
52
+ * 预测下一个可能加载的模型
53
+ * @param {string} currentPath - 当前模型路径
54
+ * @returns {Array<string>} 预测的模型路径列表
55
+ */
56
+ predictNext(e) {
57
+ const s = /* @__PURE__ */ new Map(), t = this.associations.get(e);
58
+ t && t.forEach((i, n) => {
59
+ s.set(n, (s.get(n) || 0) + i * 2);
60
+ });
61
+ const o = Array.from(this.loadHistory.values()).reduce((i, n) => i + n.count, 0) / (this.loadHistory.size || 1);
62
+ this.loadHistory.forEach((i, n) => {
63
+ if (n !== e) {
64
+ const c = i.count / o;
65
+ s.set(n, (s.get(n) || 0) + c);
66
+ }
67
+ });
68
+ const a = this.loadSequence.slice(-10);
69
+ return new Set(a.map((i) => i.path)).forEach((i) => {
70
+ i !== e && s.set(i, (s.get(i) || 0) + 0.5);
71
+ }), Array.from(s.entries()).sort((i, n) => n[1] - i[1]).slice(0, this.options.maxPreloadCount).map(([i]) => i);
72
+ }
73
+ /**
74
+ * 预加载模型列表
75
+ * @param {Array<string>} paths - 模型路径列表
76
+ * @param {string} version - 模型版本
77
+ */
78
+ async preload(e, s = "latest") {
79
+ if (this.isPreloading)
80
+ return;
81
+ this.isPreloading = !0;
82
+ const { asyncFetch: t } = this.getLoader(), o = e.filter((a) => !this.preloadQueue.has(a)).slice(0, this.options.maxPreloadCount).map(async (a) => {
83
+ this.preloadQueue.add(a);
84
+ try {
85
+ console.log(`[ 智能预加载 ] 开始预加载: ${a}`), await t(a, s), console.log(`[ 智能预加载 ] 完成: ${a}`);
86
+ } catch (r) {
87
+ console.warn(`[ 智能预加载 ] 失败: ${a}`, r);
88
+ } finally {
89
+ this.preloadQueue.delete(a);
90
+ }
91
+ });
92
+ await Promise.all(o), this.isPreloading = !1;
93
+ }
94
+ /**
95
+ * 手动添加关联规则
96
+ * @param {string} fromPath - 源模型路径
97
+ * @param {Array<string>} toPaths - 关联的模型路径列表
98
+ */
99
+ addAssociation(e, s) {
100
+ this.associations.has(e) || this.associations.set(e, /* @__PURE__ */ new Map());
101
+ const t = this.associations.get(e);
102
+ s.forEach((o) => {
103
+ const a = t.get(o) || 0;
104
+ t.set(o, a + 10);
105
+ });
106
+ }
107
+ /**
108
+ * 获取加载统计信息
109
+ * @returns {Object} 统计数据
110
+ */
111
+ getStats() {
112
+ const e = Array.from(this.loadHistory.entries()).sort((s, t) => t[1].count - s[1].count).slice(0, 10).map(([s, t]) => ({
113
+ path: s,
114
+ loadCount: t.count,
115
+ lastLoadTime: new Date(t.lastLoadTime).toLocaleString()
116
+ }));
117
+ return {
118
+ totalModelsLoaded: this.loadHistory.size,
119
+ totalAssociations: this.associations.size,
120
+ topModels: e,
121
+ preloadQueueSize: this.preloadQueue.size
122
+ };
123
+ }
124
+ /**
125
+ * 清空历史记录
126
+ */
127
+ clearHistory() {
128
+ this.loadHistory.clear(), this.loadSequence = [], this.associations.clear();
129
+ }
130
+ /**
131
+ * 导出关联规则(可持久化)
132
+ * @returns {Object} 关联规则数据
133
+ */
134
+ exportAssociations() {
135
+ const e = {};
136
+ return this.associations.forEach((s, t) => {
137
+ e[t] = Array.from(s.entries());
138
+ }), e;
139
+ }
140
+ /**
141
+ * 导入关联规则
142
+ * @param {Object} data - 关联规则数据
143
+ */
144
+ importAssociations(e) {
145
+ Object.entries(e).forEach(([s, t]) => {
146
+ const o = new Map(t);
147
+ this.associations.set(s, o);
148
+ });
149
+ }
150
+ }
151
+ const g = new d();
152
+ export {
153
+ d as PredictiveLoader,
154
+ g as predictiveLoader
155
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class l{static async retry(t,e={}){const{maxRetries:r=3,initialDelay:s=1e3,maxDelay:m=1e4,backoffFactor:y=2,shouldRetry:E=l.defaultShouldRetry}=e;let u,i=s;for(let a=0;a<=r;a++)try{return await t()}catch(n){if(u=n,a===r||!E(n,a))throw n;console.warn(`[ RetryHelper ] 操作失败,第 ${a+1} 次尝试失败,${i}ms 后进行第 ${a+2} 次尝试...`,n),await l.delay(i),i=Math.min(i*y,m)}throw u}static defaultShouldRetry(t,e){if(t.name==="TypeError"&&t.message.includes("fetch"))return!0;if(t.message.includes("HTTP error")){const r=t.message.match(/status:\s*(\d+)/);if(r){const s=parseInt(r[1],10);return s>=500||s===429||s===408}}return!1}static delay(t){return new Promise(e=>setTimeout(e,t))}}const c={NETWORK:"NETWORK",PARSE:"PARSE",VERSION_MISMATCH:"VERSION",UNKNOWN:"UNKNOWN"};class o extends Error{constructor(t,e,r,s){super(t),this.name="ModelLoadError",this.type=e,this.path=r,this.originalError=s,this.timestamp=Date.now()}static networkError(t,e){return new o(`网络加载失败: ${t}`,c.NETWORK,t,e)}static parseError(t,e){return new o(`模型解析失败: ${t}`,c.PARSE,t,e)}static versionMismatchError(t,e,r){return new o(`版本不匹配: ${t} (期望: ${e}, 实际: ${r})`,c.VERSION_MISMATCH,t)}}exports.ErrorType=c;exports.ModelLoadError=o;exports.RetryHelper=l;
@@ -0,0 +1,108 @@
1
+ class u {
2
+ /**
3
+ * 异步操作并支持重试
4
+ * @param {Function} operation - 要执行的异步操作
5
+ * @param {RetryOptions} options - 重试配置
6
+ * @returns {Promise} 操作结果
7
+ */
8
+ static async retry(t, e = {}) {
9
+ const {
10
+ maxRetries: r = 3,
11
+ initialDelay: s = 1e3,
12
+ maxDelay: m = 1e4,
13
+ backoffFactor: E = 2,
14
+ shouldRetry: h = u.defaultShouldRetry
15
+ } = e;
16
+ let l, i = s;
17
+ for (let a = 0; a <= r; a++)
18
+ try {
19
+ return await t();
20
+ } catch (n) {
21
+ if (l = n, a === r || !h(n, a))
22
+ throw n;
23
+ console.warn(
24
+ `[ RetryHelper ] 操作失败,第 ${a + 1} 次尝试失败,${i}ms 后进行第 ${a + 2} 次尝试...`,
25
+ n
26
+ ), await u.delay(i), i = Math.min(i * E, m);
27
+ }
28
+ throw l;
29
+ }
30
+ /**
31
+ * 默认的重试判断逻辑
32
+ * @param {Error} error - 错误对象
33
+ * @param {number} attempt - 当前尝试次数
34
+ * @returns {boolean} 是否应该重试
35
+ */
36
+ static defaultShouldRetry(t, e) {
37
+ if (t.name === "TypeError" && t.message.includes("fetch"))
38
+ return !0;
39
+ if (t.message.includes("HTTP error")) {
40
+ const r = t.message.match(/status:\s*(\d+)/);
41
+ if (r) {
42
+ const s = parseInt(r[1], 10);
43
+ return s >= 500 || s === 429 || s === 408;
44
+ }
45
+ }
46
+ return !1;
47
+ }
48
+ /**
49
+ * 延迟指定时间
50
+ * @param {number} ms - 延迟毫秒数
51
+ * @returns {Promise}
52
+ */
53
+ static delay(t) {
54
+ return new Promise((e) => setTimeout(e, t));
55
+ }
56
+ }
57
+ const c = {
58
+ NETWORK: "NETWORK",
59
+ // 网络错误
60
+ PARSE: "PARSE",
61
+ // 解析错误
62
+ VERSION_MISMATCH: "VERSION",
63
+ // 版本不匹配
64
+ UNKNOWN: "UNKNOWN"
65
+ // 未知错误
66
+ };
67
+ class o extends Error {
68
+ constructor(t, e, r, s) {
69
+ super(t), this.name = "ModelLoadError", this.type = e, this.path = r, this.originalError = s, this.timestamp = Date.now();
70
+ }
71
+ /**
72
+ * 创建网络错误
73
+ */
74
+ static networkError(t, e) {
75
+ return new o(
76
+ `网络加载失败: ${t}`,
77
+ c.NETWORK,
78
+ t,
79
+ e
80
+ );
81
+ }
82
+ /**
83
+ * 创建解析错误
84
+ */
85
+ static parseError(t, e) {
86
+ return new o(
87
+ `模型解析失败: ${t}`,
88
+ c.PARSE,
89
+ t,
90
+ e
91
+ );
92
+ }
93
+ /**
94
+ * 创建版本不匹配错误
95
+ */
96
+ static versionMismatchError(t, e, r) {
97
+ return new o(
98
+ `版本不匹配: ${t} (期望: ${e}, 实际: ${r})`,
99
+ c.VERSION_MISMATCH,
100
+ t
101
+ );
102
+ }
103
+ }
104
+ export {
105
+ c as ErrorType,
106
+ o as ModelLoadError,
107
+ u as RetryHelper
108
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=(u,i)=>{const t={};u.forEach(n=>{let e=n.parent;for(;e;)t[e.uuid]?t[e.uuid]++:t[e.uuid]=1,e=e.parent});let o=null,r=0;for(const n in t)t[n]>r&&(r=t[n],o=i.getObjectByProperty("uuid",n));return o};exports.getCommonParent=a;
@@ -0,0 +1,15 @@
1
+ const a = (r, i) => {
2
+ const t = {};
3
+ r.forEach((n) => {
4
+ let e = n.parent;
5
+ for (; e; )
6
+ t[e.uuid] ? t[e.uuid]++ : t[e.uuid] = 1, e = e.parent;
7
+ });
8
+ let u = null, o = 0;
9
+ for (const n in t)
10
+ t[n] > o && (o = t[n], u = i.getObjectByProperty("uuid", n));
11
+ return u;
12
+ };
13
+ export {
14
+ a as getCommonParent
15
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/renderers/CSS3DRenderer.cjs");function s(n,e=[.3,.3,.3]){const t=document.querySelector(`#${n}`);if(!t){console.log(" 获取 infoPlane 元素失败 (id) =====> :",n);return}const r=t.cloneNode(!0);r.style.display="block";const o=new l.CSS3DSprite(r);return o.visible=!1,o.scale.set(...e),o}function c(n,e){const t=a(n);t.style.display="block";const r=new l.CSS3DSprite(t);return r.visible=!1,r.scale.set(e,e,e),r}const a=n=>{const e=document.createElement("div");e.style.cssText=`
2
+ border-radius: 50px;
3
+ border: 2px solid rgba(255, 255, 255, 0.5);
4
+ background-color: rgba(15, 20, 22, 0.562);
5
+ justify-content: flex-start;
6
+ align-items: center;
7
+ padding: 20px 30px;
8
+ display: flex;
9
+ transform-origin: center 0;`;const t=document.createElement("span");return t.style.cssText=`
10
+ font-size: 40px;
11
+ line-height: 1;
12
+ white-space: nowrap;
13
+ color: #fff;
14
+ font-weight: 700;
15
+ `,t.innerText=n,e.appendChild(t),e};exports.createInfoPlane=s;exports.createTagPlane=c;
@@ -0,0 +1,42 @@
1
+ import { CSS3DSprite as r } from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/renderers/CSS3DRenderer.js";
2
+ function a(n, e = [0.3, 0.3, 0.3]) {
3
+ const t = document.querySelector(`#${n}`);
4
+ if (!t) {
5
+ console.log(" 获取 infoPlane 元素失败 (id) =====> :", n);
6
+ return;
7
+ }
8
+ const o = t.cloneNode(!0);
9
+ o.style.display = "block";
10
+ const l = new r(o);
11
+ return l.visible = !1, l.scale.set(...e), l;
12
+ }
13
+ function i(n, e) {
14
+ const t = s(n);
15
+ t.style.display = "block";
16
+ const o = new r(t);
17
+ return o.visible = !1, o.scale.set(e, e, e), o;
18
+ }
19
+ const s = (n) => {
20
+ const e = document.createElement("div");
21
+ e.style.cssText = `
22
+ border-radius: 50px;
23
+ border: 2px solid rgba(255, 255, 255, 0.5);
24
+ background-color: rgba(15, 20, 22, 0.562);
25
+ justify-content: flex-start;
26
+ align-items: center;
27
+ padding: 20px 30px;
28
+ display: flex;
29
+ transform-origin: center 0;`;
30
+ const t = document.createElement("span");
31
+ return t.style.cssText = `
32
+ font-size: 40px;
33
+ line-height: 1;
34
+ white-space: nowrap;
35
+ color: #fff;
36
+ font-weight: 700;
37
+ `, t.innerText = n, e.appendChild(t), e;
38
+ };
39
+ export {
40
+ a as createInfoPlane,
41
+ i as createTagPlane
42
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=e=>{e.geometry&&e.geometry.dispose(),e.material&&(Array.isArray(e.material)?e.material.forEach(i=>{r(i)}):r(e.material)),e.children&&e.children.forEach(i=>s(i))};function r(e){for(const i in e)e[i]&&e[i].isTexture&&e[i].dispose();e.dispose()}exports.disposeThreeObject=s;
@@ -0,0 +1,13 @@
1
+ const e = (i) => {
2
+ i.geometry && i.geometry.dispose(), i.material && (Array.isArray(i.material) ? i.material.forEach((r) => {
3
+ s(r);
4
+ }) : s(i.material)), i.children && i.children.forEach((r) => e(r));
5
+ };
6
+ function s(i) {
7
+ for (const r in i)
8
+ i[r] && i[r].isTexture && i[r].dispose();
9
+ i.dispose();
10
+ }
11
+ export {
12
+ e as disposeThreeObject
13
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("three"),c=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/controls/OrbitControls.cjs"),a=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/controls/MapControls.cjs"),s=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/libs/stats.module.cjs");function l(e){return new t.CameraHelper(e)}function i(e=150,...r){return new t.GridHelper(e,e/10,...r)}function u(e){return new t.BoxHelper(e,16776960)}function p(e,r){return new c.OrbitControls(e,r)}function f(e,r){return new a.MapControls(e,r)}function H(){const e=new t.Raycaster,r=new t.Vector2(0,0);return{raycaster:e,pointer:r}}function w(e=10){return new t.AxesHelper(e)}function C(e=new t.Vector3(1,1,1),r=new t.Vector3(10,10,10),n=5,o=16776960){return e.normalize(),new t.ArrowHelper(e,r,n,o)}function x(){const e=new s;return e.dom.style.cssText="position:absolute;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000",e}exports.createArrowHelper=C;exports.createAxesHelper=w;exports.createBox3Helper=u;exports.createCameraHelper=l;exports.createGridHelper=i;exports.createMapControls=f;exports.createOrbitControl=p;exports.createRaycaster=H;exports.createStats=x;
@@ -0,0 +1,47 @@
1
+ import { Vector3 as t, CameraHelper as c, GridHelper as a, BoxHelper as f, Raycaster as i, Vector2 as p, AxesHelper as s, ArrowHelper as u } from "three";
2
+ import { OrbitControls as l } from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/controls/OrbitControls.js";
3
+ import { MapControls as w } from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/controls/MapControls.js";
4
+ import m from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/libs/stats.module.js";
5
+ function A(e) {
6
+ return new c(e);
7
+ }
8
+ function b(e = 150, ...r) {
9
+ return new a(e, e / 10, ...r);
10
+ }
11
+ function d(e) {
12
+ return new f(e, 16776960);
13
+ }
14
+ function B(e, r) {
15
+ return new l(e, r);
16
+ }
17
+ function G(e, r) {
18
+ return new w(e, r);
19
+ }
20
+ function M() {
21
+ const e = new i(), r = new p(0, 0);
22
+ return {
23
+ raycaster: e,
24
+ pointer: r
25
+ };
26
+ }
27
+ function O(e = 10) {
28
+ return new s(e);
29
+ }
30
+ function R(e = new t(1, 1, 1), r = new t(10, 10, 10), n = 5, o = 16776960) {
31
+ return e.normalize(), new u(e, r, n, o);
32
+ }
33
+ function S() {
34
+ const e = new m();
35
+ return e.dom.style.cssText = "position:absolute;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000", e;
36
+ }
37
+ export {
38
+ R as createArrowHelper,
39
+ O as createAxesHelper,
40
+ d as createBox3Helper,
41
+ A as createCameraHelper,
42
+ b as createGridHelper,
43
+ G as createMapControls,
44
+ B as createOrbitControl,
45
+ M as createRaycaster,
46
+ S as createStats
47
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const D=require("three");function d(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const a=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,a.get?a:{enumerable:!0,get:()=>e[t]})}}return n.default=e,Object.freeze(n)}const l=d(D),h={};async function A(e,n=50){const t={type:e.type,name:e.name,position:e.position.toArray(),rotation:e.rotation.toArray(),scale:e.scale.toArray(),visible:e.visible,children:[],geometry:null,material:null,userData:e.userData};e.isMesh&&(t.geometry=y(e.geometry),t.material=m(e.material));const a=[{object:e,parentData:t}];let s=0;for(;a.length>0;){const{object:r,parentData:i}=a.pop();for(const o of r.children){const c={type:o.type,name:o.name,position:o.position.toArray(),rotation:o.rotation.toArray(),scale:o.scale.toArray(),visible:o.visible,children:[],geometry:null,material:null,userData:o.userData};o.isMesh&&(c.geometry=y(o.geometry),c.material=m(o.material)),i.children.push(c),a.push({object:o,parentData:c}),s++,s%n===0&&await new Promise(p=>requestAnimationFrame(p))}}return t}function g(e){const n={type:e.type,name:e.name,position:e.position.toArray(),rotation:e.rotation.toArray(),scale:e.scale.toArray(),visible:e.visible,children:[],geometry:null,material:null,userData:e.userData};e.isMesh&&(n.geometry=y(e.geometry),n.material=m(e.material));const t=[{object:e,parentData:n}];for(;t.length>0;){const{object:a,parentData:s}=t.pop();for(const r of a.children){const i={type:r.type,name:r.name,position:r.position.toArray(),rotation:r.rotation.toArray(),scale:r.scale.toArray(),visible:r.visible,children:[],geometry:null,material:null,userData:r.userData};r.isMesh&&(i.geometry=y(r.geometry),i.material=m(r.material)),s.children.push(i),t.push({object:r,parentData:i})}}return n}async function w(e,n=50){const t=[];let a;switch(e.type){case"Mesh":const r=u(e.geometry),i=f(e.material);a=new l.Mesh(r,i);break;case"Group":a=new l.Group;break;case"Object3D":a=new l.Object3D;break;default:return console.warn(`Unsupported object type: ${e.type}`),null}a.name=e.name,a.position.fromArray(e.position),a.rotation.fromArray(e.rotation),a.scale.fromArray(e.scale),a.visible=e.visible,a.userData=e.userData,t.push({data:e,object:a});let s=0;for(;t.length>0;){const{data:r,object:i}=t.pop();for(const o of[...r.children].reverse()){let c;switch(o.type){case"Mesh":const p=u(o.geometry),b=f(o.material);c=new l.Mesh(p,b);break;case"Group":c=new l.Group;break;case"Object3D":c=new l.Object3D;break;default:console.warn(`Unsupported object type: ${o.type}`);continue}c&&(c.name=o.name,c.position.fromArray(o.position),c.rotation.fromArray(o.rotation),c.scale.fromArray(o.scale),c.visible=o.visible,c.userData=o.userData,i.add(c),t.push({data:o,object:c}),s++,s%n===0&&await new Promise(p=>requestAnimationFrame(p)))}}return a}function O(e){const n=[];let t;switch(e.type){case"Mesh":const a=u(e.geometry),s=f(e.material);t=new l.Mesh(a,s);break;case"Group":t=new l.Group;break;case"Object3D":t=new l.Object3D;break;default:return console.warn(`Unsupported object type: ${e.type}`),null}for(t.name=e.name,t.position.fromArray(e.position),t.rotation.fromArray(e.rotation),t.scale.fromArray(e.scale),t.visible=e.visible,t.userData=e.userData,n.push({data:e,object:t});n.length>0;){const{data:a,object:s}=n.pop();for(const r of[...a.children].reverse()){let i;switch(r.type){case"Mesh":const o=u(r.geometry),c=f(r.material);i=new l.Mesh(o,c);break;case"Group":i=new l.Group;break;case"Object3D":i=new l.Object3D;break;default:console.warn(`Unsupported object type: ${r.type}`);continue}i&&(i.name=r.name,i.position.fromArray(r.position),i.rotation.fromArray(r.rotation),i.scale.fromArray(r.scale),i.visible=r.visible,i.userData=r.userData,s.add(i),n.push({data:r,object:i}))}}return t}function y(e){const n={},{attributes:t,index:a,type:s}=e;t.position&&(n.position={type:"Float32Array",array:Array.from(t.position.array),itemSize:3}),t.normal&&(n.normal={type:"Float32Array",array:Array.from(t.normal.array),itemSize:3}),t.uv&&(n.uv={type:"Float32Array",array:Array.from(t.uv.array),itemSize:2});const r={type:s,attributes:n};return a&&a.array&&(r.index={type:"Uint32Array",array:Array.from(a.array),itemSize:1}),r}function u(e){const{type:n,attributes:t,index:a}=e,s=new l.BufferGeometry;for(const r in t)if(t.hasOwnProperty(r)){const{type:i,array:o,itemSize:c}=t[r];s.setAttribute(r,new l.BufferAttribute(new Float32Array(o),c))}return a&&s.setIndex(a.array),s}function m(e){return{type:e.type,color:e.color.getHex(),map:e.map?e.map.image.src:null,opacity:e.opacity,name:e.name,depthTest:e.depthTest,depthWrite:e.depthWrite,transparent:e.transparent,side:e.side,roughness:e.roughness,metalness:e.metalness,emissive:e.emissive.getHex()}}function f(e){if(h[e.name])return h[e.name];const{type:n,...t}=e,a=n||"MeshStandardMaterial",s=new l[a]({...t});if(e.map){const r=new l.TextureLoader().load(e.map);s.map=r}return s.needsUpdate=!0,h[e.name]=s,s}exports.dataToObject3D=w;exports.dataToObject3DSync=O;exports.object3DToData=A;exports.object3DToDataSync=g;