fl-web-component 2.0.19-beta.1 → 2.0.19
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/fl-web-component.common.1.js.map +1 -1
- package/dist/fl-web-component.common.2.js.map +1 -1
- package/dist/fl-web-component.common.js +868 -1050
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +3 -4
- package/packages/components/com-graphics/box.json +77 -0
- package/packages/components/com-graphics/index.vue +6 -75
- package/packages/utils/StreamLoader.js +107 -250
- package/packages/utils/StreamLoaderParser.worker.js +76 -184
- package/src/utils/flgltf-parser.js +9 -21
- package/src/utils/instance-parser.js +75 -75
- package/packages/components/com-graphics/mock.json +0 -115
|
@@ -88,11 +88,8 @@ function createStreamState(prefixIdKey) {
|
|
|
88
88
|
return {
|
|
89
89
|
prefixIdKey: prefixIdKey || '',
|
|
90
90
|
buffer: new Uint8Array(),
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
pendingPrimitiveGroups: [],
|
|
94
|
-
pendingMatchedPrimitiveIds: new Set(),
|
|
95
|
-
expectingMesh: true,
|
|
91
|
+
pendingPrimitives: new Map(),
|
|
92
|
+
expectingPrimitive: true,
|
|
96
93
|
isFullProps: true,
|
|
97
94
|
};
|
|
98
95
|
}
|
|
@@ -108,179 +105,101 @@ function parseStreamChunk(state, chunkView, flushing = false) {
|
|
|
108
105
|
const meshes = [];
|
|
109
106
|
const primitives = [];
|
|
110
107
|
|
|
111
|
-
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
const meshList = Array.isArray(state.pendingMesh) ? state.pendingMesh : [state.pendingMesh];
|
|
115
|
-
meshList.forEach(mesh => {
|
|
116
|
-
meshes.push(mesh);
|
|
117
|
-
primitives.push(state.pendingPrimitiveGroups);
|
|
118
|
-
});
|
|
108
|
+
while (state.buffer.length > 0) {
|
|
109
|
+
if (state.expectingPrimitive) {
|
|
110
|
+
if (state.buffer.length < 12) break;
|
|
119
111
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
try {
|
|
113
|
+
const dataView = new DataView(
|
|
114
|
+
state.buffer.buffer,
|
|
115
|
+
state.buffer.byteOffset,
|
|
116
|
+
state.buffer.byteLength
|
|
117
|
+
);
|
|
118
|
+
const primitiveResult = parsePrimitive(dataView, state.buffer, 0, state.isFullProps);
|
|
119
|
+
const primitiveData = primitiveResult.primitive;
|
|
120
|
+
|
|
121
|
+
_applyPrefixId(primitiveData, 'id', null, state.prefixIdKey);
|
|
122
|
+
_applyPrefixId(primitiveData, 'material', null, state.prefixIdKey);
|
|
123
|
+
|
|
124
|
+
if (state.isFullProps) {
|
|
125
|
+
const { position, normal, posindex, nolindex, indices } =
|
|
126
|
+
parsePrimitiveData(primitiveData);
|
|
127
|
+
const formatted = formatPrimitiveData({ position, normal, posindex, nolindex });
|
|
128
|
+
delete primitiveData.nolindex;
|
|
129
|
+
delete primitiveData.posindex;
|
|
130
|
+
primitiveData.position = formatted.position;
|
|
131
|
+
primitiveData.normal = formatted.normal;
|
|
132
|
+
primitiveData.indices = indices;
|
|
133
|
+
}
|
|
125
134
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (meshResult.status === 'invalid') {
|
|
135
|
+
state.pendingPrimitives.set(primitiveData.id, primitiveData);
|
|
136
|
+
state.expectingPrimitive = false;
|
|
137
|
+
state.buffer = state.buffer.slice(primitiveResult.offset);
|
|
138
|
+
} catch (e) {
|
|
131
139
|
break;
|
|
132
140
|
}
|
|
133
|
-
|
|
134
|
-
commitPendingMesh();
|
|
135
|
-
state.pendingMesh = meshResult.mesh;
|
|
136
|
-
state.pendingPrimitiveIds = new Set(collectMeshPrimitiveIds(meshResult.mesh));
|
|
137
|
-
state.pendingPrimitiveGroups = [];
|
|
138
|
-
state.pendingMatchedPrimitiveIds = new Set();
|
|
139
|
-
state.expectingMesh = false;
|
|
140
|
-
state.buffer = state.buffer.slice(meshResult.totalLen);
|
|
141
141
|
} else {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
state.
|
|
147
|
-
state.pendingPrimitiveGroups = [];
|
|
148
|
-
state.pendingMatchedPrimitiveIds = new Set();
|
|
149
|
-
state.expectingMesh = false;
|
|
150
|
-
state.buffer = state.buffer.slice(nextMeshResult.totalLen);
|
|
142
|
+
if (state.buffer.length < 4) break;
|
|
143
|
+
|
|
144
|
+
const length = new DataView(state.buffer.buffer, state.buffer.byteOffset).getUint32(0, false);
|
|
145
|
+
if (length > 10 * 1024 * 1024) {
|
|
146
|
+
state.expectingPrimitive = true;
|
|
151
147
|
continue;
|
|
152
148
|
}
|
|
153
149
|
|
|
154
|
-
|
|
150
|
+
const totalLen = 4 + length;
|
|
151
|
+
if (state.buffer.length < totalLen) break;
|
|
152
|
+
|
|
153
|
+
const data = state.buffer.slice(4, totalLen);
|
|
154
|
+
let mesh = null;
|
|
155
155
|
|
|
156
|
-
let primitiveResult = null;
|
|
157
156
|
try {
|
|
158
|
-
|
|
157
|
+
const jsonStr = utf8Decoder.decode(data);
|
|
158
|
+
mesh = JSON.parse(jsonStr);
|
|
159
159
|
} catch (e) {
|
|
160
|
-
|
|
160
|
+
state.expectingPrimitive = true;
|
|
161
|
+
continue;
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
|
|
164
|
+
if (mesh) {
|
|
165
|
+
state.isFullProps = true;
|
|
164
166
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
_applyPrefixId(mesh, 'id', null, state.prefixIdKey);
|
|
168
|
+
if (Array.isArray(mesh)) {
|
|
169
|
+
mesh.forEach(item => {
|
|
170
|
+
_applyPrefixId(item.primitives, 'prmid', item.documentId, state.prefixIdKey);
|
|
171
|
+
});
|
|
172
|
+
} else {
|
|
173
|
+
_applyPrefixId(mesh.primitives, 'prmid', mesh.documentId, state.prefixIdKey);
|
|
174
|
+
}
|
|
169
175
|
|
|
170
|
-
|
|
176
|
+
const docId = mesh.id;
|
|
177
|
+
const meshToPrimId = mesh.primitives.map(item => item.prmid);
|
|
178
|
+
const hasPendingPrimitive = meshToPrimId.some(item => state.pendingPrimitives.has(item));
|
|
179
|
+
const hasPendingMesh = state.pendingPrimitives.has(docId);
|
|
180
|
+
|
|
181
|
+
if (hasPendingMesh || hasPendingPrimitive) {
|
|
182
|
+
let primitiveData = state.pendingPrimitives.get(docId);
|
|
183
|
+
if (!hasPendingMesh && hasPendingPrimitive) {
|
|
184
|
+
primitiveData = state.pendingPrimitives.get(meshToPrimId[0]);
|
|
185
|
+
}
|
|
186
|
+
meshes.push(mesh);
|
|
187
|
+
primitives.push(primitiveData);
|
|
188
|
+
}
|
|
171
189
|
|
|
172
|
-
|
|
173
|
-
state.
|
|
174
|
-
state.pendingMatchedPrimitiveIds.size >= state.pendingPrimitiveIds.size
|
|
175
|
-
) {
|
|
176
|
-
commitPendingMesh();
|
|
177
|
-
state.expectingMesh = true;
|
|
190
|
+
state.expectingPrimitive = false;
|
|
191
|
+
state.buffer = state.buffer.slice(totalLen);
|
|
178
192
|
}
|
|
179
193
|
}
|
|
180
194
|
}
|
|
181
195
|
|
|
182
196
|
if (flushing) {
|
|
183
|
-
commitPendingMesh();
|
|
184
197
|
state.buffer = new Uint8Array();
|
|
185
198
|
}
|
|
186
199
|
|
|
187
200
|
return { meshes, primitives };
|
|
188
201
|
}
|
|
189
202
|
|
|
190
|
-
function normalizeStreamMesh(mesh, prefixIdKey) {
|
|
191
|
-
_applyPrefixId(mesh, 'id', null, prefixIdKey);
|
|
192
|
-
const meshList = Array.isArray(mesh) ? mesh : [mesh];
|
|
193
|
-
|
|
194
|
-
meshList.forEach(item => {
|
|
195
|
-
if (!item) return;
|
|
196
|
-
if (!Array.isArray(item.primitives)) {
|
|
197
|
-
item.primitives = [];
|
|
198
|
-
}
|
|
199
|
-
_applyPrefixId(item.primitives, 'prmid', item.documentId, prefixIdKey);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
return mesh;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function collectMeshPrimitiveIds(mesh) {
|
|
206
|
-
const ids = [];
|
|
207
|
-
const meshList = Array.isArray(mesh) ? mesh : [mesh];
|
|
208
|
-
|
|
209
|
-
meshList.forEach(item => {
|
|
210
|
-
if (!item || !Array.isArray(item.primitives)) return;
|
|
211
|
-
item.primitives.forEach(primitive => {
|
|
212
|
-
if (primitive && primitive.prmid != null) {
|
|
213
|
-
ids.push(primitive.prmid);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
return ids;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function isValidStreamMesh(mesh) {
|
|
222
|
-
const meshList = Array.isArray(mesh) ? mesh : [mesh];
|
|
223
|
-
if (meshList.length === 0) return false;
|
|
224
|
-
return meshList.every(item => item && typeof item === 'object' && Array.isArray(item.primitives));
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function tryParseMeshFromState(state) {
|
|
228
|
-
if (state.buffer.length < 4) {
|
|
229
|
-
return { status: 'incomplete' };
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const length = new DataView(state.buffer.buffer, state.buffer.byteOffset).getUint32(0, false);
|
|
233
|
-
if (length <= 0 || length > 10 * 1024 * 1024) {
|
|
234
|
-
return { status: 'invalid' };
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const totalLen = 4 + length;
|
|
238
|
-
if (state.buffer.length < totalLen) {
|
|
239
|
-
return { status: 'incomplete' };
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
try {
|
|
243
|
-
const data = state.buffer.slice(4, totalLen);
|
|
244
|
-
const parsedMesh = JSON.parse(utf8Decoder.decode(data));
|
|
245
|
-
if (!isValidStreamMesh(parsedMesh)) {
|
|
246
|
-
return { status: 'invalid' };
|
|
247
|
-
}
|
|
248
|
-
const mesh = normalizeStreamMesh(parsedMesh, state.prefixIdKey);
|
|
249
|
-
return { status: 'success', mesh, totalLen };
|
|
250
|
-
} catch (e) {
|
|
251
|
-
return { status: 'invalid' };
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function parsePrimitiveFromState(state) {
|
|
256
|
-
const dataView = new DataView(
|
|
257
|
-
state.buffer.buffer,
|
|
258
|
-
state.buffer.byteOffset,
|
|
259
|
-
state.buffer.byteLength
|
|
260
|
-
);
|
|
261
|
-
const primitiveResult = parsePrimitive(dataView, state.buffer, 0, state.isFullProps);
|
|
262
|
-
const primitiveData = primitiveResult.primitive;
|
|
263
|
-
|
|
264
|
-
_applyPrefixId(primitiveData, 'id', null, state.prefixIdKey);
|
|
265
|
-
_applyPrefixId(primitiveData, 'material', null, state.prefixIdKey);
|
|
266
|
-
|
|
267
|
-
if (state.isFullProps) {
|
|
268
|
-
const { position, normal, posindex, nolindex, indices } =
|
|
269
|
-
parsePrimitiveData(primitiveData);
|
|
270
|
-
const formatted = formatPrimitiveData({ position, normal, posindex, nolindex });
|
|
271
|
-
delete primitiveData.nolindex;
|
|
272
|
-
delete primitiveData.posindex;
|
|
273
|
-
primitiveData.position = formatted.position;
|
|
274
|
-
primitiveData.normal = formatted.normal;
|
|
275
|
-
primitiveData.indices = indices;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return {
|
|
279
|
-
primitive: primitiveData,
|
|
280
|
-
consumedBytes: primitiveResult.offset,
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
|
|
284
203
|
function parseBufferData(buffer, prefixIdKey) {
|
|
285
204
|
let uint8Array = null;
|
|
286
205
|
let dataView = null;
|
|
@@ -369,20 +288,8 @@ function parsePrimitive(dataView, uint8Array, offset, isFullProps = true) {
|
|
|
369
288
|
if (dataView.byteLength < offset + 12) {
|
|
370
289
|
throw new Error('Insufficient data for primitive header');
|
|
371
290
|
}
|
|
372
|
-
|
|
291
|
+
primitive.id = dataView.getInt32(offset, false);
|
|
373
292
|
offset += 4;
|
|
374
|
-
if (primitiveIdTextLen === 0xffffffff) {
|
|
375
|
-
primitive.id = null;
|
|
376
|
-
} else if (primitiveIdTextLen > 0) {
|
|
377
|
-
if (dataView.byteLength < offset + primitiveIdTextLen) {
|
|
378
|
-
throw new Error('Insufficient data for primitive id content');
|
|
379
|
-
}
|
|
380
|
-
const textBytes = uint8Array.subarray(offset, offset + primitiveIdTextLen);
|
|
381
|
-
primitive.id = utf8Decoder.decode(textBytes);
|
|
382
|
-
offset += primitiveIdTextLen;
|
|
383
|
-
} else {
|
|
384
|
-
primitive.id = '';
|
|
385
|
-
}
|
|
386
293
|
|
|
387
294
|
if (dataView.byteLength < offset + 4) {
|
|
388
295
|
throw new Error('Insufficient data for GeomText length');
|
|
@@ -402,26 +309,11 @@ function parsePrimitive(dataView, uint8Array, offset, isFullProps = true) {
|
|
|
402
309
|
primitive.documentId = '';
|
|
403
310
|
}
|
|
404
311
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
if (materialTextLen === 0xffffffff) {
|
|
411
|
-
primitive.material = null;
|
|
412
|
-
} else if (materialTextLen > 0) {
|
|
413
|
-
if (dataView.byteLength < offset + materialTextLen) {
|
|
414
|
-
throw new Error('Insufficient data for Material content');
|
|
415
|
-
}
|
|
416
|
-
const textBytes = uint8Array.subarray(offset, offset + materialTextLen);
|
|
417
|
-
primitive.material = utf8Decoder.decode(textBytes);
|
|
418
|
-
offset += materialTextLen;
|
|
419
|
-
} else {
|
|
420
|
-
primitive.material = '';
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
if (dataView.byteLength < offset + 4) {
|
|
424
|
-
throw new Error('Insufficient data for GeomText length');
|
|
312
|
+
primitive.material = dataView.getInt32(offset, false);
|
|
313
|
+
offset += 4;
|
|
314
|
+
|
|
315
|
+
if (dataView.byteLength < offset + 4) {
|
|
316
|
+
throw new Error('Insufficient data for GeomText length');
|
|
425
317
|
}
|
|
426
318
|
const geomTextLen = dataView.getUint32(offset, false);
|
|
427
319
|
offset += 4;
|
|
@@ -24,12 +24,8 @@ function processMeshData(input, options) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const identity = new THREE.Matrix4().identity();
|
|
28
|
-
const identityElements = identity.elements;
|
|
29
|
-
|
|
30
27
|
input.mesh.forEach(meshItem => {
|
|
31
28
|
const geomList = [];
|
|
32
|
-
const meshMatrix = meshItem.matrix?.length ? meshItem.matrix : identityElements;
|
|
33
29
|
meshItem.primitives.forEach(primitive => {
|
|
34
30
|
const primitiveData = input.primitive.find(g => g.id === primitive.prmid);
|
|
35
31
|
if (primitiveData) {
|
|
@@ -38,27 +34,26 @@ function processMeshData(input, options) {
|
|
|
38
34
|
const material = mergedMaterial || baseMaterial;
|
|
39
35
|
const sourceVisible =
|
|
40
36
|
mergedMaterial?.visible === false || baseMaterial?.visible === false ? false : true;
|
|
41
|
-
const baseColor = [255, 255, 255, 1];
|
|
42
37
|
const prop = {
|
|
43
|
-
color: material?.color
|
|
44
|
-
? material?.color.length
|
|
45
|
-
? material.color
|
|
46
|
-
: baseColor
|
|
47
|
-
: baseColor,
|
|
38
|
+
color: material?.color || [255, 255, 255, 1],
|
|
48
39
|
fontsize: material?.fontsize !== undefined ? material?.fontsize : 20,
|
|
49
40
|
frontname: material?.frontname !== undefined ? material?.frontname : '',
|
|
50
41
|
italic: material?.italic,
|
|
51
42
|
linepacing: 1, // 默认值
|
|
52
|
-
linewidth: material?.linewidth !== undefined ? material?.linewidth :
|
|
43
|
+
linewidth: material?.linewidth !== undefined ? material?.linewidth : 1, // 默认值
|
|
53
44
|
visible: sourceVisible,
|
|
54
45
|
sourceVisible,
|
|
55
46
|
transparent: material?.transp !== undefined ? material?.transp : 0,
|
|
56
47
|
};
|
|
57
48
|
|
|
49
|
+
const identity = new THREE.Matrix4().identity();
|
|
50
|
+
|
|
58
51
|
geomList.push({
|
|
59
52
|
matrix: {
|
|
60
|
-
val: primitive.matrix?.length ? primitive.matrix :
|
|
53
|
+
val: primitive.matrix?.length ? primitive.matrix : identity.elements,
|
|
54
|
+
// val: identity.elements,
|
|
61
55
|
},
|
|
56
|
+
// originMatrix: meshItem.id == primitive.prmid ? [] : identity.elements,
|
|
62
57
|
prmid: primitive.prmid,
|
|
63
58
|
geomId: primitiveData.id,
|
|
64
59
|
type: primitiveData.geomType,
|
|
@@ -76,9 +71,6 @@ function processMeshData(input, options) {
|
|
|
76
71
|
|
|
77
72
|
drawObjMap.set(meshItem.id, {
|
|
78
73
|
drawObjId: meshItem.id,
|
|
79
|
-
matrix: {
|
|
80
|
-
val: meshMatrix,
|
|
81
|
-
},
|
|
82
74
|
geoms: geomList,
|
|
83
75
|
// lodLevel: meshItem.type || 2,
|
|
84
76
|
});
|
|
@@ -154,7 +146,7 @@ function processOnePrimtiveToMultiMesh(primitive) {
|
|
|
154
146
|
return {
|
|
155
147
|
instanceId: primitive.drawObjId, // 实例与drawObj一对多关系
|
|
156
148
|
drawObject: primitive.geoms[0]?.prmid || '',
|
|
157
|
-
matrix: primitive.matrix ||
|
|
149
|
+
matrix: primitive.geoms[0]?.matrix || [],
|
|
158
150
|
};
|
|
159
151
|
}
|
|
160
152
|
|
|
@@ -248,8 +240,6 @@ function parseNode(node, isFlatNode) {
|
|
|
248
240
|
// 生成默认node节点
|
|
249
241
|
function generateNode(mesh) {
|
|
250
242
|
let nodes = [];
|
|
251
|
-
const identity = new THREE.Matrix4().identity();
|
|
252
|
-
const identityElements = identity.elements;
|
|
253
243
|
mesh.forEach(item => {
|
|
254
244
|
if (item.primitives.length) {
|
|
255
245
|
let tempNode = {
|
|
@@ -257,9 +247,7 @@ function generateNode(mesh) {
|
|
|
257
247
|
_batchId: item.id,
|
|
258
248
|
name: item.id,
|
|
259
249
|
mesh: item.id,
|
|
260
|
-
matrix: {
|
|
261
|
-
val: item.matrix?.length ? item.matrix : identityElements,
|
|
262
|
-
},
|
|
250
|
+
matrix: {},
|
|
263
251
|
nodeType: 3,
|
|
264
252
|
};
|
|
265
253
|
nodes.push(tempNode);
|
|
@@ -5,7 +5,7 @@ import helvetikerFont from 'three/examples/fonts/helvetiker_regular.typeface.jso
|
|
|
5
5
|
import { MeshLineGeometry, MeshLineMaterial } from 'meshline';
|
|
6
6
|
import StreamLoaderParserWorker from '../../packages/utils/StreamLoaderParser.worker.js';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const GEOM_TYPES = {
|
|
9
9
|
geom_3d: 53248,
|
|
10
10
|
geom_3d_text: 53249,
|
|
11
11
|
geom_3d_mtext: 53250,
|
|
@@ -91,46 +91,15 @@ function requestInstancedMapping(instances, drawObjs) {
|
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
function getInstanceNormalSign(matrix) {
|
|
95
|
-
if (!matrix || typeof matrix.determinant !== 'function') return 1;
|
|
96
|
-
return matrix.determinant() < 0 ? -1 : 1;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
function composeInstanceMatrix(instance, mesh, geometry) {
|
|
105
|
-
const resultMatrix = new THREE.Matrix4();
|
|
106
|
-
const meshMatrix = new THREE.Matrix4();
|
|
107
|
-
const primitiveMatrix = new THREE.Matrix4();
|
|
108
|
-
const meshMatrixVal = getMatrixVal(instance && instance.matrix);
|
|
109
|
-
const primitiveMatrixVal = getMatrixVal(mesh && mesh.matrix);
|
|
110
|
-
|
|
111
|
-
if (meshMatrixVal) {
|
|
112
|
-
meshMatrix.fromArray(meshMatrixVal);
|
|
113
|
-
}
|
|
114
|
-
if (primitiveMatrixVal) {
|
|
115
|
-
primitiveMatrix.fromArray(primitiveMatrixVal);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const { points, alignType } = mesh || {};
|
|
119
|
-
if (mesh && isTextType(mesh.type) && points && points.length >= 3) {
|
|
120
|
-
const positionMatrix = new THREE.Matrix4();
|
|
121
|
-
const alignMatrix = createAlignedText(alignType, geometry);
|
|
122
|
-
positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
|
|
123
|
-
primitiveMatrix.multiply(alignMatrix).multiply(positionMatrix);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
resultMatrix.multiplyMatrices(meshMatrix, primitiveMatrix);
|
|
127
|
-
return resultMatrix;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* 重置处理状态,用于新的批量加载会话
|
|
132
|
-
*/
|
|
133
|
-
function resetProcessingState() {
|
|
94
|
+
function getInstanceNormalSign(matrix) {
|
|
95
|
+
if (!matrix || typeof matrix.determinant !== 'function') return 1;
|
|
96
|
+
return matrix.determinant() < 0 ? -1 : 1;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 重置处理状态,用于新的批量加载会话
|
|
101
|
+
*/
|
|
102
|
+
function resetProcessingState() {
|
|
134
103
|
drawObjMapInstance = {};
|
|
135
104
|
// instanceToInstancedMeshMap.clear();
|
|
136
105
|
// processedDrawObjects.clear();
|
|
@@ -465,27 +434,47 @@ function setInstanceMatricesAndColors(model, drawObj, mesh, meshName, customColo
|
|
|
465
434
|
|
|
466
435
|
// const instancedMesh = instanceToInstancedMeshMap.get(item.instanceId);
|
|
467
436
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
.
|
|
484
|
-
.
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
437
|
+
// 处理矩阵变换
|
|
438
|
+
const matrixVal = item.matrix?.val;
|
|
439
|
+
if (matrixVal) {
|
|
440
|
+
const m4 = new THREE.Matrix4();
|
|
441
|
+
const meshMatrix = new THREE.Matrix4();
|
|
442
|
+
const geomMatrix = new THREE.Matrix4();
|
|
443
|
+
|
|
444
|
+
meshMatrix.fromArray(matrixVal);
|
|
445
|
+
geomMatrix.fromArray(new THREE.Matrix4().identity().elements);
|
|
446
|
+
|
|
447
|
+
// 处理文本居中对齐
|
|
448
|
+
const { points, alignType } = mesh;
|
|
449
|
+
if (isTextType(mesh.type)) {
|
|
450
|
+
const positionMatrix = new THREE.Matrix4();
|
|
451
|
+
const alignMatrix = createAlignedText(alignType, model.geometry);
|
|
452
|
+
positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
|
|
453
|
+
geomMatrix.multiply(alignMatrix).multiply(positionMatrix);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
m4.multiplyMatrices(meshMatrix, geomMatrix);
|
|
457
|
+
model.setMatrixAt(index, m4);
|
|
458
|
+
|
|
459
|
+
const normalSignAttr = model.geometry && model.geometry.getAttribute('instanceNormalSign');
|
|
460
|
+
if (normalSignAttr && normalSignAttr.array && index < normalSignAttr.array.length) {
|
|
461
|
+
normalSignAttr.array[index] = getInstanceNormalSign(m4);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const copyMatrix = new THREE.Matrix4().copy(m4);
|
|
465
|
+
model.userData.copyMatrix = copyMatrix;
|
|
466
|
+
|
|
467
|
+
const temp = model.userData.instancesMap.get(item.instanceId);
|
|
468
|
+
temp.copyMatrix = copyMatrix;
|
|
469
|
+
if (sourceVisible === false) {
|
|
470
|
+
const offsetMatrix = new THREE.Matrix4()
|
|
471
|
+
.copy(copyMatrix)
|
|
472
|
+
.makeTranslation(9999999, 9999999, 9999999);
|
|
473
|
+
model.setMatrixAt(index, offsetMatrix);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// 设置颜色
|
|
489
478
|
model.setColorAt(index, meshColor);
|
|
490
479
|
});
|
|
491
480
|
|
|
@@ -560,9 +549,25 @@ function appendInstanceToInstancedMesh(model, drawObj, mesh, instance, customCol
|
|
|
560
549
|
? new THREE.Color(customColor)
|
|
561
550
|
: new THREE.Color(`rgb(${colorArr[0]}, ${colorArr[1]}, ${colorArr[2]})`);
|
|
562
551
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
552
|
+
const matrixVal = instance.matrix?.val;
|
|
553
|
+
if (!matrixVal || !mesh || !mesh.matrix || !mesh.matrix.val) return;
|
|
554
|
+
|
|
555
|
+
const m4 = new THREE.Matrix4();
|
|
556
|
+
const meshMatrix = new THREE.Matrix4();
|
|
557
|
+
const geomMatrix = new THREE.Matrix4();
|
|
558
|
+
|
|
559
|
+
meshMatrix.fromArray(instance.matrix.val);
|
|
560
|
+
geomMatrix.fromArray(new THREE.Matrix4().identity().elements);
|
|
561
|
+
|
|
562
|
+
const { points, alignType } = mesh;
|
|
563
|
+
if (isTextType(mesh.type)) {
|
|
564
|
+
const positionMatrix = new THREE.Matrix4();
|
|
565
|
+
const alignMatrix = createAlignedText(alignType, model.geometry);
|
|
566
|
+
positionMatrix.identity().makeTranslation(points[0], points[1], points[2]);
|
|
567
|
+
geomMatrix.multiply(alignMatrix).multiply(positionMatrix);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
m4.multiplyMatrices(meshMatrix, geomMatrix);
|
|
566
571
|
const renderMatrix =
|
|
567
572
|
sourceVisible === false
|
|
568
573
|
? new THREE.Matrix4().copy(m4).makeTranslation(9999999, 9999999, 9999999)
|
|
@@ -674,7 +679,7 @@ function drawModel(geom, instanceName, instanceCount, nColor, nOpacity, options
|
|
|
674
679
|
let model;
|
|
675
680
|
// 处理二维几何体(普通2D图形和特殊2D图形)
|
|
676
681
|
if (geom.type == GEOM_TYPES.geom_2d || geom.type == GEOM_TYPES.geom_2d_others) {
|
|
677
|
-
model = draw2Dmodel(geom, instanceName, instanceCount,
|
|
682
|
+
model = draw2Dmodel(geom, instanceName, instanceCount, options); // TODO 该类型调试中
|
|
678
683
|
// 处理二维文本类型
|
|
679
684
|
} else if (isTextType(geom.type)) {
|
|
680
685
|
model = drawText(geom, instanceName, instanceCount, options);
|
|
@@ -685,7 +690,7 @@ function drawModel(geom, instanceName, instanceCount, nColor, nOpacity, options
|
|
|
685
690
|
geom.type == GEOM_TYPES.geom_2d_ellipse ||
|
|
686
691
|
geom.type == GEOM_TYPES.geom_2d_ellipseArc
|
|
687
692
|
) {
|
|
688
|
-
model = drawCurves(geom, instanceName, instanceCount,
|
|
693
|
+
model = drawCurves(geom, instanceName, instanceCount, options); // TODO 该类型调试中
|
|
689
694
|
// 处理三维几何体(普通3D模型和OBJ模型)
|
|
690
695
|
} else if (geom.type == GEOM_TYPES.geom_3d || geom.type == GEOM_TYPES.geom_3d_obj) {
|
|
691
696
|
model = draw3Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options);
|
|
@@ -714,7 +719,7 @@ function isTextType(type) {
|
|
|
714
719
|
* @param {String} instanceName- 曲线实例的名称
|
|
715
720
|
* @return {Object}- 包含曲线模型和曲线信息的对象
|
|
716
721
|
*/
|
|
717
|
-
function drawCurves(geom, instanceName, instanceCount,
|
|
722
|
+
function drawCurves(geom, instanceName, instanceCount, options = {}) {
|
|
718
723
|
let { points, normals } = geom;
|
|
719
724
|
let aX = points[0];
|
|
720
725
|
let aY = points[1];
|
|
@@ -755,8 +760,6 @@ function drawCurves(geom, instanceName, instanceCount, nColor, nOpacity, options
|
|
|
755
760
|
},
|
|
756
761
|
instanceName,
|
|
757
762
|
instanceCount,
|
|
758
|
-
nColor,
|
|
759
|
-
nOpacity,
|
|
760
763
|
options
|
|
761
764
|
);
|
|
762
765
|
// model.rotation.x = -Math.PI / 2;
|
|
@@ -940,8 +943,7 @@ function draw3Dmodel(
|
|
|
940
943
|
// 处理transparent透明度
|
|
941
944
|
opacity = 1 - transparent;
|
|
942
945
|
|
|
943
|
-
const finalOpacity =
|
|
944
|
-
nOpacity !== undefined && nOpacity !== null && nOpacity !== '' ? nOpacity : opacity;
|
|
946
|
+
const finalOpacity = nOpacity !== '' ? nOpacity : opacity;
|
|
945
947
|
|
|
946
948
|
// 判断是否全透明
|
|
947
949
|
const isTransparent = finalOpacity < 1.0;
|
|
@@ -1068,7 +1070,7 @@ function draw3Dmodel(
|
|
|
1068
1070
|
* @param {String} instanceName - 模型实例的名称
|
|
1069
1071
|
* @returns {Object} - 包含所有 2D 模型的组对象
|
|
1070
1072
|
*/
|
|
1071
|
-
function draw2Dmodel(geom, instanceName, instanceCount,
|
|
1073
|
+
function draw2Dmodel(geom, instanceName, instanceCount, options = {}) {
|
|
1072
1074
|
const points = geom.points;
|
|
1073
1075
|
const normals = geom.normals;
|
|
1074
1076
|
const geometry = new THREE.BufferGeometry();
|
|
@@ -1101,8 +1103,6 @@ function draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, option
|
|
|
1101
1103
|
},
|
|
1102
1104
|
instanceName,
|
|
1103
1105
|
instanceCount,
|
|
1104
|
-
nColor,
|
|
1105
|
-
nOpacity,
|
|
1106
1106
|
options
|
|
1107
1107
|
);
|
|
1108
1108
|
// mesh.raycast = raycast;
|