@galacean/effects-plugin-editor-gizmo 0.0.1-alpha.0

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/index.mjs ADDED
@@ -0,0 +1,3340 @@
1
+ /*!
2
+ * Name: @galacean/effects-plugin-editor-gizmo
3
+ * Description: Galacean Effects player editor gizmo plugin
4
+ * Author: Ant Group CO., Ltd.
5
+ * Contributors: 茂安,旻诺
6
+ * Version: v0.0.1-alpha.0
7
+ */
8
+
9
+ import { GLGeometry, DestroyOptions, glContext, ShaderType, GLSLVersion, Material, Mesh, createShaderWithMarcos, Geometry, Transform, Texture, noop, assertExist, spec, HitTestType, intersectRayTriangle, intersectRaySphere, intersectRayBox, VFXItem, RenderPass, RenderPassPriorityPostprocess, TextureLoadAction, RenderPassPriorityPrepare, AbstractPlugin, registerPlugin } from '@galacean/effects';
10
+
11
+ /******************************************************************************
12
+ Copyright (c) Microsoft Corporation.
13
+
14
+ Permission to use, copy, modify, and/or distribute this software for any
15
+ purpose with or without fee is hereby granted.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
18
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
20
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23
+ PERFORMANCE OF THIS SOFTWARE.
24
+ ***************************************************************************** */
25
+ /* global Reflect, Promise, SuppressedError, Symbol */
26
+
27
+ var extendStatics = function(d, b) {
28
+ extendStatics = Object.setPrototypeOf ||
29
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
30
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
31
+ return extendStatics(d, b);
32
+ };
33
+
34
+ function __extends(d, b) {
35
+ if (typeof b !== "function" && b !== null)
36
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
37
+ extendStatics(d, b);
38
+ function __() { this.constructor = d; }
39
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
40
+ }
41
+
42
+ var __assign = function() {
43
+ __assign = Object.assign || function __assign(t) {
44
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
45
+ s = arguments[i];
46
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
47
+ }
48
+ return t;
49
+ };
50
+ return __assign.apply(this, arguments);
51
+ };
52
+
53
+ function __awaiter(thisArg, _arguments, P, generator) {
54
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
55
+ return new (P || (P = Promise))(function (resolve, reject) {
56
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
57
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
58
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
59
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
60
+ });
61
+ }
62
+
63
+ function __generator(thisArg, body) {
64
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
65
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
66
+ function verb(n) { return function (v) { return step([n, v]); }; }
67
+ function step(op) {
68
+ if (f) throw new TypeError("Generator is already executing.");
69
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
70
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
71
+ if (y = 0, t) op = [op[0] & 2, t.value];
72
+ switch (op[0]) {
73
+ case 0: case 1: t = op; break;
74
+ case 4: _.label++; return { value: op[1], done: false };
75
+ case 5: _.label++; y = op[1]; op = [0]; continue;
76
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
77
+ default:
78
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
79
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
80
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
81
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
82
+ if (t[2]) _.ops.pop();
83
+ _.trys.pop(); continue;
84
+ }
85
+ op = body.call(thisArg, _);
86
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
87
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
88
+ }
89
+ }
90
+
91
+ function __values(o) {
92
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
93
+ if (m) return m.call(o);
94
+ if (o && typeof o.length === "number") return {
95
+ next: function () {
96
+ if (o && i >= o.length) o = void 0;
97
+ return { value: o && o[i++], done: !o };
98
+ }
99
+ };
100
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
101
+ }
102
+
103
+ function __read(o, n) {
104
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
105
+ if (!m) return o;
106
+ var i = m.call(o), r, ar = [], e;
107
+ try {
108
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
109
+ }
110
+ catch (error) { e = { error: error }; }
111
+ finally {
112
+ try {
113
+ if (r && !r.done && (m = i["return"])) m.call(i);
114
+ }
115
+ finally { if (e) throw e.error; }
116
+ }
117
+ return ar;
118
+ }
119
+
120
+ function __spreadArray(to, from, pack) {
121
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
122
+ if (ar || !(i in from)) {
123
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
124
+ ar[i] = from[i];
125
+ }
126
+ }
127
+ return to.concat(ar || Array.prototype.slice.call(from));
128
+ }
129
+
130
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
131
+ var e = new Error(message);
132
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
133
+ };
134
+
135
+ var GizmoVFXItemType = 'gizmo';
136
+ /**
137
+ * Gizmo 类型
138
+ */
139
+ var GizmoSubType;
140
+ (function (GizmoSubType) {
141
+ GizmoSubType[GizmoSubType["particleEmitter"] = 1] = "particleEmitter";
142
+ GizmoSubType[GizmoSubType["modelWireframe"] = 2] = "modelWireframe";
143
+ GizmoSubType[GizmoSubType["box"] = 3] = "box";
144
+ GizmoSubType[GizmoSubType["sphere"] = 4] = "sphere";
145
+ GizmoSubType[GizmoSubType["cylinder"] = 5] = "cylinder";
146
+ GizmoSubType[GizmoSubType["cone"] = 6] = "cone";
147
+ GizmoSubType[GizmoSubType["torus"] = 7] = "torus";
148
+ GizmoSubType[GizmoSubType["sprite"] = 8] = "sprite";
149
+ GizmoSubType[GizmoSubType["plane"] = 9] = "plane";
150
+ GizmoSubType[GizmoSubType["rotation"] = 10] = "rotation";
151
+ GizmoSubType[GizmoSubType["translation"] = 11] = "translation";
152
+ GizmoSubType[GizmoSubType["scale"] = 12] = "scale";
153
+ GizmoSubType[GizmoSubType["viewHelper"] = 13] = "viewHelper";
154
+ GizmoSubType[GizmoSubType["camera"] = 14] = "camera";
155
+ GizmoSubType[GizmoSubType["frustum"] = 15] = "frustum";
156
+ GizmoSubType[GizmoSubType["light"] = 16] = "light";
157
+ GizmoSubType[GizmoSubType["directionLight"] = 17] = "directionLight";
158
+ GizmoSubType[GizmoSubType["pointLight"] = 18] = "pointLight";
159
+ GizmoSubType[GizmoSubType["spotLight"] = 19] = "spotLight";
160
+ GizmoSubType[GizmoSubType["boundingBox"] = 20] = "boundingBox";
161
+ GizmoSubType[GizmoSubType["floorGrid"] = 21] = "floorGrid";
162
+ })(GizmoSubType || (GizmoSubType = {}));
163
+
164
+ var WireframeGeometryType;
165
+ (function (WireframeGeometryType) {
166
+ WireframeGeometryType[WireframeGeometryType["triangle"] = 0] = "triangle";
167
+ WireframeGeometryType[WireframeGeometryType["quad"] = 1] = "quad";
168
+ })(WireframeGeometryType || (WireframeGeometryType = {}));
169
+ function destroyWireframeMesh(mesh) {
170
+ //mesh.geometry?.destroy();
171
+ mesh.dispose({ material: { textures: DestroyOptions.keep }, geometries: DestroyOptions.keep });
172
+ }
173
+ function updateWireframeMesh(originMesh, wireframe, type) {
174
+ wireframe.material.cloneUniforms(originMesh.material);
175
+ var geometry = originMesh.firstGeometry();
176
+ var wireframeGeometry = wireframe.firstGeometry();
177
+ if (type === WireframeGeometryType.triangle) {
178
+ // 线框模式不绘制模型的时候,drawCount 为负数
179
+ var drawCount = Math.abs(geometry.getDrawCount());
180
+ if (drawCount !== 0) {
181
+ if (drawCount !== wireframeGeometry.getDrawCount() / 2) {
182
+ var indexData = geometry.getIndexData();
183
+ var data = indexData ? getTriangleIndexData(indexData) : getTriangleIndexDataByCount(drawCount);
184
+ wireframeGeometry.setIndexData(data);
185
+ wireframeGeometry.setDrawCount(data.length);
186
+ }
187
+ }
188
+ }
189
+ else if (type === WireframeGeometryType.quad) {
190
+ if (geometry.getDrawCount() / 6 !== wireframeGeometry.getDrawCount() / 8) {
191
+ var data = getQuadIndexData(geometry.getDrawCount() / 6, geometry.getIndexData());
192
+ wireframeGeometry.setIndexData(data);
193
+ wireframeGeometry.setDrawCount(data.length);
194
+ }
195
+ }
196
+ return wireframe;
197
+ }
198
+ function getQuadIndexData(faceCount, oid) {
199
+ var indexData = new Uint16Array(faceCount * 8);
200
+ for (var i = 0; i < faceCount; i++) {
201
+ var idx = i * 8;
202
+ var base = i * 4;
203
+ indexData[idx] = base;
204
+ indexData[idx + 1] = 1 + base;
205
+ indexData[idx + 2] = 1 + base;
206
+ indexData[idx + 3] = 3 + base;
207
+ indexData[idx + 4] = 3 + base;
208
+ indexData[idx + 5] = 2 + base;
209
+ indexData[idx + 6] = 2 + base;
210
+ indexData[idx + 7] = base;
211
+ }
212
+ return indexData;
213
+ }
214
+ function createModeWireframe(engine, mesh, color) {
215
+ var _a;
216
+ var level = engine.gpuCapability.level;
217
+ var geometry = new SharedGeometry(engine, {
218
+ geometry: mesh.firstGeometry(),
219
+ mode: glContext.LINES,
220
+ index: {
221
+ data: new Uint32Array(0),
222
+ },
223
+ });
224
+ var _b = mesh.material.props.shader, vertex = _b.vertex, fragment = _b.fragment, marcos = _b.marcos;
225
+ var materialOptions = __assign({}, mesh.material.props);
226
+ var newMarcos = __spreadArray(__spreadArray([], __read((marcos || [])), false), [['PREVIEW_BORDER', 1]], false);
227
+ materialOptions.shader = {
228
+ vertex: createGizmoShader(newMarcos, vertex, ShaderType.vertex, level),
229
+ fragment: createGizmoShader(newMarcos, fragment, ShaderType.fragment, level),
230
+ shared: true,
231
+ name: ((_a = mesh.name) !== null && _a !== void 0 ? _a : 'unamedmesh') + '_wireframe',
232
+ glslVersion: engine.gpuCapability.level === 2 ? GLSLVersion.GLSL3 : GLSLVersion.GLSL1,
233
+ };
234
+ var material = Material.create(engine, materialOptions);
235
+ material.depthTest = mesh.material.depthTest;
236
+ material.setVector4('uPreviewColor', [color[0], color[1], color[2], 1]);
237
+ return updateWireframeMesh(mesh, Mesh.create(engine, {
238
+ geometry: geometry,
239
+ material: material,
240
+ priority: 3000,
241
+ name: materialOptions.shader.name,
242
+ }), WireframeGeometryType.triangle);
243
+ }
244
+ function getTriangleIndexDataByCount(drawCount) {
245
+ var faceCount = drawCount / 3;
246
+ var indexData = new Uint32Array(faceCount * 6);
247
+ for (var i = 0; i < faceCount; i++) {
248
+ var idx = i * 6;
249
+ var p0 = i * 3;
250
+ var p1 = p0 + 1;
251
+ var p2 = p0 + 2;
252
+ indexData[idx] = p0;
253
+ indexData[idx + 1] = p1;
254
+ indexData[idx + 2] = p1;
255
+ indexData[idx + 3] = p2;
256
+ indexData[idx + 4] = p2;
257
+ indexData[idx + 5] = p0;
258
+ }
259
+ return indexData;
260
+ }
261
+ function getTriangleIndexData(oid) {
262
+ var faceCount = oid.length / 3;
263
+ var indexData = new Uint32Array(faceCount * 6);
264
+ for (var i = 0; i < faceCount; i++) {
265
+ var idx = i * 6;
266
+ var base = i * 3;
267
+ var p0 = oid[base];
268
+ var p1 = oid[base + 1];
269
+ var p2 = oid[base + 2];
270
+ indexData[idx] = p0;
271
+ indexData[idx + 1] = p1;
272
+ indexData[idx + 2] = p1;
273
+ indexData[idx + 3] = p2;
274
+ indexData[idx + 4] = p2;
275
+ indexData[idx + 5] = p0;
276
+ }
277
+ return indexData;
278
+ }
279
+ var SharedGeometry = /** @class */ (function (_super) {
280
+ __extends(SharedGeometry, _super);
281
+ function SharedGeometry(engine, options) {
282
+ var _this = _super.call(this, engine, __assign({ attributes: {} }, options)) || this;
283
+ var indexData = options.index ? options.index.data : options.geometry.getIndexData();
284
+ if (indexData) {
285
+ //@ts-expect-error safe to assign
286
+ indexData = new indexData.constructor(indexData);
287
+ }
288
+ _this.indices = indexData;
289
+ _this.source = options.geometry;
290
+ _this.drawCount = options.drawCount || 0;
291
+ _this.drawStart = options.drawStart || 0;
292
+ _this.mode = options.mode || 0;
293
+ for (var name_1 in _this.source.attributes) {
294
+ _this.attributes[name_1] = __assign({}, _this.source.attributes[name_1]);
295
+ }
296
+ return _this;
297
+ }
298
+ SharedGeometry.prototype.initialize = function () {
299
+ if (!this.isInitialized) {
300
+ var geometry = this.source;
301
+ geometry.initialize();
302
+ //this.indicesBuffer = this._source.indicesBuffer;
303
+ this.buffers = this.source.buffers;
304
+ this.bufferProps = this.source.bufferProps;
305
+ //this.dirtyFlags = this._source.dirtyFlags;
306
+ //this.vaos = this._source.vaos;
307
+ //创建ibo
308
+ if (this.indices) {
309
+ this.indicesBuffer = this.createIndicesBuffer(this.engine.getGLPipelineContext(), this.indices);
310
+ }
311
+ this.flush();
312
+ this.initialized = true;
313
+ }
314
+ };
315
+ SharedGeometry.prototype.getAttributeNames = function () {
316
+ return this.source.getAttributeNames();
317
+ };
318
+ SharedGeometry.prototype.flush = function () {
319
+ this.source.flush();
320
+ _super.prototype.flush.call(this);
321
+ };
322
+ SharedGeometry.prototype.destroy = function () {
323
+ _super.prototype.dispose.call(this);
324
+ };
325
+ return SharedGeometry;
326
+ }(GLGeometry));
327
+ function createGizmoShader(marcos, shader, shaderType, level) {
328
+ var versionTag = /#version\s+\b\d{3}\b\s*(es)?/;
329
+ var shaderMatch = shader.match(versionTag);
330
+ var newShader = shaderMatch ? shader.substring(shaderMatch[0].length) : shader;
331
+ return createShaderWithMarcos(marcos, newShader, shaderType, level);
332
+ }
333
+
334
+ var d2r = Math.PI / 180;
335
+ var cos = Math.cos;
336
+ var sin = Math.sin;
337
+ function vecAdd(out, a, b) {
338
+ for (var i = 0, len = a.length; i < len; i++) {
339
+ out[i] = a[i] + b[i];
340
+ }
341
+ return out;
342
+ }
343
+ function vecSub(out, a, b) {
344
+ for (var i = 0, len = a.length; i < len; i++) {
345
+ out[i] = a[i] - b[i];
346
+ }
347
+ return out;
348
+ }
349
+ function vecSquareDistance(v0, v1) {
350
+ var sum = 0;
351
+ for (var i = 0, len = v0.length; i < len; i++) {
352
+ var d = v0[i] - v1[i];
353
+ sum += d * d;
354
+ }
355
+ return sum;
356
+ }
357
+ function vecNormalize(a) {
358
+ var sum = 0;
359
+ for (var i = 0, len = a.length; i < len; i++) {
360
+ sum += a[i] * a[i];
361
+ }
362
+ sum = Math.sqrt(sum);
363
+ return sum === 0 ? a.slice() : a.map(function (b) { return b / sum; });
364
+ }
365
+ function vecMulScalar(out, vec, a) {
366
+ for (var i = 0, len = vec.length; i < len; i++) {
367
+ out[i] = vec[i] * a;
368
+ }
369
+ return out;
370
+ }
371
+ function vec3MulMat4(out, vec3, mat4) {
372
+ var x = vec3[0], y = vec3[1], z = vec3[2];
373
+ var w = mat4[3] * x + mat4[7] * y + mat4[11] * z + mat4[15];
374
+ w = w || 1.0;
375
+ out[0] = (mat4[0] * x + mat4[4] * y + mat4[8] * z + mat4[12]) / w;
376
+ out[1] = (mat4[1] * x + mat4[5] * y + mat4[9] * z + mat4[13]) / w;
377
+ out[2] = (mat4[2] * x + mat4[6] * y + mat4[10] * z + mat4[14]) / w;
378
+ return out;
379
+ }
380
+ function vec4MulMat4(out, cartesian, mat4) {
381
+ var vX = cartesian[0];
382
+ var vY = cartesian[1];
383
+ var vZ = cartesian[2];
384
+ var vW = cartesian[3];
385
+ var x = mat4[0] * vX + mat4[4] * vY + mat4[8] * vZ + mat4[12] * vW;
386
+ var y = mat4[1] * vX + mat4[5] * vY + mat4[9] * vZ + mat4[13] * vW;
387
+ var z = mat4[2] * vX + mat4[6] * vY + mat4[10] * vZ + mat4[14] * vW;
388
+ var w = mat4[3] * vX + mat4[7] * vY + mat4[11] * vZ + mat4[15] * vW;
389
+ out[0] = x;
390
+ out[1] = y;
391
+ out[2] = z;
392
+ out[3] = w;
393
+ return out;
394
+ }
395
+ function vec3MulMat3(out, a, m) {
396
+ var x = a[0], y = a[1], z = a[2];
397
+ out[0] = x * m[0] + y * m[3] + z * m[6];
398
+ out[1] = x * m[1] + y * m[4] + z * m[7];
399
+ out[2] = x * m[2] + y * m[5] + z * m[8];
400
+ return out;
401
+ }
402
+ function vec3MulMat3ByPoint(out, a, m, c) {
403
+ a[0]; a[1]; a[2];
404
+ var deltaX = a[0] - c[0], deltaY = a[1] - c[1], deltaZ = a[2] - c[2];
405
+ var deltaOut = vec3MulMat3([], [deltaX, deltaY, deltaZ], m);
406
+ out[0] = deltaOut[0] + c[0];
407
+ out[1] = deltaOut[1] + c[1];
408
+ out[2] = deltaOut[2] + c[2];
409
+ return out;
410
+ }
411
+ function mat3FromRotationZYX(ret, x, y, z) {
412
+ var cosX = cos(x * d2r);
413
+ var cosY = cos(y * d2r);
414
+ var cosZ = cos(z * d2r);
415
+ var sinX = sin(x * d2r);
416
+ var sinY = sin(y * d2r);
417
+ var sinZ = sin(z * d2r);
418
+ ret[0] = cosY * cosZ;
419
+ ret[1] = cosY * sinZ;
420
+ ret[2] = -sinY;
421
+ ret[3] = -cosX * sinZ + sinX * sinY * cosZ;
422
+ ret[4] = cosX * cosZ + sinX * sinY * sinZ;
423
+ ret[5] = sinX * cosY;
424
+ ret[6] = sinZ * sinX + cosX * sinY * cosZ;
425
+ ret[7] = -sinX * cosZ + cosX * sinY * sinZ;
426
+ ret[8] = cosX * cosY;
427
+ return ret;
428
+ }
429
+ function mat3FromRotation(ret, rotation) {
430
+ return mat3FromRotationZYX(ret, -rotation[0], -rotation[1], -rotation[2]);
431
+ }
432
+ function mat4MulMat4(a, b) {
433
+ var out = [];
434
+ var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
435
+ var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
436
+ var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
437
+ var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
438
+ var b00 = b[0], b01 = b[1], b02 = b[2], b03 = b[3];
439
+ var b10 = b[4], b11 = b[5], b12 = b[6], b13 = b[7];
440
+ var b20 = b[8], b21 = b[9], b22 = b[10], b23 = b[11];
441
+ var b30 = b[12], b31 = b[13], b32 = b[14], b33 = b[15];
442
+ out[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
443
+ out[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
444
+ out[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
445
+ out[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
446
+ out[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
447
+ out[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
448
+ out[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
449
+ out[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
450
+ out[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
451
+ out[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
452
+ out[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
453
+ out[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
454
+ out[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
455
+ out[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
456
+ out[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
457
+ out[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
458
+ return out;
459
+ }
460
+ function vec3ToVec2(a) {
461
+ return [a[0], a[1]];
462
+ }
463
+ function distanceOfPointAndLine(point, line) {
464
+ //三角形三个边长
465
+ var AC = [0, 0];
466
+ var BC = [0, 0];
467
+ var AB = [0, 0];
468
+ vecSub(AC, point, line[0]);
469
+ vecSub(BC, point, line[1]);
470
+ vecSub(AB, line[1], line[0]);
471
+ var lengthAC = Math.hypot.apply(Math, __spreadArray([], __read(AC), false));
472
+ var lengthBC = Math.hypot.apply(Math, __spreadArray([], __read(BC), false));
473
+ var lengthAB = Math.hypot.apply(Math, __spreadArray([], __read(AB), false));
474
+ //利用海伦公式计算三角形面积
475
+ //周长的一半
476
+ var P = (lengthAC + lengthBC + lengthAB) / 2;
477
+ var allArea = Math.abs(Math.sqrt(P * (P - lengthAC) * (P - lengthBC) * (P - lengthAB)));
478
+ //普通公式计算三角形面积反推点到线的垂直距离
479
+ var distance = (2 * allArea) / lengthAB;
480
+ var l1 = Math.sqrt(Math.pow(lengthAC, 2) - Math.pow(distance, 2));
481
+ var l2 = Math.sqrt(Math.pow(lengthBC, 2) - Math.pow(distance, 2));
482
+ var isInLine = false;
483
+ if (l1 <= lengthAB && l2 <= lengthAB) {
484
+ isInLine = true;
485
+ }
486
+ return {
487
+ distance: distance,
488
+ isInLine: isInLine,
489
+ };
490
+ }
491
+ function projectionOfPointAndLine(point, line) {
492
+ var AC = [0, 0];
493
+ var BC = [0, 0];
494
+ var AB = [0, 0];
495
+ vecSub(AC, point, vec3ToVec2(line[0]));
496
+ vecSub(BC, point, vec3ToVec2(line[1]));
497
+ vecSub(AB, vec3ToVec2(line[1]), vec3ToVec2(line[0]));
498
+ var lengthAC = Math.hypot.apply(Math, __spreadArray([], __read(AC), false));
499
+ var lengthBC = Math.hypot.apply(Math, __spreadArray([], __read(BC), false));
500
+ var lengthAB = Math.hypot.apply(Math, __spreadArray([], __read(AB), false));
501
+ //利用海伦公式计算三角形面积
502
+ //周长的一半
503
+ var P = (lengthAC + lengthBC + lengthAB) / 2;
504
+ var allArea = Math.abs(Math.sqrt(P * (P - lengthAC) * (P - lengthBC) * (P - lengthAB)));
505
+ //普通公式计算三角形面积反推点到线的垂直距离
506
+ var distance = (2 * allArea) / lengthAB;
507
+ var l1 = Math.sqrt(Math.pow(lengthAC, 2) - Math.pow(distance, 2));
508
+ var l2 = Math.sqrt(Math.pow(lengthBC, 2) - Math.pow(distance, 2));
509
+ var worldAB = [0, 0, 0];
510
+ vecSub(worldAB, line[1], line[0]);
511
+ var worldAP = [0, 0, 0];
512
+ vecMulScalar(worldAP, worldAB, l1 / (l1 + l2));
513
+ var worldP = [0, 0, 0];
514
+ vecAdd(worldP, line[0], worldAP);
515
+ return worldP;
516
+ }
517
+ function computeOrthographicOffCenter(left, right, bottom, top, near, far) {
518
+ var a = 1.0 / (right - left);
519
+ var b = 1.0 / (top - bottom);
520
+ var c = 1.0 / (far - near);
521
+ var tx = -(right + left) * a;
522
+ var ty = -(top + bottom) * b;
523
+ var tz = -(far + near) * c;
524
+ a *= 2.0;
525
+ b *= 2.0;
526
+ c *= -2.0;
527
+ var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
528
+ result[0] = a;
529
+ result[1] = 0.0;
530
+ result[2] = 0.0;
531
+ result[3] = 0.0;
532
+ result[4] = 0.0;
533
+ result[5] = b;
534
+ result[6] = 0.0;
535
+ result[7] = 0.0;
536
+ result[8] = 0.0;
537
+ result[9] = 0.0;
538
+ result[10] = c;
539
+ result[11] = 0.0;
540
+ result[12] = tx;
541
+ result[13] = ty;
542
+ result[14] = tz;
543
+ result[15] = 1.0;
544
+ return result;
545
+ }
546
+
547
+ var rectSize = 0.04;
548
+ var DEG2RAD = Math.PI / 180;
549
+ function arcPath(radius, arc, options) {
550
+ if (options === void 0) { options = {}; }
551
+ var plane = options.plane, _a = options.translate, translate = _a === void 0 ? [0, 0, 0] : _a, _b = options.rotate, rotate = _b === void 0 ? [0, 0, 0] : _b;
552
+ var rotation = mat3FromRotation([], rotate);
553
+ var points = [];
554
+ var indices = [];
555
+ addPoint(radius, 0);
556
+ var i = 1;
557
+ for (; i <= arc; i++) {
558
+ var angle = i * DEG2RAD;
559
+ indices.push(i - 1, i);
560
+ addPoint(Math.cos(angle) * radius, Math.sin(angle) * radius);
561
+ }
562
+ return {
563
+ points: points,
564
+ indices: indices,
565
+ };
566
+ function addPoint(cos, sin) {
567
+ var point;
568
+ if (plane === 'xz') {
569
+ point = [cos, 0, sin];
570
+ }
571
+ else if (plane === 'yz') {
572
+ point = [0, cos, sin];
573
+ }
574
+ else {
575
+ point = [cos, sin, 0];
576
+ }
577
+ point = vec3MulMat3(point, point, rotation);
578
+ points.push(vecAdd(point, point, translate));
579
+ }
580
+ }
581
+ function line(p0, p1) {
582
+ return {
583
+ points: [p0, p1],
584
+ indices: [0, 1],
585
+ };
586
+ }
587
+ function box(width, height, depth, center) {
588
+ var w = width / 2;
589
+ var h = height / 2;
590
+ var d = depth / 2;
591
+ var myCenter = center !== null && center !== void 0 ? center : [0, 0, 0];
592
+ var points = [
593
+ [-w, h, -d], [-w, -h, -d], [-w, h, d], [-w, -h, d],
594
+ [w, h, -d], [w, -h, -d], [w, h, d], [w, -h, d],
595
+ ].map(function (item) {
596
+ return [item[0] + myCenter[0], item[1] + myCenter[1], item[2] + myCenter[2]];
597
+ });
598
+ return {
599
+ points: points,
600
+ indices: [
601
+ 0, 1, 1, 3, 3, 2, 2, 0,
602
+ 4, 5, 5, 7, 7, 6, 6, 4,
603
+ 0, 4, 2, 6, 3, 7, 1, 5,
604
+ ],
605
+ };
606
+ }
607
+ function rect(width, height, pos) {
608
+ var w = width / 2;
609
+ var h = height / 2;
610
+ var points = [[-w, h, 0], [w, h, 0], [w, -h, 0], [-w, -h, 0]];
611
+ if (pos) {
612
+ points.forEach(function (vec) {
613
+ vec[0] += pos[0];
614
+ vec[1] += pos[1];
615
+ vec[2] += pos[2];
616
+ });
617
+ }
618
+ return {
619
+ points: points,
620
+ indices: [
621
+ 0, 1, 1, 2, 2, 3, 3, 0,
622
+ ],
623
+ };
624
+ }
625
+ function combineGeometries(geometries) {
626
+ var points = [];
627
+ var indices = [];
628
+ var _loop_1 = function (i, indicesBase) {
629
+ var geometry = geometries[i];
630
+ if (geometry) {
631
+ geometry.points.forEach(function (point) {
632
+ points.push(point[0], point[1], point[2]);
633
+ });
634
+ geometry.indices.forEach(function (index) { return indices.push(index + indicesBase); });
635
+ indicesBase += geometry.points.length;
636
+ }
637
+ out_indicesBase_1 = indicesBase;
638
+ };
639
+ var out_indicesBase_1;
640
+ for (var i = 0, indicesBase = 0; i < geometries.length; i++) {
641
+ _loop_1(i, indicesBase);
642
+ indicesBase = out_indicesBase_1;
643
+ }
644
+ return {
645
+ points: new Float32Array(points),
646
+ indices: new Uint16Array(indices),
647
+ };
648
+ }
649
+ var Shapes = {
650
+ Texture: function (arg) {
651
+ var ret = [];
652
+ if (arg.detail) {
653
+ var anchors = arg.detail.anchors;
654
+ var block = arg.detail.block;
655
+ var width = arg.width;
656
+ var height = arg.height;
657
+ for (var i = 0; i < anchors.length; i += 2) {
658
+ ret.push(rect(block[0] * width, block[1] * height, [
659
+ width * (anchors[i] - 0.5),
660
+ height * (anchors[i + 1] - 0.5),
661
+ 0,
662
+ ]));
663
+ }
664
+ }
665
+ else {
666
+ ret.unshift(Shapes.Rectangle(arg)[0]);
667
+ }
668
+ return ret;
669
+ },
670
+ Circle: function (arg) {
671
+ var radius = arg.radius, arc = arg.arc;
672
+ return [
673
+ arcPath(radius, arc),
674
+ arc !== 360 && line([0, 0, 0], [radius, 0, 0]),
675
+ arc !== 360 && line([0, 0, 0], [Math.cos(arc * DEG2RAD) * radius, Math.sin(arc * DEG2RAD) * radius, 0]),
676
+ ];
677
+ },
678
+ Box: function (arg) {
679
+ var width = arg.width, height = arg.height, depth = arg.depth, center = arg.center;
680
+ var data = box(width, height, depth, center);
681
+ return [data];
682
+ },
683
+ Sphere: function (arg) {
684
+ var radius = arg.radius, arc = arg.arc;
685
+ var ret = [
686
+ line([0, 0, -radius], [0, 0, radius]),
687
+ arcPath(radius, arc > 180 ? 360 : 180, { plane: 'xz', rotate: [0, 90, 0] }),
688
+ arcPath(radius, arc, { plane: 'xy' }),
689
+ arcPath(radius, 180, { plane: 'xz', rotate: [0, 90, arc] }),
690
+ ];
691
+ if (arc > 90) {
692
+ ret.push(arcPath(radius, arc > 270 ? 360 : 180, { plane: 'yz', rotate: [-90, 0, 0] }));
693
+ }
694
+ return ret;
695
+ },
696
+ Hemisphere: function (arg) {
697
+ var radius = arg.radius, arc = arg.arc;
698
+ var ret = [
699
+ line([0, 0, radius], [0, 0, 0]),
700
+ line([arc > 180 ? -radius : 0, 0, 0], [radius, 0, 0]),
701
+ arg > 90 && line([0, arc > 270 ? -radius : 0, 0], [0, radius, 0]),
702
+ arcPath(radius, (arc > 180 ? 360 : 180) / 2, { plane: 'xz' }),
703
+ arcPath(radius, arc, { plane: 'xy' }),
704
+ arcPath(radius, 90, { plane: 'xz', rotate: [0, 0, arc] }),
705
+ line([0, 0, 0], [Math.cos(arc * DEG2RAD) * radius, Math.sin(arc * DEG2RAD) * radius, 0]),
706
+ ];
707
+ if (arc > 90) {
708
+ ret.push(arcPath(radius, arc > 270 ? 180 : 90, { plane: 'yz' }));
709
+ }
710
+ return ret;
711
+ },
712
+ Cone: function (arg) {
713
+ var radius = arg.radius, arc = arg.arc;
714
+ var outerRadius = radius * Math.tan(arg.angle * DEG2RAD) + radius;
715
+ return [
716
+ arcPath(outerRadius, arc, { translate: [0, 0, radius] }),
717
+ line([radius, 0, 0], [outerRadius, 0, radius]),
718
+ arc > 90 && line([0, radius, 0], [0, outerRadius, radius]),
719
+ arc > 180 && line([-radius, 0, 0], [-outerRadius, 0, radius]),
720
+ arc > 270 && line([0, -radius, 0], [0, -outerRadius, radius]),
721
+ line([Math.cos(arc * DEG2RAD) * radius, Math.sin(arc * DEG2RAD) * radius, 0], [Math.cos(arc * DEG2RAD) * outerRadius, Math.sin(arc * DEG2RAD) * outerRadius, radius]),
722
+ ].concat(Shapes.Circle(arg));
723
+ },
724
+ Edge: function (arg) {
725
+ var hw = arg.width / 2;
726
+ return [
727
+ line([-hw, 0, 0], [hw, 0, 0]),
728
+ ];
729
+ },
730
+ Rectangle: function (arg) {
731
+ return [
732
+ rect(arg.width, arg.height),
733
+ ];
734
+ },
735
+ RectangleEdge: function (arg) {
736
+ return [
737
+ rect(arg.width, arg.height),
738
+ ];
739
+ },
740
+ Donut: function (arg) {
741
+ var arc = arg.arc, radius = arg.radius, donutRadius = arg.donutRadius;
742
+ return [
743
+ arcPath(donutRadius, 360, { translate: [radius, 0, 0], rotate: [90, 0, 0] }),
744
+ arcPath(radius - donutRadius, arc),
745
+ arcPath(radius + donutRadius, arc),
746
+ arcPath(radius, arc, { translate: [0, 0, donutRadius] }),
747
+ arcPath(radius, arc, { translate: [0, 0, -donutRadius] }),
748
+ arc % 360 === 0 ? arcPath(donutRadius, 360, {
749
+ translate: [-radius, 0, 0],
750
+ rotate: [90, 0, 0],
751
+ }) : arcPath(donutRadius, 360, {
752
+ translate: [Math.cos(arc * DEG2RAD) * radius, Math.sin(arc * DEG2RAD) * radius, 0],
753
+ rotate: [90, 0, arc],
754
+ }),
755
+ ];
756
+ },
757
+ path: function (arg) {
758
+ var positions = arg.keys;
759
+ var ret = [];
760
+ for (var i = 0; i < positions.length - 1; i++) {
761
+ ret.push(rect(rectSize, rectSize, positions[i]));
762
+ ret.push(line(positions[i], positions[i + 1]));
763
+ }
764
+ ret.push(rect(rectSize, rectSize, positions[positions.length - 1]));
765
+ return ret;
766
+ },
767
+ };
768
+ Shapes['0'] = Shapes.None;
769
+ Shapes['1'] = Shapes.Sphere;
770
+ Shapes['2'] = Shapes.Cone;
771
+ Shapes['3'] = Shapes.Hemisphere;
772
+ Shapes['4'] = Shapes.Circle;
773
+ Shapes['5'] = Shapes.Donut;
774
+ Shapes['6'] = Shapes.Rectangle;
775
+ Shapes['7'] = Shapes.RectangleEdge;
776
+ Shapes['8'] = Shapes.Edge;
777
+ Shapes['9'] = Shapes.Texture;
778
+ function createMeshFromShape(engine, args, options) {
779
+ var ret = Shapes[args.type || args.shape](args);
780
+ var geo = combineGeometries(ret);
781
+ return createMesh(engine, geo.points, geo.indices, options.color || [1, 0, 0], options.depthTest, args.shape);
782
+ }
783
+ function createMesh(engine, points, indices, color, depthTest, name) {
784
+ if (depthTest === void 0) { depthTest = false; }
785
+ var material = Material.create(engine, {
786
+ uniformValues: {
787
+ u_color: new Float32Array(color),
788
+ u_model: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
789
+ },
790
+ uniformSemantics: {
791
+ u_vp: 'VIEWPROJECTION',
792
+ u_et: 'EDITOR_TRANSFORM',
793
+ },
794
+ shader: {
795
+ shared: true,
796
+ fragment: "\n precision mediump float;\n\n uniform vec3 u_color;\n\n void main(){\n gl_FragColor = vec4(u_color,1.0);\n }",
797
+ vertex: "precision highp float;\n\n attribute vec3 a_Position;\n\n uniform mat4 u_model;\n uniform mat4 effects_MatrixVP;\n uniform vec4 uEditorTransform;\n void main(){\n gl_Position = effects_MatrixVP * u_model * vec4(a_Position,1.0);\n gl_Position = vec4(gl_Position.xy * uEditorTransform.xy + uEditorTransform.zw * gl_Position.w,gl_Position.zw);\n }",
798
+ },
799
+ });
800
+ material.setVector3('u_color', color);
801
+ material.setMatrix('u_model', [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
802
+ material.depthTest = depthTest;
803
+ material.stencilTest = false;
804
+ material.blending = false;
805
+ material.depthMask = true;
806
+ var geometry = Geometry.create(engine, {
807
+ attributes: {
808
+ a_Position: {
809
+ size: 3,
810
+ data: points,
811
+ },
812
+ },
813
+ indices: {
814
+ data: indices,
815
+ },
816
+ mode: glContext.LINES,
817
+ drawCount: indices.length,
818
+ });
819
+ return Mesh.create(engine, {
820
+ name: name,
821
+ geometry: geometry,
822
+ material: material,
823
+ priority: 3000,
824
+ });
825
+ }
826
+
827
+ /**
828
+ * 基础几何数据[抽象类,不可以直接用来初始化]
829
+ */
830
+ var GeometryData = /** @class */ (function () {
831
+ function GeometryData() {
832
+ this.points = [];
833
+ this.uvs = [];
834
+ this.normals = [];
835
+ this.indices = [];
836
+ }
837
+ /**
838
+ * 构件 XY 平面圆(圆心为(0, 0, z))
839
+ * @param radius - 圆半径
840
+ * @param z - z 值
841
+ * @param segments - 圆精度
842
+ * @param thetaStart - 起始弧度
843
+ * @param thetaLength - 终止弧度
844
+ * @param startIndex - 索引起始值
845
+ * @param points - 点数据
846
+ * @param indices - 索引数据
847
+ */
848
+ GeometryData.prototype.createXYPlaneCircle = function (radius, z, segments, thetaStart, thetaLength, startIndex, points, indices) {
849
+ for (var i = 0; i < segments; i++) {
850
+ var theta = thetaStart + i * thetaLength / segments;
851
+ var x = radius * Math.cos(theta);
852
+ var y = radius * Math.sin(theta);
853
+ points.push(x, y, z);
854
+ indices.push(startIndex + i, startIndex + (i + 1) % segments);
855
+ }
856
+ };
857
+ /**
858
+ * 构件 XZ 平面圆(圆心为(0, y, 0))
859
+ * @param radius - 圆半径
860
+ * @param y - y 值
861
+ * @param segments - 圆精度
862
+ * @param thetaStart - 起始弧度
863
+ * @param thetaLength - 终止弧度
864
+ * @param startIndex - 索引起始值
865
+ * @param points - 点数据
866
+ * @param indices - 索引数据
867
+ */
868
+ GeometryData.prototype.createXZPlaneCircle = function (radius, y, segments, thetaStart, thetaLength, startIndex, points, indices) {
869
+ for (var i = 0; i < segments; i++) {
870
+ var theta = thetaStart + i * thetaLength / segments;
871
+ var x = radius * Math.cos(theta);
872
+ var z = radius * Math.sin(theta);
873
+ points.push(x, y, z);
874
+ indices.push(startIndex + i, startIndex + (i + 1) % segments);
875
+ }
876
+ };
877
+ /**
878
+ * 构件 YZ 平面圆(圆心为(x, 0, 0))
879
+ * @param radius - 圆半径
880
+ * @param x - x 值
881
+ * @param segments - 圆精度
882
+ * @param thetaStart - 起始弧度
883
+ * @param thetaLength - 终止弧度
884
+ * @param startIndex - 索引起始值
885
+ * @param points - 点数据
886
+ * @param indices - 索引数据
887
+ */
888
+ GeometryData.prototype.createYZPlaneCircle = function (radius, x, segments, thetaStart, thetaLength, startIndex, points, indices) {
889
+ for (var i = 0; i < segments; i++) {
890
+ var theta = thetaStart + i * thetaLength / segments;
891
+ var z = radius * Math.cos(theta);
892
+ var y = radius * Math.sin(theta);
893
+ points.push(x, y, z);
894
+ indices.push(startIndex + i, startIndex + (i + 1) % segments);
895
+ }
896
+ };
897
+ return GeometryData;
898
+ }());
899
+
900
+ /**
901
+ *
902
+ */
903
+ var SphereGeometryData = /** @class */ (function (_super) {
904
+ __extends(SphereGeometryData, _super);
905
+ /**
906
+ *
907
+ * @param radius
908
+ * @param widthSegments
909
+ * @param heightSegments
910
+ * @param phiStart
911
+ * @param phiLength
912
+ * @param thetaStart
913
+ * @param thetaLength
914
+ */
915
+ function SphereGeometryData(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength) {
916
+ var _a;
917
+ if (radius === void 0) { radius = 1; }
918
+ if (widthSegments === void 0) { widthSegments = 8; }
919
+ if (heightSegments === void 0) { heightSegments = 6; }
920
+ if (phiStart === void 0) { phiStart = 0; }
921
+ if (phiLength === void 0) { phiLength = Math.PI * 2; }
922
+ if (thetaStart === void 0) { thetaStart = 0; }
923
+ if (thetaLength === void 0) { thetaLength = Math.PI; }
924
+ var _this = _super.call(this) || this;
925
+ // 限制至少需要分为六块以保持形状
926
+ widthSegments = Math.max(3, Math.floor(widthSegments));
927
+ heightSegments = Math.max(2, Math.floor(heightSegments));
928
+ var thetaEnd = Math.min(thetaStart + thetaLength, Math.PI);
929
+ var grid = [];
930
+ var index = 0;
931
+ for (var iy = 0; iy <= heightSegments; iy++) {
932
+ var verticesRow = [];
933
+ var v = iy / heightSegments;
934
+ var uOffset = 0;
935
+ if (iy == 0 && thetaStart == 0) {
936
+ uOffset = 0.5 / widthSegments;
937
+ }
938
+ else if (iy == heightSegments && thetaEnd == Math.PI) {
939
+ uOffset = -0.5 / widthSegments;
940
+ }
941
+ for (var ix = 0; ix <= widthSegments; ix++) {
942
+ var u = ix / widthSegments;
943
+ // point
944
+ var x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
945
+ var y = radius * Math.cos(thetaStart + v * thetaLength);
946
+ var z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
947
+ _this.points.push(x, y, z);
948
+ // normal
949
+ var normal = vecNormalize([x, y, z]);
950
+ (_a = _this.normals).push.apply(_a, __spreadArray([], __read(normal), false));
951
+ // uv
952
+ _this.uvs.push(u + uOffset, 1 - v);
953
+ verticesRow.push(index++);
954
+ }
955
+ grid.push(verticesRow);
956
+ }
957
+ // indices
958
+ for (var iy = 0; iy < heightSegments; iy++) {
959
+ for (var ix = 0; ix < widthSegments; ix++) {
960
+ var a = grid[iy][ix + 1];
961
+ var b = grid[iy][ix];
962
+ var c = grid[iy + 1][ix];
963
+ var d = grid[iy + 1][ix + 1];
964
+ if (iy !== 0 || thetaStart > 0) {
965
+ _this.indices.push(a, b, d);
966
+ }
967
+ if (iy !== heightSegments - 1 || thetaEnd < Math.PI) {
968
+ _this.indices.push(b, c, d);
969
+ }
970
+ }
971
+ }
972
+ return _this;
973
+ }
974
+ return SphereGeometryData;
975
+ }(GeometryData));
976
+
977
+ // 面造型未单独抽离, 整个包围盒只接受一个材质
978
+ var BoxGeometryData = /** @class */ (function (_super) {
979
+ __extends(BoxGeometryData, _super);
980
+ /**
981
+ *
982
+ * @param width
983
+ * @param height
984
+ * @param depth
985
+ */
986
+ function BoxGeometryData(width, height, depth) {
987
+ if (width === void 0) { width = 1; }
988
+ if (height === void 0) { height = 1; }
989
+ if (depth === void 0) { depth = 1; }
990
+ var _this = _super.call(this) || this;
991
+ var numberOfVertices = 0;
992
+ buildPlane(2, 1, 0, -1, -1, depth, height, width, _this.points, _this.uvs, _this.normals, _this.indices); // px
993
+ buildPlane(2, 1, 0, 1, -1, depth, height, -width, _this.points, _this.uvs, _this.normals, _this.indices); // nx
994
+ buildPlane(0, 2, 1, 1, 1, width, depth, height, _this.points, _this.uvs, _this.normals, _this.indices); // py
995
+ buildPlane(0, 2, 1, 1, -1, width, depth, -height, _this.points, _this.uvs, _this.normals, _this.indices); // ny
996
+ buildPlane(0, 1, 2, 1, -1, width, height, depth, _this.points, _this.uvs, _this.normals, _this.indices); // pz
997
+ buildPlane(0, 1, 2, -1, -1, width, height, -depth, _this.points, _this.uvs, _this.normals, _this.indices); // nz
998
+ function buildPlane(u, v, w, uDir, vDir, width, height, depth, points, uvs, normals, indices) {
999
+ var widthHalf = width / 2;
1000
+ var heightHalf = height / 2;
1001
+ var depthHalf = depth / 2;
1002
+ var point = [0, 0, 0];
1003
+ var vertexCounter = 0;
1004
+ for (var iy = 0; iy < 2; iy++) {
1005
+ var y = iy * height - heightHalf;
1006
+ for (var ix = 0; ix < 2; ix++) {
1007
+ var x = ix * width - widthHalf;
1008
+ point[u] = x * uDir;
1009
+ point[v] = y * vDir;
1010
+ point[w] = depthHalf;
1011
+ points.push.apply(points, __spreadArray([], __read(point), false));
1012
+ point[u] = 0;
1013
+ point[v] = 0;
1014
+ point[w] = depth > 0 ? 1 : -1;
1015
+ normals.push.apply(normals, __spreadArray([], __read(point), false));
1016
+ uvs.push(ix);
1017
+ uvs.push(1 - iy);
1018
+ vertexCounter += 1;
1019
+ }
1020
+ }
1021
+ for (var iy = 0; iy < 1; iy++) {
1022
+ for (var ix = 0; ix < 1; ix++) {
1023
+ var a = numberOfVertices + ix + 2 * iy;
1024
+ var b = numberOfVertices + ix + 2 * (iy + 1);
1025
+ var c = numberOfVertices + (ix + 1) + 2 * (iy + 1);
1026
+ var d = numberOfVertices + (ix + 1) + 2 * iy;
1027
+ indices.push(a, b, d);
1028
+ indices.push(b, c, d);
1029
+ }
1030
+ }
1031
+ numberOfVertices += vertexCounter;
1032
+ }
1033
+ return _this;
1034
+ }
1035
+ return BoxGeometryData;
1036
+ }(GeometryData));
1037
+
1038
+ /**
1039
+ *
1040
+ */
1041
+ var CylinderGeometryData = /** @class */ (function (_super) {
1042
+ __extends(CylinderGeometryData, _super);
1043
+ /**
1044
+ *
1045
+ * @param radiusTop
1046
+ * @param radiusBottom
1047
+ * @param height
1048
+ * @param radialSegments
1049
+ * @param heightSegments
1050
+ * @param openEnded
1051
+ * @param thetaStart
1052
+ * @param thetaLength
1053
+ */
1054
+ function CylinderGeometryData(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) {
1055
+ if (radiusTop === void 0) { radiusTop = 1; }
1056
+ if (radiusBottom === void 0) { radiusBottom = 1; }
1057
+ if (height === void 0) { height = 1; }
1058
+ if (radialSegments === void 0) { radialSegments = 8; }
1059
+ if (heightSegments === void 0) { heightSegments = 1; }
1060
+ if (openEnded === void 0) { openEnded = false; }
1061
+ if (thetaStart === void 0) { thetaStart = 0; }
1062
+ if (thetaLength === void 0) { thetaLength = Math.PI * 2; }
1063
+ var _this = _super.call(this) || this;
1064
+ radialSegments = Math.floor(radialSegments);
1065
+ heightSegments = Math.floor(heightSegments);
1066
+ var index = 0;
1067
+ var indexArray = [];
1068
+ var halfHeight = height / 2;
1069
+ generateTorso(_this.points, _this.uvs, _this.normals, _this.indices);
1070
+ if (openEnded === false) {
1071
+ if (radiusTop > 0) {
1072
+ generateCap(true, _this.points, _this.uvs, _this.normals, _this.indices);
1073
+ }
1074
+ if (radiusBottom > 0) {
1075
+ generateCap(false, _this.points, _this.uvs, _this.normals, _this.indices);
1076
+ }
1077
+ }
1078
+ function generateTorso(points, uvs, normals, indices) {
1079
+ // this will be used to calculate the normal
1080
+ var slope = (radiusBottom - radiusTop) / height;
1081
+ for (var y = 0; y <= heightSegments; y++) {
1082
+ var indexRow = [];
1083
+ var v = y / heightSegments;
1084
+ var radius = v * (radiusBottom - radiusTop) + radiusTop;
1085
+ for (var x = 0; x <= radialSegments; x++) {
1086
+ var u = x / radialSegments;
1087
+ var theta = u * thetaLength + thetaStart;
1088
+ var sinTheta = Math.sin(theta);
1089
+ var cosTheta = Math.cos(theta);
1090
+ var px = radius * sinTheta;
1091
+ var py = -v * height + halfHeight;
1092
+ var pz = radius * cosTheta;
1093
+ points.push(px, py, pz);
1094
+ var normal = vecNormalize([sinTheta, slope, cosTheta]);
1095
+ normals.push.apply(normals, __spreadArray([], __read(normal), false));
1096
+ uvs.push(u, 1 - v);
1097
+ indexRow.push(index++);
1098
+ }
1099
+ indexArray.push(indexRow);
1100
+ }
1101
+ for (var x = 0; x < radialSegments; x++) {
1102
+ for (var y = 0; y < heightSegments; y++) {
1103
+ var a = indexArray[y][x];
1104
+ var b = indexArray[y + 1][x];
1105
+ var c = indexArray[y + 1][x + 1];
1106
+ var d = indexArray[y][x + 1];
1107
+ indices.push(a, b, d);
1108
+ indices.push(b, c, d);
1109
+ }
1110
+ }
1111
+ }
1112
+ function generateCap(top, points, uvs, normals, indices) {
1113
+ var centerIndexStart = index;
1114
+ var radius = (top === true) ? radiusTop : radiusBottom;
1115
+ var sign = (top === true) ? 1 : -1;
1116
+ for (var x = 1; x <= radialSegments; x++) {
1117
+ points.push(0, halfHeight * sign, 0);
1118
+ normals.push(0, sign, 0);
1119
+ uvs.push(0.5, 0.5);
1120
+ index++;
1121
+ }
1122
+ var centerIndexEnd = index;
1123
+ for (var x = 0; x <= radialSegments; x++) {
1124
+ var u = x / radialSegments;
1125
+ var theta = u * thetaLength + thetaStart;
1126
+ var cosTheta = Math.cos(theta);
1127
+ var sinTheta = Math.sin(theta);
1128
+ var px = radius * sinTheta;
1129
+ var py = halfHeight * sign;
1130
+ var pz = radius * cosTheta;
1131
+ points.push(px, py, pz);
1132
+ normals.push(0, sign, 0);
1133
+ var uvU = (cosTheta * 0.5) + 0.5;
1134
+ var uvV = (sinTheta * 0.5 * sign) + 0.5;
1135
+ uvs.push(uvU, uvV);
1136
+ index++;
1137
+ }
1138
+ for (var x = 0; x < radialSegments; x++) {
1139
+ var c = centerIndexStart + x;
1140
+ var i = centerIndexEnd + x;
1141
+ if (top === true) {
1142
+ indices.push(i, i + 1, c);
1143
+ }
1144
+ else {
1145
+ indices.push(i + 1, i, c);
1146
+ }
1147
+ }
1148
+ }
1149
+ return _this;
1150
+ }
1151
+ return CylinderGeometryData;
1152
+ }(GeometryData));
1153
+
1154
+ /**
1155
+ *
1156
+ */
1157
+ var ConeGeometryData = /** @class */ (function (_super) {
1158
+ __extends(ConeGeometryData, _super);
1159
+ /**
1160
+ *
1161
+ * @param radius
1162
+ * @param height
1163
+ * @param radialSegments
1164
+ * @param heightSegments
1165
+ * @param openEnded
1166
+ * @param thetaStart
1167
+ * @param thetaLength
1168
+ */
1169
+ function ConeGeometryData(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) {
1170
+ if (radius === void 0) { radius = 1; }
1171
+ if (height === void 0) { height = 1; }
1172
+ if (radialSegments === void 0) { radialSegments = 8; }
1173
+ if (heightSegments === void 0) { heightSegments = 1; }
1174
+ if (openEnded === void 0) { openEnded = false; }
1175
+ if (thetaStart === void 0) { thetaStart = 0; }
1176
+ if (thetaLength === void 0) { thetaLength = Math.PI * 2; }
1177
+ return _super.call(this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength) || this;
1178
+ }
1179
+ return ConeGeometryData;
1180
+ }(CylinderGeometryData));
1181
+
1182
+ /**
1183
+ *
1184
+ */
1185
+ var TorusGeometryData = /** @class */ (function (_super) {
1186
+ __extends(TorusGeometryData, _super);
1187
+ /**
1188
+ *
1189
+ * @param radius
1190
+ * @param tube
1191
+ * @param radialSegments
1192
+ * @param tubularSegments
1193
+ * @param arc
1194
+ */
1195
+ function TorusGeometryData(radius, tube, radialSegments, tubularSegments, arc) {
1196
+ var _a;
1197
+ if (radius === void 0) { radius = 1; }
1198
+ if (tube === void 0) { tube = 0.4; }
1199
+ if (radialSegments === void 0) { radialSegments = 64; }
1200
+ if (tubularSegments === void 0) { tubularSegments = 64; }
1201
+ if (arc === void 0) { arc = Math.PI * 2; }
1202
+ var _this = _super.call(this) || this;
1203
+ radialSegments = Math.floor(radialSegments);
1204
+ tubularSegments = Math.floor(tubularSegments);
1205
+ for (var j = 0; j <= radialSegments; j++) {
1206
+ for (var i = 0; i <= tubularSegments; i++) {
1207
+ var u = i / tubularSegments * arc;
1208
+ var v = j / radialSegments * Math.PI * 2;
1209
+ var px = (radius + tube * Math.cos(v)) * Math.cos(u);
1210
+ var py = (radius + tube * Math.cos(v)) * Math.sin(u);
1211
+ var pz = tube * Math.sin(v);
1212
+ _this.points.push(px, py, pz);
1213
+ var cx = radius * Math.cos(u);
1214
+ var cy = radius * Math.sin(u);
1215
+ var normal = vecNormalize(vecSub([], [px, py, pz], [cx, cy, 0]));
1216
+ (_a = _this.normals).push.apply(_a, __spreadArray([], __read(normal), false));
1217
+ _this.uvs.push(i / tubularSegments);
1218
+ _this.uvs.push(j / radialSegments);
1219
+ }
1220
+ }
1221
+ for (var j = 1; j <= radialSegments; j++) {
1222
+ for (var i = 1; i <= tubularSegments; i++) {
1223
+ var a = (tubularSegments + 1) * j + i - 1;
1224
+ var b = (tubularSegments + 1) * (j - 1) + i - 1;
1225
+ var c = (tubularSegments + 1) * (j - 1) + i;
1226
+ var d = (tubularSegments + 1) * j + i;
1227
+ _this.indices.push(a, b, d);
1228
+ _this.indices.push(b, c, d);
1229
+ }
1230
+ }
1231
+ return _this;
1232
+ }
1233
+ return TorusGeometryData;
1234
+ }(GeometryData));
1235
+
1236
+ /**
1237
+ *
1238
+ */
1239
+ var PlaneGeometryData = /** @class */ (function (_super) {
1240
+ __extends(PlaneGeometryData, _super);
1241
+ /**
1242
+ *
1243
+ * @param width
1244
+ * @param height
1245
+ * @param widthSegments
1246
+ * @param heightSegments
1247
+ */
1248
+ function PlaneGeometryData(width, height, widthSegments, heightSegments) {
1249
+ if (width === void 0) { width = 1; }
1250
+ if (height === void 0) { height = 1; }
1251
+ if (widthSegments === void 0) { widthSegments = 1; }
1252
+ if (heightSegments === void 0) { heightSegments = 1; }
1253
+ var _this = _super.call(this) || this;
1254
+ var widthHalf = width / 2;
1255
+ var heightHalf = height / 2;
1256
+ var gridX = Math.floor(widthSegments);
1257
+ var gridY = Math.floor(heightSegments);
1258
+ var gridX1 = gridX + 1;
1259
+ var gridY1 = gridY + 1;
1260
+ var segmentWidth = width / gridX;
1261
+ var segmentHeight = height / gridY;
1262
+ for (var iy = 0; iy < gridY1; iy++) {
1263
+ var y = iy * segmentHeight - heightHalf;
1264
+ for (var ix = 0; ix < gridX1; ix++) {
1265
+ var x = ix * segmentWidth - widthHalf;
1266
+ _this.points.push(x, -y, 0);
1267
+ _this.normals.push(0, 0, 1);
1268
+ _this.uvs.push(ix / gridX);
1269
+ _this.uvs.push(1 - (iy / gridY));
1270
+ }
1271
+ }
1272
+ for (var iy = 0; iy < gridY; iy++) {
1273
+ for (var ix = 0; ix < gridX; ix++) {
1274
+ var a = ix + gridX1 * iy;
1275
+ var b = ix + gridX1 * (iy + 1);
1276
+ var c = (ix + 1) + gridX1 * (iy + 1);
1277
+ var d = (ix + 1) + gridX1 * iy;
1278
+ _this.indices.push(a, b, d);
1279
+ _this.indices.push(b, c, d);
1280
+ }
1281
+ }
1282
+ return _this;
1283
+ }
1284
+ return PlaneGeometryData;
1285
+ }(GeometryData));
1286
+
1287
+ /**
1288
+ *
1289
+ */
1290
+ var FrustumGeometryData = /** @class */ (function (_super) {
1291
+ __extends(FrustumGeometryData, _super);
1292
+ /**
1293
+ *
1294
+ * @param position
1295
+ * @param rotation
1296
+ * @param fov
1297
+ * @param aspect
1298
+ * @param near
1299
+ * @param far
1300
+ */
1301
+ function FrustumGeometryData(position, rotation, fov, aspect, near, far) {
1302
+ var _a;
1303
+ var _this = _super.call(this) || this;
1304
+ var fovY = fov / 180 * Math.PI;
1305
+ var ratio = aspect;
1306
+ var halfY = far * Math.tan(fovY / 2);
1307
+ var halfX = halfY * ratio;
1308
+ var point1 = vecAdd([], position, [halfX, halfY, far]);
1309
+ var point2 = vecAdd([], position, [-halfX, halfY, far]);
1310
+ var point3 = vecAdd([], position, [-halfX, -halfY, far]);
1311
+ var point4 = vecAdd([], position, [halfX, -halfY, far]);
1312
+ var matrix = mat3FromRotationZYX([], rotation[0], rotation[1], rotation[2]);
1313
+ var result1 = vec3MulMat3ByPoint([], point1, matrix, position);
1314
+ var result2 = vec3MulMat3ByPoint([], point2, matrix, position);
1315
+ var result3 = vec3MulMat3ByPoint([], point3, matrix, position);
1316
+ var result4 = vec3MulMat3ByPoint([], point4, matrix, position);
1317
+ (_a = _this.points).push.apply(_a, __spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(position), false), __read(result1), false), __read(result2), false), __read(result3), false), __read(result4), false));
1318
+ _this.indices.push(0, 1, 0, 2, 0, 3, 0, 4, 1, 2, 2, 3, 3, 4, 4, 1);
1319
+ return _this;
1320
+ }
1321
+ return FrustumGeometryData;
1322
+ }(GeometryData));
1323
+
1324
+ /**
1325
+ * 方向光造型数据
1326
+ * lines
1327
+ */
1328
+ var DirectionLightData = /** @class */ (function (_super) {
1329
+ __extends(DirectionLightData, _super);
1330
+ /**
1331
+ * 构造函数
1332
+ * @param radius - 圆半径
1333
+ * @param length - 光线长度
1334
+ * @param segments - 圆精度
1335
+ * @param linesNumber - 光线数量
1336
+ * @param thetaStart - 起始弧度
1337
+ * @param thetaLength - 终止弧度
1338
+ */
1339
+ function DirectionLightData(radius, length, segments, linesNumber, thetaStart, thetaLength) {
1340
+ if (radius === void 0) { radius = 1; }
1341
+ if (length === void 0) { length = 2; }
1342
+ if (segments === void 0) { segments = 64; }
1343
+ if (linesNumber === void 0) { linesNumber = 8; }
1344
+ if (thetaStart === void 0) { thetaStart = 0; }
1345
+ if (thetaLength === void 0) { thetaLength = Math.PI * 2; }
1346
+ var _this = _super.call(this) || this;
1347
+ _this.createXYPlaneCircle(radius, 0, segments, thetaStart, thetaLength, 0, _this.points, _this.indices);
1348
+ var start = segments % linesNumber / 2;
1349
+ var step = segments / linesNumber;
1350
+ for (var i = 0; i < linesNumber; i++) {
1351
+ var index = start + i * step;
1352
+ var x = _this.points[3 * index];
1353
+ var y = _this.points[3 * index + 1];
1354
+ var z = -length;
1355
+ _this.points.push(x, y, z);
1356
+ _this.indices.push(index, segments + i);
1357
+ }
1358
+ return _this;
1359
+ }
1360
+ return DirectionLightData;
1361
+ }(GeometryData));
1362
+
1363
+ /**
1364
+ * 点光源造型数据
1365
+ * lines
1366
+ */
1367
+ var PointLightData = /** @class */ (function (_super) {
1368
+ __extends(PointLightData, _super);
1369
+ /**
1370
+ * 构造函数
1371
+ * @param range - 光照范围
1372
+ * @param segments - 圆精度
1373
+ * @param thetaStart - 起始弧度
1374
+ * @param thetaLength - 终止弧度
1375
+ */
1376
+ function PointLightData(range, segments, thetaStart, thetaLength) {
1377
+ if (range === void 0) { range = 10; }
1378
+ if (segments === void 0) { segments = 64; }
1379
+ if (thetaStart === void 0) { thetaStart = 0; }
1380
+ if (thetaLength === void 0) { thetaLength = Math.PI * 2; }
1381
+ var _this = _super.call(this) || this;
1382
+ _this.createXYPlaneCircle(range, 0, segments, thetaStart, thetaLength, 0, _this.points, _this.indices);
1383
+ _this.createXZPlaneCircle(range, 0, segments, thetaStart, thetaLength, segments, _this.points, _this.indices);
1384
+ _this.createYZPlaneCircle(range, 0, segments, thetaStart, thetaLength, 2 * segments, _this.points, _this.indices);
1385
+ return _this;
1386
+ }
1387
+ return PointLightData;
1388
+ }(GeometryData));
1389
+
1390
+ /**
1391
+ * 聚光灯造型数据
1392
+ * lines
1393
+ */
1394
+ var SpotLightData = /** @class */ (function (_super) {
1395
+ __extends(SpotLightData, _super);
1396
+ /**
1397
+ * 构造函数
1398
+ * @param range - 光线范围
1399
+ * @param spotAngle - 光线范围[角度]
1400
+ * @param segments - 圆精度
1401
+ * @param thetaStart - 起始弧度
1402
+ * @param thetaLength - 终止弧度
1403
+ */
1404
+ function SpotLightData(range, spotAngle, segments, thetaStart, thetaLength) {
1405
+ if (range === void 0) { range = 10; }
1406
+ if (spotAngle === void 0) { spotAngle = 30; }
1407
+ if (segments === void 0) { segments = 64; }
1408
+ if (thetaStart === void 0) { thetaStart = 0; }
1409
+ if (thetaLength === void 0) { thetaLength = Math.PI * 2; }
1410
+ var _this = _super.call(this) || this;
1411
+ var angle = spotAngle / 2 / 180 * Math.PI;
1412
+ var radius = range * Math.tan(angle);
1413
+ _this.createXYPlaneCircle(radius, -range, segments, thetaStart, thetaLength, 0, _this.points, _this.indices);
1414
+ _this.points.push(0, 0, 0);
1415
+ var step = segments / 4;
1416
+ var start = segments % 4 / 2;
1417
+ for (var i = 0; i < 4; i++) {
1418
+ _this.indices.push(segments, start + i * step);
1419
+ }
1420
+ return _this;
1421
+ }
1422
+ return SpotLightData;
1423
+ }(GeometryData));
1424
+
1425
+ /**
1426
+ * 地板线边框造型数据
1427
+ * lines
1428
+ */
1429
+ var FloorLineEdgeGeometryData = /** @class */ (function (_super) {
1430
+ __extends(FloorLineEdgeGeometryData, _super);
1431
+ /**
1432
+ *
1433
+ * @param sideLength
1434
+ * @param parts
1435
+ */
1436
+ function FloorLineEdgeGeometryData(sideLength, parts) {
1437
+ if (sideLength === void 0) { sideLength = 12; }
1438
+ if (parts === void 0) { parts = 6; }
1439
+ var _this = _super.call(this) || this;
1440
+ var index = 0;
1441
+ var z = 0;
1442
+ var end = sideLength / 2;
1443
+ var start = -sideLength / 2;
1444
+ for (var i = 0; i <= parts; i++) {
1445
+ var v = start + i * sideLength / parts;
1446
+ _this.points.push(v, start, z, v, end, z, start, v, z, end, v, z);
1447
+ _this.indices.push(index, index + 1, index + 2, index + 3);
1448
+ index += 4;
1449
+ }
1450
+ return _this;
1451
+ }
1452
+ return FloorLineEdgeGeometryData;
1453
+ }(GeometryData));
1454
+
1455
+ /**
1456
+ * 几何体类型
1457
+ */
1458
+ var GeometryType;
1459
+ (function (GeometryType) {
1460
+ GeometryType[GeometryType["Box"] = 0] = "Box";
1461
+ GeometryType[GeometryType["Sphere"] = 1] = "Sphere";
1462
+ GeometryType[GeometryType["Cylinder"] = 2] = "Cylinder";
1463
+ GeometryType[GeometryType["Cone"] = 3] = "Cone";
1464
+ GeometryType[GeometryType["Torus"] = 4] = "Torus";
1465
+ GeometryType[GeometryType["Frustum"] = 5] = "Frustum";
1466
+ GeometryType[GeometryType["Sprite"] = 6] = "Sprite";
1467
+ GeometryType[GeometryType["Plane"] = 7] = "Plane";
1468
+ GeometryType[GeometryType["DirectionLight"] = 8] = "DirectionLight";
1469
+ GeometryType[GeometryType["SpotLight"] = 9] = "SpotLight";
1470
+ GeometryType[GeometryType["PointLight"] = 10] = "PointLight";
1471
+ GeometryType[GeometryType["FloorGrid"] = 11] = "FloorGrid";
1472
+ })(GeometryType || (GeometryType = {}));
1473
+ /**
1474
+ * 合并多个几何体数据
1475
+ * @param geometries - 几何体数据数组
1476
+ * @returns 合并后的几何体数据
1477
+ */
1478
+ // export function combineGeometries (geometries: GeometryData[]): GeometryData {
1479
+ // const points: number[] = [];
1480
+ // const indices: number[] = [];
1481
+ // const uvs: number[] = [];
1482
+ // const normals: number[] = [];
1483
+ // for (let i = 0, indicesBase = 0; i < geometries.length; i++) {
1484
+ // const geometryData = geometries[i];
1485
+ // if (geometryData) {
1486
+ // points.push(...geometryData.points);
1487
+ // uvs.push(...geometryData.uvs);
1488
+ // normals.push(...geometryData.normals);
1489
+ // geometryData.indices.forEach(index => indices.push(index + indicesBase));
1490
+ // indicesBase += geometryData.points.length;
1491
+ // }
1492
+ // }
1493
+ // return {
1494
+ // points,
1495
+ // indices,
1496
+ // uvs,
1497
+ // normals,
1498
+ // };
1499
+ // }
1500
+ /**
1501
+ * 创建几何体对象
1502
+ * @param type - 几何体类型
1503
+ * @param size - 几何体尺寸
1504
+ * @param renderMode - 绘制模式:`gl.TRIANGLES`、`gl.LINES`
1505
+ * @returns
1506
+ */
1507
+ function createGeometry(engine, type, size, renderMode) {
1508
+ var geometryData;
1509
+ switch (type) {
1510
+ case GeometryType.Sphere:
1511
+ geometryData = new SphereGeometryData(size.radius, size.widthSegments, size.heightSegments);
1512
+ break;
1513
+ case GeometryType.Cylinder:
1514
+ geometryData = new CylinderGeometryData(size.radius, size.radius, size.height);
1515
+ break;
1516
+ case GeometryType.Cone:
1517
+ geometryData = new ConeGeometryData(size.radius, size.height);
1518
+ break;
1519
+ case GeometryType.Torus:
1520
+ geometryData = new TorusGeometryData(size.radius, size.tube, size.radialSegments, size.tubularSegments, size.arc);
1521
+ break;
1522
+ case GeometryType.Sprite:
1523
+ case GeometryType.Plane:
1524
+ geometryData = new PlaneGeometryData(size.width, size.height);
1525
+ break;
1526
+ case GeometryType.Frustum:
1527
+ geometryData = new FrustumGeometryData(size.position, size.rotation, size.fov, size.aspect, size.near, size.far);
1528
+ break;
1529
+ case GeometryType.DirectionLight:
1530
+ geometryData = new DirectionLightData(size.radius, size.length, size.segments4, size.linesNumber, size.thetaStart, size.thetaLength);
1531
+ break;
1532
+ case GeometryType.PointLight:
1533
+ geometryData = new PointLightData(size.range, size.segments, size.thetaStart, size.thetaLength);
1534
+ break;
1535
+ case GeometryType.SpotLight:
1536
+ geometryData = new SpotLightData(size.range, size.spotAngle, size.segments, size.thetaStart, size.thetaLength);
1537
+ break;
1538
+ case GeometryType.FloorGrid:
1539
+ geometryData = new FloorLineEdgeGeometryData(size.sideLength, size.parts);
1540
+ break;
1541
+ default:
1542
+ geometryData = new BoxGeometryData(size.width, size.height, size.depth);
1543
+ break;
1544
+ }
1545
+ var result = Geometry.create(engine, {
1546
+ attributes: {
1547
+ a_Position: {
1548
+ size: 3,
1549
+ data: new Float32Array(geometryData.points),
1550
+ },
1551
+ a_Normal: {
1552
+ size: 3,
1553
+ data: new Float32Array(geometryData.normals),
1554
+ },
1555
+ a_UV1: {
1556
+ size: 2,
1557
+ data: new Float32Array(geometryData.uvs),
1558
+ },
1559
+ },
1560
+ indices: {
1561
+ data: new Uint16Array(geometryData.indices),
1562
+ },
1563
+ mode: renderMode,
1564
+ drawCount: geometryData.indices.length,
1565
+ });
1566
+ return result;
1567
+ }
1568
+
1569
+ // 坐标轴默认颜色
1570
+ var color = {
1571
+ xAxisColor: [216 / 255, 178 / 255, 76 / 255],
1572
+ yAxisColor: [38 / 255, 149 / 255, 235 / 255],
1573
+ zAxisColor: [134 / 255, 74 / 255, 245 / 255],
1574
+ };
1575
+ var renderMode = glContext.TRIANGLES;
1576
+ // 坐标轴默认图标
1577
+ var axisIconMap = new Map();
1578
+ axisIconMap.set('light', "data:image/png;base64,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");
1579
+ axisIconMap.set('camera', "data:image/png;base64,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");
1580
+ axisIconMap.set('posX', "data:image/png;base64,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\n RK5CYII=");
1581
+ axisIconMap.set('posY', "data:image/png;base64,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");
1582
+ axisIconMap.set('posZ', "data:image/png;base64,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");
1583
+ axisIconMap.set('negX', "data:image/png;base64,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\n 5ErkJggg==");
1584
+ axisIconMap.set('negY', "data:image/png;base64,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\n 5ErkJggg==");
1585
+ axisIconMap.set('negZ', "data:image/png;base64,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");
1586
+
1587
+ /**
1588
+ * 根据 gizmoSubType 类型创建几何体 Mesh
1589
+ * @param subType - gizmoSubType 类型
1590
+ * @param boundingMap - 包围盒 Map
1591
+ * @param iconTexture - 图标纹理
1592
+ * @param options - 几何体参数
1593
+ * @returns 基础几何体 Mesh | 组合几何体 Map<Mesh, Transform>
1594
+ */
1595
+ function createMeshFromSubType(engine, subType, boundingMap, iconTexture, options) {
1596
+ var result;
1597
+ if (!options) {
1598
+ options = { size: 0, renderMode: WebGLRenderingContext['TRIANGLES'] };
1599
+ }
1600
+ switch (subType) {
1601
+ case GizmoSubType.sprite:
1602
+ result = createSpriteMesh(engine, options);
1603
+ break;
1604
+ case GizmoSubType.camera:
1605
+ result = createSpriteMesh(engine, options, iconTexture ? iconTexture.get('camera') : undefined, boundingMap);
1606
+ break;
1607
+ case GizmoSubType.light:
1608
+ result = createSpriteMesh(engine, options, iconTexture ? iconTexture.get('light') : undefined, boundingMap);
1609
+ break;
1610
+ case GizmoSubType.translation:
1611
+ result = createTranslationMesh(engine, options, boundingMap);
1612
+ break;
1613
+ case GizmoSubType.scale:
1614
+ result = createScaleMesh(engine, options, boundingMap);
1615
+ break;
1616
+ case GizmoSubType.viewHelper:
1617
+ result = createViewHelperMesh(engine, options, boundingMap, iconTexture);
1618
+ break;
1619
+ case GizmoSubType.rotation:
1620
+ result = createRotationMesh(engine, options, boundingMap);
1621
+ break;
1622
+ default:
1623
+ result = createBasicMesh(engine, subType, options);
1624
+ break;
1625
+ }
1626
+ return result;
1627
+ }
1628
+ /**
1629
+ * 创建旋转组件 Mesh 数组
1630
+ * @internal
1631
+ * @param options
1632
+ * @param boundingMap - 包围盒 Map
1633
+ * @returns Mesh 数组和对应的 Transform 组成的 Map
1634
+ */
1635
+ function createRotationMesh(engine, options, boundingMap) {
1636
+ var result = new Map();
1637
+ var scale = options.size.scale || 1;
1638
+ var size = {
1639
+ radius: 0.8 * scale,
1640
+ tube: 0.02 * scale,
1641
+ radiusSegments: 10 * scale,
1642
+ widthSegments: 20,
1643
+ heightSegments: 20,
1644
+ };
1645
+ var boundSize = __assign(__assign({}, size), { tube: size.tube * 2 });
1646
+ var name = 'rotation';
1647
+ var xCircle = createBasicMesh(engine, GizmoSubType.torus, {
1648
+ size: size,
1649
+ color: color.xAxisColor,
1650
+ renderMode: renderMode,
1651
+ name: name,
1652
+ }, 'hideBack');
1653
+ var yCircle = createBasicMesh(engine, GizmoSubType.torus, {
1654
+ size: size,
1655
+ color: color.yAxisColor,
1656
+ renderMode: renderMode,
1657
+ name: name,
1658
+ }, 'hideBack');
1659
+ var zCircle = createBasicMesh(engine, GizmoSubType.torus, {
1660
+ size: size,
1661
+ color: color.zAxisColor,
1662
+ renderMode: renderMode,
1663
+ name: name,
1664
+ }, 'hideBack');
1665
+ var center = createBasicMesh(engine, GizmoSubType.sphere, {
1666
+ size: size,
1667
+ color: [0.3, 0.3, 0.3], alpha: 0.1,
1668
+ renderMode: renderMode,
1669
+ name: name,
1670
+ }, 'blend');
1671
+ var xCircleBounding = createBasicMesh(engine, GizmoSubType.torus, {
1672
+ size: boundSize,
1673
+ color: color.xAxisColor,
1674
+ renderMode: renderMode,
1675
+ });
1676
+ var yCircleBounding = createBasicMesh(engine, GizmoSubType.torus, {
1677
+ size: boundSize,
1678
+ color: color.yAxisColor,
1679
+ renderMode: renderMode,
1680
+ });
1681
+ var zCircleBounding = createBasicMesh(engine, GizmoSubType.torus, {
1682
+ size: boundSize,
1683
+ color: color.zAxisColor,
1684
+ renderMode: renderMode,
1685
+ });
1686
+ var xCircleTransform = new Transform({
1687
+ valid: true,
1688
+ });
1689
+ var yCircleTransform = new Transform({
1690
+ valid: true,
1691
+ });
1692
+ var zCircleTransform = new Transform({
1693
+ valid: true,
1694
+ });
1695
+ var centerTransform = new Transform({
1696
+ valid: true,
1697
+ });
1698
+ xCircleTransform.setRotation(0, 90, 0);
1699
+ yCircleTransform.setRotation(-90, 0, 0);
1700
+ zCircleTransform.setRotation(0, 0, 0);
1701
+ result.set(center, centerTransform);
1702
+ result.set(xCircle, xCircleTransform);
1703
+ result.set(yCircle, yCircleTransform);
1704
+ result.set(zCircle, zCircleTransform);
1705
+ boundingMap.set('xAxis', {
1706
+ type: BoundingType.triangle,
1707
+ triangles: xCircleBounding.firstGeometry() ? getTriangle(xCircleBounding.firstGeometry(), xCircleTransform) : [],
1708
+ backfaceCulling: true,
1709
+ });
1710
+ boundingMap.set('yAxis', {
1711
+ type: BoundingType.triangle,
1712
+ triangles: yCircleBounding.firstGeometry() ? getTriangle(yCircleBounding.firstGeometry(), yCircleTransform) : [],
1713
+ backfaceCulling: true,
1714
+ });
1715
+ boundingMap.set('zAxis', {
1716
+ type: BoundingType.triangle,
1717
+ triangles: zCircleBounding.firstGeometry() ? getTriangle(zCircleBounding.firstGeometry(), zCircleTransform) : [],
1718
+ backfaceCulling: true,
1719
+ });
1720
+ return result;
1721
+ }
1722
+ /**
1723
+ * 获取几何体的三角面数组
1724
+ * @internal
1725
+ * @param geometry - 几何体
1726
+ * @param transform - 变换式
1727
+ * @returns 三角面数组
1728
+ */
1729
+ function getTriangle(geometry, transform) {
1730
+ var result = [];
1731
+ var indices = geometry.getIndexData();
1732
+ var points = geometry.getAttributeData('a_Position');
1733
+ var mat4 = transform.getWorldMatrix();
1734
+ if (points && indices && indices.length > 0) {
1735
+ indices === null || indices === void 0 ? void 0 : indices.forEach(function (index, i) {
1736
+ var position = [points[index * 3], points[index * 3 + 1], points[index * 3 + 2]];
1737
+ var localPosition = [0, 0, 0];
1738
+ vec3MulMat4(localPosition, position, mat4);
1739
+ if (result[Math.floor(i / 3)] === undefined) {
1740
+ result[Math.floor(i / 3)] = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
1741
+ }
1742
+ result[Math.floor(i / 3)][i % 3] = localPosition;
1743
+ });
1744
+ }
1745
+ return result;
1746
+ }
1747
+ /**
1748
+ * 创建位移组件 Mesh 数组
1749
+ * @internal
1750
+ * @param options
1751
+ * @param boundingMap - 包围盒 Map
1752
+ * @returns Mesh 数组和对应的 Transform 组成的 Map
1753
+ */
1754
+ function createTranslationMesh(engine, options, boundingMap) {
1755
+ var e_1, _a;
1756
+ var result = new Map();
1757
+ var scale = options.size.scale || 1;
1758
+ var axisSize = {
1759
+ width: 0.8 * scale,
1760
+ height: 0.02 * scale,
1761
+ depth: 0.02 * scale,
1762
+ };
1763
+ var name = 'translation';
1764
+ var axisMesh = createAxisMesh(engine, axisSize, false, name);
1765
+ try {
1766
+ for (var axisMesh_1 = __values(axisMesh), axisMesh_1_1 = axisMesh_1.next(); !axisMesh_1_1.done; axisMesh_1_1 = axisMesh_1.next()) {
1767
+ var _b = __read(axisMesh_1_1.value, 2), mesh = _b[0], transform = _b[1];
1768
+ result.set(mesh, transform);
1769
+ }
1770
+ }
1771
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1772
+ finally {
1773
+ try {
1774
+ if (axisMesh_1_1 && !axisMesh_1_1.done && (_a = axisMesh_1.return)) _a.call(axisMesh_1);
1775
+ }
1776
+ finally { if (e_1) throw e_1.error; }
1777
+ }
1778
+ var arrowSize = {
1779
+ radius: 0.05 * scale,
1780
+ height: 0.2 * scale,
1781
+ };
1782
+ var xArrow = createBasicMesh(engine, GizmoSubType.cone, {
1783
+ size: arrowSize,
1784
+ color: color.xAxisColor,
1785
+ renderMode: renderMode,
1786
+ depthTest: true,
1787
+ name: name,
1788
+ }, 'blend');
1789
+ var yArrow = createBasicMesh(engine, GizmoSubType.cone, {
1790
+ size: arrowSize,
1791
+ color: color.yAxisColor,
1792
+ renderMode: renderMode,
1793
+ depthTest: true,
1794
+ name: name,
1795
+ }, 'blend');
1796
+ var zArrow = createBasicMesh(engine, GizmoSubType.cone, {
1797
+ size: arrowSize,
1798
+ color: color.zAxisColor,
1799
+ renderMode: renderMode,
1800
+ name: name,
1801
+ depthTest: true,
1802
+ }, 'blend');
1803
+ var xArrowTransform = new Transform({
1804
+ valid: true,
1805
+ });
1806
+ var yArrowTransform = new Transform({
1807
+ valid: true,
1808
+ });
1809
+ var zArrowTransform = new Transform({
1810
+ valid: true,
1811
+ });
1812
+ xArrowTransform.setRotation(0, 0, 90);
1813
+ yArrowTransform.setRotation(0, 0, 0);
1814
+ zArrowTransform.setRotation(-90, 0, 0);
1815
+ xArrowTransform.translate(axisSize.width, 0, 0);
1816
+ yArrowTransform.translate(0, axisSize.width, 0);
1817
+ zArrowTransform.translate(0, 0, axisSize.width);
1818
+ var planeSize = {
1819
+ width: 0.2 * scale,
1820
+ height: 0.2 * scale,
1821
+ };
1822
+ var xyPlane = createBasicMesh(engine, GizmoSubType.plane, {
1823
+ size: planeSize, color: color.zAxisColor,
1824
+ renderMode: renderMode,
1825
+ depthTest: true,
1826
+ name: name,
1827
+ });
1828
+ var yzPlane = createBasicMesh(engine, GizmoSubType.plane, {
1829
+ size: planeSize, color: color.xAxisColor,
1830
+ renderMode: renderMode,
1831
+ depthTest: true,
1832
+ name: name,
1833
+ });
1834
+ var zxPlane = createBasicMesh(engine, GizmoSubType.plane, {
1835
+ size: planeSize, color: color.yAxisColor,
1836
+ renderMode: renderMode,
1837
+ depthTest: true,
1838
+ name: name,
1839
+ });
1840
+ var xyPlaneTransform = new Transform({
1841
+ valid: true,
1842
+ });
1843
+ var yzPlaneTransform = new Transform({
1844
+ valid: true,
1845
+ });
1846
+ var zxPlaneTransform = new Transform({
1847
+ valid: true,
1848
+ });
1849
+ var delta = axisSize.width / 8;
1850
+ xyPlaneTransform.translate(planeSize.width / 2 + delta, planeSize.height / 2 + delta, 0);
1851
+ yzPlaneTransform.setRotation(0, 90, 0);
1852
+ yzPlaneTransform.translate(0, planeSize.height / 2 + delta, planeSize.width / 2 + delta);
1853
+ zxPlaneTransform.setRotation(-90, 0, 0);
1854
+ zxPlaneTransform.translate(planeSize.width / 2 + delta, 0, planeSize.height / 2 + delta);
1855
+ result.set(xArrow, xArrowTransform);
1856
+ result.set(yArrow, yArrowTransform);
1857
+ result.set(zArrow, zArrowTransform);
1858
+ result.set(xyPlane, xyPlaneTransform);
1859
+ result.set(yzPlane, yzPlaneTransform);
1860
+ result.set(zxPlane, zxPlaneTransform);
1861
+ createAxisBounding({ width: arrowSize.radius * 2.4, length: axisSize.width + arrowSize.height / 2 }, boundingMap);
1862
+ boundingMap.set('xyPlane', {
1863
+ type: BoundingType.triangle,
1864
+ triangles: xyPlane.firstGeometry() ? getTriangle(xyPlane.firstGeometry(), xyPlaneTransform) : [],
1865
+ backfaceCulling: false,
1866
+ });
1867
+ // FIXME: getTriangle 函数调用 getWorldMatrix 后 worldMatrix被修改
1868
+ boundingMap.set('yzPlane', {
1869
+ type: BoundingType.triangle,
1870
+ triangles: yzPlane.firstGeometry() ? getTriangle(yzPlane.firstGeometry(), yzPlaneTransform) : [],
1871
+ backfaceCulling: false,
1872
+ });
1873
+ boundingMap.set('zxPlane', {
1874
+ type: BoundingType.triangle,
1875
+ triangles: zxPlane.firstGeometry() ? getTriangle(zxPlane.firstGeometry(), zxPlaneTransform) : [],
1876
+ backfaceCulling: false,
1877
+ });
1878
+ return result;
1879
+ }
1880
+ /**
1881
+ * 创建缩放组件 Mesh 数组
1882
+ * @internal
1883
+ * @param options
1884
+ * @param boundingMap - 包围盒 Map
1885
+ * @returns Mesh 数组和对应的 Transform 组成的 Map
1886
+ */
1887
+ function createScaleMesh(engine, options, boundingMap) {
1888
+ var e_2, _a;
1889
+ var result = new Map();
1890
+ var scale = options.size.scale || 1;
1891
+ var axisSize = {
1892
+ width: 0.8 * scale,
1893
+ height: 0.02 * scale,
1894
+ depth: 0.02 * scale,
1895
+ };
1896
+ var name = 'scale';
1897
+ var axisMesh = createAxisMesh(engine, axisSize, false, name);
1898
+ try {
1899
+ for (var axisMesh_2 = __values(axisMesh), axisMesh_2_1 = axisMesh_2.next(); !axisMesh_2_1.done; axisMesh_2_1 = axisMesh_2.next()) {
1900
+ var _b = __read(axisMesh_2_1.value, 2), mesh = _b[0], transform = _b[1];
1901
+ result.set(mesh, transform);
1902
+ }
1903
+ }
1904
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
1905
+ finally {
1906
+ try {
1907
+ if (axisMesh_2_1 && !axisMesh_2_1.done && (_a = axisMesh_2.return)) _a.call(axisMesh_2);
1908
+ }
1909
+ finally { if (e_2) throw e_2.error; }
1910
+ }
1911
+ var boxSize = {
1912
+ width: 0.1 * scale,
1913
+ height: 0.1 * scale,
1914
+ depth: 0.1 * scale,
1915
+ };
1916
+ var centerBoxSize = {
1917
+ width: 0.2 * scale,
1918
+ height: 0.2 * scale,
1919
+ depth: 0.2 * scale,
1920
+ };
1921
+ var xCube = createBasicMesh(engine, GizmoSubType.box, {
1922
+ size: boxSize, color: color.xAxisColor,
1923
+ renderMode: renderMode,
1924
+ depthTest: true,
1925
+ name: name,
1926
+ }, 'blend');
1927
+ var yCube = createBasicMesh(engine, GizmoSubType.box, {
1928
+ size: boxSize, color: color.yAxisColor,
1929
+ renderMode: renderMode,
1930
+ depthTest: true,
1931
+ name: name,
1932
+ }, 'blend');
1933
+ var zCube = createBasicMesh(engine, GizmoSubType.box, {
1934
+ size: boxSize, color: color.zAxisColor,
1935
+ renderMode: renderMode,
1936
+ depthTest: true,
1937
+ name: name,
1938
+ }, 'blend');
1939
+ var centerCube = createBasicMesh(engine, GizmoSubType.box, {
1940
+ size: centerBoxSize,
1941
+ color: [0.8, 0.8, 0.8],
1942
+ renderMode: renderMode,
1943
+ depthTest: true,
1944
+ name: name,
1945
+ }, 'blend');
1946
+ var xCubeTransform = new Transform({
1947
+ valid: true,
1948
+ });
1949
+ var yCubeTransform = new Transform({
1950
+ valid: true,
1951
+ });
1952
+ var zCubeTransform = new Transform({
1953
+ valid: true,
1954
+ });
1955
+ var centerCubeTransform = new Transform({
1956
+ valid: true,
1957
+ });
1958
+ xCubeTransform.translate(axisSize.width, 0, 0);
1959
+ yCubeTransform.translate(0, axisSize.width, 0);
1960
+ zCubeTransform.translate(0, 0, axisSize.width);
1961
+ result.set(centerCube, centerCubeTransform);
1962
+ result.set(xCube, xCubeTransform);
1963
+ result.set(yCube, yCubeTransform);
1964
+ result.set(zCube, zCubeTransform);
1965
+ createAxisBounding({ width: boxSize.width * 1.2, length: axisSize.width + boxSize.width / 2 }, boundingMap);
1966
+ boundingMap.set('center', {
1967
+ type: BoundingType.sphere,
1968
+ center: [0, 0, 0],
1969
+ radius: Math.pow(Math.pow(centerBoxSize.width, 2) + Math.pow(centerBoxSize.height, 2) + Math.pow(centerBoxSize.depth, 2), 0.5) / 2,
1970
+ });
1971
+ return result;
1972
+ }
1973
+ /**
1974
+ * 创建视图辅助组件 Mesh 数组
1975
+ * @internal
1976
+ * @param options
1977
+ * @param boundingMap - 包围盒 Map
1978
+ * @returns Mesh 数组和对应的 Transform 组成的 Map
1979
+ */
1980
+ function createViewHelperMesh(engine, options, boundingMap, texture) {
1981
+ var e_3, _a;
1982
+ var result = new Map();
1983
+ var scale = options.size.scale || 1;
1984
+ var axisSize = {
1985
+ width: 0.8 * scale,
1986
+ height: 0.02 * scale,
1987
+ depth: 0.02 * scale,
1988
+ };
1989
+ var axisMesh = createAxisMesh(engine, axisSize, true);
1990
+ try {
1991
+ for (var axisMesh_3 = __values(axisMesh), axisMesh_3_1 = axisMesh_3.next(); !axisMesh_3_1.done; axisMesh_3_1 = axisMesh_3.next()) {
1992
+ var _b = __read(axisMesh_3_1.value, 2), mesh = _b[0], transform = _b[1];
1993
+ result.set(mesh, transform);
1994
+ }
1995
+ }
1996
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
1997
+ finally {
1998
+ try {
1999
+ if (axisMesh_3_1 && !axisMesh_3_1.done && (_a = axisMesh_3.return)) _a.call(axisMesh_3);
2000
+ }
2001
+ finally { if (e_3) throw e_3.error; }
2002
+ }
2003
+ var planeSize = {
2004
+ width: 0.14 * scale,
2005
+ height: 0.14 * scale,
2006
+ };
2007
+ var length = (axisSize.width + planeSize.width) / 2;
2008
+ var depthTest = true;
2009
+ var posXSphere = createSpriteMesh(engine, { size: planeSize, renderMode: renderMode, depthTest: depthTest }, texture.get('posX'));
2010
+ var posYSphere = createSpriteMesh(engine, { size: planeSize, renderMode: renderMode, depthTest: depthTest }, texture.get('posY'));
2011
+ var posZSphere = createSpriteMesh(engine, { size: planeSize, renderMode: renderMode, depthTest: depthTest }, texture.get('posZ'));
2012
+ var posXSphereTransform = new Transform({
2013
+ valid: true,
2014
+ });
2015
+ var posYSphereTransform = new Transform({
2016
+ valid: true,
2017
+ });
2018
+ var posZSphereTransform = new Transform({
2019
+ valid: true,
2020
+ });
2021
+ posXSphereTransform.translate(length, 0, 0);
2022
+ posYSphereTransform.translate(0, length, 0);
2023
+ posZSphereTransform.translate(0, 0, length);
2024
+ var negXSphere = createSpriteMesh(engine, { size: planeSize, renderMode: renderMode, depthTest: depthTest }, texture.get('negX'));
2025
+ var negYSphere = createSpriteMesh(engine, { size: planeSize, renderMode: renderMode, depthTest: depthTest }, texture.get('negY'));
2026
+ var negZSphere = createSpriteMesh(engine, { size: planeSize, renderMode: renderMode, depthTest: depthTest }, texture.get('negZ'));
2027
+ var negXSphereTransform = new Transform({
2028
+ valid: true,
2029
+ });
2030
+ var negYSphereTransform = new Transform({
2031
+ valid: true,
2032
+ });
2033
+ var negZSphereTransform = new Transform({
2034
+ valid: true,
2035
+ });
2036
+ negXSphereTransform.translate(-length, 0, 0);
2037
+ negYSphereTransform.translate(0, -length, 0);
2038
+ negZSphereTransform.translate(0, 0, -length);
2039
+ result.set(posXSphere, posXSphereTransform);
2040
+ result.set(posYSphere, posYSphereTransform);
2041
+ result.set(posZSphere, posZSphereTransform);
2042
+ result.set(negXSphere, negXSphereTransform);
2043
+ result.set(negYSphere, negYSphereTransform);
2044
+ result.set(negZSphere, negZSphereTransform);
2045
+ var radius = (planeSize.height / 2) * 1.2;
2046
+ boundingMap.set('posX', {
2047
+ type: BoundingType.sphere,
2048
+ center: posXSphereTransform.position,
2049
+ radius: radius,
2050
+ });
2051
+ boundingMap.set('posY', {
2052
+ type: BoundingType.sphere,
2053
+ center: posYSphereTransform.position,
2054
+ radius: radius,
2055
+ });
2056
+ boundingMap.set('posZ', {
2057
+ type: BoundingType.sphere,
2058
+ center: posZSphereTransform.position,
2059
+ radius: radius,
2060
+ });
2061
+ boundingMap.set('negX', {
2062
+ type: BoundingType.sphere,
2063
+ center: negXSphereTransform.position,
2064
+ radius: radius,
2065
+ });
2066
+ boundingMap.set('negY', {
2067
+ type: BoundingType.sphere,
2068
+ center: negYSphereTransform.position,
2069
+ radius: radius,
2070
+ });
2071
+ boundingMap.set('negZ', {
2072
+ type: BoundingType.sphere,
2073
+ center: negZSphereTransform.position,
2074
+ radius: radius,
2075
+ });
2076
+ return result;
2077
+ }
2078
+ /**
2079
+ * 创建坐标轴 Mesh 数组
2080
+ * @internal
2081
+ * @param axisSize - 坐标轴尺寸
2082
+ * @param isCentered - 是否居中,默认 false
2083
+ * @returns Mesh 数组和对应的 Transform 组成的 Map
2084
+ */
2085
+ function createAxisMesh(engine, axisSize, isCentered, name) {
2086
+ if (isCentered === void 0) { isCentered = false; }
2087
+ var result = new Map();
2088
+ var xAxis = createBasicMesh(engine, GizmoSubType.box, {
2089
+ size: axisSize, color: color.xAxisColor,
2090
+ renderMode: renderMode,
2091
+ depthTest: true,
2092
+ name: name,
2093
+ });
2094
+ var yAxis = createBasicMesh(engine, GizmoSubType.box, {
2095
+ size: axisSize, color: color.yAxisColor,
2096
+ renderMode: renderMode,
2097
+ depthTest: true,
2098
+ name: name,
2099
+ });
2100
+ var zAxis = createBasicMesh(engine, GizmoSubType.box, {
2101
+ size: axisSize, color: color.zAxisColor,
2102
+ renderMode: renderMode,
2103
+ depthTest: true,
2104
+ name: name,
2105
+ });
2106
+ var xAxisTransform = new Transform({
2107
+ valid: true,
2108
+ });
2109
+ var yAxisTransform = new Transform({
2110
+ valid: true,
2111
+ });
2112
+ var zAxisTransform = new Transform({
2113
+ valid: true,
2114
+ });
2115
+ yAxisTransform.setRotation(0, 0, 90);
2116
+ zAxisTransform.setRotation(0, -90, 0);
2117
+ if (!isCentered) {
2118
+ xAxisTransform.translate(axisSize.width / 2, 0, 0);
2119
+ yAxisTransform.translate(0, axisSize.width / 2, 0);
2120
+ zAxisTransform.translate(0, 0, axisSize.width / 2);
2121
+ }
2122
+ result.set(xAxis, xAxisTransform);
2123
+ result.set(yAxis, yAxisTransform);
2124
+ result.set(zAxis, zAxisTransform);
2125
+ return result;
2126
+ }
2127
+ /**
2128
+ * 创建基础几何体 Mesh
2129
+ * @internal
2130
+ * @param subType - gizmoSubType 类型
2131
+ * @param options - 几何体参数
2132
+ * @returns 几何体 Mesh
2133
+ */
2134
+ function createBasicMesh(engine, subType, options, materialType) {
2135
+ if (materialType === void 0) { materialType = 'default'; }
2136
+ var size = options.size, color = options.color, alpha = options.alpha, renderMode = options.renderMode, depthTest = options.depthTest, name = options.name;
2137
+ var geometryType;
2138
+ switch (subType) {
2139
+ case GizmoSubType.sphere:
2140
+ geometryType = GeometryType.Sphere;
2141
+ break;
2142
+ case GizmoSubType.cylinder:
2143
+ geometryType = GeometryType.Cylinder;
2144
+ break;
2145
+ case GizmoSubType.cone:
2146
+ geometryType = GeometryType.Cone;
2147
+ break;
2148
+ case GizmoSubType.torus:
2149
+ geometryType = GeometryType.Torus;
2150
+ break;
2151
+ case GizmoSubType.sprite:
2152
+ geometryType = GeometryType.Sprite;
2153
+ break;
2154
+ case GizmoSubType.plane:
2155
+ geometryType = GeometryType.Plane;
2156
+ break;
2157
+ case GizmoSubType.frustum:
2158
+ geometryType = GeometryType.Frustum;
2159
+ break;
2160
+ case GizmoSubType.directionLight:
2161
+ geometryType = GeometryType.DirectionLight;
2162
+ break;
2163
+ case GizmoSubType.spotLight:
2164
+ geometryType = GeometryType.SpotLight;
2165
+ break;
2166
+ case GizmoSubType.pointLight:
2167
+ geometryType = GeometryType.PointLight;
2168
+ break;
2169
+ case GizmoSubType.floorGrid:
2170
+ geometryType = GeometryType.FloorGrid;
2171
+ break;
2172
+ default:
2173
+ geometryType = GeometryType.Box;
2174
+ break;
2175
+ }
2176
+ var geometry = createGeometry(engine, geometryType, size, renderMode);
2177
+ var material;
2178
+ switch (materialType) {
2179
+ case 'blend':
2180
+ material = createBlendMaterial(engine, color, depthTest, alpha);
2181
+ break;
2182
+ case 'hideBack':
2183
+ material = createHideBackMaterial(engine, color, depthTest);
2184
+ break;
2185
+ default:
2186
+ material = createMaterial(engine, color, depthTest);
2187
+ break;
2188
+ }
2189
+ return Mesh.create(engine, {
2190
+ name: name ? name : geometryType.toString(),
2191
+ geometry: geometry,
2192
+ material: material,
2193
+ priority: 3000,
2194
+ });
2195
+ }
2196
+ /**
2197
+ * @internal
2198
+ * @param options
2199
+ * @param texture
2200
+ * @param boundingMap
2201
+ * @returns
2202
+ */
2203
+ function createSpriteMesh(engine, options, texture, boundingMap) {
2204
+ var geometry = createGeometry(engine, GeometryType.Sprite, options.size, renderMode);
2205
+ var spriteColor;
2206
+ if (texture) {
2207
+ spriteColor = texture;
2208
+ }
2209
+ else {
2210
+ spriteColor = options.color;
2211
+ }
2212
+ var material = createSpriteMaterial(engine, spriteColor, options.depthTest);
2213
+ if (boundingMap) {
2214
+ boundingMap.set('sprite', {
2215
+ type: BoundingType.sphere,
2216
+ radius: Math.pow(Math.pow(options.size.width, 2) + Math.pow(options.size.height, 2), 0.5) / 2,
2217
+ });
2218
+ }
2219
+ return Mesh.create(engine, {
2220
+ name: options.name || 'sprite',
2221
+ geometry: geometry,
2222
+ material: material,
2223
+ priority: 3000,
2224
+ });
2225
+ }
2226
+ /**
2227
+ * 创建材质
2228
+ * @internal
2229
+ * @param color - 颜色
2230
+ * @param depthTest
2231
+ * @returns 纯色材质,无光照,无透明
2232
+ */
2233
+ function createMaterial(engine, color, depthTest) {
2234
+ var myColor = color ? color : [255, 255, 255];
2235
+ var myDepthTest = depthTest ? depthTest : false;
2236
+ var material = Material.create(engine, {
2237
+ uniformValues: {
2238
+ u_color: new Float32Array(myColor),
2239
+ u_model: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
2240
+ },
2241
+ uniformSemantics: {
2242
+ u_viewinverse: 'VIEWINVERSE',
2243
+ u_v: 'VIEW',
2244
+ u_p: 'PROJECTION',
2245
+ u_et: 'EDITOR_TRANSFORM',
2246
+ },
2247
+ shader: {
2248
+ fragment: "\n precision mediump float;\n\n uniform vec3 u_color;\n\n void main(){\n gl_FragColor = vec4(u_color,1.0);\n }",
2249
+ vertex: "\n precision highp float;\n\n attribute vec3 a_Position;\n\n uniform mat4 u_model;\n uniform mat4 effects_MatrixV;\n uniform mat4 _MatrixP;\n uniform vec4 uEditorTransform;\n\n void main(){\n gl_Position = _MatrixP * effects_MatrixV * u_model * vec4(a_Position,1.0);\n gl_Position = vec4(gl_Position.xy * uEditorTransform.xy + uEditorTransform.zw * gl_Position.w,gl_Position.zw);\n }",
2250
+ shared: true,
2251
+ },
2252
+ });
2253
+ material.setVector3('u_color', myColor);
2254
+ material.setMatrix('u_model', [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
2255
+ material.depthTest = myDepthTest;
2256
+ material.stencilTest = false;
2257
+ material.blending = false;
2258
+ material.depthMask = true;
2259
+ return material;
2260
+ }
2261
+ /**
2262
+ *
2263
+ * @internal
2264
+ * @param color
2265
+ * @param depthTest
2266
+ * @returns
2267
+ */
2268
+ function createHideBackMaterial(engine, color, depthTest) {
2269
+ var myColor = color ? color : [255, 255, 255];
2270
+ var myDepthTest = depthTest ? depthTest : false;
2271
+ var material = Material.create(engine, {
2272
+ uniformValues: {
2273
+ u_color: new Float32Array(myColor),
2274
+ u_model: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
2275
+ u_cameraPos: new Float32Array([0, 0, 0]),
2276
+ u_center: new Float32Array([0, 0, 0]),
2277
+ },
2278
+ uniformSemantics: {
2279
+ u_viewinverse: 'VIEWINVERSE',
2280
+ u_v: 'VIEW',
2281
+ u_p: 'PROJECTION',
2282
+ u_et: 'EDITOR_TRANSFORM',
2283
+ },
2284
+ shader: {
2285
+ fragment: "\n precision mediump float;\n\n uniform vec3 u_color;\n\n varying float flag;\n\n void main(){\n if(flag > 0.0) {\n discard;\n }\n\n gl_FragColor = vec4(u_color,1.0);\n }",
2286
+ vertex: "\n precision highp float;\n\n attribute vec3 a_Position;\n\n uniform mat4 u_model;\n uniform mat4 effects_MatrixV;\n uniform mat4 _MatrixP;\n uniform vec4 uEditorTransform;\n\n uniform vec3 u_cameraPos;\n uniform vec3 u_center;\n\n varying float flag;\n void main(){\n float distance = length(u_cameraPos - u_center);\n vec3 worldPosition = (u_model * vec4(a_Position,1.0)).xyz;\n flag = length(u_cameraPos - worldPosition) - distance;\n gl_Position = _MatrixP * effects_MatrixV * u_model * vec4(a_Position,1.0);\n gl_Position = vec4(gl_Position.xy * uEditorTransform.xy + uEditorTransform.zw * gl_Position.w,gl_Position.zw);\n }",
2287
+ shared: true,
2288
+ },
2289
+ });
2290
+ material.setVector3('u_color', myColor);
2291
+ material.setMatrix('u_model', [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
2292
+ material.setVector3('u_cameraPos', [0, 0, 0]);
2293
+ material.setVector3('u_center', [0, 0, 0]);
2294
+ material.depthTest = myDepthTest;
2295
+ material.stencilTest = false;
2296
+ material.blending = false;
2297
+ material.depthMask = true;
2298
+ return material;
2299
+ }
2300
+ /**
2301
+ *
2302
+ * @internal
2303
+ * @param color
2304
+ * @param depthTest
2305
+ * @param alpha
2306
+ * @returns
2307
+ */
2308
+ function createBlendMaterial(engine, color, depthTest, alpha) {
2309
+ var myColor = color ? color : [255, 255, 255];
2310
+ var myDepthTest = depthTest ? depthTest : false;
2311
+ var myAlpha = alpha ? alpha : 1;
2312
+ var material = Material.create(engine, {
2313
+ uniformValues: {
2314
+ u_color: new Float32Array(myColor),
2315
+ u_alpha: new Float32Array([myAlpha, 0]),
2316
+ u_model: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
2317
+ },
2318
+ uniformSemantics: {
2319
+ u_viewinverse: 'VIEWINVERSE',
2320
+ u_v: 'VIEW',
2321
+ u_p: 'PROJECTION',
2322
+ u_et: 'EDITOR_TRANSFORM',
2323
+ },
2324
+ shader: {
2325
+ shared: true,
2326
+ fragment: "\n precision mediump float;\n\n uniform vec3 u_color;\n uniform vec2 u_alpha;\n\n void main(){\n gl_FragColor = vec4(u_color,u_alpha);\n }",
2327
+ vertex: "\n precision highp float;\n\n attribute vec3 a_Position;\n\n uniform mat4 u_model;\n uniform mat4 effects_MatrixV;\n uniform mat4 _MatrixP;\n uniform vec4 uEditorTransform;\n void main(){\n gl_Position = _MatrixP * effects_MatrixV * u_model * vec4(a_Position,1.0);\n gl_Position = vec4(gl_Position.xy * uEditorTransform.xy + uEditorTransform.zw * gl_Position.w,gl_Position.zw);\n }",
2328
+ },
2329
+ });
2330
+ material.setVector3('u_color', myColor);
2331
+ material.setVector2('u_alpha', [myAlpha, 0]);
2332
+ material.setMatrix('u_model', [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
2333
+ material.depthTest = myDepthTest;
2334
+ material.stencilTest = false;
2335
+ material.blending = true;
2336
+ material.blendEquation = [glContext.FUNC_ADD, glContext.FUNC_ADD];
2337
+ material.blendFunction = [glContext.SRC_ALPHA, glContext.ONE_MINUS_SRC_ALPHA, glContext.SRC_ALPHA, glContext.ONE_MINUS_SRC_ALPHA];
2338
+ material.depthMask = true;
2339
+ return material;
2340
+ }
2341
+ function createSpriteMaterial(engine, data, depthTest) {
2342
+ var myDepthTest = depthTest ? depthTest : false;
2343
+ var uniformValues = {
2344
+ u_model: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
2345
+ u_alpha: new Float32Array([1, 0]),
2346
+ };
2347
+ var material = Material.create(engine, {
2348
+ uniformValues: uniformValues,
2349
+ uniformSemantics: {
2350
+ u_viewinverse: 'VIEWINVERSE',
2351
+ u_v: 'VIEW',
2352
+ u_p: 'PROJECTION',
2353
+ u_et: 'EDITOR_TRANSFORM',
2354
+ },
2355
+ shader: {
2356
+ shared: true,
2357
+ fragment: "\n precision highp float;\n\n uniform vec2 u_alpha;\n uniform vec3 u_color;\n uniform sampler2D u_iconTex;\n\n varying vec2 v_uv;\n\n void main(){\n vec4 color = texture2D(u_iconTex, vec2(v_uv.x, 1.0 - v_uv.y));\n if(color.a < 0.001)\n {\n discard;\n }\n gl_FragColor = vec4(color.xyz, color.w * u_alpha.x);\n }",
2358
+ vertex: "\n precision highp float;\n\n attribute vec3 a_Position;\n attribute vec2 a_UV1;\n\n uniform mat4 u_model;\n uniform mat4 effects_MatrixV;\n uniform mat4 _MatrixP;\n uniform mat4 effects_MatrixInvV;\n uniform vec4 uEditorTransform;\n varying vec2 v_uv;\n\n void main(){\n v_uv = a_UV1;\n vec4 pos = u_model * vec4(0., 0., 0., 1.0);\n // vec4 pos = u_model * vec4(a_Position,1.0);\n\n pos.xyz += effects_MatrixInvV[0].xyz * a_Position.x + effects_MatrixInvV[1].xyz * a_Position.y;\n gl_Position = _MatrixP * effects_MatrixV * pos;\n gl_Position = vec4(gl_Position.xy * uEditorTransform.xy + uEditorTransform.zw * gl_Position.w,gl_Position.zw);\n }",
2359
+ },
2360
+ });
2361
+ material.setMatrix('u_model', [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
2362
+ material.setVector2('u_alpha', [1, 0]);
2363
+ if (data instanceof Texture) {
2364
+ material.setTexture('u_iconTex', data);
2365
+ // uniformValues.u_iconTex = data;
2366
+ }
2367
+ else {
2368
+ var color_1;
2369
+ if (data === undefined) {
2370
+ color_1 = [255, 255, 255];
2371
+ }
2372
+ else {
2373
+ color_1 = data;
2374
+ }
2375
+ material.setVector3('u_color', color_1);
2376
+ // uniformValues.u_color = new Float32Array(color);
2377
+ }
2378
+ material.depthTest = myDepthTest;
2379
+ material.stencilTest = false;
2380
+ material.blending = true;
2381
+ material.blendEquation = [glContext.FUNC_ADD, glContext.FUNC_ADD];
2382
+ material.blendFunction = [glContext.SRC_ALPHA, glContext.ONE_MINUS_SRC_ALPHA, glContext.SRC_ALPHA, glContext.ONE_MINUS_SRC_ALPHA];
2383
+ return material;
2384
+ }
2385
+ /**
2386
+ * 创建坐标轴包围盒
2387
+ * @internal
2388
+ * @param size 包围盒尺寸
2389
+ * @param boundingMap 包围盒 Map
2390
+ */
2391
+ function createAxisBounding(size, boundingMap) {
2392
+ boundingMap.set('xAxis', {
2393
+ type: BoundingType.line,
2394
+ points: [[0, 0, 0], [size.length, 0, 0]],
2395
+ width: size.width,
2396
+ });
2397
+ boundingMap.set('yAxis', {
2398
+ type: BoundingType.line,
2399
+ points: [[0, 0, 0], [0, size.length, 0]],
2400
+ width: size.width,
2401
+ });
2402
+ boundingMap.set('zAxis', {
2403
+ type: BoundingType.line,
2404
+ points: [[0, 0, 0], [0, 0, size.length]],
2405
+ width: size.width,
2406
+ });
2407
+ }
2408
+
2409
+ /**
2410
+ * 线条包围盒射线检测算法
2411
+ * @param out - 射线与包围盒交点位置
2412
+ * @param pointInCanvas - 归一化的画布交互点坐标
2413
+ * @param points - 线条包围盒两端点位置
2414
+ * @param radius - 线条包围盒辐射半径
2415
+ * @param camera - 相机对象
2416
+ * @returns 射线与包围盒交点位置 | null
2417
+ */
2418
+ function intersectRayLine(out, pointInCanvas, points, radius, worldMat4, camera) {
2419
+ // 构造一个辐射半径边缘的点 radiusPoint
2420
+ var radiusPoint = [0, 0, 0];
2421
+ var up = [
2422
+ worldMat4[1],
2423
+ worldMat4[5],
2424
+ worldMat4[9],
2425
+ ];
2426
+ vecMulScalar(radiusPoint, vecNormalize(up), radius);
2427
+ vecAdd(radiusPoint, points[0], radiusPoint);
2428
+ // 计算 start、end、radius 在屏幕空间上的投影
2429
+ var mvpMat4 = camera.getModelViewProjection([], worldMat4);
2430
+ var screenStart = [0, 0, 0];
2431
+ var screenEnd = [0, 0, 0];
2432
+ var screenRadiusPoint = [0, 0, 0];
2433
+ vec3MulMat4(screenStart, points[0], mvpMat4);
2434
+ vec3MulMat4(screenEnd, points[1], mvpMat4);
2435
+ vec3MulMat4(screenRadiusPoint, radiusPoint, mvpMat4);
2436
+ var screenRadiusVector = [0, 0, 0];
2437
+ vecSub(screenRadiusVector, screenRadiusPoint, screenStart);
2438
+ var screenRadius = Math.hypot.apply(Math, __spreadArray([], __read(screenRadiusVector), false));
2439
+ // 计算屏幕交互点与线条的距离
2440
+ var _a = distanceOfPointAndLine(pointInCanvas, [vec3ToVec2(screenStart), vec3ToVec2(screenEnd)]), distance = _a.distance, isInLine = _a.isInLine;
2441
+ if (distance <= screenRadius && isInLine) { // 距离小于阈值且交互点在线条上的投影位于线段内
2442
+ // 计算交互点在线条上的投影并转换为世界坐标
2443
+ var screenPosition = projectionOfPointAndLine(pointInCanvas, [screenStart, screenEnd]);
2444
+ var inverseViewProjection = camera.getInverseViewProjectionMatrix();
2445
+ var worldPosition = [0, 0, 0];
2446
+ vec3MulMat4(worldPosition, screenPosition, inverseViewProjection);
2447
+ return worldPosition;
2448
+ }
2449
+ return null;
2450
+ }
2451
+
2452
+ /**
2453
+ * 下载图片
2454
+ * @param imageUrl - 图片url
2455
+ * @returns 图片对象
2456
+ */
2457
+ function createImage(imageUrl) {
2458
+ return __awaiter(this, void 0, void 0, function () {
2459
+ var image;
2460
+ return __generator(this, function (_a) {
2461
+ image = new Image();
2462
+ image.src = imageUrl;
2463
+ return [2 /*return*/, new Promise(function (resolve, reject) {
2464
+ image.onload = function () {
2465
+ resolve(image);
2466
+ };
2467
+ image.onerror = reject;
2468
+ })];
2469
+ });
2470
+ });
2471
+ }
2472
+ /**
2473
+ * 创建 Texture 对象
2474
+ * @param engine - engine 对象
2475
+ * @param image - 图片对象
2476
+ * @returns 纹理
2477
+ */
2478
+ function createTexture(engine, image, hookDestroy) {
2479
+ var texture = Texture.create(engine, { image: image });
2480
+ if (hookDestroy) {
2481
+ texture.dispose = noop;
2482
+ }
2483
+ return texture;
2484
+ }
2485
+ /**
2486
+ * 移动到距离目标点指定距离的位置
2487
+ * @param targetPos - 目标点
2488
+ * @param currentPos - 当前点
2489
+ * @returns 指定点
2490
+ */
2491
+ function moveToPointWidthFixDistance(targetPos, currentPos) {
2492
+ var vecCameraItem = [0, 0, 0];
2493
+ vecSub(vecCameraItem, currentPos, targetPos);
2494
+ var normalVecCameraItem = vecNormalize(vecCameraItem);
2495
+ var newPos = [0, 0, 0];
2496
+ var scalerVecCameraItem = [0, 0, 0];
2497
+ vecMulScalar(scalerVecCameraItem, normalVecCameraItem, 20);
2498
+ var vecScalerItem = [0, 0, 0];
2499
+ var vecItemScaler = [0, 0, 0];
2500
+ vecSub(vecScalerItem, vecCameraItem, scalerVecCameraItem);
2501
+ vecMulScalar(vecItemScaler, vecScalerItem, -1);
2502
+ vecAdd(newPos, currentPos, vecItemScaler);
2503
+ return newPos;
2504
+ }
2505
+
2506
+ var constants = glContext;
2507
+ /**
2508
+ * 包围盒类型
2509
+ */
2510
+ var BoundingType;
2511
+ (function (BoundingType) {
2512
+ BoundingType[BoundingType["box"] = 0] = "box";
2513
+ BoundingType[BoundingType["sphere"] = 1] = "sphere";
2514
+ BoundingType[BoundingType["triangle"] = 2] = "triangle";
2515
+ BoundingType[BoundingType["line"] = 3] = "line";
2516
+ })(BoundingType || (BoundingType = {}));
2517
+ /**
2518
+ *
2519
+ */
2520
+ var GizmoVFXItem = /** @class */ (function (_super) {
2521
+ __extends(GizmoVFXItem, _super);
2522
+ function GizmoVFXItem() {
2523
+ var _this = _super !== null && _super.apply(this, arguments) || this;
2524
+ _this.boundingMap = new Map();
2525
+ _this.mat = [];
2526
+ return _this;
2527
+ }
2528
+ Object.defineProperty(GizmoVFXItem.prototype, "type", {
2529
+ get: function () {
2530
+ return GizmoVFXItemType;
2531
+ },
2532
+ set: function (t) {
2533
+ },
2534
+ enumerable: false,
2535
+ configurable: true
2536
+ });
2537
+ Object.defineProperty(GizmoVFXItem.prototype, "content", {
2538
+ get: function () {
2539
+ return this._content;
2540
+ },
2541
+ set: function (content) {
2542
+ },
2543
+ enumerable: false,
2544
+ configurable: true
2545
+ });
2546
+ GizmoVFXItem.prototype.onConstructed = function (options) {
2547
+ this.duration = 999;
2548
+ var opt = options.content.options;
2549
+ this.target = opt.target;
2550
+ this.subType = opt.subType;
2551
+ this.renderMode = opt.renderMode || this.getDefaultRenderMode();
2552
+ this.size = opt.size || this.getDefaultSize();
2553
+ this.depthTest = opt.depthTest;
2554
+ var c = (opt.color || [255, 255, 255]);
2555
+ this.color = [c[0] / 255, c[1] / 255, c[2] / 255];
2556
+ if (options.content) {
2557
+ this.transform = new Transform(options.content.transform);
2558
+ }
2559
+ };
2560
+ /**
2561
+ * 获取默认绘制模式
2562
+ * @returns 绘制模式常量
2563
+ */
2564
+ GizmoVFXItem.prototype.getDefaultRenderMode = function () {
2565
+ var result;
2566
+ switch (this.subType) {
2567
+ case GizmoSubType.particleEmitter:
2568
+ case GizmoSubType.modelWireframe:
2569
+ case GizmoSubType.frustum:
2570
+ case GizmoSubType.directionLight:
2571
+ case GizmoSubType.spotLight:
2572
+ case GizmoSubType.pointLight:
2573
+ case GizmoSubType.floorGrid:
2574
+ result = constants.LINES;
2575
+ break;
2576
+ default:
2577
+ result = constants.TRIANGLES;
2578
+ break;
2579
+ }
2580
+ return result;
2581
+ };
2582
+ /**
2583
+ * 获取默认尺寸
2584
+ * @returns 几何体尺寸
2585
+ */
2586
+ GizmoVFXItem.prototype.getDefaultSize = function () {
2587
+ var result = {};
2588
+ switch (this.subType) {
2589
+ case GizmoSubType.box:
2590
+ result = { width: 1, height: 1, depth: 1 };
2591
+ break;
2592
+ case GizmoSubType.sphere:
2593
+ result = { radius: 1 };
2594
+ break;
2595
+ case GizmoSubType.cylinder:
2596
+ result = { radius: 1, height: 1 };
2597
+ break;
2598
+ case GizmoSubType.cone:
2599
+ result = { radius: 1, height: 1 };
2600
+ break;
2601
+ default:
2602
+ result = {};
2603
+ break;
2604
+ }
2605
+ return result;
2606
+ };
2607
+ GizmoVFXItem.prototype.createModelContent = function (item, meshesToAdd) {
2608
+ var _this = this;
2609
+ var _a;
2610
+ var ms = item.content.mriMeshs;
2611
+ var engine = (_a = this.composition) === null || _a === void 0 ? void 0 : _a.renderer.engine;
2612
+ assertExist(engine);
2613
+ if (ms) {
2614
+ this.targetItem = item;
2615
+ ms.forEach(function (m) {
2616
+ var mesh = _this.wireframeMesh = createModeWireframe(engine, m, _this.color);
2617
+ meshesToAdd.push(mesh);
2618
+ });
2619
+ }
2620
+ };
2621
+ GizmoVFXItem.prototype.createParticleContent = function (item, meshesToAdd) {
2622
+ var _a, _b;
2623
+ var shape = (_a = item.particle) === null || _a === void 0 ? void 0 : _a.shape;
2624
+ var engine = (_b = this.composition) === null || _b === void 0 ? void 0 : _b.renderer.engine;
2625
+ assertExist(engine);
2626
+ this.targetItem = item;
2627
+ if (shape && shape.type) {
2628
+ var mesh = this._content = createMeshFromShape(engine, shape, { color: this.color });
2629
+ meshesToAdd.push(mesh);
2630
+ }
2631
+ // if (item.content?.particleMesh) {
2632
+ // const mesh = this.wireframeMesh = createParticleWireframe(engine, item.content.particleMesh.mesh, this.color);
2633
+ // meshesToAdd.push(mesh);
2634
+ // }
2635
+ if (item.type === spec.ItemType.sprite || item.type === spec.ItemType.filter) {
2636
+ var color = this.color.slice();
2637
+ var mesh = this.spriteMesh = item.createWireframeMesh(item.content, color);
2638
+ this.wireframeMesh = mesh.mesh;
2639
+ meshesToAdd.push(mesh.mesh);
2640
+ }
2641
+ };
2642
+ /**
2643
+ * 创建 BoundingBox 几何体模型
2644
+ * @param item - VFXItem
2645
+ * @param meshesToAdd - 插件缓存的 Mesh 数组
2646
+ */
2647
+ GizmoVFXItem.prototype.createBoundingBoxContent = function (item, meshesToAdd) {
2648
+ var _a;
2649
+ var shape = {
2650
+ shape: 'Box',
2651
+ width: this.size.width,
2652
+ height: this.size.height,
2653
+ depth: this.size.depth,
2654
+ center: this.size.center,
2655
+ };
2656
+ var engine = (_a = this.composition) === null || _a === void 0 ? void 0 : _a.renderer.engine;
2657
+ assertExist(engine);
2658
+ this.targetItem = item;
2659
+ if (shape) {
2660
+ var mesh = this._content = createMeshFromShape(engine, shape, { color: this.color, depthTest: this.depthTest });
2661
+ meshesToAdd.push(mesh);
2662
+ }
2663
+ };
2664
+ /**
2665
+ * 创建基础几何体模型
2666
+ * @param item - VFXItem
2667
+ * @param meshesToAdd - 插件缓存的 Mesh 数组
2668
+ * @param subType - GizmoSubType 类型
2669
+ */
2670
+ GizmoVFXItem.prototype.createBasicContent = function (item, meshesToAdd, subType, iconTextures) {
2671
+ var _a;
2672
+ var options = {
2673
+ size: this.size,
2674
+ color: this.color,
2675
+ renderMode: this.renderMode,
2676
+ depthTest: this.depthTest,
2677
+ };
2678
+ var engine = (_a = this.composition) === null || _a === void 0 ? void 0 : _a.renderer.engine;
2679
+ assertExist(engine);
2680
+ var mesh = this._content = createMeshFromSubType(engine, subType, this.boundingMap, iconTextures, options);
2681
+ this.targetItem = item;
2682
+ meshesToAdd.push(mesh);
2683
+ };
2684
+ /**
2685
+ * 创建组合几何体模型
2686
+ * @param item - VFXItem
2687
+ * @param meshesToAdd - 插件缓存的 Mesh 数组
2688
+ * @param subType - GizmoSubType 类型
2689
+ * @param iconTextures - XYZ 图标纹理(viewHelper 专用)
2690
+ */
2691
+ GizmoVFXItem.prototype.createCombinationContent = function (item, meshesToAdd, subType, iconTextures) {
2692
+ var e_1, _a;
2693
+ var _b;
2694
+ var options = {
2695
+ size: this.size,
2696
+ renderMode: this.renderMode,
2697
+ };
2698
+ var engine = (_b = this.composition) === null || _b === void 0 ? void 0 : _b.renderer.engine;
2699
+ assertExist(engine);
2700
+ this.contents = createMeshFromSubType(engine, subType, this.boundingMap, iconTextures, options);
2701
+ try {
2702
+ for (var _c = __values(this.contents.keys()), _d = _c.next(); !_d.done; _d = _c.next()) {
2703
+ var mesh = _d.value;
2704
+ meshesToAdd.push(mesh);
2705
+ }
2706
+ }
2707
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2708
+ finally {
2709
+ try {
2710
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
2711
+ }
2712
+ finally { if (e_1) throw e_1.error; }
2713
+ }
2714
+ this.targetItem = item;
2715
+ };
2716
+ GizmoVFXItem.prototype.onItemUpdate = function () {
2717
+ };
2718
+ GizmoVFXItem.prototype.updateRenderData = function () {
2719
+ var e_2, _a;
2720
+ if (this.subType === GizmoSubType.particleEmitter) { // 粒子发射器
2721
+ if (this.targetItem && this.content) {
2722
+ this.mat = this.targetItem.transform.getWorldMatrix();
2723
+ this.content.material.setMatrix('u_model', this.mat);
2724
+ }
2725
+ if (this.spriteMesh) {
2726
+ this.spriteMesh.updateItem(this.targetItem.content);
2727
+ }
2728
+ else if (this.wireframeMesh && this.targetItem) {
2729
+ var particle = this.targetItem.content;
2730
+ if (particle) {
2731
+ updateWireframeMesh(particle.particleMesh.mesh, this.wireframeMesh, WireframeGeometryType.quad);
2732
+ this.wireframeMesh.worldMatrix = particle.particleMesh.mesh.worldMatrix;
2733
+ }
2734
+ }
2735
+ }
2736
+ else if (this.subType === GizmoSubType.modelWireframe) { // 模型线框
2737
+ if (this.wireframeMesh && this.targetItem) {
2738
+ var meshes = this.targetItem.content.mriMeshs;
2739
+ var wireframeMesh_1 = this.wireframeMesh;
2740
+ if ((meshes === null || meshes === void 0 ? void 0 : meshes.length) > 0) {
2741
+ meshes.forEach(function (mesh) { return updateWireframeMesh(mesh, wireframeMesh_1, WireframeGeometryType.triangle); });
2742
+ }
2743
+ }
2744
+ }
2745
+ else { // 几何体模型
2746
+ if (this.targetItem) {
2747
+ if (this.contents) { // 组合几何体
2748
+ // const targetTransform = this.targetItem.transform.clone();
2749
+ var worldPos = [0, 0, 0];
2750
+ var worldQuat = [0, 0, 0, 0];
2751
+ var worldSca = [1, 1, 1];
2752
+ this.targetItem.transform.assignWorldTRS(worldPos, worldQuat);
2753
+ var targetTransform = new Transform({
2754
+ position: worldPos,
2755
+ quat: worldQuat,
2756
+ scale: worldSca,
2757
+ valid: true,
2758
+ });
2759
+ // 移动\旋转\缩放gizmo去除近大远小
2760
+ if (this.subType === GizmoSubType.rotation || this.subType === GizmoSubType.scale || this.subType === GizmoSubType.translation) {
2761
+ var camera = this.composition.camera;
2762
+ var cameraPos = camera.position || [0, 0, 0];
2763
+ var itemPos = targetTransform.position;
2764
+ var newPos = moveToPointWidthFixDistance(cameraPos, itemPos);
2765
+ targetTransform.setPosition.apply(targetTransform, __spreadArray([], __read(newPos), false));
2766
+ }
2767
+ this.mat = targetTransform.getWorldMatrix();
2768
+ var center = targetTransform.position;
2769
+ try {
2770
+ for (var _b = __values(this.contents), _c = _b.next(); !_c.done; _c = _b.next()) {
2771
+ var _d = __read(_c.value, 2), mesh = _d[0], transform = _d[1];
2772
+ var worldMat4 = [];
2773
+ transform.parentTransform = targetTransform;
2774
+ var position = [0, 0, 0];
2775
+ transform.assignWorldTRS(position);
2776
+ // 物体和中心点在屏幕空间上投影的距离
2777
+ var distanceToCneter = 100;
2778
+ var theta = 1;
2779
+ if (this.subType === GizmoSubType.viewHelper) {
2780
+ // 正交投影只需要计算物体在XY平面上的投影与中心点的距离
2781
+ if (mesh.name === 'sprite') {
2782
+ distanceToCneter = Math.pow(vecSquareDistance(vec3ToVec2(position), vec3ToVec2(center)), 0.5);
2783
+ theta = this.boundingMap.get('posX').radius;
2784
+ }
2785
+ // 将物体挂到相机的transform上
2786
+ var fov = 30; // 指定fov角度
2787
+ var screenWidth = this.composition.renderer.getWidth();
2788
+ var screenHeight = this.composition.renderer.getHeight();
2789
+ var distance = 16; // 指定物体与相机的距离
2790
+ var width = 2 * Math.tan(fov * Math.PI / 360) * distance;
2791
+ var aspect = screenWidth / screenHeight;
2792
+ var height = width / aspect;
2793
+ var cameraModelMat4 = this.composition.camera.getInverseViewMatrix();
2794
+ var padding = this.size.padding || 1; // 指定viewHelper与屏幕右上角的边距
2795
+ var localMat = [];
2796
+ localMat = transform.getWorldMatrix();
2797
+ var worldTransform = new Transform({
2798
+ valid: true,
2799
+ });
2800
+ worldTransform.cloneFromMatrix(localMat);
2801
+ worldTransform.setPosition((position[0] + width / 2) - padding, (position[1] + height / 2) - padding, position[2]);
2802
+ localMat = worldTransform.getWorldMatrix();
2803
+ worldMat4 = mat4MulMat4(cameraModelMat4, localMat);
2804
+ // 正交投影到屏幕上
2805
+ var proMat5 = computeOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, -distance, distance);
2806
+ mesh.material.setMatrix('_MatrixP', proMat5);
2807
+ }
2808
+ else {
2809
+ if (this.subType === GizmoSubType.rotation) {
2810
+ var cameraPos = this.composition.camera.position || [0, 0, 0];
2811
+ mesh.material.setVector3('u_cameraPos', cameraPos);
2812
+ mesh.material.setVector3('u_center', center);
2813
+ }
2814
+ worldMat4 = transform.getWorldMatrix();
2815
+ // TODO 计算物体和中心点在屏幕空间上投影的距离 distanceToCneter
2816
+ }
2817
+ mesh.material.setMatrix('u_model', worldMat4);
2818
+ // 使用distanceToCneter处理坐标轴旋转到中心点附近时的遮挡问题
2819
+ if (distanceToCneter < theta) {
2820
+ if (distanceToCneter < theta * 0.5) {
2821
+ mesh.material.setVector2('u_alpha', [0, 0]);
2822
+ }
2823
+ else {
2824
+ mesh.material.setVector2('u_alpha', [(2 / theta) * distanceToCneter - 1, 0]);
2825
+ }
2826
+ }
2827
+ }
2828
+ }
2829
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2830
+ finally {
2831
+ try {
2832
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2833
+ }
2834
+ finally { if (e_2) throw e_2.error; }
2835
+ }
2836
+ }
2837
+ if (this.content) { // 基础几何体
2838
+ var worldPos = [0, 0, 0];
2839
+ var worldQuat = [0, 0, 0, 0];
2840
+ var worldSca = [1, 1, 1];
2841
+ this.targetItem.transform.assignWorldTRS(worldPos, worldQuat);
2842
+ var targetTransform = new Transform({
2843
+ position: worldPos,
2844
+ quat: worldQuat,
2845
+ scale: worldSca,
2846
+ valid: true,
2847
+ });
2848
+ if (this.subType === GizmoSubType.light || this.subType === GizmoSubType.camera) {
2849
+ var camera = this.composition.camera;
2850
+ var cameraPos = camera.position || [0, 0, 0];
2851
+ var itemPos = targetTransform.position;
2852
+ var newPos = moveToPointWidthFixDistance(cameraPos, itemPos);
2853
+ targetTransform.setPosition.apply(targetTransform, __spreadArray([], __read(newPos), false));
2854
+ }
2855
+ this.mat = targetTransform.getWorldMatrix();
2856
+ this.content.material.setMatrix('u_model', targetTransform.getWorldMatrix());
2857
+ }
2858
+ }
2859
+ }
2860
+ };
2861
+ /**
2862
+ * 射线检测算法
2863
+ * @returns 包含射线检测算法回调方法的参数
2864
+ */
2865
+ GizmoVFXItem.prototype.getHitTestParams = function () {
2866
+ var boundingMap = this.boundingMap;
2867
+ if (boundingMap.size > 0) {
2868
+ var boundingKeys_1 = boundingMap.keys();
2869
+ var worldMat4_1 = [];
2870
+ worldMat4_1 = this.transform.getWorldMatrix();
2871
+ if (this.targetItem) {
2872
+ //const targetTransform = this.targetItem.transform.clone();
2873
+ var worldPos = [0, 0, 0];
2874
+ var worldQuat = [0, 0, 0, 0];
2875
+ var worldSca = [1, 1, 1];
2876
+ this.targetItem.transform.assignWorldTRS(worldPos, worldQuat);
2877
+ var targetTransform = new Transform({
2878
+ position: worldPos,
2879
+ quat: worldQuat,
2880
+ scale: worldSca,
2881
+ valid: true,
2882
+ });
2883
+ // 移动\旋转\缩放gizmo去除近大远小
2884
+ if (this.subType === GizmoSubType.rotation ||
2885
+ this.subType === GizmoSubType.scale ||
2886
+ this.subType === GizmoSubType.translation ||
2887
+ this.subType === GizmoSubType.camera ||
2888
+ this.subType === GizmoSubType.light) {
2889
+ var camera = this.composition.camera;
2890
+ var cameraPos = camera.position || [0, 0, 0];
2891
+ var itemPos = targetTransform.position;
2892
+ var newPos = moveToPointWidthFixDistance(cameraPos, itemPos);
2893
+ targetTransform.setPosition.apply(targetTransform, __spreadArray([], __read(newPos), false));
2894
+ worldMat4_1 = targetTransform.getWorldMatrix();
2895
+ }
2896
+ else {
2897
+ worldMat4_1 = targetTransform.getWorldMatrix();
2898
+ }
2899
+ }
2900
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
2901
+ var self_1 = this;
2902
+ return {
2903
+ type: HitTestType.custom,
2904
+ /**
2905
+ * 自定义射线检测算法
2906
+ * @param ray 射线参数
2907
+ * @param pointInCanvas 屏幕坐标
2908
+ * @returns
2909
+ */
2910
+ collect: function (ray, pointInCanvas) {
2911
+ var e_3, _a;
2912
+ var hitPositions = [];
2913
+ self_1.hitBounding = undefined;
2914
+ var _loop_1 = function (key) {
2915
+ var bounding = boundingMap.get(key);
2916
+ var center = [0, 0, 0];
2917
+ var worldCenter = [0, 0, 0];
2918
+ if ((bounding === null || bounding === void 0 ? void 0 : bounding.type) === BoundingType.box || (bounding === null || bounding === void 0 ? void 0 : bounding.type) === BoundingType.sphere) {
2919
+ center = (bounding === null || bounding === void 0 ? void 0 : bounding.center) ? bounding.center.slice() : [0, 0, 0];
2920
+ vec3MulMat4(worldCenter, center, worldMat4_1);
2921
+ }
2922
+ var position;
2923
+ switch (bounding === null || bounding === void 0 ? void 0 : bounding.type) {
2924
+ case BoundingType.box: // 立方体包围盒
2925
+ position = intersectRayBox([], ray.center, ray.direction, worldCenter, bounding === null || bounding === void 0 ? void 0 : bounding.size);
2926
+ break;
2927
+ case BoundingType.sphere: // 球体包围盒
2928
+ // viewHelper 使用了正交投影,使用屏幕投影点计算
2929
+ if (self_1.subType === GizmoSubType.viewHelper) {
2930
+ // 计算正交投影矩阵
2931
+ var viewMat4 = self_1.composition.camera.getViewMatrix();
2932
+ var fov = 30; // 指定fov角度
2933
+ var screenWidth = self_1.composition.renderer.getWidth();
2934
+ var screenHeight = self_1.composition.renderer.getHeight();
2935
+ var distance = 16; // 指定物体与相机的距离
2936
+ var width = 2 * Math.tan(fov * Math.PI / 360) * distance;
2937
+ var aspect = screenWidth / screenHeight;
2938
+ var height = width / aspect;
2939
+ var proMat4 = computeOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, -distance, distance);
2940
+ // 将包围盒挂到相机的 transform 上
2941
+ var cameraModelMat4 = self_1.composition.camera.getInverseViewMatrix();
2942
+ var localTransform = new Transform({
2943
+ valid: true,
2944
+ });
2945
+ var localMat4 = [];
2946
+ localTransform.cloneFromMatrix(worldMat4_1);
2947
+ var pos = localTransform.position;
2948
+ var padding = self_1.size.padding || 1; // 指定viewHelper与屏幕右上角的边距
2949
+ localTransform.setPosition((pos[0] + width / 2) - padding, (pos[1] + height / 2) - padding, pos[2]);
2950
+ localMat4 = localTransform.getWorldMatrix();
2951
+ var modelMat4 = mat4MulMat4(cameraModelMat4, localMat4);
2952
+ vec3MulMat4(worldCenter, center, modelMat4);
2953
+ // 包围球中心点正交投影到屏幕上
2954
+ var screenCenter = [0, 0, 0, 0];
2955
+ var vpMat4 = mat4MulMat4(proMat4, viewMat4);
2956
+ var mvpMat4 = mat4MulMat4(vpMat4, modelMat4);
2957
+ vec4MulMat4(screenCenter, __spreadArray(__spreadArray([], __read(center), false), [1.0], false), mvpMat4);
2958
+ var screenCenterX = screenCenter[0] / screenCenter[3];
2959
+ var screenCenterY = screenCenter[1] / screenCenter[3];
2960
+ // 包围球上的点正交投影到屏幕上
2961
+ var radius = bounding.radius;
2962
+ var point = [0, 0, 0];
2963
+ var up = [
2964
+ localMat4[1],
2965
+ localMat4[5],
2966
+ localMat4[9],
2967
+ ];
2968
+ vecMulScalar(point, vecNormalize(up), radius);
2969
+ vecAdd(point, center, point);
2970
+ var screenPoint = [0, 0, 0, 0];
2971
+ vec4MulMat4(screenPoint, __spreadArray(__spreadArray([], __read(point), false), [1.0], false), mvpMat4);
2972
+ var screenPointX = screenPoint[0] / screenPoint[3];
2973
+ var screenPointY = screenPoint[1] / screenPoint[3];
2974
+ // 计算正交投影到屏幕上的包围球的半径
2975
+ var vecRadius = [0, 0];
2976
+ vecSub(vecRadius, [screenCenterX, screenCenterY], [screenPointX, screenPointY]);
2977
+ var screenRadius = Math.hypot.apply(Math, __spreadArray([], __read(vecRadius), false));
2978
+ if (Math.pow(vecSquareDistance(pointInCanvas, [screenCenterX, screenCenterY]), 0.5) < screenRadius * 1.2) {
2979
+ position = worldCenter;
2980
+ }
2981
+ }
2982
+ else {
2983
+ position = intersectRaySphere([], ray.center, ray.direction, worldCenter, bounding === null || bounding === void 0 ? void 0 : bounding.radius);
2984
+ }
2985
+ break;
2986
+ case BoundingType.triangle: { // 三角数组包围盒
2987
+ var triangles = bounding.triangles, backfaceCulling = bounding.backfaceCulling;
2988
+ var tmpPositions = [];
2989
+ var tmpPosition = void 0;
2990
+ for (var j = 0; j < triangles.length; j++) {
2991
+ var triangle = triangles[j];
2992
+ var worldTriangle = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
2993
+ // 坐标转换为世界坐标
2994
+ for (var i = 0; i < 3; i++) {
2995
+ var worldPosition = [0, 0, 0];
2996
+ vec3MulMat4(worldPosition, triangle[i], worldMat4_1);
2997
+ worldTriangle[i] = worldPosition;
2998
+ }
2999
+ tmpPosition = intersectRayTriangle([], ray.center, ray.direction, worldTriangle, backfaceCulling);
3000
+ if (tmpPosition) {
3001
+ tmpPositions.push(tmpPosition);
3002
+ }
3003
+ }
3004
+ // 仅保存距离相机最近的点
3005
+ if (tmpPositions.length > 0) {
3006
+ var lastDistance_1;
3007
+ tmpPositions.forEach(function (item) {
3008
+ var distance = vecSquareDistance(ray.center, item);
3009
+ if (!lastDistance_1 || distance < lastDistance_1) {
3010
+ lastDistance_1 = distance;
3011
+ position = item;
3012
+ }
3013
+ });
3014
+ }
3015
+ break;
3016
+ }
3017
+ case BoundingType.line: { // 线条包围盒,将线条转换到屏幕空间,计算线条与屏幕交互点的距离,小于阈值判定为点中
3018
+ var points = bounding.points, width = bounding.width;
3019
+ position = intersectRayLine([], pointInCanvas, points, width / 2, worldMat4_1, self_1.composition.camera);
3020
+ break;
3021
+ }
3022
+ }
3023
+ if (position) {
3024
+ hitPositions.push(position);
3025
+ // 缓存距离相机最近的 BoundingKey
3026
+ if (self_1.hitBounding) {
3027
+ var distance = vecSquareDistance(ray.center, position);
3028
+ var lastDistance = vecSquareDistance(ray.center, self_1.hitBounding.position);
3029
+ if (distance < lastDistance) {
3030
+ self_1.hitBounding.key = key;
3031
+ self_1.hitBounding.position = position;
3032
+ }
3033
+ }
3034
+ else {
3035
+ self_1.hitBounding = {
3036
+ key: key,
3037
+ position: position,
3038
+ };
3039
+ }
3040
+ }
3041
+ };
3042
+ try {
3043
+ for (var boundingKeys_2 = __values(boundingKeys_1), boundingKeys_2_1 = boundingKeys_2.next(); !boundingKeys_2_1.done; boundingKeys_2_1 = boundingKeys_2.next()) {
3044
+ var key = boundingKeys_2_1.value;
3045
+ _loop_1(key);
3046
+ }
3047
+ }
3048
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
3049
+ finally {
3050
+ try {
3051
+ if (boundingKeys_2_1 && !boundingKeys_2_1.done && (_a = boundingKeys_2.return)) _a.call(boundingKeys_2);
3052
+ }
3053
+ finally { if (e_3) throw e_3.error; }
3054
+ }
3055
+ if (hitPositions.length === 0) {
3056
+ self_1.hitBounding = undefined;
3057
+ }
3058
+ return hitPositions;
3059
+ },
3060
+ behavior: spec.InteractBehavior.NOTIFY,
3061
+ };
3062
+ }
3063
+ };
3064
+ return GizmoVFXItem;
3065
+ }(VFXItem));
3066
+
3067
+ var editorRenderPassName = 'editor-gizmo';
3068
+ var frontRenderPassName = 'front-gizmo';
3069
+ var behindRenderPassName = 'behind-gizmo';
3070
+ var iconImages = new Map();
3071
+ var iconTextures = new Map();
3072
+ var EditorGizmoPlugin = /** @class */ (function (_super) {
3073
+ __extends(EditorGizmoPlugin, _super);
3074
+ function EditorGizmoPlugin() {
3075
+ var _this = _super !== null && _super.apply(this, arguments) || this;
3076
+ _this.meshToAdd = [];
3077
+ _this.meshToRemove = [];
3078
+ _this.order = 1001;
3079
+ return _this;
3080
+ }
3081
+ EditorGizmoPlugin.prepareResource = function (scene) {
3082
+ return __awaiter(this, void 0, void 0, function () {
3083
+ var axisIconMap_1, axisIconMap_1_1, _a, name_1, data, _b, _c, _d, e_1_1;
3084
+ var e_1, _e;
3085
+ return __generator(this, function (_f) {
3086
+ switch (_f.label) {
3087
+ case 0:
3088
+ if (!(iconImages.size !== axisIconMap.size)) return [3 /*break*/, 8];
3089
+ _f.label = 1;
3090
+ case 1:
3091
+ _f.trys.push([1, 6, 7, 8]);
3092
+ axisIconMap_1 = __values(axisIconMap), axisIconMap_1_1 = axisIconMap_1.next();
3093
+ _f.label = 2;
3094
+ case 2:
3095
+ if (!!axisIconMap_1_1.done) return [3 /*break*/, 5];
3096
+ _a = __read(axisIconMap_1_1.value, 2), name_1 = _a[0], data = _a[1];
3097
+ _c = (_b = iconImages).set;
3098
+ _d = [name_1];
3099
+ return [4 /*yield*/, createImage(data)];
3100
+ case 3:
3101
+ _c.apply(_b, _d.concat([_f.sent()]));
3102
+ _f.label = 4;
3103
+ case 4:
3104
+ axisIconMap_1_1 = axisIconMap_1.next();
3105
+ return [3 /*break*/, 2];
3106
+ case 5: return [3 /*break*/, 8];
3107
+ case 6:
3108
+ e_1_1 = _f.sent();
3109
+ e_1 = { error: e_1_1 };
3110
+ return [3 /*break*/, 8];
3111
+ case 7:
3112
+ try {
3113
+ if (axisIconMap_1_1 && !axisIconMap_1_1.done && (_e = axisIconMap_1.return)) _e.call(axisIconMap_1);
3114
+ }
3115
+ finally { if (e_1) throw e_1.error; }
3116
+ return [7 /*endfinally*/];
3117
+ case 8: return [2 /*return*/, true];
3118
+ }
3119
+ });
3120
+ });
3121
+ };
3122
+ EditorGizmoPlugin.onPlayerDestroy = function () {
3123
+ iconTextures.clear();
3124
+ };
3125
+ EditorGizmoPlugin.prototype.onCompositionConstructed = function (composition, scene) {
3126
+ var engine = composition.renderer.engine;
3127
+ iconImages.forEach(function (image, name) {
3128
+ iconTextures.set(name, createTexture(engine, image));
3129
+ });
3130
+ iconImages.clear();
3131
+ };
3132
+ EditorGizmoPlugin.prototype.onCompositionReset = function (composition) {
3133
+ var items = composition.items;
3134
+ var targetMap = {};
3135
+ for (var i = 0; i < items.length; i++) {
3136
+ var item = items[i];
3137
+ if (item instanceof GizmoVFXItem) {
3138
+ if (!targetMap[item.target]) {
3139
+ targetMap[item.target] = [];
3140
+ }
3141
+ targetMap[item.target].push(item);
3142
+ }
3143
+ }
3144
+ composition.loaderData.gizmoTarget = targetMap;
3145
+ composition.loaderData.gizmoItems = [];
3146
+ };
3147
+ EditorGizmoPlugin.prototype.onCompositionItemLifeBegin = function (composition, item) {
3148
+ var e_2, _a;
3149
+ if (item.type === '7') {
3150
+ return;
3151
+ }
3152
+ var gizmoVFXItemList = composition.loaderData.gizmoTarget[item.id];
3153
+ if (gizmoVFXItemList && gizmoVFXItemList.length > 0) {
3154
+ try {
3155
+ for (var gizmoVFXItemList_1 = __values(gizmoVFXItemList), gizmoVFXItemList_1_1 = gizmoVFXItemList_1.next(); !gizmoVFXItemList_1_1.done; gizmoVFXItemList_1_1 = gizmoVFXItemList_1.next()) {
3156
+ var gizmoVFXItem = gizmoVFXItemList_1_1.value;
3157
+ switch (gizmoVFXItem.subType) {
3158
+ case GizmoSubType.particleEmitter:
3159
+ gizmoVFXItem.createParticleContent(item, this.meshToAdd);
3160
+ break;
3161
+ case GizmoSubType.modelWireframe:
3162
+ gizmoVFXItem.createModelContent(item, this.meshToAdd);
3163
+ break;
3164
+ case GizmoSubType.box:
3165
+ case GizmoSubType.sphere:
3166
+ case GizmoSubType.cylinder:
3167
+ case GizmoSubType.cone:
3168
+ case GizmoSubType.torus:
3169
+ case GizmoSubType.sprite:
3170
+ case GizmoSubType.frustum:
3171
+ case GizmoSubType.directionLight:
3172
+ case GizmoSubType.pointLight:
3173
+ case GizmoSubType.spotLight:
3174
+ case GizmoSubType.floorGrid:
3175
+ gizmoVFXItem.createBasicContent(item, this.meshToAdd, gizmoVFXItem.subType);
3176
+ break;
3177
+ case GizmoSubType.camera:
3178
+ case GizmoSubType.light:
3179
+ gizmoVFXItem.createBasicContent(item, this.meshToAdd, gizmoVFXItem.subType, iconTextures);
3180
+ break;
3181
+ case GizmoSubType.rotation:
3182
+ case GizmoSubType.scale:
3183
+ case GizmoSubType.translation:
3184
+ gizmoVFXItem.createCombinationContent(item, this.meshToAdd, gizmoVFXItem.subType);
3185
+ break;
3186
+ case GizmoSubType.viewHelper:
3187
+ gizmoVFXItem.createCombinationContent(item, this.meshToAdd, gizmoVFXItem.subType, iconTextures);
3188
+ break;
3189
+ case GizmoSubType.boundingBox:
3190
+ gizmoVFXItem.createBoundingBoxContent(item, this.meshToAdd);
3191
+ break;
3192
+ default:
3193
+ break;
3194
+ }
3195
+ }
3196
+ }
3197
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
3198
+ finally {
3199
+ try {
3200
+ if (gizmoVFXItemList_1_1 && !gizmoVFXItemList_1_1.done && (_a = gizmoVFXItemList_1.return)) _a.call(gizmoVFXItemList_1);
3201
+ }
3202
+ finally { if (e_2) throw e_2.error; }
3203
+ }
3204
+ }
3205
+ if (item.type === GizmoVFXItemType) {
3206
+ composition.loaderData.gizmoItems.push(item);
3207
+ }
3208
+ };
3209
+ EditorGizmoPlugin.prototype.onCompositionItemRemoved = function (composition, item) {
3210
+ var _this = this;
3211
+ if (item.type === GizmoVFXItemType) {
3212
+ this.removeGizmoItem(composition, item);
3213
+ }
3214
+ else {
3215
+ var gizmoVFXItemList = composition.loaderData.gizmoTarget[item.id];
3216
+ if (gizmoVFXItemList && gizmoVFXItemList.length > 0) {
3217
+ gizmoVFXItemList.forEach(function (gizmoVFXItem) {
3218
+ _this.removeGizmoItem(composition, gizmoVFXItem);
3219
+ });
3220
+ }
3221
+ }
3222
+ };
3223
+ EditorGizmoPlugin.prototype.removeGizmoItem = function (composition, gizmoVFXItem) {
3224
+ var e_3, _a;
3225
+ if (gizmoVFXItem.content && !gizmoVFXItem.content.isDestroyed) {
3226
+ gizmoVFXItem.content.dispose();
3227
+ if (gizmoVFXItem.content.name === GeometryType.FloorGrid.toString() || gizmoVFXItem.content.name === 'Box') {
3228
+ this.getFrontRenderPass(composition.renderFrame).removeMesh(gizmoVFXItem.content);
3229
+ }
3230
+ else {
3231
+ this.getEditorRenderPass(composition.renderFrame).removeMesh(gizmoVFXItem.content);
3232
+ }
3233
+ }
3234
+ if (gizmoVFXItem.contents) {
3235
+ try {
3236
+ for (var _b = __values(gizmoVFXItem.contents), _c = _b.next(); !_c.done; _c = _b.next()) {
3237
+ var _d = __read(_c.value, 1), mesh = _d[0];
3238
+ if (!mesh.isDestroyed) {
3239
+ mesh.dispose();
3240
+ if (mesh.name === 'translation' || mesh.name === 'scale' || mesh.name === 'rotation') {
3241
+ this.getBehindRenderPass(composition.renderFrame).removeMesh(mesh);
3242
+ }
3243
+ else {
3244
+ this.getEditorRenderPass(composition.renderFrame).removeMesh(mesh);
3245
+ }
3246
+ }
3247
+ }
3248
+ }
3249
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
3250
+ finally {
3251
+ try {
3252
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3253
+ }
3254
+ finally { if (e_3) throw e_3.error; }
3255
+ }
3256
+ }
3257
+ var wireframeMesh = gizmoVFXItem.wireframeMesh;
3258
+ if (wireframeMesh && !wireframeMesh.isDestroyed) {
3259
+ destroyWireframeMesh(wireframeMesh);
3260
+ this.getEditorRenderPass(composition.renderFrame).removeMesh(wireframeMesh);
3261
+ }
3262
+ var arr = composition.loaderData.gizmoItems;
3263
+ var index = arr.indexOf(gizmoVFXItem);
3264
+ if (index > -1) {
3265
+ arr.splice(index, 1);
3266
+ }
3267
+ };
3268
+ EditorGizmoPlugin.prototype.prepareRenderFrame = function (composition, renderFrame) {
3269
+ var _this = this;
3270
+ this.meshToAdd.forEach(function (mesh) {
3271
+ if (mesh.name === GeometryType.FloorGrid.toString() || mesh.name === 'Box') {
3272
+ _this.getFrontRenderPass(renderFrame).addMesh(mesh);
3273
+ }
3274
+ else if (mesh.name === 'translation' || mesh.name === 'scale' || mesh.name === 'rotation') {
3275
+ _this.getBehindRenderPass(renderFrame).addMesh(mesh);
3276
+ }
3277
+ else {
3278
+ _this.getEditorRenderPass(renderFrame).addMesh(mesh);
3279
+ }
3280
+ });
3281
+ this.meshToRemove.forEach(function (mesh) {
3282
+ if (mesh.name === GeometryType.FloorGrid.toString() || mesh.name === 'Box') {
3283
+ _this.getFrontRenderPass(renderFrame).removeMesh(mesh);
3284
+ }
3285
+ else if (mesh.name === 'translation' || mesh.name === 'scale' || mesh.name === 'rotation') {
3286
+ _this.getBehindRenderPass(renderFrame).removeMesh(mesh);
3287
+ }
3288
+ else {
3289
+ _this.getEditorRenderPass(renderFrame).removeMesh(mesh);
3290
+ }
3291
+ });
3292
+ this.meshToAdd.length = this.meshToRemove.length = 0;
3293
+ composition.loaderData.gizmoItems.forEach(function (item) { return item.updateRenderData(); });
3294
+ return false;
3295
+ };
3296
+ EditorGizmoPlugin.prototype.getBehindRenderPass = function (pipeline) {
3297
+ var rp = pipeline.renderPasses.find(function (renderPass) { return renderPass.name === behindRenderPassName; });
3298
+ if (!rp) {
3299
+ rp = new RenderPass(pipeline.renderer, {
3300
+ name: behindRenderPassName,
3301
+ priority: RenderPassPriorityPostprocess + RenderPassPriorityPostprocess,
3302
+ clearAction: {
3303
+ depthAction: TextureLoadAction.clear,
3304
+ },
3305
+ });
3306
+ pipeline.addRenderPass(rp);
3307
+ }
3308
+ return rp;
3309
+ };
3310
+ EditorGizmoPlugin.prototype.getEditorRenderPass = function (pipeline) {
3311
+ var rp = pipeline.renderPasses.find(function (renderPass) { return renderPass.name === editorRenderPassName; });
3312
+ if (!rp) {
3313
+ rp = new RenderPass(pipeline.renderer, {
3314
+ name: editorRenderPassName,
3315
+ priority: RenderPassPriorityPostprocess + 2,
3316
+ });
3317
+ pipeline.addRenderPass(rp);
3318
+ }
3319
+ return rp;
3320
+ };
3321
+ EditorGizmoPlugin.prototype.getFrontRenderPass = function (pipeline) {
3322
+ var rp = pipeline.renderPasses.find(function (renderPass) { return renderPass.name === frontRenderPassName; });
3323
+ if (!rp) {
3324
+ rp = new RenderPass(pipeline.renderer, {
3325
+ name: frontRenderPassName,
3326
+ priority: RenderPassPriorityPrepare + 2,
3327
+ });
3328
+ pipeline.addRenderPass(rp);
3329
+ }
3330
+ return rp;
3331
+ };
3332
+ return EditorGizmoPlugin;
3333
+ }(AbstractPlugin));
3334
+
3335
+ var version = "0.0.1-alpha.0";
3336
+ console.info('[Galacean Effects Plugin Editor Gizmo] version: ' + version);
3337
+ registerPlugin('editor-gizmo', EditorGizmoPlugin, GizmoVFXItem);
3338
+
3339
+ export { DirectionLightData, GeometryType, GizmoSubType, GizmoVFXItem, createGeometry, version };
3340
+ //# sourceMappingURL=index.mjs.map