diamon-engine 0.1.0 → 0.1.1
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/package/{OrbitCameraController-COklTntj.js → OrbitCameraController-CrUu0k53.js} +6 -6
- package/dist/package/{Spin3D-BW0UYD9X.js → Spin3D-CKrkOLkJ.js} +54 -29
- package/dist/package/engine3d.js +2 -2
- package/dist/package/index.js +2 -2
- package/dist/package/types/engine3d/components/OrbitCameraController.d.ts +1 -0
- package/dist/package/types/engine3d/core/Engine3D.d.ts +5 -0
- package/dist/package/types/engine3d/systems/Input3D.d.ts +5 -1
- package/dist/package/workbench.js +211 -177
- package/package.json +1 -1
package/dist/package/{OrbitCameraController-COklTntj.js → OrbitCameraController-CrUu0k53.js}
RENAMED
|
@@ -365,28 +365,28 @@ class f extends a {
|
|
|
365
365
|
maxDistance;
|
|
366
366
|
azimuth;
|
|
367
367
|
polar;
|
|
368
|
+
cameraDirty = !0;
|
|
368
369
|
constructor(t = {}) {
|
|
369
370
|
super(), this.target.copy(t.target ?? new i.Vector3()), this.distance = t.distance ?? 9, this.minDistance = t.minDistance ?? 4, this.maxDistance = t.maxDistance ?? 18, this.azimuth = t.azimuth ?? Math.PI * 0.25, this.polar = t.polar ?? Math.PI * 0.32;
|
|
370
371
|
}
|
|
371
372
|
onUpdate() {
|
|
372
373
|
const t = this.scene, e = this.engine?.input;
|
|
373
|
-
if (!t || !e)
|
|
374
|
-
return;
|
|
375
|
-
e.isMouseDown(0) && (this.azimuth -= e.pointerDelta.x * 6e-3, this.polar = i.MathUtils.clamp(
|
|
374
|
+
if (!t || !e || (e.isMouseDown(0) && e.pointerDelta.lengthSq() > 0 && (this.azimuth -= e.pointerDelta.x * 6e-3, this.polar = i.MathUtils.clamp(
|
|
376
375
|
this.polar - e.pointerDelta.y * 6e-3,
|
|
377
376
|
0.18,
|
|
378
377
|
Math.PI * 0.48
|
|
379
|
-
)), e.wheelDelta !== 0 && (this.distance = i.MathUtils.clamp(
|
|
378
|
+
), this.cameraDirty = !0), e.wheelDelta !== 0 && (this.distance = i.MathUtils.clamp(
|
|
380
379
|
this.distance + e.wheelDelta * 0.01,
|
|
381
380
|
this.minDistance,
|
|
382
381
|
this.maxDistance
|
|
383
|
-
))
|
|
382
|
+
), this.cameraDirty = !0), !this.cameraDirty))
|
|
383
|
+
return;
|
|
384
384
|
const s = Math.sin(this.polar) * this.distance;
|
|
385
385
|
t.camera.position.set(
|
|
386
386
|
this.target.x + Math.cos(this.azimuth) * s,
|
|
387
387
|
this.target.y + Math.cos(this.polar) * this.distance,
|
|
388
388
|
this.target.z + Math.sin(this.azimuth) * s
|
|
389
|
-
), t.camera.lookAt(this.target);
|
|
389
|
+
), t.camera.lookAt(this.target), this.cameraDirty = !1;
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
export {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { C as f } from "./OrbitCameraController-
|
|
3
|
-
class
|
|
1
|
+
import * as n from "three";
|
|
2
|
+
import { C as f } from "./OrbitCameraController-CrUu0k53.js";
|
|
3
|
+
class w {
|
|
4
4
|
constructor(e) {
|
|
5
|
-
this.canvas = e, window.addEventListener("keydown", this.handleKeyDown), window.addEventListener("keyup", this.handleKeyUp), e.addEventListener("pointermove", this.handlePointerMove), e.addEventListener("pointerdown", this.handlePointerDown), e.addEventListener("pointerup", this.handlePointerUp), e.addEventListener("pointercancel", this.handlePointerUp), e.addEventListener("wheel", this.handleWheel, { passive: !1 });
|
|
5
|
+
this.canvas = e, this.refreshCanvasRect(), window.addEventListener("keydown", this.handleKeyDown), window.addEventListener("keyup", this.handleKeyUp), window.addEventListener("resize", this.handleWindowResize), e.addEventListener("pointermove", this.handlePointerMove), e.addEventListener("pointerdown", this.handlePointerDown), e.addEventListener("pointerup", this.handlePointerUp), e.addEventListener("pointercancel", this.handlePointerUp), e.addEventListener("wheel", this.handleWheel, { passive: !1 });
|
|
6
6
|
}
|
|
7
7
|
canvas;
|
|
8
|
-
pointer = new
|
|
9
|
-
pointerDelta = new
|
|
8
|
+
pointer = new n.Vector2();
|
|
9
|
+
pointerDelta = new n.Vector2();
|
|
10
10
|
wheelDelta = 0;
|
|
11
11
|
downKeys = /* @__PURE__ */ new Set();
|
|
12
12
|
pressedKeys = /* @__PURE__ */ new Set();
|
|
@@ -14,6 +14,8 @@ class y {
|
|
|
14
14
|
downButtons = /* @__PURE__ */ new Set();
|
|
15
15
|
pressedButtons = /* @__PURE__ */ new Set();
|
|
16
16
|
releasedButtons = /* @__PURE__ */ new Set();
|
|
17
|
+
canvasLeft = 0;
|
|
18
|
+
canvasTop = 0;
|
|
17
19
|
isKeyDown(e) {
|
|
18
20
|
return this.downKeys.has(this.normalizeKey(e));
|
|
19
21
|
}
|
|
@@ -42,21 +44,27 @@ class y {
|
|
|
42
44
|
this.downKeys.delete(t), this.releasedKeys.add(t);
|
|
43
45
|
};
|
|
44
46
|
handlePointerMove = (e) => {
|
|
45
|
-
const t = this.
|
|
46
|
-
this.pointerDelta.
|
|
47
|
+
const t = this.pointer.x, s = this.pointer.y;
|
|
48
|
+
this.setPointerFromEvent(e), this.pointerDelta.x += this.pointer.x - t, this.pointerDelta.y += this.pointer.y - s;
|
|
47
49
|
};
|
|
48
50
|
handlePointerDown = (e) => {
|
|
49
|
-
this.canvas.focus(), this.canvas.setPointerCapture(e.pointerId), this.
|
|
51
|
+
this.refreshCanvasRect(), this.canvas.focus(), this.canvas.setPointerCapture(e.pointerId), this.setPointerFromEvent(e), this.pointerDelta.set(0, 0), this.downButtons.add(e.button), this.pressedButtons.add(e.button);
|
|
50
52
|
};
|
|
51
53
|
handlePointerUp = (e) => {
|
|
52
|
-
this.
|
|
54
|
+
this.setPointerFromEvent(e), this.downButtons.delete(e.button), this.releasedButtons.add(e.button);
|
|
53
55
|
};
|
|
54
56
|
handleWheel = (e) => {
|
|
55
57
|
e.preventDefault(), this.wheelDelta += e.deltaY;
|
|
56
58
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
handleWindowResize = () => {
|
|
60
|
+
this.refreshCanvasRect();
|
|
61
|
+
};
|
|
62
|
+
refreshCanvasRect() {
|
|
63
|
+
const e = this.canvas.getBoundingClientRect();
|
|
64
|
+
this.canvasLeft = e.left, this.canvasTop = e.top;
|
|
65
|
+
}
|
|
66
|
+
setPointerFromEvent(e) {
|
|
67
|
+
this.pointer.set(e.clientX - this.canvasLeft, e.clientY - this.canvasTop);
|
|
60
68
|
}
|
|
61
69
|
getKeyAliases(e) {
|
|
62
70
|
return [e.code, e.key].filter(Boolean).map((t) => this.normalizeKey(t));
|
|
@@ -65,15 +73,21 @@ class y {
|
|
|
65
73
|
return e.length === 1 ? e.toLowerCase() : e;
|
|
66
74
|
}
|
|
67
75
|
}
|
|
68
|
-
class
|
|
76
|
+
class v {
|
|
69
77
|
constructor(e) {
|
|
70
|
-
this.options = e, this.options.canvas.tabIndex = 0, this.input = new
|
|
78
|
+
this.options = e, this.options.canvas.tabIndex = 0, this.input = new w(this.options.canvas), this.captureCanvasSize(), typeof ResizeObserver < "u" && (this.resizeObserver = new ResizeObserver((t) => {
|
|
79
|
+
const s = t[t.length - 1];
|
|
80
|
+
if (!s)
|
|
81
|
+
return;
|
|
82
|
+
const i = Math.max(1, Math.floor(s.contentRect.width)), a = Math.max(1, Math.floor(s.contentRect.height));
|
|
83
|
+
i === this.canvasWidth && a === this.canvasHeight || (this.canvasWidth = i, this.canvasHeight = a, this.resizeDirty = !0);
|
|
84
|
+
}), this.resizeObserver.observe(this.options.canvas)), window.addEventListener("resize", this.handleWindowResize), this.renderer = new n.WebGLRenderer({
|
|
71
85
|
canvas: this.options.canvas,
|
|
72
86
|
antialias: !0,
|
|
73
87
|
alpha: !1,
|
|
74
88
|
preserveDrawingBuffer: this.options.preserveDrawingBuffer ?? !1,
|
|
75
89
|
powerPreference: "high-performance"
|
|
76
|
-
}), this.renderer.setClearColor(new
|
|
90
|
+
}), this.renderer.setClearColor(new n.Color(e.background ?? "#07100f"), 1), this.configureShadows(e.shadowQuality ?? "off"), this.renderer.outputColorSpace = n.SRGBColorSpace;
|
|
77
91
|
}
|
|
78
92
|
options;
|
|
79
93
|
renderer;
|
|
@@ -107,6 +121,12 @@ class S {
|
|
|
107
121
|
resizeDirty = !0;
|
|
108
122
|
slowQualitySamples = 0;
|
|
109
123
|
fastQualitySamples = 0;
|
|
124
|
+
canvasWidth = 1;
|
|
125
|
+
canvasHeight = 1;
|
|
126
|
+
resizeObserver;
|
|
127
|
+
handleWindowResize = () => {
|
|
128
|
+
this.resizeDirty = !0;
|
|
129
|
+
};
|
|
110
130
|
setScene(e) {
|
|
111
131
|
this.activeScene?.stopInternal(), this.activeScene = e, e.startInternal(this), this.resize(), this.renderOnce();
|
|
112
132
|
}
|
|
@@ -121,17 +141,17 @@ class S {
|
|
|
121
141
|
}
|
|
122
142
|
sampleFrame() {
|
|
123
143
|
this.renderOnce();
|
|
124
|
-
const e = this.renderer.getContext(), t = e.drawingBufferWidth, s = e.drawingBufferHeight, i = Math.max(1, Math.min(t, 96)),
|
|
125
|
-
e.readPixels(
|
|
126
|
-
let
|
|
127
|
-
for (let
|
|
128
|
-
const
|
|
129
|
-
(Math.max(l, d
|
|
144
|
+
const e = this.renderer.getContext(), t = e.drawingBufferWidth, s = e.drawingBufferHeight, i = Math.max(1, Math.min(t, 96)), a = Math.max(1, Math.min(s, 64)), u = Math.floor((t - i) / 2), m = Math.floor((s - a) / 2), r = new Uint8Array(i * a * 4);
|
|
145
|
+
e.readPixels(u, m, i, a, e.RGBA, e.UNSIGNED_BYTE, r);
|
|
146
|
+
let p = 0;
|
|
147
|
+
for (let h = 0; h < r.length; h += 4) {
|
|
148
|
+
const o = r[h], l = r[h + 1], d = r[h + 2];
|
|
149
|
+
(Math.max(o, l, d) - Math.min(o, l, d) > 12 || o + l + d > 60) && (p += 1);
|
|
130
150
|
}
|
|
131
151
|
return {
|
|
132
152
|
width: t,
|
|
133
153
|
height: s,
|
|
134
|
-
coloredRatio:
|
|
154
|
+
coloredRatio: p / (r.length / 4)
|
|
135
155
|
};
|
|
136
156
|
}
|
|
137
157
|
tick = (e) => {
|
|
@@ -145,10 +165,15 @@ class S {
|
|
|
145
165
|
this.stats.frameTimeMs = Math.round(i * 10) / 10, this.updateFrameTimeAverage(i), this.updateFps(t), this.updateRenderStats(), this.input.endFrame(), this.animationFrame = requestAnimationFrame(this.tick);
|
|
146
166
|
};
|
|
147
167
|
resize() {
|
|
148
|
-
|
|
149
|
-
|
|
168
|
+
this.resizeDirty && !this.resizeObserver && this.captureCanvasSize();
|
|
169
|
+
const e = this.canvasWidth, t = this.canvasHeight, s = this.options.maxPixelRatio ?? 2, i = this.options.minPixelRatio ?? 0.6, a = Math.round(
|
|
170
|
+
Math.max(i, Math.min(window.devicePixelRatio || 1, s) * this.qualityScale) * 100
|
|
150
171
|
) / 100;
|
|
151
|
-
this.stats.width =
|
|
172
|
+
this.stats.width = e, this.stats.height = t, this.stats.pixelRatio = a, this.stats.qualityScale = Math.round(this.qualityScale * 100) / 100, !(!this.resizeDirty && e === this.lastResizeWidth && t === this.lastResizeHeight && a === this.lastPixelRatio) && (this.resizeDirty = !1, this.lastResizeWidth = e, this.lastResizeHeight = t, this.lastPixelRatio = a, this.renderer.setPixelRatio(a), this.renderer.setSize(e, t, !1), this.activeScene && (this.activeScene.camera.aspect = e / t, this.activeScene.camera.updateProjectionMatrix()));
|
|
173
|
+
}
|
|
174
|
+
captureCanvasSize() {
|
|
175
|
+
const e = this.options.canvas.getBoundingClientRect();
|
|
176
|
+
this.canvasWidth = Math.max(1, Math.floor(e.width)), this.canvasHeight = Math.max(1, Math.floor(e.height));
|
|
152
177
|
}
|
|
153
178
|
updateFrameTimeAverage(e) {
|
|
154
179
|
this.frameTimeAverageMs = this.frameTimeAverageMs === 0 ? e : this.frameTimeAverageMs * 0.88 + e * 0.12, this.stats.frameTimeAverageMs = Math.round(this.frameTimeAverageMs * 10) / 10;
|
|
@@ -172,7 +197,7 @@ class S {
|
|
|
172
197
|
this.fastQualitySamples >= 4 && this.qualityScale < 1 && (this.qualityScale = Math.min(1, this.qualityScale + 0.04), this.resizeDirty = !0, this.fastQualitySamples = 0);
|
|
173
198
|
}
|
|
174
199
|
configureShadows(e) {
|
|
175
|
-
this.renderer.shadowMap.enabled = e !== "off", this.renderer.shadowMap.enabled && (this.renderer.shadowMap.type = e === "high" ?
|
|
200
|
+
this.renderer.shadowMap.enabled = e !== "off", this.renderer.shadowMap.enabled && (this.renderer.shadowMap.type = e === "high" ? n.PCFSoftShadowMap : n.PCFShadowMap);
|
|
176
201
|
}
|
|
177
202
|
}
|
|
178
203
|
class g extends f {
|
|
@@ -187,7 +212,7 @@ class g extends f {
|
|
|
187
212
|
}
|
|
188
213
|
}
|
|
189
214
|
export {
|
|
190
|
-
|
|
191
|
-
|
|
215
|
+
v as E,
|
|
216
|
+
w as I,
|
|
192
217
|
g as S
|
|
193
218
|
};
|
package/dist/package/engine3d.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as t, E as n, L as s, M as o, O as r, a as D, S as i } from "./OrbitCameraController-
|
|
2
|
-
import { E as p, I as C, S as E } from "./Spin3D-
|
|
1
|
+
import { C as t, E as n, L as s, M as o, O as r, a as D, S as i } from "./OrbitCameraController-CrUu0k53.js";
|
|
2
|
+
import { E as p, I as C, S as E } from "./Spin3D-CKrkOLkJ.js";
|
|
3
3
|
export {
|
|
4
4
|
t as Component3D,
|
|
5
5
|
p as Engine3D,
|
package/dist/package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as t, E as n, L as s, M as o, O as r, a as D, S as i } from "./OrbitCameraController-
|
|
2
|
-
import { E as p, I as C, S as E } from "./Spin3D-
|
|
1
|
+
import { C as t, E as n, L as s, M as o, O as r, a as D, S as i } from "./OrbitCameraController-CrUu0k53.js";
|
|
2
|
+
import { E as p, I as C, S as E } from "./Spin3D-CKrkOLkJ.js";
|
|
3
3
|
export {
|
|
4
4
|
t as Component3D,
|
|
5
5
|
p as Engine3D,
|
|
@@ -45,6 +45,10 @@ export declare class Engine3D {
|
|
|
45
45
|
private resizeDirty;
|
|
46
46
|
private slowQualitySamples;
|
|
47
47
|
private fastQualitySamples;
|
|
48
|
+
private canvasWidth;
|
|
49
|
+
private canvasHeight;
|
|
50
|
+
private readonly resizeObserver?;
|
|
51
|
+
private readonly handleWindowResize;
|
|
48
52
|
constructor(options: Engine3DOptions);
|
|
49
53
|
setScene(scene: Scene3D): void;
|
|
50
54
|
start(): void;
|
|
@@ -57,6 +61,7 @@ export declare class Engine3D {
|
|
|
57
61
|
};
|
|
58
62
|
private readonly tick;
|
|
59
63
|
private resize;
|
|
64
|
+
private captureCanvasSize;
|
|
60
65
|
private updateFrameTimeAverage;
|
|
61
66
|
private updateFps;
|
|
62
67
|
private updateRenderStats;
|
|
@@ -10,6 +10,8 @@ export declare class Input3D {
|
|
|
10
10
|
private readonly downButtons;
|
|
11
11
|
private readonly pressedButtons;
|
|
12
12
|
private readonly releasedButtons;
|
|
13
|
+
private canvasLeft;
|
|
14
|
+
private canvasTop;
|
|
13
15
|
constructor(canvas: HTMLCanvasElement);
|
|
14
16
|
isKeyDown(key: string): boolean;
|
|
15
17
|
wasKeyPressed(key: string): boolean;
|
|
@@ -23,7 +25,9 @@ export declare class Input3D {
|
|
|
23
25
|
private readonly handlePointerDown;
|
|
24
26
|
private readonly handlePointerUp;
|
|
25
27
|
private readonly handleWheel;
|
|
26
|
-
private
|
|
28
|
+
private readonly handleWindowResize;
|
|
29
|
+
private refreshCanvasRect;
|
|
30
|
+
private setPointerFromEvent;
|
|
27
31
|
private getKeyAliases;
|
|
28
32
|
private normalizeKey;
|
|
29
33
|
}
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import * as l from "three";
|
|
2
|
-
import { GLTFLoader as
|
|
3
|
-
import { E as m, S as
|
|
4
|
-
const
|
|
2
|
+
import { GLTFLoader as T } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
3
|
+
import { E as m, S as O, O as y, M as C, a as U, L as x, C as P } from "./OrbitCameraController-CrUu0k53.js";
|
|
4
|
+
const E = {
|
|
5
5
|
box: "#1ec7a6",
|
|
6
6
|
sphere: "#f5c95f",
|
|
7
7
|
cylinder: "#4ba3ff",
|
|
8
8
|
cone: "#ef6f50",
|
|
9
9
|
torus: "#d989ff"
|
|
10
|
-
},
|
|
10
|
+
}, $ = {
|
|
11
11
|
box: "Cube",
|
|
12
12
|
sphere: "Sphere",
|
|
13
13
|
cylinder: "Cylinder",
|
|
14
14
|
cone: "Cone",
|
|
15
15
|
torus: "Torus"
|
|
16
|
-
},
|
|
16
|
+
}, A = {
|
|
17
17
|
box: { kind: "box", width: 1, height: 1, depth: 1 },
|
|
18
18
|
sphere: { kind: "sphere", radius: 0.62 },
|
|
19
19
|
cylinder: { kind: "cylinder", radius: 0.52, height: 1.15 },
|
|
20
20
|
cone: { kind: "cone", radius: 0.6, height: 1.25 },
|
|
21
21
|
torus: { kind: "torus", radius: 0.62, tube: 0.18 }
|
|
22
|
-
}, D = 700, H = 2500,
|
|
23
|
-
function
|
|
22
|
+
}, D = 700, H = 2500, _ = 12e4, F = 8e3, N = 5e9, j = 0.07, B = 1e3;
|
|
23
|
+
function se(r) {
|
|
24
24
|
return new G(r);
|
|
25
25
|
}
|
|
26
26
|
class G {
|
|
27
27
|
constructor(e) {
|
|
28
|
-
this.ui = e, this.scene.threeScene.background = new l.Color("#07100f"), this.scene.threeScene.fog = new l.Fog("#07100f", 32, 90), this.scene.add(
|
|
28
|
+
this.ui = e, this.scene.threeScene.background = new l.Color("#07100f"), this.scene.threeScene.fog = new l.Fog("#07100f", 32, 90), this.scene.add(W()), this.scene.add(q()), this.scene.add(K()), this.scene.add(V()), this.scene.add(X());
|
|
29
29
|
const t = new m("Workbench Runtime");
|
|
30
|
-
t.addComponent(new
|
|
30
|
+
t.addComponent(new z(() => this.updateRuntimeUi(), 0.25)), this.scene.add(t), this.addPrimitive("box"), this.addPrimitive("sphere"), this.addPrimitive("cylinder"), this.commitHistory("初始场景"), this.bindCanvasPicking(), this.bindSceneTreeSelection(), this.bindPrefabList(), this.refreshUi(), this.log("引擎编辑器已启动");
|
|
31
31
|
}
|
|
32
32
|
ui;
|
|
33
|
-
scene = new
|
|
33
|
+
scene = new O("Engine Workbench");
|
|
34
34
|
objects = /* @__PURE__ */ new Map();
|
|
35
35
|
resources = /* @__PURE__ */ new Map();
|
|
36
36
|
prefabs = /* @__PURE__ */ new Map();
|
|
@@ -40,16 +40,22 @@ class G {
|
|
|
40
40
|
clipboard = [];
|
|
41
41
|
raycaster = new l.Raycaster();
|
|
42
42
|
pointer = new l.Vector2();
|
|
43
|
-
gltfLoader = new
|
|
43
|
+
gltfLoader = new T();
|
|
44
44
|
objectSerial = 0;
|
|
45
45
|
resourceSerial = 0;
|
|
46
46
|
prefabSerial = 0;
|
|
47
47
|
groupSerial = 0;
|
|
48
48
|
lastStressResult = "未测试";
|
|
49
49
|
restoring = !1;
|
|
50
|
+
logicalCountsDirty = !0;
|
|
51
|
+
logicalObjectCountCache = 0;
|
|
52
|
+
logicalVisibleObjectCountCache = 0;
|
|
53
|
+
lastMemorySampleMs = 0;
|
|
54
|
+
memoryTextCache = "未知";
|
|
55
|
+
uiTextCache = /* @__PURE__ */ new Map();
|
|
50
56
|
addPrimitive(e) {
|
|
51
57
|
const t = this.createPrimitiveRecord(e);
|
|
52
|
-
return this.selectOnly(t.id), this.commitHistory(`添加 ${
|
|
58
|
+
return this.selectOnly(t.id), this.commitHistory(`添加 ${$[e]}`), this.refreshUi(), t.entity;
|
|
53
59
|
}
|
|
54
60
|
copySelection() {
|
|
55
61
|
this.clipboard.length = 0;
|
|
@@ -161,40 +167,40 @@ class G {
|
|
|
161
167
|
const t = performance.now();
|
|
162
168
|
this.selectedIds.clear();
|
|
163
169
|
const s = Math.ceil(Math.sqrt(e));
|
|
164
|
-
for (let
|
|
165
|
-
const
|
|
170
|
+
for (let n = 0; n < e; n += 1) {
|
|
171
|
+
const o = this.createPrimitiveRecord("box", {
|
|
166
172
|
name: `Stress Cube ${this.objectSerial + 1}`,
|
|
167
|
-
color:
|
|
173
|
+
color: n % 2 === 0 ? "#1ec7a6" : "#4ba3ff",
|
|
168
174
|
position: [
|
|
169
|
-
|
|
175
|
+
n % s * 0.78 - s * 0.39,
|
|
170
176
|
0.45,
|
|
171
|
-
Math.floor(
|
|
177
|
+
Math.floor(n / s) * 0.78 + 5
|
|
172
178
|
],
|
|
173
179
|
layer: 2,
|
|
174
180
|
group: "Stress Objects"
|
|
175
181
|
});
|
|
176
|
-
|
|
182
|
+
n < 20 && this.selectedIds.add(o.id);
|
|
177
183
|
}
|
|
178
|
-
const
|
|
179
|
-
this.lastStressResult = `新增 ${e} 个对象,用时 ${
|
|
184
|
+
const i = Math.round(performance.now() - t);
|
|
185
|
+
this.lastStressResult = `新增 ${e} 个对象,用时 ${i}ms`, this.commitHistory("大量对象压力测试"), this.refreshUi(), this.log(this.lastStressResult);
|
|
180
186
|
}
|
|
181
187
|
addInstancedStressObjects(e) {
|
|
182
188
|
const t = performance.now(), s = new m(`Instanced Stress ${e}`);
|
|
183
189
|
s.tag = "workbench-object";
|
|
184
|
-
const
|
|
190
|
+
const i = new l.BoxGeometry(0.42, 0.42, 0.42), n = new l.MeshStandardMaterial({
|
|
185
191
|
color: "#1ec7a6",
|
|
186
192
|
roughness: 0.65,
|
|
187
193
|
metalness: 0.08
|
|
188
|
-
}),
|
|
189
|
-
|
|
190
|
-
const
|
|
194
|
+
}), o = new l.InstancedMesh(i, n, e);
|
|
195
|
+
o.castShadow = !1, o.receiveShadow = !1;
|
|
196
|
+
const a = new l.Matrix4(), c = Math.ceil(Math.sqrt(e));
|
|
191
197
|
for (let f = 0; f < e; f += 1) {
|
|
192
|
-
const g = f %
|
|
193
|
-
|
|
198
|
+
const g = f % c * 0.55 - c * 0.275, S = Math.floor(f / c) * 0.55 + 16;
|
|
199
|
+
a.makeTranslation(g, 0.35, S), o.setMatrixAt(f, a);
|
|
194
200
|
}
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
id:
|
|
201
|
+
o.instanceMatrix.needsUpdate = !0, o.userData.workbenchId = `object-${this.objectSerial + 1}`, s.addComponent(new y(o, { disposeOnDestroy: !0 }));
|
|
202
|
+
const h = this.nextObjectId(), u = {
|
|
203
|
+
id: h,
|
|
198
204
|
entity: s,
|
|
199
205
|
kind: "instanced",
|
|
200
206
|
primitiveKind: "box",
|
|
@@ -205,26 +211,26 @@ class G {
|
|
|
205
211
|
locked: !1,
|
|
206
212
|
visible: !0
|
|
207
213
|
};
|
|
208
|
-
|
|
214
|
+
o.userData.workbenchId = h, this.scene.add(s), this.objects.set(h, u), this.invalidateLogicalCounts(), this.selectOnly(h);
|
|
209
215
|
const v = Math.round(performance.now() - t);
|
|
210
216
|
this.lastStressResult = `实例化 ${e} 个对象,用时 ${v}ms`, this.commitHistory("实例化压力测试"), this.refreshUi(), this.log(this.lastStressResult);
|
|
211
217
|
}
|
|
212
218
|
addMegaInstancedStressObjects(e) {
|
|
213
219
|
const t = performance.now(), s = this.getMegaStressRecord();
|
|
214
220
|
if (s) {
|
|
215
|
-
const
|
|
216
|
-
this.updateMegaStressRecord(s,
|
|
221
|
+
const i = (s.instancedCount ?? 0) + e;
|
|
222
|
+
this.updateMegaStressRecord(s, i, t, "合并极限压力层", "极限实例化累计");
|
|
217
223
|
return;
|
|
218
224
|
}
|
|
219
225
|
this.createMegaStressRecord(e, t, "500万对象极限压力测试", "极限实例化");
|
|
220
226
|
}
|
|
221
227
|
setMegaInstancedStressObjects(e) {
|
|
222
|
-
const t = performance.now(), s =
|
|
223
|
-
if (
|
|
224
|
-
this.updateMegaStressRecord(
|
|
228
|
+
const t = performance.now(), s = Z(e), i = `设置${s}极限压力层`, n = `${s}目标`, o = this.getMegaStressRecord();
|
|
229
|
+
if (o) {
|
|
230
|
+
this.updateMegaStressRecord(o, e, t, i, n);
|
|
225
231
|
return;
|
|
226
232
|
}
|
|
227
|
-
this.createMegaStressRecord(e, t,
|
|
233
|
+
this.createMegaStressRecord(e, t, i, n);
|
|
228
234
|
}
|
|
229
235
|
importAssets(e) {
|
|
230
236
|
const t = Array.from(e);
|
|
@@ -248,38 +254,38 @@ class G {
|
|
|
248
254
|
};
|
|
249
255
|
}
|
|
250
256
|
createPrimitiveRecord(e, t = {}) {
|
|
251
|
-
const s = this.nextObjectId(),
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
-3 +
|
|
257
|
+
const s = this.nextObjectId(), i = this.objectSerial, n = new m(t.name ?? `${$[e]} ${i}`);
|
|
258
|
+
n.tag = "workbench-object";
|
|
259
|
+
const o = t.position ?? [
|
|
260
|
+
-3 + i % 6 * 1.15,
|
|
255
261
|
0.62,
|
|
256
|
-
Math.floor(
|
|
262
|
+
Math.floor(i / 6) * 1.15
|
|
257
263
|
];
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
new
|
|
262
|
-
...
|
|
263
|
-
color:
|
|
264
|
+
n.position.set(o[0], o[1], o[2]), t.rotation && n.rotation.set(t.rotation[0], t.rotation[1], t.rotation[2]), t.scale && n.scale.set(t.scale[0], t.scale[1], t.scale[2]);
|
|
265
|
+
const a = t.color ?? E[e];
|
|
266
|
+
n.addComponent(
|
|
267
|
+
new C({
|
|
268
|
+
...A[e],
|
|
269
|
+
color: a,
|
|
264
270
|
segments: 24,
|
|
265
271
|
metalness: 0.14,
|
|
266
272
|
roughness: 0.5
|
|
267
273
|
})
|
|
268
|
-
),
|
|
269
|
-
|
|
274
|
+
), n.object.traverse((h) => {
|
|
275
|
+
h.userData.workbenchId = s;
|
|
270
276
|
});
|
|
271
|
-
const
|
|
277
|
+
const c = {
|
|
272
278
|
id: s,
|
|
273
|
-
entity:
|
|
279
|
+
entity: n,
|
|
274
280
|
kind: "primitive",
|
|
275
281
|
primitiveKind: e,
|
|
276
|
-
color:
|
|
282
|
+
color: a,
|
|
277
283
|
layer: t.layer ?? 0,
|
|
278
284
|
group: t.group ?? "",
|
|
279
285
|
locked: t.locked ?? !1,
|
|
280
286
|
visible: t.visible ?? !0
|
|
281
287
|
};
|
|
282
|
-
return
|
|
288
|
+
return n.enabled = c.visible, n.object.visible = c.visible, this.scene.add(n), this.objects.set(s, c), this.invalidateLogicalCounts(), c;
|
|
283
289
|
}
|
|
284
290
|
createRecordFromSerialized(e) {
|
|
285
291
|
return e.kind === "mega-instanced" ? this.createMegaInstancedRecordFromSerialized(e) : e.kind === "instanced" ? this.createInstancedRecordFromSerialized(e) : e.kind === "model" ? this.createModelPlaceholder(e) : this.createPrimitiveRecord(e.primitiveKind ?? "box", e);
|
|
@@ -308,27 +314,27 @@ class G {
|
|
|
308
314
|
}
|
|
309
315
|
registerAsset(e) {
|
|
310
316
|
this.resourceSerial += 1;
|
|
311
|
-
const t = `asset-${this.resourceSerial}`, s = J(e.name),
|
|
317
|
+
const t = `asset-${this.resourceSerial}`, s = J(e.name), i = URL.createObjectURL(e), n = {
|
|
312
318
|
id: t,
|
|
313
319
|
kind: s,
|
|
314
320
|
name: e.name,
|
|
315
321
|
size: e.size,
|
|
316
|
-
url:
|
|
322
|
+
url: i
|
|
317
323
|
};
|
|
318
|
-
this.resources.set(t,
|
|
319
|
-
|
|
320
|
-
(
|
|
321
|
-
const
|
|
322
|
-
|
|
324
|
+
this.resources.set(t, n), this.log(`导入资源:${e.name}`), s === "model" && this.gltfLoader.load(
|
|
325
|
+
i,
|
|
326
|
+
(o) => {
|
|
327
|
+
const a = new m(e.name.replace(/\.[^.]+$/, ""));
|
|
328
|
+
a.tag = "workbench-object", a.position.set(0, 0, 3 + this.objects.size * 0.45), o.scene.traverse((u) => {
|
|
323
329
|
u.userData.workbenchId = t, u instanceof l.Mesh && (u.castShadow = !0, u.receiveShadow = !0);
|
|
324
|
-
}),
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
u.userData.workbenchId =
|
|
330
|
+
}), a.addComponent(new y(o.scene));
|
|
331
|
+
const c = this.nextObjectId();
|
|
332
|
+
o.scene.traverse((u) => {
|
|
333
|
+
u.userData.workbenchId = c;
|
|
328
334
|
});
|
|
329
|
-
const
|
|
330
|
-
id:
|
|
331
|
-
entity:
|
|
335
|
+
const h = {
|
|
336
|
+
id: c,
|
|
337
|
+
entity: a,
|
|
332
338
|
kind: "model",
|
|
333
339
|
resourceId: t,
|
|
334
340
|
color: "#ffffff",
|
|
@@ -337,20 +343,20 @@ class G {
|
|
|
337
343
|
locked: !1,
|
|
338
344
|
visible: !0
|
|
339
345
|
};
|
|
340
|
-
this.scene.add(
|
|
346
|
+
this.scene.add(a), this.objects.set(c, h), this.invalidateLogicalCounts(), this.selectOnly(c), this.commitHistory("导入模型"), this.refreshUi(), this.log(`模型已加入场景:${e.name}`);
|
|
341
347
|
},
|
|
342
348
|
void 0,
|
|
343
|
-
(
|
|
349
|
+
(o) => this.log(`模型加载失败:${o instanceof Error ? o.message : String(o)}`)
|
|
344
350
|
);
|
|
345
351
|
}
|
|
346
|
-
createMegaStressRecord(e, t, s,
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
const
|
|
352
|
-
id:
|
|
353
|
-
entity:
|
|
352
|
+
createMegaStressRecord(e, t, s, i) {
|
|
353
|
+
const n = this.nextObjectId(), o = new m(`Mega Instance Stress ${e}`);
|
|
354
|
+
o.tag = "workbench-object";
|
|
355
|
+
const a = this.createMegaStressPoints(e, n);
|
|
356
|
+
o.addComponent(new y(a, { disposeOnDestroy: !0 }));
|
|
357
|
+
const c = {
|
|
358
|
+
id: n,
|
|
359
|
+
entity: o,
|
|
354
360
|
kind: "mega-instanced",
|
|
355
361
|
primitiveKind: "box",
|
|
356
362
|
instancedCount: e,
|
|
@@ -360,33 +366,33 @@ class G {
|
|
|
360
366
|
locked: !1,
|
|
361
367
|
visible: !0
|
|
362
368
|
};
|
|
363
|
-
return this.scene.add(
|
|
369
|
+
return this.scene.add(o), this.objects.set(n, c), this.invalidateLogicalCounts(), this.selectOnly(n), this.finishMegaStressUpdate(c, t, s, i), c;
|
|
364
370
|
}
|
|
365
|
-
updateMegaStressRecord(e, t, s,
|
|
366
|
-
const
|
|
367
|
-
e.entity.getComponent(y)?.replaceObject(
|
|
371
|
+
updateMegaStressRecord(e, t, s, i, n) {
|
|
372
|
+
const o = this.createMegaStressPoints(t, e.id);
|
|
373
|
+
e.entity.getComponent(y)?.replaceObject(o), e.instancedCount = t, e.entity.name = `Mega Instance Stress ${t}`, e.entity.object.name = e.entity.name, this.invalidateLogicalCounts(), this.selectOnly(e.id), this.finishMegaStressUpdate(e, s, i, n);
|
|
368
374
|
}
|
|
369
|
-
finishMegaStressUpdate(e, t, s,
|
|
370
|
-
const
|
|
371
|
-
this.lastStressResult = `${
|
|
375
|
+
finishMegaStressUpdate(e, t, s, i) {
|
|
376
|
+
const n = e.instancedCount ?? 0, o = k(n), a = Math.round(performance.now() - t);
|
|
377
|
+
this.lastStressResult = `${i} ${n} 个对象,渲染代表点 ${o},用时 ${a}ms`, this.commitHistory(s), this.refreshUi(), this.log(this.lastStressResult);
|
|
372
378
|
}
|
|
373
379
|
createMegaStressPoints(e, t) {
|
|
374
|
-
const s =
|
|
380
|
+
const s = k(e), i = new Float32Array(s * 3), n = H, o = Math.ceil(e / n), a = (n - 1) * j, c = (o - 1) * j;
|
|
375
381
|
for (let g = 0; g < s; g += 1) {
|
|
376
|
-
const S = g * 3,
|
|
377
|
-
|
|
382
|
+
const S = g * 3, M = Math.min(e - 1, Math.floor(g / s * e)), I = M % n, L = Math.floor(M / n);
|
|
383
|
+
i[S] = I * j - a * 0.5, i[S + 1] = 0.32 + g * 17 % 11 * 0.01, i[S + 2] = L * j + 8;
|
|
378
384
|
}
|
|
379
|
-
const
|
|
380
|
-
u.setUsage(l.StaticDrawUsage),
|
|
381
|
-
new l.Vector3(0, 0.4, 8 +
|
|
382
|
-
Math.sqrt((
|
|
385
|
+
const h = new l.BufferGeometry(), u = new l.BufferAttribute(i, 3);
|
|
386
|
+
u.setUsage(l.StaticDrawUsage), h.setAttribute("position", u), h.boundingSphere = new l.Sphere(
|
|
387
|
+
new l.Vector3(0, 0.4, 8 + c * 0.5),
|
|
388
|
+
Math.sqrt((a * 0.5) ** 2 + (c * 0.5) ** 2 + 2)
|
|
383
389
|
);
|
|
384
390
|
const v = new l.PointsMaterial({
|
|
385
391
|
color: "#75f0c8",
|
|
386
392
|
size: 0.055,
|
|
387
393
|
sizeAttenuation: !0,
|
|
388
394
|
depthWrite: !1
|
|
389
|
-
}), f = new l.Points(
|
|
395
|
+
}), f = new l.Points(h, v);
|
|
390
396
|
return f.frustumCulled = !1, f.userData.workbenchId = t, f;
|
|
391
397
|
}
|
|
392
398
|
selectOnly(e) {
|
|
@@ -402,7 +408,7 @@ class G {
|
|
|
402
408
|
return this.getSelectedRecords()[0];
|
|
403
409
|
}
|
|
404
410
|
removeRecord(e) {
|
|
405
|
-
this.scene.remove(e.entity), this.objects.delete(e.id);
|
|
411
|
+
this.scene.remove(e.entity), this.objects.delete(e.id), this.invalidateLogicalCounts();
|
|
406
412
|
}
|
|
407
413
|
commitHistory(e) {
|
|
408
414
|
this.restoring || (this.undoStack.push(this.makeSnapshot()), this.undoStack.length > 60 && this.undoStack.shift(), this.redoStack.length = 0, e && this.log(e));
|
|
@@ -435,14 +441,14 @@ class G {
|
|
|
435
441
|
});
|
|
436
442
|
for (const t of e.objects ?? []) {
|
|
437
443
|
const s = this.createRecordFromSerialized(t);
|
|
438
|
-
t.id && t.id !== s.id && (this.objects.delete(s.id), s.id = t.id, s.entity.object.traverse((
|
|
439
|
-
|
|
444
|
+
t.id && t.id !== s.id && (this.objects.delete(s.id), s.id = t.id, s.entity.object.traverse((i) => {
|
|
445
|
+
i.userData.workbenchId = s.id;
|
|
440
446
|
}), this.objects.set(s.id, s));
|
|
441
447
|
}
|
|
442
448
|
this.restoring = !1, this.refreshUi();
|
|
443
449
|
}
|
|
444
450
|
serializeObject(e, t) {
|
|
445
|
-
const s = e.entity,
|
|
451
|
+
const s = e.entity, i = {
|
|
446
452
|
name: s.name,
|
|
447
453
|
kind: e.kind,
|
|
448
454
|
primitiveKind: e.primitiveKind,
|
|
@@ -457,38 +463,52 @@ class G {
|
|
|
457
463
|
rotation: [s.rotation.x, s.rotation.y, s.rotation.z],
|
|
458
464
|
scale: [s.scale.x, s.scale.y, s.scale.z]
|
|
459
465
|
};
|
|
460
|
-
return t && (
|
|
466
|
+
return t && (i.id = e.id), i;
|
|
461
467
|
}
|
|
462
468
|
refreshUi() {
|
|
463
469
|
this.renderSceneTree(), this.renderResourceList(), this.renderPrefabList(), this.renderPropertyPanel(), this.updateRuntimeUi();
|
|
464
470
|
}
|
|
465
471
|
updateRuntimeUi() {
|
|
466
|
-
const e = this.scene.engine?.stats, t = this.primarySelection(), s = this.logicalObjectCount(),
|
|
467
|
-
this.ui.objects
|
|
472
|
+
const e = this.scene.engine?.stats, t = this.primarySelection(), s = this.logicalObjectCount(), i = this.logicalVisibleObjectCount(), n = this.getMemoryText(), o = this.detectSlowSystem();
|
|
473
|
+
this.setUiText(this.ui.objects, `${s}`), this.setUiText(this.ui.visible, `${i}`), this.setUiText(this.ui.drawCalls, `${e?.drawCalls ?? 0}`), this.setUiText(this.ui.triangles, `${e?.triangles ?? 0}`), this.setUiText(this.ui.fps, `${e?.fps ?? 0}`), this.setUiText(this.ui.frame, `${e?.frameTimeMs ?? 0}ms`), this.setUiText(this.ui.geometries, `${e?.geometries ?? 0}`), this.setUiText(this.ui.textures, `${e?.textures ?? 0}`), this.setUiText(this.ui.assets, `${this.resources.size}`), this.setUiText(this.ui.memory, n), this.setUiText(this.ui.quality, `${Math.round((e?.qualityScale ?? 1) * 100)}%`), this.setUiText(this.ui.slowSystem, o), this.setUiText(this.ui.state, `编辑器运行中 · ${this.lastStressResult}`), this.setUiText(this.ui.selected, t ? t.entity.name : `${this.selectedIds.size} 个对象`);
|
|
474
|
+
}
|
|
475
|
+
setUiText(e, t) {
|
|
476
|
+
this.uiTextCache.get(e) !== t && (e.textContent = t, this.uiTextCache.set(e, t));
|
|
477
|
+
}
|
|
478
|
+
getMemoryText() {
|
|
479
|
+
const e = performance.now();
|
|
480
|
+
return e - this.lastMemorySampleMs < B ? this.memoryTextCache : (this.lastMemorySampleMs = e, this.memoryTextCache = Q(), this.memoryTextCache);
|
|
468
481
|
}
|
|
469
482
|
renderSceneTree() {
|
|
470
|
-
const e =
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
483
|
+
const e = [], t = [];
|
|
484
|
+
for (const o of this.objects.values())
|
|
485
|
+
this.selectedIds.has(o.id) ? e.push(o) : t.push(o);
|
|
486
|
+
const s = e.length + t.length, i = [...e, ...t].slice(0, D), n = i.map((o) => {
|
|
487
|
+
const a = this.selectedIds.has(o.id) ? " is-selected" : "", c = o.visible ? "" : " is-hidden", h = o.group ? ` · ${o.group}` : "";
|
|
488
|
+
return `<div class="tree-row${a}${c}" data-id="${o.id}">
|
|
489
|
+
<span class="tree-name">${w(o.entity.name)}</span>
|
|
490
|
+
<span class="tree-meta">L${o.layer}${h}</span>
|
|
475
491
|
</div>`;
|
|
476
492
|
});
|
|
477
|
-
|
|
478
|
-
<span class="tree-name">已省略 ${
|
|
479
|
-
<span class="tree-meta">场景总数 ${
|
|
480
|
-
</div>`), this.ui.sceneTree.innerHTML =
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
493
|
+
s > i.length && n.push(`<div class="tree-row">
|
|
494
|
+
<span class="tree-name">已省略 ${s - i.length} 个编辑对象</span>
|
|
495
|
+
<span class="tree-meta">场景总数 ${s},逻辑对象 ${this.logicalObjectCount()}</span>
|
|
496
|
+
</div>`), this.ui.sceneTree.innerHTML = n.join("") || '<div class="tree-row">空场景</div>';
|
|
497
|
+
}
|
|
498
|
+
bindSceneTreeSelection() {
|
|
499
|
+
this.ui.sceneTree.addEventListener("click", (e) => {
|
|
500
|
+
const t = e.target;
|
|
501
|
+
if (!(t instanceof HTMLElement))
|
|
502
|
+
return;
|
|
503
|
+
const s = t.closest(".tree-row[data-id]"), i = s?.dataset.id;
|
|
504
|
+
!s || !this.ui.sceneTree.contains(s) || !i || (e.shiftKey || e.metaKey ? this.selectedIds.has(i) ? this.selectedIds.delete(i) : this.selectedIds.add(i) : this.selectOnly(i), this.refreshUi());
|
|
505
|
+
});
|
|
486
506
|
}
|
|
487
507
|
renderResourceList() {
|
|
488
508
|
const e = Array.from(this.resources.values()).map(
|
|
489
509
|
(t) => `<div class="resource-row">
|
|
490
510
|
<span class="resource-name">${w(t.name)}</span>
|
|
491
|
-
<span class="resource-kind">${t.kind} · ${
|
|
511
|
+
<span class="resource-kind">${t.kind} · ${R(t.size)}</span>
|
|
492
512
|
</div>`
|
|
493
513
|
);
|
|
494
514
|
this.ui.resourceList.innerHTML = e.join("") || '<div class="resource-row">暂无资源</div>';
|
|
@@ -501,22 +521,29 @@ class G {
|
|
|
501
521
|
</button>`
|
|
502
522
|
);
|
|
503
523
|
this.ui.prefabList.innerHTML = e.join("") || '<div class="resource-row">暂无预制体</div>';
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
524
|
+
}
|
|
525
|
+
bindPrefabList() {
|
|
526
|
+
this.ui.prefabList.addEventListener("click", (e) => {
|
|
527
|
+
const t = e.target;
|
|
528
|
+
if (!(t instanceof HTMLElement))
|
|
529
|
+
return;
|
|
530
|
+
const s = t.closest("[data-prefab]");
|
|
531
|
+
if (!s || !this.ui.prefabList.contains(s))
|
|
532
|
+
return;
|
|
533
|
+
const i = this.prefabs.get(s.dataset.prefab ?? "");
|
|
534
|
+
if (i) {
|
|
535
|
+
this.selectedIds.clear();
|
|
536
|
+
for (const n of i.objects) {
|
|
537
|
+
const o = this.createRecordFromSerialized({
|
|
538
|
+
...n,
|
|
539
|
+
name: `${n.name} Instance`,
|
|
540
|
+
position: [n.position[0] + 1, n.position[1], n.position[2] + 1]
|
|
541
|
+
});
|
|
542
|
+
this.selectedIds.add(o.id);
|
|
518
543
|
}
|
|
519
|
-
|
|
544
|
+
this.commitHistory(`实例化预制体 ${i.name}`), this.refreshUi();
|
|
545
|
+
}
|
|
546
|
+
});
|
|
520
547
|
}
|
|
521
548
|
renderPropertyPanel() {
|
|
522
549
|
const e = this.primarySelection();
|
|
@@ -527,19 +554,19 @@ class G {
|
|
|
527
554
|
const t = e.entity;
|
|
528
555
|
this.ui.propertyPanel.innerHTML = `
|
|
529
556
|
<div class="property-grid">
|
|
530
|
-
${
|
|
531
|
-
${
|
|
532
|
-
${
|
|
533
|
-
${
|
|
534
|
-
${
|
|
535
|
-
${
|
|
536
|
-
${
|
|
537
|
-
${
|
|
538
|
-
${
|
|
539
|
-
${
|
|
540
|
-
${
|
|
541
|
-
${
|
|
542
|
-
${
|
|
557
|
+
${d("名称", "name", t.name, "text", "full")}
|
|
558
|
+
${d("X", "px", b(t.position.x))}
|
|
559
|
+
${d("Y", "py", b(t.position.y))}
|
|
560
|
+
${d("Z", "pz", b(t.position.z))}
|
|
561
|
+
${d("旋转X", "rx", b(t.rotation.x))}
|
|
562
|
+
${d("旋转Y", "ry", b(t.rotation.y))}
|
|
563
|
+
${d("旋转Z", "rz", b(t.rotation.z))}
|
|
564
|
+
${d("缩放X", "sx", b(t.scale.x))}
|
|
565
|
+
${d("缩放Y", "sy", b(t.scale.y))}
|
|
566
|
+
${d("缩放Z", "sz", b(t.scale.z))}
|
|
567
|
+
${d("颜色", "color", e.color, "color")}
|
|
568
|
+
${d("图层", "layer", `${e.layer}`, "number")}
|
|
569
|
+
${d("分组", "group", e.group, "text")}
|
|
543
570
|
<div class="property-field">
|
|
544
571
|
<label>显示</label>
|
|
545
572
|
<input id="prop-visible" type="checkbox" ${e.visible ? "checked" : ""} />
|
|
@@ -564,8 +591,8 @@ class G {
|
|
|
564
591
|
this.log("对象已锁定,不能修改");
|
|
565
592
|
return;
|
|
566
593
|
}
|
|
567
|
-
const t = (
|
|
568
|
-
e.entity.name = t("name") || e.entity.name, e.entity.object.name = e.entity.name, e.entity.position.set(p(t("px")), p(t("py")), p(t("pz"))), e.entity.rotation.set(p(t("rx")), p(t("ry")), p(t("rz"))), e.entity.scale.set(p(t("sx"), 1), p(t("sy"), 1), p(t("sz"), 1)), e.color = t("color") || e.color, e.layer = Math.max(0, Math.floor(p(t("layer")))), e.group = t("group"), e.visible = s("visible"), e.locked = s("locked"), e.entity.enabled = e.visible, e.entity.object.visible = e.visible, e.entity.getComponent(
|
|
594
|
+
const t = (i) => this.ui.propertyPanel.querySelector(`#prop-${i}`)?.value ?? "", s = (i) => this.ui.propertyPanel.querySelector(`#prop-${i}`)?.checked ?? !1;
|
|
595
|
+
e.entity.name = t("name") || e.entity.name, e.entity.object.name = e.entity.name, e.entity.position.set(p(t("px")), p(t("py")), p(t("pz"))), e.entity.rotation.set(p(t("rx")), p(t("ry")), p(t("rz"))), e.entity.scale.set(p(t("sx"), 1), p(t("sy"), 1), p(t("sz"), 1)), e.color = t("color") || e.color, e.layer = Math.max(0, Math.floor(p(t("layer")))), e.group = t("group"), e.visible = s("visible"), e.locked = s("locked"), e.entity.enabled = e.visible, e.entity.object.visible = e.visible, e.entity.getComponent(C)?.setColor(e.color), this.invalidateLogicalCounts(), this.commitHistory("修改对象属性"), this.refreshUi();
|
|
569
596
|
}
|
|
570
597
|
focusObject(e) {
|
|
571
598
|
const t = this.scene.camera, s = e.entity.position;
|
|
@@ -579,8 +606,8 @@ class G {
|
|
|
579
606
|
return;
|
|
580
607
|
const s = e.getBoundingClientRect();
|
|
581
608
|
this.pointer.x = (t.clientX - s.left) / s.width * 2 - 1, this.pointer.y = -((t.clientY - s.top) / s.height * 2 - 1), this.raycaster.setFromCamera(this.pointer, this.scene.camera);
|
|
582
|
-
const
|
|
583
|
-
|
|
609
|
+
const o = this.raycaster.intersectObjects(this.scene.threeScene.children, !0).find((a) => !!a.object.userData.workbenchId)?.object.userData.workbenchId;
|
|
610
|
+
o && this.objects.has(o) && (this.selectOnly(o), this.refreshUi());
|
|
584
611
|
});
|
|
585
612
|
}, 0);
|
|
586
613
|
}
|
|
@@ -589,20 +616,27 @@ class G {
|
|
|
589
616
|
return e ? e.frameTimeMs > 33 ? "帧耗时过高" : e.updatableEntities > 1e3 ? "逐帧对象过多" : e.drawCalls > 900 ? "Draw Call 过高" : e.triangles > 15e5 ? "三角面过高" : e.qualityScale < 0.95 ? "已自动降画质" : "无" : "无";
|
|
590
617
|
}
|
|
591
618
|
logicalObjectCount() {
|
|
592
|
-
|
|
593
|
-
for (const t of this.objects.values())
|
|
594
|
-
e += t.instancedCount ?? 1;
|
|
595
|
-
return e;
|
|
619
|
+
return this.refreshLogicalCountCache(), this.logicalObjectCountCache;
|
|
596
620
|
}
|
|
597
621
|
logicalVisibleObjectCount() {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
622
|
+
return this.refreshLogicalCountCache(), this.logicalVisibleObjectCountCache;
|
|
623
|
+
}
|
|
624
|
+
invalidateLogicalCounts() {
|
|
625
|
+
this.logicalCountsDirty = !0;
|
|
626
|
+
}
|
|
627
|
+
refreshLogicalCountCache() {
|
|
628
|
+
if (!this.logicalCountsDirty)
|
|
629
|
+
return;
|
|
630
|
+
let e = 0, t = 0;
|
|
631
|
+
for (const s of this.objects.values()) {
|
|
632
|
+
const i = s.instancedCount ?? 1;
|
|
633
|
+
e += i, s.visible && (t += i);
|
|
634
|
+
}
|
|
635
|
+
this.logicalObjectCountCache = e, this.logicalVisibleObjectCountCache = t, this.logicalCountsDirty = !1;
|
|
602
636
|
}
|
|
603
637
|
downloadText(e, t, s) {
|
|
604
|
-
const
|
|
605
|
-
|
|
638
|
+
const i = URL.createObjectURL(new Blob([t], { type: s })), n = document.createElement("a");
|
|
639
|
+
n.href = i, n.download = e, document.body.append(n), n.click(), n.remove(), URL.revokeObjectURL(i);
|
|
606
640
|
}
|
|
607
641
|
log(e) {
|
|
608
642
|
const t = document.createElement("div");
|
|
@@ -610,7 +644,7 @@ class G {
|
|
|
610
644
|
this.ui.logList.lastElementChild?.remove();
|
|
611
645
|
}
|
|
612
646
|
}
|
|
613
|
-
class
|
|
647
|
+
class z extends P {
|
|
614
648
|
constructor(e, t) {
|
|
615
649
|
super(), this.onFrame = e, this.intervalSeconds = t;
|
|
616
650
|
}
|
|
@@ -621,10 +655,10 @@ class N extends E {
|
|
|
621
655
|
this.elapsed += e, !(this.elapsed < this.intervalSeconds) && (this.elapsed = 0, this.onFrame());
|
|
622
656
|
}
|
|
623
657
|
}
|
|
624
|
-
function
|
|
658
|
+
function W() {
|
|
625
659
|
const r = new m("Editor Camera");
|
|
626
660
|
return r.addComponent(
|
|
627
|
-
new
|
|
661
|
+
new U({
|
|
628
662
|
target: new l.Vector3(0, 0.7, 0),
|
|
629
663
|
distance: 10,
|
|
630
664
|
azimuth: Math.PI * 0.24,
|
|
@@ -632,18 +666,18 @@ function q() {
|
|
|
632
666
|
})
|
|
633
667
|
), r;
|
|
634
668
|
}
|
|
635
|
-
function
|
|
669
|
+
function q() {
|
|
636
670
|
const r = new m("Ambient Light");
|
|
637
|
-
return r.addComponent(new
|
|
671
|
+
return r.addComponent(new x({ kind: "ambient", color: "#d7f8ee", intensity: 0.78 })), r;
|
|
638
672
|
}
|
|
639
|
-
function
|
|
673
|
+
function K() {
|
|
640
674
|
const r = new m("Directional Light");
|
|
641
|
-
return r.position.set(4, 7, 5), r.addComponent(new
|
|
675
|
+
return r.position.set(4, 7, 5), r.addComponent(new x({ kind: "directional", color: "#fff4d2", intensity: 2.75 })), r;
|
|
642
676
|
}
|
|
643
|
-
function
|
|
677
|
+
function V() {
|
|
644
678
|
const r = new m("Workbench Grid");
|
|
645
679
|
return r.position.set(0, -0.05, 0), r.rotation.x = -Math.PI / 2, r.addComponent(
|
|
646
|
-
new
|
|
680
|
+
new C({
|
|
647
681
|
kind: "plane",
|
|
648
682
|
width: 32,
|
|
649
683
|
depth: 32,
|
|
@@ -652,13 +686,13 @@ function K() {
|
|
|
652
686
|
receiveShadow: !0,
|
|
653
687
|
castShadow: !1
|
|
654
688
|
})
|
|
655
|
-
), r.addComponent(new y(
|
|
689
|
+
), r.addComponent(new y(Y())), r;
|
|
656
690
|
}
|
|
657
|
-
function
|
|
691
|
+
function X() {
|
|
658
692
|
const r = new m("World Axis");
|
|
659
693
|
return r.addComponent(new y(new l.AxesHelper(3))), r;
|
|
660
694
|
}
|
|
661
|
-
function
|
|
695
|
+
function Y() {
|
|
662
696
|
const r = new l.GridHelper(32, 32, "#1ec7a6", "#31403a"), e = r.material;
|
|
663
697
|
return Array.isArray(e) || (e.transparent = !0, e.opacity = 0.42), r.position.y = 0.02, r;
|
|
664
698
|
}
|
|
@@ -666,8 +700,8 @@ function J(r) {
|
|
|
666
700
|
const e = r.split(".").pop()?.toLowerCase() ?? "";
|
|
667
701
|
return ["glb", "gltf"].includes(e) ? "model" : ["png", "jpg", "jpeg", "webp", "ktx2"].includes(e) ? "texture" : ["mp3", "wav", "ogg", "m4a"].includes(e) ? "audio" : ["mat", "json"].includes(e) ? "material" : "unknown";
|
|
668
702
|
}
|
|
669
|
-
function
|
|
670
|
-
return `<div class="property-field ${
|
|
703
|
+
function d(r, e, t, s = "number", i = "") {
|
|
704
|
+
return `<div class="property-field ${i}">
|
|
671
705
|
<label for="prop-${e}">${r}</label>
|
|
672
706
|
<input id="prop-${e}" type="${s}" value="${w(String(t))}" />
|
|
673
707
|
</div>`;
|
|
@@ -679,10 +713,10 @@ function p(r, e = 0) {
|
|
|
679
713
|
const t = Number(r);
|
|
680
714
|
return Number.isFinite(t) ? t : e;
|
|
681
715
|
}
|
|
682
|
-
function
|
|
683
|
-
return r >=
|
|
716
|
+
function k(r) {
|
|
717
|
+
return r >= N ? Math.min(r, F) : Math.min(r, _);
|
|
684
718
|
}
|
|
685
|
-
function
|
|
719
|
+
function Z(r) {
|
|
686
720
|
return r >= 1e8 && r % 1e8 === 0 ? `${r / 1e8}亿` : `${r}`;
|
|
687
721
|
}
|
|
688
722
|
function w(r) {
|
|
@@ -701,13 +735,13 @@ function w(r) {
|
|
|
701
735
|
}
|
|
702
736
|
});
|
|
703
737
|
}
|
|
704
|
-
function
|
|
738
|
+
function R(r) {
|
|
705
739
|
return r < 1024 ? `${r}B` : r < 1024 * 1024 ? `${Math.round(r / 1024)}KB` : `${Math.round(r / (1024 * 1024) * 10) / 10}MB`;
|
|
706
740
|
}
|
|
707
|
-
function
|
|
741
|
+
function Q() {
|
|
708
742
|
const e = performance.memory?.usedJSHeapSize;
|
|
709
|
-
return typeof e == "number" ?
|
|
743
|
+
return typeof e == "number" ? R(e) : "未知";
|
|
710
744
|
}
|
|
711
745
|
export {
|
|
712
|
-
|
|
746
|
+
se as createEngineWorkbench
|
|
713
747
|
};
|