@ridp/threejs 1.4.1 → 1.4.2
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.
- package/dist/hooks.cjs +1 -1
- package/dist/hooks.js +12 -9
- package/dist/packages/threejs/package.json.cjs +1 -0
- package/dist/packages/threejs/package.json.js +4 -0
- package/dist/packages/threejs/src/hooks/useBatchGLTFLoader.cjs +1 -0
- package/dist/packages/threejs/src/hooks/useBatchGLTFLoader.js +83 -0
- package/dist/packages/threejs/src/hooks/useGLTFLoader.cjs +1 -0
- package/dist/packages/threejs/src/hooks/useGLTFLoader.js +292 -0
- package/dist/packages/threejs/src/hooks/useObb.cjs +1 -0
- package/dist/packages/threejs/src/hooks/useObb.js +41 -0
- package/dist/packages/threejs/src/hooks/useRaycaster.cjs +1 -0
- package/dist/packages/threejs/src/hooks/useRaycaster.js +35 -0
- package/dist/packages/threejs/src/hooks/useThreeJs.cjs +5 -0
- package/dist/packages/threejs/src/hooks/useThreeJs.js +153 -0
- package/dist/packages/threejs/src/instance/IDBCache.cjs +1 -0
- package/dist/packages/threejs/src/instance/IDBCache.js +142 -0
- package/dist/packages/threejs/src/instance/threeIns.cjs +3 -0
- package/dist/packages/threejs/src/instance/threeIns.js +369 -0
- package/dist/packages/threejs/src/utils/CacheMonitor.cjs +1 -0
- package/dist/packages/threejs/src/utils/CacheMonitor.js +125 -0
- package/dist/packages/threejs/src/utils/ImageLoader.cjs +1 -0
- package/dist/packages/threejs/src/utils/ImageLoader.js +33 -0
- package/dist/packages/threejs/src/utils/PredictiveLoader.cjs +1 -0
- package/dist/packages/threejs/src/utils/PredictiveLoader.js +155 -0
- package/dist/packages/threejs/src/utils/RetryHelper.cjs +1 -0
- package/dist/packages/threejs/src/utils/RetryHelper.js +108 -0
- package/dist/packages/threejs/src/utils/common.cjs +1 -0
- package/dist/packages/threejs/src/utils/common.js +15 -0
- package/dist/packages/threejs/src/utils/css3dHelper.cjs +15 -0
- package/dist/packages/threejs/src/utils/css3dHelper.js +42 -0
- package/dist/packages/threejs/src/utils/disposeObject.cjs +1 -0
- package/dist/packages/threejs/src/utils/disposeObject.js +13 -0
- package/dist/packages/threejs/src/utils/helper.cjs +1 -0
- package/dist/packages/threejs/src/utils/helper.js +47 -0
- package/dist/packages/threejs/src/utils/modelSerialize.cjs +1 -0
- package/dist/packages/threejs/src/utils/modelSerialize.js +225 -0
- package/dist/packages/threejs/src/utils/sceneRebuilder.cjs +1 -0
- package/dist/packages/threejs/src/utils/sceneRebuilder.js +138 -0
- package/dist/packages/threejs/src/workers/gltfParser.worker.cjs +1 -0
- package/dist/packages/threejs/src/workers/gltfParser.worker.js +11 -0
- package/dist/packages/threejs/src/workers/gltfParserOptimized.worker.cjs +1 -0
- package/dist/packages/threejs/src/workers/gltfParserOptimized.worker.js +11 -0
- package/dist/threejs.cjs +1 -3
- package/dist/threejs.js +58 -404
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +40 -32
- package/package.json +1 -1
- package/dist/ImageLoader-Br_nvMOg.js +0 -1444
- package/dist/ImageLoader-DL32KyTh.cjs +0 -24
- package/dist/PredictiveLoader-CZfMSjv-.js +0 -3731
- package/dist/PredictiveLoader-DDxh7dDg.cjs +0 -2
- package/dist/useBatchGLTFLoader-B5EUagWI.js +0 -493
- package/dist/useBatchGLTFLoader-BjAvIpyB.cjs +0 -5
- /package/dist/{modelOptimizer-A0Cs6f9e.cjs → packages/threejs/src/utils/modelOptimizer.cjs} +0 -0
- /package/dist/{modelOptimizer-BRPnM2RH.js → packages/threejs/src/utils/modelOptimizer.js} +0 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { MathUtils as I, WebGLRenderer as G, Scene as N, PerspectiveCamera as Y, Box3 as K, Vector3 as y } from "three";
|
|
2
|
+
import { ref as b, shallowRef as Q, onMounted as X, onUnmounted as Z, nextTick as k } from "vue";
|
|
3
|
+
import $ from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/libs/stats.module.js";
|
|
4
|
+
import { CSS3DRenderer as ee } from "../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/renderers/CSS3DRenderer.js";
|
|
5
|
+
import { createOrbitControl as te } from "../utils/helper.js";
|
|
6
|
+
import { disposeThreeObject as ne } from "../utils/disposeObject.js";
|
|
7
|
+
import "../utils/PredictiveLoader.js";
|
|
8
|
+
const oe = {
|
|
9
|
+
enableDamping: !0,
|
|
10
|
+
dampingFactor: 0.25,
|
|
11
|
+
screenSpacePanning: !1,
|
|
12
|
+
minDistance: 0.1,
|
|
13
|
+
maxDistance: 1e3,
|
|
14
|
+
maxPolarAngle: I.degToRad(60)
|
|
15
|
+
};
|
|
16
|
+
function pe(L, j) {
|
|
17
|
+
typeof console < "u" && console.warn && console.warn(
|
|
18
|
+
`[ThreeIns] useThreeJs() Hook 已弃用,建议使用 ThreeIns 类代替。
|
|
19
|
+
旧用法: const { scene, camera } = useThreeJs(selector, options)
|
|
20
|
+
新用法: const threeIns = new ThreeIns(selector, options)
|
|
21
|
+
|
|
22
|
+
ThreeIns 类提供更完整的 API 和更好的性能。`
|
|
23
|
+
);
|
|
24
|
+
const r = Object.assign(
|
|
25
|
+
{
|
|
26
|
+
css3d: !1,
|
|
27
|
+
stats: !1,
|
|
28
|
+
renderType: "change",
|
|
29
|
+
control: {
|
|
30
|
+
init: !0,
|
|
31
|
+
options: {}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
j || {}
|
|
35
|
+
);
|
|
36
|
+
let c, p, n, x = [];
|
|
37
|
+
const z = b(!1), u = Q(), s = b(0), i = b(0), o = new G({
|
|
38
|
+
antialias: !0,
|
|
39
|
+
alpha: !0,
|
|
40
|
+
precision: "mediump",
|
|
41
|
+
logarithmicDepthBuffer: !0
|
|
42
|
+
}), f = new N({}), e = new Y(50, 1, 0.1, 2e3), T = Math.tan(Math.PI / 180 * e.fov / 2);
|
|
43
|
+
let w = !1;
|
|
44
|
+
o.setPixelRatio(window.devicePixelRatio);
|
|
45
|
+
function S() {
|
|
46
|
+
z.value = !1;
|
|
47
|
+
const t = O();
|
|
48
|
+
s.value = t[0], i.value = t[1], e.aspect = s.value / i.value, e.position.set(47, 39, 100), e.fov = 360 / Math.PI * Math.atan(T * (i.value / s.value)), e.lookAt(0, 0, 0), e.updateProjectionMatrix(), o.setSize(s.value, i.value), c.appendChild(o.domElement), r.stats && _(), r.css3d && J();
|
|
49
|
+
let a;
|
|
50
|
+
if (r.control && r.control.init) {
|
|
51
|
+
a = te(e, o.domElement);
|
|
52
|
+
const l = Object.assign(
|
|
53
|
+
oe,
|
|
54
|
+
r.control.options || {}
|
|
55
|
+
);
|
|
56
|
+
Object.keys(l).forEach((h) => {
|
|
57
|
+
a[h] = l[h];
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return k(() => z.value = !0), a;
|
|
61
|
+
}
|
|
62
|
+
function A(t) {
|
|
63
|
+
t.preventDefault(), cancelAnimationFrame(v);
|
|
64
|
+
}
|
|
65
|
+
function R(t) {
|
|
66
|
+
t.preventDefault(), S(), v();
|
|
67
|
+
}
|
|
68
|
+
function q(t) {
|
|
69
|
+
x.push(t);
|
|
70
|
+
}
|
|
71
|
+
function v(t) {
|
|
72
|
+
x && x.length && x.forEach((a) => {
|
|
73
|
+
typeof a == "function" && a();
|
|
74
|
+
}), r.renderType === "loop" && g(), requestAnimationFrame(v);
|
|
75
|
+
}
|
|
76
|
+
function g() {
|
|
77
|
+
w = !1, p && p.update(), u.value && u.value.update(), o.render(f, e), n && n.render(f, e);
|
|
78
|
+
}
|
|
79
|
+
function D() {
|
|
80
|
+
w || (w = !0, requestAnimationFrame(g));
|
|
81
|
+
}
|
|
82
|
+
function C() {
|
|
83
|
+
k(() => {
|
|
84
|
+
const t = O();
|
|
85
|
+
s.value = t[0], i.value = t[1], e.aspect = s.value / i.value, e.fov = 360 / Math.PI * Math.atan(T * (i.value / s.value)), e.updateProjectionMatrix(), e.lookAt(f.position), o.setSize(s.value, i.value), n && n.setSize(s.value, i.value), g();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function O() {
|
|
89
|
+
return c = document.querySelector(L), c ? [c.clientWidth, c.clientHeight] : [0, 0];
|
|
90
|
+
}
|
|
91
|
+
function _() {
|
|
92
|
+
p = new $(), p.dom.style.cssText = "position:absolute;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000", c.appendChild(p.dom);
|
|
93
|
+
}
|
|
94
|
+
function H(t, a, l, h, P) {
|
|
95
|
+
const F = new K().setFromObject(t), M = F.getSize(new y()).length(), d = F.getCenter(new y());
|
|
96
|
+
P && d.add(P);
|
|
97
|
+
const W = M * a * 0.5, B = I.degToRad(l.fov * 0.5), U = W / Math.tan(B), E = new y().subVectors(l.position, d).multiply(new y(1, 1, 1)).normalize().multiplyScalar(U).add(d), m = {
|
|
98
|
+
x: E.x,
|
|
99
|
+
y: E.y,
|
|
100
|
+
z: E.z,
|
|
101
|
+
lookAt_x: d.x,
|
|
102
|
+
lookAt_y: d.y,
|
|
103
|
+
lookAt_z: d.z
|
|
104
|
+
};
|
|
105
|
+
return l.position.set(m.x, m.y, m.z), l.lookAt(
|
|
106
|
+
m.lookAt_x,
|
|
107
|
+
m.lookAt_y,
|
|
108
|
+
m.lookAt_z
|
|
109
|
+
), l.updateProjectionMatrix(), h.target.copy(d), h.update(), M;
|
|
110
|
+
}
|
|
111
|
+
function J() {
|
|
112
|
+
n = new ee(), n.setSize(s.value, i.value), n.domElement.style.position = "absolute", n.domElement.style.top = 0, n.domElement.style.left = 0, n.domElement.style.pointerEvents = "none", c.appendChild(n.domElement);
|
|
113
|
+
}
|
|
114
|
+
function V() {
|
|
115
|
+
ne(f);
|
|
116
|
+
}
|
|
117
|
+
return X(() => {
|
|
118
|
+
u.value = S(), window.addEventListener("resize", C, !1), o.domElement.addEventListener(
|
|
119
|
+
"webglcontextlost",
|
|
120
|
+
A,
|
|
121
|
+
!1
|
|
122
|
+
), o.domElement.addEventListener(
|
|
123
|
+
"webglcontextrestored",
|
|
124
|
+
R,
|
|
125
|
+
!1
|
|
126
|
+
), r.renderType === "loop" ? requestAnimationFrame(v) : r.renderType === "change" && u.value && u.value.addEventListener("change", D);
|
|
127
|
+
}), Z(() => {
|
|
128
|
+
cancelAnimationFrame(v), o.domElement.removeEventListener("resize", C, !1), o.domElement.removeEventListener(
|
|
129
|
+
"webglcontextlost",
|
|
130
|
+
A,
|
|
131
|
+
!1
|
|
132
|
+
), o.domElement.removeEventListener(
|
|
133
|
+
"webglcontextrestored",
|
|
134
|
+
R,
|
|
135
|
+
!1
|
|
136
|
+
), V();
|
|
137
|
+
}), {
|
|
138
|
+
addAnimate: q,
|
|
139
|
+
frameArea: H,
|
|
140
|
+
onRender: g,
|
|
141
|
+
css3dRenderer: n,
|
|
142
|
+
scene: f,
|
|
143
|
+
camera: e,
|
|
144
|
+
control: u,
|
|
145
|
+
renderer: o,
|
|
146
|
+
domWidth: s,
|
|
147
|
+
domHeight: i,
|
|
148
|
+
isReady: z
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export {
|
|
152
|
+
pe as useThreeJs
|
|
153
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("three");const d=require("dexie"),c=4;class r{constructor(e="threeJsIDBCache",t={}){this.version=c,this.dbName=e,this.options={maxSize:t.maxSize||500*1024*1024,maxEntries:t.maxEntries||50,evictRatio:t.evictRatio||.2},this.dbInit()}dbInit(){this.db=new d(this.dbName),this.db.version(this.version).stores({models:"&path, version, timestamp, accessCount, size"}).upgrade(async e=>{console.log("[ IDBCache 版本更新 ] ====> version",c);const t=e.table("models"),s=await t.toArray();for(const o of s)o.data instanceof ArrayBuffer||await t.delete(o.path)})}getDatabase(){return this.db}async saveModel(e,t,s){await this.ensureCapacity(s.byteLength),await this.db.table("models").put({path:e,version:t,data:s,size:s.byteLength,timestamp:Date.now(),accessCount:0})}async ensureCapacity(e){const t=await this.db.table("models").toArray(),s=t.reduce((a,i)=>a+(i.size||0),0),o=t.length,n=s+e>this.options.maxSize,l=o>=this.options.maxEntries;(n||l)&&(console.log(`[ IDBCache ] ====> 容量不足,开始 LRU 淘汰. 总大小: ${(s/1024/1024).toFixed(2)}MB, 条目数: ${o}`),await this.evictLRU(t))}async evictLRU(e){const t=e.sort((a,i)=>(a.accessCount||0)!==(i.accessCount||0)?(a.accessCount||0)-(i.accessCount||0):(a.timestamp||0)-(i.timestamp||0)),s=Math.max(1,Math.floor(t.length*this.options.evictRatio)),o=t.slice(0,s),n=o.map(a=>a.path);await this.db.table("models").bulkDelete(n);const l=o.reduce((a,i)=>a+(i.size||0),0);console.log(`[ IDBCache ] ====> LRU 淘汰完成. 删除 ${s} 个条目,释放 ${(l/1024/1024).toFixed(2)}MB`)}async getModel(e,t){const s=await this.db.table("models").get(e);return s?s.version!==t?(console.log("模型版本不一致, 清除当前记录"),await this.db.table("models").delete(e),null):(await this.db.table("models").update(e,{accessCount:(s.accessCount||0)+1,timestamp:Date.now()}),s.data):(console.warn(`Model "${e}" not found in table models`),null)}async cacheModel(e,t,s){console.log("[ ] ====> path, modelData, version",e,t,s);try{this.db.table("models").put({version:s,path:e,data:t}).then(()=>{console.log(`Model "${e}" cached successfully in table models`)})}catch{console.log(" 缓存模型失败 =====> ")}return t}async loadCachedModel(e,t){let s=null;try{if(s=await this.db.table("models").get(e),!s)return console.warn(`Model "${t}" not found in table models`),null;if(s.version!==t)return console.log(" =====> 模型版本不一致, 清除当前记录"),await this.db.table("models").delete(e),null}catch{return console.log(" =====> 查询表中模型失败"),this.db.delete().then(()=>{this.init()}),null}return s.data}async getStats(){const e=await this.db.table("models").toArray(),t=e.reduce((o,n)=>o+(n.size||0),0),s=e.reduce((o,n)=>o+(n.accessCount||0),0);return{count:e.length,totalSize:t,totalSizeMB:(t/1024/1024).toFixed(2),maxEntries:this.options.maxEntries,maxSizeMB:(this.options.maxSize/1024/1024).toFixed(2),usagePercentage:(t/this.options.maxSize*100).toFixed(2),totalAccessCount:s,avgAccessCount:e.length>0?(s/e.length).toFixed(2):0}}async clear(){await this.db.table("models").clear(),console.log("[ IDBCache ] ====> 缓存已清空")}async deleteModel(e){await this.db.table("models").delete(e)}}exports.IDBCache=r;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import "three";
|
|
2
|
+
import d from "dexie";
|
|
3
|
+
const c = 4;
|
|
4
|
+
class m {
|
|
5
|
+
/**
|
|
6
|
+
* 构造函数
|
|
7
|
+
* @param {string} dbName - 数据库名称
|
|
8
|
+
* @param {CacheOptions} options - 缓存配置选项
|
|
9
|
+
*/
|
|
10
|
+
constructor(e = "threeJsIDBCache", t = {}) {
|
|
11
|
+
this.version = c, this.dbName = e, this.options = {
|
|
12
|
+
maxSize: t.maxSize || 500 * 1024 * 1024,
|
|
13
|
+
// 默认 500MB
|
|
14
|
+
maxEntries: t.maxEntries || 50,
|
|
15
|
+
// 默认最多 50 个模型
|
|
16
|
+
evictRatio: t.evictRatio || 0.2
|
|
17
|
+
// 淘汰 20%
|
|
18
|
+
}, this.dbInit();
|
|
19
|
+
}
|
|
20
|
+
dbInit() {
|
|
21
|
+
this.db = new d(this.dbName), this.db.version(this.version).stores({
|
|
22
|
+
models: "&path, version, timestamp, accessCount, size"
|
|
23
|
+
}).upgrade(async (e) => {
|
|
24
|
+
console.log("[ IDBCache 版本更新 ] ====> version", c);
|
|
25
|
+
const t = e.table("models"), s = await t.toArray();
|
|
26
|
+
for (const o of s)
|
|
27
|
+
o.data instanceof ArrayBuffer || await t.delete(o.path);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 获取 Dexie 数据库实例
|
|
32
|
+
* @returns {Dexie} Dexie 实例
|
|
33
|
+
*/
|
|
34
|
+
getDatabase() {
|
|
35
|
+
return this.db;
|
|
36
|
+
}
|
|
37
|
+
async saveModel(e, t, s) {
|
|
38
|
+
await this.ensureCapacity(s.byteLength), await this.db.table("models").put({
|
|
39
|
+
path: e,
|
|
40
|
+
version: t,
|
|
41
|
+
data: s,
|
|
42
|
+
size: s.byteLength,
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
accessCount: 0
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 确保缓存容量足够,不足时执行 LRU 淘汰
|
|
49
|
+
* @param {number} requiredSize - 需要的额外空间(字节)
|
|
50
|
+
*/
|
|
51
|
+
async ensureCapacity(e) {
|
|
52
|
+
const t = await this.db.table("models").toArray(), s = t.reduce((a, i) => a + (i.size || 0), 0), o = t.length, n = s + e > this.options.maxSize, l = o >= this.options.maxEntries;
|
|
53
|
+
(n || l) && (console.log(`[ IDBCache ] ====> 容量不足,开始 LRU 淘汰. 总大小: ${(s / 1024 / 1024).toFixed(2)}MB, 条目数: ${o}`), await this.evictLRU(t));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 执行 LRU 淘汰策略
|
|
57
|
+
* @param {Array} models - 所有缓存记录
|
|
58
|
+
*/
|
|
59
|
+
async evictLRU(e) {
|
|
60
|
+
const t = e.sort((a, i) => (a.accessCount || 0) !== (i.accessCount || 0) ? (a.accessCount || 0) - (i.accessCount || 0) : (a.timestamp || 0) - (i.timestamp || 0)), s = Math.max(1, Math.floor(t.length * this.options.evictRatio)), o = t.slice(0, s), n = o.map((a) => a.path);
|
|
61
|
+
await this.db.table("models").bulkDelete(n);
|
|
62
|
+
const l = o.reduce((a, i) => a + (i.size || 0), 0);
|
|
63
|
+
console.log(`[ IDBCache ] ====> LRU 淘汰完成. 删除 ${s} 个条目,释放 ${(l / 1024 / 1024).toFixed(2)}MB`);
|
|
64
|
+
}
|
|
65
|
+
async getModel(e, t) {
|
|
66
|
+
const s = await this.db.table("models").get(e);
|
|
67
|
+
return s ? s.version !== t ? (console.log("模型版本不一致, 清除当前记录"), await this.db.table("models").delete(e), null) : (await this.db.table("models").update(e, {
|
|
68
|
+
accessCount: (s.accessCount || 0) + 1,
|
|
69
|
+
timestamp: Date.now()
|
|
70
|
+
}), s.data) : (console.warn(`Model "${e}" not found in table models`), null);
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------- ---------------------------------
|
|
73
|
+
/**
|
|
74
|
+
* 缓存模型到 IndexedDB
|
|
75
|
+
* @param {string} path - 主键值
|
|
76
|
+
* @param {THREE.Object3D} model - 要缓存的模型
|
|
77
|
+
* @param {string} [version] - 缓存模型版本
|
|
78
|
+
*/
|
|
79
|
+
async cacheModel(e, t, s) {
|
|
80
|
+
console.log("[ ] ====> path, modelData, version", e, t, s);
|
|
81
|
+
try {
|
|
82
|
+
this.db.table("models").put({ version: s, path: e, data: t }).then(() => {
|
|
83
|
+
console.log(`Model "${e}" cached successfully in table models`);
|
|
84
|
+
});
|
|
85
|
+
} catch {
|
|
86
|
+
console.log(" 缓存模型失败 =====> ");
|
|
87
|
+
}
|
|
88
|
+
return t;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 从 IndexedDB 加载缓存的模型
|
|
92
|
+
* @param {string} path - 主键值
|
|
93
|
+
* @returns {THREE.Object3D | null} 加载的模型
|
|
94
|
+
*/
|
|
95
|
+
async loadCachedModel(e, t) {
|
|
96
|
+
let s = null;
|
|
97
|
+
try {
|
|
98
|
+
if (s = await this.db.table("models").get(e), !s)
|
|
99
|
+
return console.warn(`Model "${t}" not found in table models`), null;
|
|
100
|
+
if (s.version !== t)
|
|
101
|
+
return console.log(" =====> 模型版本不一致, 清除当前记录"), await this.db.table("models").delete(e), null;
|
|
102
|
+
} catch {
|
|
103
|
+
return console.log(" =====> 查询表中模型失败"), this.db.delete().then(() => {
|
|
104
|
+
this.init();
|
|
105
|
+
}), null;
|
|
106
|
+
}
|
|
107
|
+
return s.data;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 获取缓存统计信息
|
|
111
|
+
* @returns {Promise<Object>} 缓存统计数据
|
|
112
|
+
*/
|
|
113
|
+
async getStats() {
|
|
114
|
+
const e = await this.db.table("models").toArray(), t = e.reduce((o, n) => o + (n.size || 0), 0), s = e.reduce((o, n) => o + (n.accessCount || 0), 0);
|
|
115
|
+
return {
|
|
116
|
+
count: e.length,
|
|
117
|
+
totalSize: t,
|
|
118
|
+
totalSizeMB: (t / 1024 / 1024).toFixed(2),
|
|
119
|
+
maxEntries: this.options.maxEntries,
|
|
120
|
+
maxSizeMB: (this.options.maxSize / 1024 / 1024).toFixed(2),
|
|
121
|
+
usagePercentage: (t / this.options.maxSize * 100).toFixed(2),
|
|
122
|
+
totalAccessCount: s,
|
|
123
|
+
avgAccessCount: e.length > 0 ? (s / e.length).toFixed(2) : 0
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 清空所有缓存
|
|
128
|
+
*/
|
|
129
|
+
async clear() {
|
|
130
|
+
await this.db.table("models").clear(), console.log("[ IDBCache ] ====> 缓存已清空");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 删除指定模型缓存
|
|
134
|
+
* @param {string} path - 模型路径
|
|
135
|
+
*/
|
|
136
|
+
async deleteModel(e) {
|
|
137
|
+
await this.db.table("models").delete(e);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
m as IDBCache
|
|
142
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";var I=Object.defineProperty;var q=(x,e,t)=>e in x?I(x,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):x[e]=t;var i=(x,e,t)=>q(x,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("three"),A=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/renderers/CSS3DRenderer.cjs"),H=require("../../../../node_modules/.pnpm/three@0.178.0/node_modules/three/examples/jsm/libs/stats.module.cjs"),P=require("../utils/helper.cjs"),X=require("../utils/disposeObject.cjs");require("../utils/PredictiveLoader.cjs");const Y=require("../../package.json.cjs"),j=50,Z=20,_=20,E={TOP:"top",RIGHT:"right",LEFT:"left",ISO:"iso"},B={enableDamping:!0,dampingFactor:.25,screenSpacePanning:!1,minDistance:.1,maxDistance:1e3,maxPolarAngle:n.MathUtils.degToRad(60)};class C{constructor(e,t){i(this,"isReady",!1);i(this,"scene",null);i(this,"camera",null);i(this,"renderer",null);i(this,"control",null);i(this,"css3dRenderer",null);i(this,"el",null);i(this,"renderRequested",!1);i(this,"selector",null);i(this,"eventsListener",{});i(this,"stats",null);i(this,"isDispose",!1);i(this,"version","0.0.0");i(this,"boxHelper",null);i(this,"initOpt",{css3d:!1,stats:!1,renderType:"change",initListener:!0,initialFov:50,control:{init:!0,options:{}}});i(this,"setup",e=>{if(this.isDispose=!1,this.selector=e,this.el=document.querySelector(e),!this.el){console.error(`ThreeIns: 找不到元素 ${e}`);return}const[t,h]=this.getTargetSize();if(this.updateCameraFOV(t,h),this.camera.position.set(0,0,0),this.camera.lookAt(0,0,0),this.camera.updateProjectionMatrix(),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(t,h),this.el.appendChild(this.renderer.domElement),this.initOpt.control&&this.initOpt.control.init){this.control=P.createOrbitControl(this.camera,this.renderer.domElement);const s=Object.assign(B,this.initOpt.control.options||{});Object.keys(s).forEach(p=>{this.control[p]=s[p]})}setTimeout(()=>{this.isReady=!0},Z),this.initOpt.stats&&this.initStats(),this.initOpt.css3d&&this.initCss3dRenderer(),this.initOpt.renderType==="loop"?this.animate():this.initOpt.renderType==="change"&&this.control&&this.control.addEventListener("change",this.requestRenderIfNotRequested),this.initListener()});i(this,"onContextLost",e=>{e.preventDefault(),this.animationFrameId&&cancelAnimationFrame(this.animationFrameId)});i(this,"onContextRestored",e=>{e.preventDefault(),this.dispose(),setTimeout(()=>{this.setup(this.selector)},_)});i(this,"initListener",()=>{this.initOpt.initListener&&window&&window.addEventListener("resize",this.onResize,!1),this.renderer.domElement.addEventListener("webglcontextlost",this.onContextLost,!1),this.renderer.domElement.addEventListener("webglcontextrestored",this.onContextRestored,!1)});i(this,"removeListener",()=>{window&&window.removeEventListener("resize",this.onResize,!1),this.renderer&&this.renderer.domElement&&(this.renderer.domElement.removeEventListener("webglcontextlost",this.onContextLost,!1),this.renderer.domElement.removeEventListener("webglcontextrestored",this.onContextRestored,!1))});i(this,"animate",()=>{this.isDispose||(this.initOpt.renderType==="loop"&&this.onRender(),this.animationFrameId=requestAnimationFrame(this.animate))});i(this,"onRender",()=>{this.isDispose||(this.renderRequested=!1,this.stats&&this.stats.update(),this.control&&this.control.update(),this.renderer.render(this.scene,this.camera),this.css3dRenderer&&this.css3dRenderer.render(this.scene,this.camera),this.eventsListener.onRender&&this.eventsListener.onRender.length&&this.eventsListener.onRender.forEach(e=>e()))});i(this,"requestRenderIfNotRequested",()=>{this.renderRequested||(this.renderRequested=!0,requestAnimationFrame(()=>{this.onRender()}))});i(this,"onResize",()=>{this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{const[e,t]=this.getTargetSize();this.updateCameraFOV(e,t),this.camera.lookAt(this.scene.position),this.renderer.setSize(e,t),this.css3dRenderer&&this.css3dRenderer.setSize(e,t),this.onRender()},j)});i(this,"frameArea",(e,t)=>(console.warn(`[ThreeIns] frameArea() 已弃用,建议使用 setView() 方法。
|
|
2
|
+
旧用法: threeIns.frameArea(model, scale)
|
|
3
|
+
新用法: threeIns.setView(model, ViewType.ISO, { scale })`),this.setView(e,E.ISO,{scale:t,animate:!1,showBox:!1})));i(this,"setView",(e,t,h={})=>{let s=h.scale||.8,p=h.offset||null,F=h.showBox||!1,y=h.boxColor||16776960,w=h.animate!==void 0?h.animate:!0,z=h.duration||1e3;const g=new n.Box3().setFromObject(e);let c=g.getCenter(new n.Vector3);p&&c.add(p);const T={top:new n.Vector3(0,1,0),right:new n.Vector3(2,1,1).normalize(),left:new n.Vector3(-2,1,1).normalize(),iso:new n.Vector3(0,1,1).normalize()},R=T[t]||T.iso,o=g.getSize(new n.Vector3),b=this.camera.aspect,r=n.MathUtils.degToRad(this.camera.fov*.5),S=n.MathUtils.degToRad(80),d=Math.min(Math.atan(Math.tan(r)*b),S);let m;if(t==="top"){const a=o.x*.5/(Math.tan(d)*s),l=o.z*.5/(Math.tan(r)*s);m=Math.max(a,l)}else if(t==="right"||t==="left"){const a=o.y*.5/(Math.tan(r)*s),l=o.z*.5/(Math.tan(r)*s);m=Math.max(a,l)}else{const a=o.x*.5/(Math.tan(d)*s),l=o.y*.5/(Math.tan(r)*s),f=o.z*.5/(Math.tan(r)*s);m=Math.max(a,l,f)}const u=R.clone().multiplyScalar(m).add(c);if(F&&(console.log("📍 相机位置验证:"),console.log(" - 方向向量:",R),console.log(" - 距离:",m.toFixed(2)),console.log(" - 包围盒中心:",c),console.log(" - 计算公式: direction * distance + boxCenter"),console.log(" - 目标位置:",u),console.log(" - 实际相机与中心的距离:",u.clone().sub(c).length().toFixed(2))),F?(this.boxHelper&&(this.scene.remove(this.boxHelper),this.boxHelper=null),this.boxHelper=new n.Box3Helper(g,y),this.scene.add(this.boxHelper)):this.boxHelper&&(this.scene.remove(this.boxHelper),this.boxHelper=null),w){const a=this.camera.position.clone(),l=this.control?this.control.target.clone():new n.Vector3(0,0,0),f=c,V=Date.now(),v=()=>{const D=Date.now()-V,L=Math.min(D/z,1),O=1-Math.pow(1-L,3);if(this.camera.position.lerpVectors(a,u,O),this.control){const M=new n.Vector3;M.lerpVectors(l,f,O),this.control.target.copy(M),this.camera.lookAt(M)}else this.camera.lookAt(c);this.camera.updateProjectionMatrix(),L<1?requestAnimationFrame(v):(this.camera.position.copy(u),this.camera.lookAt(c),this.camera.updateProjectionMatrix(),this.control&&(this.control.target.copy(c),this.control.update()),this.onRender())};v()}else this.camera.position.copy(u),this.camera.lookAt(c),this.camera.updateProjectionMatrix(),this.control&&(this.control.target.copy(c),this.control.update()),this.onRender();if(F){if(console.log("🎥 视角切换信息:"),console.log(" - 视角类型:",t),console.log(" - 相机位置:",u),console.log(" - 观察目标:",c),console.log(" - 方向向量:",R),console.log(" - 包围盒尺寸:",o),console.log(" - 包围盒中心:",g.getCenter(new n.Vector3)),console.log(" - 水平 FOV:",n.MathUtils.radToDeg(d*2).toFixed(2)+"°"),console.log(" - 垂直 FOV:",n.MathUtils.radToDeg(r*2).toFixed(2)+"°"),console.log(" - 宽高比:",b.toFixed(4)),console.log(" - 模型宽度:",o.x.toFixed(2)),console.log(" - 模型高度:",o.y.toFixed(2)),console.log(" - 模型深度:",o.z.toFixed(2)),console.log(" - 传入的 scale 参数:",s),t==="top"){const a=o.x*.5/(Math.tan(d)*s),l=o.z*.5/(Math.tan(r)*s);console.log(" - 模型 X 尺寸 (宽度):",o.x.toFixed(2)),console.log(" - 模型 Z 尺寸 (深度):",o.z.toFixed(2)),console.log(" - tan(halfFovX):",Math.tan(d).toFixed(4)),console.log(" - tan(halfFovY):",Math.tan(r).toFixed(4)),console.log(" - X方向距离计算: (",(o.x*.5).toFixed(2),") / (",Math.tan(d).toFixed(4)," *",s,") =",a.toFixed(2)),console.log(" - Z方向距离计算: (",(o.z*.5).toFixed(2),") / (",Math.tan(r).toFixed(4)," *",s,") =",l.toFixed(2)),console.log(" - X方向距离 (scale="+s+"):",a.toFixed(2)),console.log(" - Z方向距离 (scale="+s+"):",l.toFixed(2))}else if(t==="right"||t==="left"){const a=o.y*.5/(Math.tan(r)*s),l=o.z*.5/(Math.tan(r)*s);console.log(" - Y方向距离 (scale="+s+"):",a.toFixed(2)),console.log(" - Z方向距离 (scale="+s+"):",l.toFixed(2))}else{const a=o.x*.5/(Math.tan(d)*s),l=o.y*.5/(Math.tan(r)*s),f=o.z*.5/(Math.tan(r)*s);console.log(" - 模型 X 尺寸 (宽度):",o.x.toFixed(2)),console.log(" - 模型 Y 尺寸 (高度):",o.y.toFixed(2)),console.log(" - 模型 Z 尺寸 (深度):",o.z.toFixed(2)),console.log(" - tan(halfFovX):",Math.tan(d).toFixed(4)),console.log(" - tan(halfFovY):",Math.tan(r).toFixed(4)),console.log(" - X方向距离计算: (",(o.x*.5).toFixed(2),") / (",Math.tan(d).toFixed(4)," *",s,") =",a.toFixed(2)),console.log(" - Y方向距离计算: (",(o.y*.5).toFixed(2),") / (",Math.tan(r).toFixed(4)," *",s,") =",l.toFixed(2)),console.log(" - Z方向距离计算: (",(o.z*.5).toFixed(2),") / (",Math.tan(r).toFixed(4)," *",s,") =",f.toFixed(2)),console.log(" - X方向距离 (scale="+s+"):",a.toFixed(2)),console.log(" - Y方向距离 (scale="+s+"):",l.toFixed(2)),console.log(" - Z方向距离 (scale="+s+"):",f.toFixed(2)),console.log(" - 最大距离 (Max):",Math.max(a,l,f).toFixed(2))}console.log(" - 最终距离:",m.toFixed(2)),console.log(" - 缩放比例:",s),console.log(" - 动画:",w?"是 ("+z+"ms)":"否")}return{position:u,target:c,distance:m,viewType:t}});i(this,"on",(e,t)=>!e||!t||typeof t!="function"?(console.warn("ThreeIns.on: 无效的参数"),()=>{}):(this.eventsListener[e]||(this.eventsListener[e]=[]),this.eventsListener[e].push(t),()=>this.off(e,t)));this.isReady=!1,this.scene=new n.Scene({}),this.camera=new n.PerspectiveCamera(50,1,.1,2e3),this.renderer=new n.WebGLRenderer({antialias:!0,alpha:!0,precision:"mediump",logarithmicDepthBuffer:!0}),this.version=Y.version,this.onContextLost=this.onContextLost.bind(this),this.onContextRestored=this.onContextRestored.bind(this),this.onResize=this.onResize.bind(this),this.animate=this.animate.bind(this),this.resizeTimer=null,this.animationFrameId=null,t&&(this.initOpt=Object.assign(this.initOpt,t)),e&&this.setup(e)}updateCameraFOV(e,t){const h=this.initOpt.initialFov||50,s=Math.tan(Math.PI/180*h/2);this.camera.aspect=e/t,this.camera.fov=360/Math.PI*Math.atan(s*(t/e)),this.camera.updateProjectionMatrix()}initStats(){this.stats=new H,this.stats.dom.style.cssText="position:absolute;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000",this.el.appendChild(this.stats.dom)}initCss3dRenderer(){this.css3dRenderer=new A.CSS3DRenderer;const[e,t]=this.getTargetSize();this.css3dRenderer.setSize(e,t),this.css3dRenderer.domElement.style.position="absolute",this.css3dRenderer.domElement.style.pointerEvents="none",this.css3dRenderer.domElement.style.top=0,this.css3dRenderer.domElement.style.left=0,this.el.appendChild(this.css3dRenderer.domElement)}getTargetSize(){return document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement?[window.innerWidth,window.innerHeight]:this.el?!document.body.contains(this.el)&&(console.warn(`ThreeIns: 缓存的元素已失效,重新查询 ${this.selector}`),this.el=document.querySelector(this.selector),!this.el)?[0,0]:[this.el.clientWidth,this.el.clientHeight]:[0,0]}off(e,t){if(!e){this.eventsListener={};return}this.eventsListener[e]&&(t?this.eventsListener[e]=this.eventsListener[e].filter(h=>h!==t):this.eventsListener[e]=[])}dispose(){this.isDispose||(this.isDispose=!0,this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null),this.removeListener(),this.eventsListener={},this.stats&&this.stats.dom&&(this.stats.dom.remove(),this.stats=null),this.css3dRenderer&&(this.css3dRenderer.domElement.remove(),this.css3dRenderer=null),this.boxHelper&&(this.scene.remove(this.boxHelper),this.boxHelper=null),this.scene&&(X.disposeThreeObject(this.scene),this.scene=null),this.renderer&&(this.renderer.dispose(),this.renderer.domElement&&this.renderer.domElement.remove(),this.renderer=null),this.control&&(this.control.dispose(),this.control=null),this.camera=null,this.el=null,this.selector=null,console.log("ThreeIns: 资源已清理完成"))}}i(C,"ViewType",E);exports.ThreeIns=C;exports.ViewType=E;
|