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