fl-web-component 2.0.18 → 2.0.19-beta.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/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 +1054 -872
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +4 -3
- package/packages/components/com-graphics/index.vue +75 -6
- package/packages/components/com-graphics/mock.json +115 -0
- package/packages/utils/StreamLoader.js +250 -107
- package/packages/utils/StreamLoaderParser.worker.js +184 -76
- package/src/utils/flgltf-parser.js +21 -9
- package/src/utils/instance-parser.js +75 -75
- package/packages/components/com-graphics/box.json +0 -77
|
@@ -88,8 +88,11 @@ function createStreamState(prefixIdKey) {
|
|
|
88
88
|
return {
|
|
89
89
|
prefixIdKey: prefixIdKey || '',
|
|
90
90
|
buffer: new Uint8Array(),
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
pendingMesh: null,
|
|
92
|
+
pendingPrimitiveIds: new Set(),
|
|
93
|
+
pendingPrimitiveGroups: [],
|
|
94
|
+
pendingMatchedPrimitiveIds: new Set(),
|
|
95
|
+
expectingMesh: true,
|
|
93
96
|
isFullProps: true,
|
|
94
97
|
};
|
|
95
98
|
}
|
|
@@ -105,101 +108,179 @@ function parseStreamChunk(state, chunkView, flushing = false) {
|
|
|
105
108
|
const meshes = [];
|
|
106
109
|
const primitives = [];
|
|
107
110
|
|
|
108
|
-
|
|
109
|
-
if (state.
|
|
110
|
-
if (state.buffer.length < 12) break;
|
|
111
|
+
const commitPendingMesh = () => {
|
|
112
|
+
if (!state.pendingMesh) return;
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
}
|
|
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
|
+
});
|
|
134
119
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
state.pendingMesh = null;
|
|
121
|
+
state.pendingPrimitiveIds = new Set();
|
|
122
|
+
state.pendingPrimitiveGroups = [];
|
|
123
|
+
state.pendingMatchedPrimitiveIds = new Set();
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
while (state.buffer.length > 0) {
|
|
127
|
+
if (state.expectingMesh) {
|
|
128
|
+
const meshResult = tryParseMeshFromState(state);
|
|
129
|
+
if (meshResult.status === 'incomplete') break;
|
|
130
|
+
if (meshResult.status === 'invalid') {
|
|
139
131
|
break;
|
|
140
132
|
}
|
|
141
|
-
} else {
|
|
142
|
-
if (state.buffer.length < 4) break;
|
|
143
133
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
+
} else {
|
|
142
|
+
const nextMeshResult = tryParseMeshFromState(state);
|
|
143
|
+
if (nextMeshResult.status === 'success') {
|
|
144
|
+
commitPendingMesh();
|
|
145
|
+
state.pendingMesh = nextMeshResult.mesh;
|
|
146
|
+
state.pendingPrimitiveIds = new Set(collectMeshPrimitiveIds(nextMeshResult.mesh));
|
|
147
|
+
state.pendingPrimitiveGroups = [];
|
|
148
|
+
state.pendingMatchedPrimitiveIds = new Set();
|
|
149
|
+
state.expectingMesh = false;
|
|
150
|
+
state.buffer = state.buffer.slice(nextMeshResult.totalLen);
|
|
147
151
|
continue;
|
|
148
152
|
}
|
|
149
153
|
|
|
150
|
-
|
|
151
|
-
if (state.buffer.length < totalLen) break;
|
|
152
|
-
|
|
153
|
-
const data = state.buffer.slice(4, totalLen);
|
|
154
|
-
let mesh = null;
|
|
154
|
+
if (state.buffer.length < 12) break;
|
|
155
155
|
|
|
156
|
+
let primitiveResult = null;
|
|
156
157
|
try {
|
|
157
|
-
|
|
158
|
-
mesh = JSON.parse(jsonStr);
|
|
158
|
+
primitiveResult = parsePrimitiveFromState(state);
|
|
159
159
|
} catch (e) {
|
|
160
|
-
|
|
161
|
-
continue;
|
|
160
|
+
break;
|
|
162
161
|
}
|
|
163
162
|
|
|
164
|
-
|
|
165
|
-
state.isFullProps = true;
|
|
163
|
+
const primitiveData = primitiveResult.primitive;
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
});
|
|
172
|
-
} else {
|
|
173
|
-
_applyPrefixId(mesh.primitives, 'prmid', mesh.documentId, state.prefixIdKey);
|
|
174
|
-
}
|
|
165
|
+
if (state.pendingPrimitiveIds.has(primitiveData.id)) {
|
|
166
|
+
state.pendingPrimitiveGroups.push(primitiveData);
|
|
167
|
+
state.pendingMatchedPrimitiveIds.add(primitiveData.id);
|
|
168
|
+
}
|
|
175
169
|
|
|
176
|
-
|
|
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
|
-
}
|
|
170
|
+
state.buffer = state.buffer.slice(primitiveResult.consumedBytes);
|
|
189
171
|
|
|
190
|
-
|
|
191
|
-
state.
|
|
172
|
+
if (
|
|
173
|
+
state.pendingPrimitiveIds.size > 0 &&
|
|
174
|
+
state.pendingMatchedPrimitiveIds.size >= state.pendingPrimitiveIds.size
|
|
175
|
+
) {
|
|
176
|
+
commitPendingMesh();
|
|
177
|
+
state.expectingMesh = true;
|
|
192
178
|
}
|
|
193
179
|
}
|
|
194
180
|
}
|
|
195
181
|
|
|
196
182
|
if (flushing) {
|
|
183
|
+
commitPendingMesh();
|
|
197
184
|
state.buffer = new Uint8Array();
|
|
198
185
|
}
|
|
199
186
|
|
|
200
187
|
return { meshes, primitives };
|
|
201
188
|
}
|
|
202
189
|
|
|
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
|
+
|
|
203
284
|
function parseBufferData(buffer, prefixIdKey) {
|
|
204
285
|
let uint8Array = null;
|
|
205
286
|
let dataView = null;
|
|
@@ -288,8 +369,20 @@ function parsePrimitive(dataView, uint8Array, offset, isFullProps = true) {
|
|
|
288
369
|
if (dataView.byteLength < offset + 12) {
|
|
289
370
|
throw new Error('Insufficient data for primitive header');
|
|
290
371
|
}
|
|
291
|
-
|
|
372
|
+
const primitiveIdTextLen = dataView.getUint32(offset, false);
|
|
292
373
|
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
|
+
}
|
|
293
386
|
|
|
294
387
|
if (dataView.byteLength < offset + 4) {
|
|
295
388
|
throw new Error('Insufficient data for GeomText length');
|
|
@@ -309,11 +402,26 @@ function parsePrimitive(dataView, uint8Array, offset, isFullProps = true) {
|
|
|
309
402
|
primitive.documentId = '';
|
|
310
403
|
}
|
|
311
404
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
405
|
+
if (dataView.byteLength < offset + 4) {
|
|
406
|
+
throw new Error('Insufficient data for Material length');
|
|
407
|
+
}
|
|
408
|
+
const materialTextLen = dataView.getUint32(offset, false);
|
|
409
|
+
offset += 4;
|
|
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');
|
|
317
425
|
}
|
|
318
426
|
const geomTextLen = dataView.getUint32(offset, false);
|
|
319
427
|
offset += 4;
|
|
@@ -24,8 +24,12 @@ function processMeshData(input, options) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
const identity = new THREE.Matrix4().identity();
|
|
28
|
+
const identityElements = identity.elements;
|
|
29
|
+
|
|
27
30
|
input.mesh.forEach(meshItem => {
|
|
28
31
|
const geomList = [];
|
|
32
|
+
const meshMatrix = meshItem.matrix?.length ? meshItem.matrix : identityElements;
|
|
29
33
|
meshItem.primitives.forEach(primitive => {
|
|
30
34
|
const primitiveData = input.primitive.find(g => g.id === primitive.prmid);
|
|
31
35
|
if (primitiveData) {
|
|
@@ -34,26 +38,27 @@ function processMeshData(input, options) {
|
|
|
34
38
|
const material = mergedMaterial || baseMaterial;
|
|
35
39
|
const sourceVisible =
|
|
36
40
|
mergedMaterial?.visible === false || baseMaterial?.visible === false ? false : true;
|
|
41
|
+
const baseColor = [255, 255, 255, 1];
|
|
37
42
|
const prop = {
|
|
38
|
-
color: material?.color
|
|
43
|
+
color: material?.color
|
|
44
|
+
? material?.color.length
|
|
45
|
+
? material.color
|
|
46
|
+
: baseColor
|
|
47
|
+
: baseColor,
|
|
39
48
|
fontsize: material?.fontsize !== undefined ? material?.fontsize : 20,
|
|
40
49
|
frontname: material?.frontname !== undefined ? material?.frontname : '',
|
|
41
50
|
italic: material?.italic,
|
|
42
51
|
linepacing: 1, // 默认值
|
|
43
|
-
linewidth: material?.linewidth !== undefined ? material?.linewidth :
|
|
52
|
+
linewidth: material?.linewidth !== undefined ? material?.linewidth : 10, // 默认值
|
|
44
53
|
visible: sourceVisible,
|
|
45
54
|
sourceVisible,
|
|
46
55
|
transparent: material?.transp !== undefined ? material?.transp : 0,
|
|
47
56
|
};
|
|
48
57
|
|
|
49
|
-
const identity = new THREE.Matrix4().identity();
|
|
50
|
-
|
|
51
58
|
geomList.push({
|
|
52
59
|
matrix: {
|
|
53
|
-
val: primitive.matrix?.length ? primitive.matrix :
|
|
54
|
-
// val: identity.elements,
|
|
60
|
+
val: primitive.matrix?.length ? primitive.matrix : identityElements,
|
|
55
61
|
},
|
|
56
|
-
// originMatrix: meshItem.id == primitive.prmid ? [] : identity.elements,
|
|
57
62
|
prmid: primitive.prmid,
|
|
58
63
|
geomId: primitiveData.id,
|
|
59
64
|
type: primitiveData.geomType,
|
|
@@ -71,6 +76,9 @@ function processMeshData(input, options) {
|
|
|
71
76
|
|
|
72
77
|
drawObjMap.set(meshItem.id, {
|
|
73
78
|
drawObjId: meshItem.id,
|
|
79
|
+
matrix: {
|
|
80
|
+
val: meshMatrix,
|
|
81
|
+
},
|
|
74
82
|
geoms: geomList,
|
|
75
83
|
// lodLevel: meshItem.type || 2,
|
|
76
84
|
});
|
|
@@ -146,7 +154,7 @@ function processOnePrimtiveToMultiMesh(primitive) {
|
|
|
146
154
|
return {
|
|
147
155
|
instanceId: primitive.drawObjId, // 实例与drawObj一对多关系
|
|
148
156
|
drawObject: primitive.geoms[0]?.prmid || '',
|
|
149
|
-
matrix: primitive.
|
|
157
|
+
matrix: primitive.matrix || {},
|
|
150
158
|
};
|
|
151
159
|
}
|
|
152
160
|
|
|
@@ -240,6 +248,8 @@ function parseNode(node, isFlatNode) {
|
|
|
240
248
|
// 生成默认node节点
|
|
241
249
|
function generateNode(mesh) {
|
|
242
250
|
let nodes = [];
|
|
251
|
+
const identity = new THREE.Matrix4().identity();
|
|
252
|
+
const identityElements = identity.elements;
|
|
243
253
|
mesh.forEach(item => {
|
|
244
254
|
if (item.primitives.length) {
|
|
245
255
|
let tempNode = {
|
|
@@ -247,7 +257,9 @@ function generateNode(mesh) {
|
|
|
247
257
|
_batchId: item.id,
|
|
248
258
|
name: item.id,
|
|
249
259
|
mesh: item.id,
|
|
250
|
-
matrix: {
|
|
260
|
+
matrix: {
|
|
261
|
+
val: item.matrix?.length ? item.matrix : identityElements,
|
|
262
|
+
},
|
|
251
263
|
nodeType: 3,
|
|
252
264
|
};
|
|
253
265
|
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
|
-
const GEOM_TYPES = {
|
|
8
|
+
export const GEOM_TYPES = {
|
|
9
9
|
geom_3d: 53248,
|
|
10
10
|
geom_3d_text: 53249,
|
|
11
11
|
geom_3d_mtext: 53250,
|
|
@@ -91,15 +91,46 @@ 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
|
-
|
|
94
|
+
function getInstanceNormalSign(matrix) {
|
|
95
|
+
if (!matrix || typeof matrix.determinant !== 'function') return 1;
|
|
96
|
+
return matrix.determinant() < 0 ? -1 : 1;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function getMatrixVal(matrix) {
|
|
100
|
+
const val = matrix && matrix.val ? matrix.val : matrix;
|
|
101
|
+
return val && val.length >= 16 ? val : null;
|
|
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() {
|
|
103
134
|
drawObjMapInstance = {};
|
|
104
135
|
// instanceToInstancedMeshMap.clear();
|
|
105
136
|
// processedDrawObjects.clear();
|
|
@@ -434,47 +465,27 @@ function setInstanceMatricesAndColors(model, drawObj, mesh, meshName, customColo
|
|
|
434
465
|
|
|
435
466
|
// const instancedMesh = instanceToInstancedMeshMap.get(item.instanceId);
|
|
436
467
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
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
|
-
// 设置颜色
|
|
468
|
+
const m4 = composeInstanceMatrix(item, mesh, model.geometry);
|
|
469
|
+
model.setMatrixAt(index, m4);
|
|
470
|
+
|
|
471
|
+
const normalSignAttr = model.geometry && model.geometry.getAttribute('instanceNormalSign');
|
|
472
|
+
if (normalSignAttr && normalSignAttr.array && index < normalSignAttr.array.length) {
|
|
473
|
+
normalSignAttr.array[index] = getInstanceNormalSign(m4);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const copyMatrix = new THREE.Matrix4().copy(m4);
|
|
477
|
+
model.userData.copyMatrix = copyMatrix;
|
|
478
|
+
|
|
479
|
+
const temp = model.userData.instancesMap.get(item.instanceId);
|
|
480
|
+
temp.copyMatrix = copyMatrix;
|
|
481
|
+
if (sourceVisible === false) {
|
|
482
|
+
const offsetMatrix = new THREE.Matrix4()
|
|
483
|
+
.copy(copyMatrix)
|
|
484
|
+
.makeTranslation(9999999, 9999999, 9999999);
|
|
485
|
+
model.setMatrixAt(index, offsetMatrix);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// 设置颜色
|
|
478
489
|
model.setColorAt(index, meshColor);
|
|
479
490
|
});
|
|
480
491
|
|
|
@@ -549,25 +560,9 @@ function appendInstanceToInstancedMesh(model, drawObj, mesh, instance, customCol
|
|
|
549
560
|
? new THREE.Color(customColor)
|
|
550
561
|
: new THREE.Color(`rgb(${colorArr[0]}, ${colorArr[1]}, ${colorArr[2]})`);
|
|
551
562
|
|
|
552
|
-
|
|
553
|
-
|
|
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);
|
|
563
|
+
if (!mesh) return;
|
|
564
|
+
|
|
565
|
+
const m4 = composeInstanceMatrix(instance, mesh, model.geometry);
|
|
571
566
|
const renderMatrix =
|
|
572
567
|
sourceVisible === false
|
|
573
568
|
? new THREE.Matrix4().copy(m4).makeTranslation(9999999, 9999999, 9999999)
|
|
@@ -679,7 +674,7 @@ function drawModel(geom, instanceName, instanceCount, nColor, nOpacity, options
|
|
|
679
674
|
let model;
|
|
680
675
|
// 处理二维几何体(普通2D图形和特殊2D图形)
|
|
681
676
|
if (geom.type == GEOM_TYPES.geom_2d || geom.type == GEOM_TYPES.geom_2d_others) {
|
|
682
|
-
model = draw2Dmodel(geom, instanceName, instanceCount, options); // TODO 该类型调试中
|
|
677
|
+
model = draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options); // TODO 该类型调试中
|
|
683
678
|
// 处理二维文本类型
|
|
684
679
|
} else if (isTextType(geom.type)) {
|
|
685
680
|
model = drawText(geom, instanceName, instanceCount, options);
|
|
@@ -690,7 +685,7 @@ function drawModel(geom, instanceName, instanceCount, nColor, nOpacity, options
|
|
|
690
685
|
geom.type == GEOM_TYPES.geom_2d_ellipse ||
|
|
691
686
|
geom.type == GEOM_TYPES.geom_2d_ellipseArc
|
|
692
687
|
) {
|
|
693
|
-
model = drawCurves(geom, instanceName, instanceCount, options); // TODO 该类型调试中
|
|
688
|
+
model = drawCurves(geom, instanceName, instanceCount, nColor, nOpacity, options); // TODO 该类型调试中
|
|
694
689
|
// 处理三维几何体(普通3D模型和OBJ模型)
|
|
695
690
|
} else if (geom.type == GEOM_TYPES.geom_3d || geom.type == GEOM_TYPES.geom_3d_obj) {
|
|
696
691
|
model = draw3Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options);
|
|
@@ -719,7 +714,7 @@ function isTextType(type) {
|
|
|
719
714
|
* @param {String} instanceName- 曲线实例的名称
|
|
720
715
|
* @return {Object}- 包含曲线模型和曲线信息的对象
|
|
721
716
|
*/
|
|
722
|
-
function drawCurves(geom, instanceName, instanceCount, options = {}) {
|
|
717
|
+
function drawCurves(geom, instanceName, instanceCount, nColor, nOpacity, options = {}) {
|
|
723
718
|
let { points, normals } = geom;
|
|
724
719
|
let aX = points[0];
|
|
725
720
|
let aY = points[1];
|
|
@@ -760,6 +755,8 @@ function drawCurves(geom, instanceName, instanceCount, options = {}) {
|
|
|
760
755
|
},
|
|
761
756
|
instanceName,
|
|
762
757
|
instanceCount,
|
|
758
|
+
nColor,
|
|
759
|
+
nOpacity,
|
|
763
760
|
options
|
|
764
761
|
);
|
|
765
762
|
// model.rotation.x = -Math.PI / 2;
|
|
@@ -943,7 +940,8 @@ function draw3Dmodel(
|
|
|
943
940
|
// 处理transparent透明度
|
|
944
941
|
opacity = 1 - transparent;
|
|
945
942
|
|
|
946
|
-
const finalOpacity =
|
|
943
|
+
const finalOpacity =
|
|
944
|
+
nOpacity !== undefined && nOpacity !== null && nOpacity !== '' ? nOpacity : opacity;
|
|
947
945
|
|
|
948
946
|
// 判断是否全透明
|
|
949
947
|
const isTransparent = finalOpacity < 1.0;
|
|
@@ -1070,7 +1068,7 @@ function draw3Dmodel(
|
|
|
1070
1068
|
* @param {String} instanceName - 模型实例的名称
|
|
1071
1069
|
* @returns {Object} - 包含所有 2D 模型的组对象
|
|
1072
1070
|
*/
|
|
1073
|
-
function draw2Dmodel(geom, instanceName, instanceCount, options = {}) {
|
|
1071
|
+
function draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options = {}) {
|
|
1074
1072
|
const points = geom.points;
|
|
1075
1073
|
const normals = geom.normals;
|
|
1076
1074
|
const geometry = new THREE.BufferGeometry();
|
|
@@ -1103,6 +1101,8 @@ function draw2Dmodel(geom, instanceName, instanceCount, options = {}) {
|
|
|
1103
1101
|
},
|
|
1104
1102
|
instanceName,
|
|
1105
1103
|
instanceCount,
|
|
1104
|
+
nColor,
|
|
1105
|
+
nOpacity,
|
|
1106
1106
|
options
|
|
1107
1107
|
);
|
|
1108
1108
|
// mesh.raycast = raycast;
|