@cesium/engine 7.0.0 → 8.0.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/Build/Workers/{chunk-MY3VNFGQ.js → chunk-23UFSGND.js} +7 -7
- package/Build/Workers/{chunk-IQBYFRVW.js → chunk-2A75IWRS.js} +7 -7
- package/Build/Workers/{chunk-VRGFV2UO.js → chunk-2FRVPMCS.js} +10 -10
- package/Build/Workers/{chunk-46UD5ABS.js → chunk-2FWRMUTY.js} +4 -4
- package/Build/Workers/{chunk-DTAIXKTO.js → chunk-2UPKWTMJ.js} +6 -6
- package/Build/Workers/{chunk-6VJVYK2V.js → chunk-34FXV7D7.js} +2 -2
- package/Build/Workers/{chunk-ODW7WYM4.js → chunk-3VAZEH7M.js} +2 -2
- package/Build/Workers/{chunk-U2VCRRQW.js → chunk-4DO5W5XZ.js} +6 -6
- package/Build/Workers/{chunk-VK3EJHWI.js → chunk-4H7PY4U5.js} +2 -2
- package/Build/Workers/{chunk-RV7ZYPFT.js → chunk-5QULIR53.js} +4 -4
- package/Build/Workers/{chunk-JY5YEZFA.js → chunk-7TC63SJW.js} +8 -8
- package/Build/Workers/{chunk-JJ4VBOQ3.js → chunk-7ZFGPDJA.js} +4 -4
- package/Build/Workers/{chunk-FP6GYBFX.js → chunk-A5DWLWCY.js} +10 -10
- package/Build/Workers/{chunk-5M3U6ZMA.js → chunk-BBWDMCVU.js} +1 -1
- package/Build/Workers/{chunk-WZU2YLWG.js → chunk-BG4UCVXN.js} +3 -3
- package/Build/Workers/{chunk-5WQ523AW.js → chunk-BIKA3NRA.js} +5 -5
- package/Build/Workers/{chunk-PTQQUQC3.js → chunk-BROJAZRZ.js} +13 -13
- package/Build/Workers/{chunk-YUCVWAY6.js → chunk-DDUQAJ4P.js} +7 -7
- package/Build/Workers/{chunk-2HJWSU7B.js → chunk-EERJKOAF.js} +4 -4
- package/Build/Workers/{chunk-LZGHD6NY.js → chunk-EG6PTBY2.js} +15 -15
- package/Build/Workers/{chunk-IX2JCCNM.js → chunk-EHWHNOEX.js} +1 -1
- package/Build/Workers/{chunk-NKPBIX7F.js → chunk-F3YA3Y2Z.js} +1 -1
- package/Build/Workers/{chunk-L2ZN645J.js → chunk-F4HFJMGM.js} +6 -6
- package/Build/Workers/{chunk-F6SE42BK.js → chunk-FJKNFAKQ.js} +15 -472
- package/Build/Workers/{chunk-PNBGBETF.js → chunk-FNIRWHJB.js} +10 -10
- package/Build/Workers/{chunk-RAEV7K66.js → chunk-FZRIVR7Y.js} +5 -5
- package/Build/Workers/{chunk-AIPU2VSX.js → chunk-G43QFN4Q.js} +6 -6
- package/Build/Workers/{chunk-ZUA2UUNV.js → chunk-GATZHF3K.js} +2 -2
- package/Build/Workers/{chunk-ZK5JOS3D.js → chunk-GRC2ZTAF.js} +14 -14
- package/Build/Workers/{chunk-5YLJ77FF.js → chunk-HU6N6EXB.js} +10 -10
- package/Build/Workers/{chunk-4EBHOMFX.js → chunk-I46ZRR5W.js} +17 -17
- package/Build/Workers/{chunk-LZ7JIV3K.js → chunk-JURN7NPV.js} +17 -17
- package/Build/Workers/{chunk-JCNXK6EL.js → chunk-KKCR2YOP.js} +11 -11
- package/Build/Workers/{chunk-S6SKF6DT.js → chunk-LPR3YNP2.js} +5 -5
- package/Build/Workers/{chunk-UDO6BFSF.js → chunk-M7ERACJJ.js} +13 -13
- package/Build/Workers/{chunk-BZP4T2JJ.js → chunk-MDWEGWPA.js} +10 -10
- package/Build/Workers/{chunk-72SANQJV.js → chunk-OGXZVPPM.js} +9 -5
- package/Build/Workers/{chunk-AR5DNBJ4.js → chunk-PGSJK77E.js} +6 -6
- package/Build/Workers/{chunk-GEJTYLCO.js → chunk-PPH7OFP3.js} +5 -5
- package/Build/Workers/{chunk-OVLG3FRS.js → chunk-SH5USDPI.js} +6 -6
- package/Build/Workers/{chunk-6HZQPRUS.js → chunk-SOWMRMWA.js} +1 -1
- package/Build/Workers/{chunk-JXDC723O.js → chunk-STW2DGFI.js} +2 -2
- package/Build/Workers/{chunk-5HDYHG3F.js → chunk-T3XIFPYR.js} +13 -13
- package/Build/Workers/chunk-TTUZP4BO.js +501 -0
- package/Build/Workers/{chunk-7XEAYGZK.js → chunk-UEXTBDBE.js} +10 -10
- package/Build/Workers/{chunk-GV56Q4LU.js → chunk-VOXYEYJT.js} +11 -11
- package/Build/Workers/{chunk-NY3K4IM3.js → chunk-X4356LRH.js} +12 -12
- package/Build/Workers/{chunk-S4MAZ3SS.js → chunk-XGI5BXZY.js} +2 -2
- package/Build/Workers/{chunk-UAEW6HKG.js → chunk-Y2ME2IJV.js} +13 -13
- package/Build/Workers/{chunk-XWXM2O2R.js → chunk-Y5UQJLYE.js} +6 -6
- package/Build/Workers/{chunk-QZAD5O7I.js → chunk-YJEBABKH.js} +7 -7
- package/Build/Workers/{chunk-UGK3FCDY.js → chunk-YWTJ2B4B.js} +1 -1
- package/Build/Workers/{chunk-R5X4OQT4.js → chunk-Z3TIFFGF.js} +7 -7
- package/Build/Workers/{chunk-WBQCVXR3.js → chunk-ZT7KWISZ.js} +4 -4
- package/Build/Workers/combineGeometry.js +24 -23
- package/Build/Workers/createBoxGeometry.js +18 -17
- package/Build/Workers/createBoxOutlineGeometry.js +16 -15
- package/Build/Workers/createCircleGeometry.js +26 -25
- package/Build/Workers/createCircleOutlineGeometry.js +19 -18
- package/Build/Workers/createCoplanarPolygonGeometry.js +33 -32
- package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -30
- package/Build/Workers/createCorridorGeometry.js +29 -28
- package/Build/Workers/createCorridorOutlineGeometry.js +28 -27
- package/Build/Workers/createCylinderGeometry.js +20 -19
- package/Build/Workers/createCylinderOutlineGeometry.js +18 -17
- package/Build/Workers/createEllipseGeometry.js +26 -25
- package/Build/Workers/createEllipseOutlineGeometry.js +19 -18
- package/Build/Workers/createEllipsoidGeometry.js +19 -18
- package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -17
- package/Build/Workers/createFrustumGeometry.js +18 -17
- package/Build/Workers/createFrustumOutlineGeometry.js +18 -17
- package/Build/Workers/createGeometry.js +54 -33
- package/Build/Workers/createGroundPolylineGeometry.js +22 -21
- package/Build/Workers/createPlaneGeometry.js +16 -15
- package/Build/Workers/createPlaneOutlineGeometry.js +15 -14
- package/Build/Workers/createPolygonGeometry.js +32 -31
- package/Build/Workers/createPolygonOutlineGeometry.js +30 -29
- package/Build/Workers/createPolylineGeometry.js +25 -24
- package/Build/Workers/createPolylineVolumeGeometry.js +31 -30
- package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -26
- package/Build/Workers/createRectangleGeometry.js +27 -26
- package/Build/Workers/createRectangleOutlineGeometry.js +20 -19
- package/Build/Workers/createSimplePolylineGeometry.js +23 -22
- package/Build/Workers/createSphereGeometry.js +19 -18
- package/Build/Workers/createSphereOutlineGeometry.js +18 -17
- package/Build/Workers/createTaskProcessorWorker.js +3 -3
- package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
- package/Build/Workers/createVectorTileGeometries.js +24 -23
- package/Build/Workers/createVectorTilePoints.js +12 -12
- package/Build/Workers/createVectorTilePolygons.js +22 -21
- package/Build/Workers/createVectorTilePolylines.js +14 -14
- package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -21
- package/Build/Workers/createVerticesFromHeightmap.js +22 -21
- package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +19 -18
- package/Build/Workers/createWallGeometry.js +24 -23
- package/Build/Workers/createWallOutlineGeometry.js +23 -22
- package/Build/Workers/decodeDraco.js +11 -11
- package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
- package/Build/Workers/decodeI3S.js +601 -92
- package/Build/Workers/transcodeKTX2.js +7 -7
- package/Build/Workers/transferTypedArrayTest.js +1 -1
- package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -21
- package/Source/Core/Ellipsoid.js +6 -0
- package/Source/Core/IntersectionTests.js +6 -3
- package/Source/Core/Ion.js +1 -1
- package/Source/Core/PixelFormat.js +5 -0
- package/Source/Core/Transforms.js +3 -0
- package/Source/Core/srgbToLinear.js +32 -0
- package/Source/DataSources/CzmlDataSource.js +51 -23
- package/Source/DataSources/DataSourceDisplay.js +27 -0
- package/Source/DataSources/Entity.js +20 -2
- package/Source/DataSources/GeometryUpdaterSet.js +114 -0
- package/Source/DataSources/GeometryVisualizer.js +19 -83
- package/Source/Renderer/Context.js +10 -0
- package/Source/Renderer/ContextLimits.js +2 -0
- package/Source/Renderer/demodernizeShader.js +4 -1
- package/Source/Scene/ArcGisMapService.js +1 -1
- package/Source/Scene/Axis.js +12 -7
- package/Source/Scene/Camera.js +46 -4
- package/Source/Scene/Cesium3DTileset.js +44 -6
- package/Source/Scene/Cesium3DTilesetBaseTraversal.js +2 -4
- package/Source/Scene/FrameState.js +5 -0
- package/Source/Scene/GlobeTranslucencyState.js +1 -1
- package/Source/Scene/GltfPipeline/updateVersion.js +69 -68
- package/Source/Scene/I3SDataProvider.js +270 -53
- package/Source/Scene/I3SDecoder.js +8 -1
- package/Source/Scene/I3SFeature.js +2 -5
- package/Source/Scene/I3SField.js +136 -31
- package/Source/Scene/I3SGeometry.js +70 -2
- package/Source/Scene/I3SLayer.js +55 -10
- package/Source/Scene/I3SNode.js +175 -18
- package/Source/Scene/I3SStatistics.js +94 -0
- package/Source/Scene/I3SSublayer.js +176 -0
- package/Source/Scene/I3SSymbology.js +337 -0
- package/Source/Scene/KeyframeNode.js +1 -1
- package/Source/Scene/Model/pickModel.js +25 -7
- package/Source/Scene/PickFramebuffer.js +37 -2
- package/Source/Scene/Picking.js +113 -39
- package/Source/Scene/Primitive.js +6 -2
- package/Source/Scene/Scene.js +126 -42
- package/Source/Scene/ScreenSpaceCameraController.js +21 -7
- package/Source/Scene/SensorVolumePortionToDisplay.js +69 -0
- package/Source/Scene/SpatialNode.js +12 -19
- package/Source/Scene/StructuralMetadata.js +1 -1
- package/Source/Scene/VoxelBoxShape.js +76 -0
- package/Source/Scene/VoxelCell.js +273 -0
- package/Source/Scene/VoxelCylinderShape.js +114 -43
- package/Source/Scene/VoxelEllipsoidShape.js +158 -116
- package/Source/Scene/VoxelPrimitive.js +3 -1
- package/Source/Scene/VoxelRenderResources.js +3 -0
- package/Source/Scene/VoxelShape.js +13 -0
- package/Source/Scene/VoxelTraversal.js +76 -54
- package/Source/Scene/buildVoxelDrawCommands.js +23 -0
- package/Source/Scene/createGooglePhotorealistic3DTileset.js +1 -0
- package/Source/Scene/processVoxelProperties.js +2 -0
- package/Source/Shaders/Voxels/IntersectCylinder.glsl +14 -111
- package/Source/Shaders/Voxels/IntersectCylinder.js +14 -111
- package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +32 -113
- package/Source/Shaders/Voxels/IntersectEllipsoid.js +32 -113
- package/Source/Shaders/Voxels/IntersectLongitude.glsl +102 -0
- package/Source/Shaders/Voxels/IntersectLongitude.js +104 -0
- package/Source/Shaders/Voxels/VoxelFS.glsl +39 -1
- package/Source/Shaders/Voxels/VoxelFS.js +39 -1
- package/Source/Shaders/Voxels/convertUvToCylinder.glsl +19 -37
- package/Source/Shaders/Voxels/convertUvToCylinder.js +19 -37
- package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +24 -44
- package/Source/Shaders/Voxels/convertUvToEllipsoid.js +24 -44
- package/Source/Workers/createGeometry.js +40 -11
- package/Source/Workers/decodeI3S.js +720 -94
- package/index.d.ts +296 -11
- package/index.js +102 -94
- package/package.json +1 -1
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import createTaskProcessorWorker from "./createTaskProcessorWorker.js";
|
|
2
|
+
import defaultValue from "../Core/defaultValue.js";
|
|
2
3
|
import defined from "../Core/defined.js";
|
|
3
4
|
import WebMercatorProjection from "../Core/WebMercatorProjection.js";
|
|
4
5
|
import Ellipsoid from "../Core/Ellipsoid.js";
|
|
5
6
|
import Cartographic from "../Core/Cartographic.js";
|
|
6
7
|
import Cartesian3 from "../Core/Cartesian3.js";
|
|
8
|
+
import Color from "../Core/Color.js";
|
|
7
9
|
import Matrix3 from "../Core/Matrix3.js";
|
|
8
10
|
import CesiumMath from "../Core/Math.js";
|
|
9
11
|
import dracoModule from "draco3d/draco_decoder_nodejs.js";
|
|
12
|
+
import srgbToLinear from "../Core/srgbToLinear.js";
|
|
10
13
|
|
|
11
14
|
let draco;
|
|
12
15
|
|
|
@@ -196,13 +199,440 @@ function cropUVs(vertexCount, uv0s, uvRegions) {
|
|
|
196
199
|
}
|
|
197
200
|
}
|
|
198
201
|
|
|
202
|
+
function generateIndexArray(
|
|
203
|
+
vertexCount,
|
|
204
|
+
indices,
|
|
205
|
+
colors,
|
|
206
|
+
splitGeometryByColorTransparency
|
|
207
|
+
) {
|
|
208
|
+
// Allocate array
|
|
209
|
+
const indexArray = new Uint32Array(vertexCount);
|
|
210
|
+
const vertexIndexFn = defined(indices)
|
|
211
|
+
? (vertexIndex) => indices[vertexIndex]
|
|
212
|
+
: (vertexIndex) => vertexIndex;
|
|
213
|
+
|
|
214
|
+
let transparentVertexOffset = 0;
|
|
215
|
+
if (splitGeometryByColorTransparency && defined(colors)) {
|
|
216
|
+
// The blending alpha mode for opaque colors is not rendered properly.
|
|
217
|
+
// If geometry contains both opaque and transparent colors we need to split vertices into two mesh primitives.
|
|
218
|
+
// Each mesh primitive could use a separate material with the specific alpha mode depending on the vertex trancparency.
|
|
219
|
+
const isVertexTransparentFn = (vertexIndex) =>
|
|
220
|
+
colors[vertexIndexFn(vertexIndex) * 4 + 3] < 255;
|
|
221
|
+
// Copy opaque vertices first
|
|
222
|
+
for (let vertexIndex = 0; vertexIndex < vertexCount; vertexIndex += 3) {
|
|
223
|
+
if (
|
|
224
|
+
!isVertexTransparentFn(vertexIndex) &&
|
|
225
|
+
!isVertexTransparentFn(vertexIndex + 1) &&
|
|
226
|
+
!isVertexTransparentFn(vertexIndex + 2)
|
|
227
|
+
) {
|
|
228
|
+
indexArray[transparentVertexOffset++] = vertexIndexFn(vertexIndex);
|
|
229
|
+
indexArray[transparentVertexOffset++] = vertexIndexFn(vertexIndex + 1);
|
|
230
|
+
indexArray[transparentVertexOffset++] = vertexIndexFn(vertexIndex + 2);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (transparentVertexOffset > 0) {
|
|
234
|
+
// Copy transparent vertices
|
|
235
|
+
let offset = transparentVertexOffset;
|
|
236
|
+
for (let vertexIndex = 0; vertexIndex < vertexCount; vertexIndex += 3) {
|
|
237
|
+
if (
|
|
238
|
+
isVertexTransparentFn(vertexIndex) ||
|
|
239
|
+
isVertexTransparentFn(vertexIndex + 1) ||
|
|
240
|
+
isVertexTransparentFn(vertexIndex + 2)
|
|
241
|
+
) {
|
|
242
|
+
indexArray[offset++] = vertexIndexFn(vertexIndex);
|
|
243
|
+
indexArray[offset++] = vertexIndexFn(vertexIndex + 1);
|
|
244
|
+
indexArray[offset++] = vertexIndexFn(vertexIndex + 2);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
// All vertices are tranparent
|
|
249
|
+
for (let vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) {
|
|
250
|
+
indexArray[vertexIndex] = vertexIndexFn(vertexIndex);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
// All vertices are considered opaque
|
|
255
|
+
transparentVertexOffset = vertexCount;
|
|
256
|
+
for (let vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) {
|
|
257
|
+
indexArray[vertexIndex] = vertexIndexFn(vertexIndex);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
indexArray: indexArray,
|
|
263
|
+
transparentVertexOffset: transparentVertexOffset,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function getFeatureHash(symbologyData, outlinesHash, featureIndex) {
|
|
268
|
+
const featureHash = outlinesHash[featureIndex];
|
|
269
|
+
if (defined(featureHash)) {
|
|
270
|
+
return featureHash;
|
|
271
|
+
}
|
|
272
|
+
const newFeatureHash = (outlinesHash[featureIndex] = {
|
|
273
|
+
positions: {},
|
|
274
|
+
indices: {},
|
|
275
|
+
edges: {},
|
|
276
|
+
});
|
|
277
|
+
const featureSymbology = defaultValue(
|
|
278
|
+
symbologyData[featureIndex],
|
|
279
|
+
symbologyData.default
|
|
280
|
+
);
|
|
281
|
+
newFeatureHash.hasOutline = defined(featureSymbology?.edges);
|
|
282
|
+
return newFeatureHash;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function addVertexToHash(indexHash, positionHash, vertexIndex, positions) {
|
|
286
|
+
if (!defined(indexHash[vertexIndex])) {
|
|
287
|
+
const startPositionIndex = vertexIndex * 3;
|
|
288
|
+
let coordinateHash = positionHash;
|
|
289
|
+
for (let index = 0; index < 3; index++) {
|
|
290
|
+
const coordinate = positions[startPositionIndex + index];
|
|
291
|
+
if (!defined(coordinateHash[coordinate])) {
|
|
292
|
+
coordinateHash[coordinate] = {};
|
|
293
|
+
}
|
|
294
|
+
coordinateHash = coordinateHash[coordinate];
|
|
295
|
+
}
|
|
296
|
+
if (!defined(coordinateHash.index)) {
|
|
297
|
+
coordinateHash.index = vertexIndex;
|
|
298
|
+
}
|
|
299
|
+
indexHash[vertexIndex] = coordinateHash.index;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function addEdgeToHash(
|
|
304
|
+
edgeHash,
|
|
305
|
+
vertexAIndex,
|
|
306
|
+
vertexBIndex,
|
|
307
|
+
vertexAIndexUnique,
|
|
308
|
+
vertexBIndexUnique,
|
|
309
|
+
normalIndex
|
|
310
|
+
) {
|
|
311
|
+
let startVertexIndex;
|
|
312
|
+
let endVertexIndex;
|
|
313
|
+
if (vertexAIndexUnique < vertexBIndexUnique) {
|
|
314
|
+
startVertexIndex = vertexAIndexUnique;
|
|
315
|
+
endVertexIndex = vertexBIndexUnique;
|
|
316
|
+
} else {
|
|
317
|
+
startVertexIndex = vertexBIndexUnique;
|
|
318
|
+
endVertexIndex = vertexAIndexUnique;
|
|
319
|
+
}
|
|
320
|
+
let edgeStart = edgeHash[startVertexIndex];
|
|
321
|
+
if (!defined(edgeStart)) {
|
|
322
|
+
edgeStart = edgeHash[startVertexIndex] = {};
|
|
323
|
+
}
|
|
324
|
+
let edgeEnd = edgeStart[endVertexIndex];
|
|
325
|
+
if (!defined(edgeEnd)) {
|
|
326
|
+
edgeEnd = edgeStart[endVertexIndex] = {
|
|
327
|
+
normalsIndex: [],
|
|
328
|
+
outlines: [],
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
edgeEnd.normalsIndex.push(normalIndex);
|
|
332
|
+
if (
|
|
333
|
+
edgeEnd.outlines.length === 0 ||
|
|
334
|
+
vertexAIndex !== vertexAIndexUnique ||
|
|
335
|
+
vertexBIndex !== vertexBIndexUnique
|
|
336
|
+
) {
|
|
337
|
+
edgeEnd.outlines.push(vertexAIndex, vertexBIndex);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function generateOutlinesHash(
|
|
342
|
+
symbologyData,
|
|
343
|
+
featureIndexArray,
|
|
344
|
+
indexArray,
|
|
345
|
+
positions
|
|
346
|
+
) {
|
|
347
|
+
const outlinesHash = [];
|
|
348
|
+
for (let i = 0; i < indexArray.length; i += 3) {
|
|
349
|
+
const featureIndex = defined(featureIndexArray)
|
|
350
|
+
? featureIndexArray[indexArray[i]]
|
|
351
|
+
: "default";
|
|
352
|
+
const featureHash = getFeatureHash(
|
|
353
|
+
symbologyData,
|
|
354
|
+
outlinesHash,
|
|
355
|
+
featureIndex
|
|
356
|
+
);
|
|
357
|
+
if (!featureHash.hasOutline) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const indexHash = featureHash.indices;
|
|
362
|
+
const positionHash = featureHash.positions;
|
|
363
|
+
for (let vertex = 0; vertex < 3; vertex++) {
|
|
364
|
+
const vertexIndex = indexArray[i + vertex];
|
|
365
|
+
addVertexToHash(indexHash, positionHash, vertexIndex, positions);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const edgeHash = featureHash.edges;
|
|
369
|
+
for (let vertex = 0; vertex < 3; vertex++) {
|
|
370
|
+
const vertexIndex = indexArray[i + vertex];
|
|
371
|
+
const nextVertexIndex = indexArray[i + ((vertex + 1) % 3)];
|
|
372
|
+
const uniqueVertexIndex = indexHash[vertexIndex];
|
|
373
|
+
const uniqueNextVertexIndex = indexHash[nextVertexIndex];
|
|
374
|
+
addEdgeToHash(
|
|
375
|
+
edgeHash,
|
|
376
|
+
vertexIndex,
|
|
377
|
+
nextVertexIndex,
|
|
378
|
+
uniqueVertexIndex,
|
|
379
|
+
uniqueNextVertexIndex,
|
|
380
|
+
i
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return outlinesHash;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const calculateFaceNormalA = new Cartesian3();
|
|
388
|
+
const calculateFaceNormalB = new Cartesian3();
|
|
389
|
+
const calculateFaceNormalC = new Cartesian3();
|
|
390
|
+
function calculateFaceNormal(normals, vertexAIndex, indexArray, positions) {
|
|
391
|
+
const positionAIndex = indexArray[vertexAIndex] * 3;
|
|
392
|
+
const positionBIndex = indexArray[vertexAIndex + 1] * 3;
|
|
393
|
+
const positionCIndex = indexArray[vertexAIndex + 2] * 3;
|
|
394
|
+
Cartesian3.fromArray(positions, positionAIndex, calculateFaceNormalA);
|
|
395
|
+
Cartesian3.fromArray(positions, positionBIndex, calculateFaceNormalB);
|
|
396
|
+
Cartesian3.fromArray(positions, positionCIndex, calculateFaceNormalC);
|
|
397
|
+
|
|
398
|
+
Cartesian3.subtract(
|
|
399
|
+
calculateFaceNormalB,
|
|
400
|
+
calculateFaceNormalA,
|
|
401
|
+
calculateFaceNormalB
|
|
402
|
+
);
|
|
403
|
+
Cartesian3.subtract(
|
|
404
|
+
calculateFaceNormalC,
|
|
405
|
+
calculateFaceNormalA,
|
|
406
|
+
calculateFaceNormalC
|
|
407
|
+
);
|
|
408
|
+
Cartesian3.cross(
|
|
409
|
+
calculateFaceNormalB,
|
|
410
|
+
calculateFaceNormalC,
|
|
411
|
+
calculateFaceNormalA
|
|
412
|
+
);
|
|
413
|
+
const magnitude = Cartesian3.magnitude(calculateFaceNormalA);
|
|
414
|
+
if (magnitude !== 0) {
|
|
415
|
+
Cartesian3.divideByScalar(
|
|
416
|
+
calculateFaceNormalA,
|
|
417
|
+
magnitude,
|
|
418
|
+
calculateFaceNormalA
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
const normalAIndex = vertexAIndex * 3;
|
|
422
|
+
const normalBIndex = (vertexAIndex + 1) * 3;
|
|
423
|
+
const normalCIndex = (vertexAIndex + 2) * 3;
|
|
424
|
+
Cartesian3.pack(calculateFaceNormalA, normals, normalAIndex);
|
|
425
|
+
Cartesian3.pack(calculateFaceNormalA, normals, normalBIndex);
|
|
426
|
+
Cartesian3.pack(calculateFaceNormalA, normals, normalCIndex);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const isEdgeSmoothA = new Cartesian3();
|
|
430
|
+
const isEdgeSmoothB = new Cartesian3();
|
|
431
|
+
function isEdgeSmooth(normals, normalAIndex, normalBIndex) {
|
|
432
|
+
Cartesian3.fromArray(normals, normalAIndex, isEdgeSmoothA);
|
|
433
|
+
Cartesian3.fromArray(normals, normalBIndex, isEdgeSmoothB);
|
|
434
|
+
const cosine = Cartesian3.dot(isEdgeSmoothA, isEdgeSmoothB);
|
|
435
|
+
const sine = Cartesian3.magnitude(
|
|
436
|
+
Cartesian3.cross(isEdgeSmoothA, isEdgeSmoothB, isEdgeSmoothA)
|
|
437
|
+
);
|
|
438
|
+
return Math.atan2(sine, cosine) < 0.25;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function addOutlinesForEdge(
|
|
442
|
+
outlines,
|
|
443
|
+
edgeData,
|
|
444
|
+
indexArray,
|
|
445
|
+
positions,
|
|
446
|
+
normals
|
|
447
|
+
) {
|
|
448
|
+
if (edgeData.normalsIndex.length > 1) {
|
|
449
|
+
const normalsByIndex = positions.length === normals.length;
|
|
450
|
+
for (let indexA = 0; indexA < edgeData.normalsIndex.length; indexA++) {
|
|
451
|
+
const vertexAIndex = edgeData.normalsIndex[indexA];
|
|
452
|
+
if (!defined(normals[vertexAIndex * 3])) {
|
|
453
|
+
calculateFaceNormal(normals, vertexAIndex, indexArray, positions);
|
|
454
|
+
}
|
|
455
|
+
if (indexA === 0) {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
for (let indexB = 0; indexB < indexA; indexB++) {
|
|
459
|
+
const vertexBIndex = edgeData.normalsIndex[indexB];
|
|
460
|
+
const normalAIndex = normalsByIndex
|
|
461
|
+
? indexArray[vertexAIndex] * 3
|
|
462
|
+
: vertexAIndex * 3;
|
|
463
|
+
const normalBIndex = normalsByIndex
|
|
464
|
+
? indexArray[vertexBIndex] * 3
|
|
465
|
+
: vertexBIndex * 3;
|
|
466
|
+
if (isEdgeSmooth(normals, normalAIndex, normalBIndex)) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
outlines.push(...edgeData.outlines);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function addOutlinesForFeature(
|
|
476
|
+
outlines,
|
|
477
|
+
edgeHash,
|
|
478
|
+
indexArray,
|
|
479
|
+
positions,
|
|
480
|
+
normals
|
|
481
|
+
) {
|
|
482
|
+
const edgeStartKeys = Object.keys(edgeHash);
|
|
483
|
+
for (let startIndex = 0; startIndex < edgeStartKeys.length; startIndex++) {
|
|
484
|
+
const edgeEnds = edgeHash[edgeStartKeys[startIndex]];
|
|
485
|
+
const edgeEndKeys = Object.keys(edgeEnds);
|
|
486
|
+
for (let endIndex = 0; endIndex < edgeEndKeys.length; endIndex++) {
|
|
487
|
+
const edgeData = edgeEnds[edgeEndKeys[endIndex]];
|
|
488
|
+
addOutlinesForEdge(outlines, edgeData, indexArray, positions, normals);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function generateOutlinesFromHash(
|
|
494
|
+
outlinesHash,
|
|
495
|
+
indexArray,
|
|
496
|
+
positions,
|
|
497
|
+
normals
|
|
498
|
+
) {
|
|
499
|
+
const outlines = [];
|
|
500
|
+
const features = Object.keys(outlinesHash);
|
|
501
|
+
for (let featureIndex = 0; featureIndex < features.length; featureIndex++) {
|
|
502
|
+
const edgeHash = outlinesHash[features[featureIndex]].edges;
|
|
503
|
+
addOutlinesForFeature(outlines, edgeHash, indexArray, positions, normals);
|
|
504
|
+
}
|
|
505
|
+
return outlines;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function generateOutlinesIndexArray(
|
|
509
|
+
symbologyData,
|
|
510
|
+
featureIndexArray,
|
|
511
|
+
indexArray,
|
|
512
|
+
positions,
|
|
513
|
+
normals
|
|
514
|
+
) {
|
|
515
|
+
if (!defined(symbologyData) || Object.keys(symbologyData).length === 0) {
|
|
516
|
+
return undefined;
|
|
517
|
+
}
|
|
518
|
+
const outlinesHash = generateOutlinesHash(
|
|
519
|
+
symbologyData,
|
|
520
|
+
featureIndexArray,
|
|
521
|
+
indexArray,
|
|
522
|
+
positions
|
|
523
|
+
);
|
|
524
|
+
if (!defined(normals) || indexArray.length * 3 !== normals.length) {
|
|
525
|
+
// Need to calculate flat normals per faces
|
|
526
|
+
normals = [];
|
|
527
|
+
}
|
|
528
|
+
const outlines = generateOutlinesFromHash(
|
|
529
|
+
outlinesHash,
|
|
530
|
+
indexArray,
|
|
531
|
+
positions,
|
|
532
|
+
normals
|
|
533
|
+
);
|
|
534
|
+
const outlinesIndexArray =
|
|
535
|
+
outlines.length > 0 ? new Uint32Array(outlines) : undefined;
|
|
536
|
+
return outlinesIndexArray;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function convertColorsArray(colors) {
|
|
540
|
+
// Colors are assumed to be normalized sRGB [0,255] while in glTF they are interpreted as linear.
|
|
541
|
+
// All values RGBA need to be stored as float to keep the precision after sRGB to linear conversion.
|
|
542
|
+
const colorsArray = new Float32Array(colors.length);
|
|
543
|
+
for (let index = 0; index < colors.length; index += 4) {
|
|
544
|
+
colorsArray[index] = srgbToLinear(Color.byteToFloat(colors[index]));
|
|
545
|
+
colorsArray[index + 1] = srgbToLinear(Color.byteToFloat(colors[index + 1]));
|
|
546
|
+
colorsArray[index + 2] = srgbToLinear(Color.byteToFloat(colors[index + 2]));
|
|
547
|
+
colorsArray[index + 3] = Color.byteToFloat(colors[index + 3]);
|
|
548
|
+
}
|
|
549
|
+
return colorsArray;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function generateNormals(
|
|
553
|
+
vertexCount,
|
|
554
|
+
indices,
|
|
555
|
+
positions,
|
|
556
|
+
normals,
|
|
557
|
+
uv0s,
|
|
558
|
+
colors,
|
|
559
|
+
featureIndex
|
|
560
|
+
) {
|
|
561
|
+
const result = {
|
|
562
|
+
normals: undefined,
|
|
563
|
+
positions: undefined,
|
|
564
|
+
uv0s: undefined,
|
|
565
|
+
colors: undefined,
|
|
566
|
+
featureIndex: undefined,
|
|
567
|
+
vertexCount: undefined,
|
|
568
|
+
};
|
|
569
|
+
if (
|
|
570
|
+
vertexCount === 0 ||
|
|
571
|
+
!defined(positions) ||
|
|
572
|
+
positions.length === 0 ||
|
|
573
|
+
defined(normals)
|
|
574
|
+
) {
|
|
575
|
+
return result;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if (defined(indices)) {
|
|
579
|
+
result.vertexCount = indices.length;
|
|
580
|
+
result.positions = new Float32Array(indices.length * 3);
|
|
581
|
+
result.uv0s = defined(uv0s)
|
|
582
|
+
? new Float32Array(indices.length * 2)
|
|
583
|
+
: undefined;
|
|
584
|
+
result.colors = defined(colors)
|
|
585
|
+
? new Uint8Array(indices.length * 4)
|
|
586
|
+
: undefined;
|
|
587
|
+
result.featureIndex = defined(featureIndex)
|
|
588
|
+
? new Array(indices.length)
|
|
589
|
+
: undefined;
|
|
590
|
+
for (let i = 0; i < indices.length; i++) {
|
|
591
|
+
const index = indices[i];
|
|
592
|
+
result.positions[i * 3] = positions[index * 3];
|
|
593
|
+
result.positions[i * 3 + 1] = positions[index * 3 + 1];
|
|
594
|
+
result.positions[i * 3 + 2] = positions[index * 3 + 2];
|
|
595
|
+
if (defined(result.uv0s)) {
|
|
596
|
+
result.uv0s[i * 2] = uv0s[index * 2];
|
|
597
|
+
result.uv0s[i * 2 + 1] = uv0s[index * 2 + 1];
|
|
598
|
+
}
|
|
599
|
+
if (defined(result.colors)) {
|
|
600
|
+
result.colors[i * 4] = colors[index * 4];
|
|
601
|
+
result.colors[i * 4 + 1] = colors[index * 4 + 1];
|
|
602
|
+
result.colors[i * 4 + 2] = colors[index * 4 + 2];
|
|
603
|
+
result.colors[i * 4 + 3] = colors[index * 4 + 3];
|
|
604
|
+
}
|
|
605
|
+
if (defined(result.featureIndex)) {
|
|
606
|
+
result.featureIndex[i] = featureIndex[index];
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
vertexCount = indices.length;
|
|
611
|
+
positions = result.positions;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
indices = new Array(vertexCount);
|
|
615
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
616
|
+
indices[i] = i;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
result.normals = new Float32Array(indices.length * 3);
|
|
620
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
621
|
+
calculateFaceNormal(result.normals, i, indices, positions);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return result;
|
|
625
|
+
}
|
|
626
|
+
|
|
199
627
|
function generateGltfBuffer(
|
|
200
628
|
vertexCount,
|
|
201
629
|
indices,
|
|
202
630
|
positions,
|
|
203
631
|
normals,
|
|
204
632
|
uv0s,
|
|
205
|
-
colors
|
|
633
|
+
colors,
|
|
634
|
+
featureIndex,
|
|
635
|
+
parameters
|
|
206
636
|
) {
|
|
207
637
|
if (vertexCount === 0 || !defined(positions) || positions.length === 0) {
|
|
208
638
|
return {
|
|
@@ -221,6 +651,8 @@ function generateGltfBuffer(
|
|
|
221
651
|
const meshes = [];
|
|
222
652
|
const nodes = [];
|
|
223
653
|
const nodesInScene = [];
|
|
654
|
+
const rootExtensions = {};
|
|
655
|
+
const extensionsUsed = [];
|
|
224
656
|
|
|
225
657
|
// If we provide indices, then the vertex count is the length
|
|
226
658
|
// of that array, otherwise we assume non-indexed triangle
|
|
@@ -228,24 +660,13 @@ function generateGltfBuffer(
|
|
|
228
660
|
vertexCount = indices.length;
|
|
229
661
|
}
|
|
230
662
|
|
|
231
|
-
//
|
|
232
|
-
const indexArray =
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
} else {
|
|
240
|
-
// Generate indices
|
|
241
|
-
for (
|
|
242
|
-
let newVertexIndex = 0;
|
|
243
|
-
newVertexIndex < vertexCount;
|
|
244
|
-
++newVertexIndex
|
|
245
|
-
) {
|
|
246
|
-
indexArray[newVertexIndex] = newVertexIndex;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
663
|
+
// Generate index array
|
|
664
|
+
const { indexArray, transparentVertexOffset } = generateIndexArray(
|
|
665
|
+
vertexCount,
|
|
666
|
+
indices,
|
|
667
|
+
colors,
|
|
668
|
+
parameters.splitGeometryByColorTransparency
|
|
669
|
+
);
|
|
249
670
|
|
|
250
671
|
// Push to the buffers, bufferViews and accessors
|
|
251
672
|
const indicesBlob = new Blob([indexArray], { type: "application/binary" });
|
|
@@ -253,6 +674,40 @@ function generateGltfBuffer(
|
|
|
253
674
|
|
|
254
675
|
const endIndex = vertexCount;
|
|
255
676
|
|
|
677
|
+
// Feature index array gives a higher level of detail, each feature object can be accessed separately
|
|
678
|
+
const featureIndexArray =
|
|
679
|
+
parameters.enableFeatures && defined(featureIndex)
|
|
680
|
+
? new Float32Array(featureIndex.length)
|
|
681
|
+
: undefined;
|
|
682
|
+
let featureCount = 0;
|
|
683
|
+
|
|
684
|
+
if (defined(featureIndexArray)) {
|
|
685
|
+
for (let index = 0; index < featureIndex.length; ++index) {
|
|
686
|
+
featureIndexArray[index] = featureIndex[index];
|
|
687
|
+
const countByIndex = featureIndex[index] + 1;
|
|
688
|
+
if (featureCount < countByIndex) {
|
|
689
|
+
// Feature count is defined by the maximum feature index
|
|
690
|
+
featureCount = countByIndex;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Outlines indices
|
|
696
|
+
let outlinesIndicesURL;
|
|
697
|
+
const outlinesIndexArray = generateOutlinesIndexArray(
|
|
698
|
+
parameters.symbologyData,
|
|
699
|
+
featureIndex,
|
|
700
|
+
indexArray,
|
|
701
|
+
positions,
|
|
702
|
+
normals
|
|
703
|
+
);
|
|
704
|
+
if (defined(outlinesIndexArray)) {
|
|
705
|
+
const outlinesIndicesBlob = new Blob([outlinesIndexArray], {
|
|
706
|
+
type: "application/binary",
|
|
707
|
+
});
|
|
708
|
+
outlinesIndicesURL = URL.createObjectURL(outlinesIndicesBlob);
|
|
709
|
+
}
|
|
710
|
+
|
|
256
711
|
// POSITIONS
|
|
257
712
|
const meshPositions = positions.subarray(0, endIndex * 3);
|
|
258
713
|
const positionsBlob = new Blob([meshPositions], {
|
|
@@ -296,7 +751,7 @@ function generateGltfBuffer(
|
|
|
296
751
|
|
|
297
752
|
// COLORS
|
|
298
753
|
const meshColorsInBytes = defined(colors)
|
|
299
|
-
? colors.subarray(0, endIndex * 4)
|
|
754
|
+
? convertColorsArray(colors.subarray(0, endIndex * 4))
|
|
300
755
|
: undefined;
|
|
301
756
|
let colorsURL;
|
|
302
757
|
if (defined(meshColorsInBytes)) {
|
|
@@ -306,33 +761,56 @@ function generateGltfBuffer(
|
|
|
306
761
|
colorsURL = URL.createObjectURL(colorsBlob);
|
|
307
762
|
}
|
|
308
763
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
764
|
+
// _FEATURE_ID_0
|
|
765
|
+
// The actual feature identifiers don't make much sense for reading attribute values, it is enough to use feature index
|
|
766
|
+
const meshFeatureId0 = defined(featureIndexArray)
|
|
767
|
+
? featureIndexArray.subarray(0, endIndex)
|
|
768
|
+
: undefined;
|
|
769
|
+
let featureId0URL;
|
|
770
|
+
if (defined(meshFeatureId0)) {
|
|
771
|
+
const featureId0Blob = new Blob([meshFeatureId0], {
|
|
772
|
+
type: "application/binary",
|
|
773
|
+
});
|
|
774
|
+
featureId0URL = URL.createObjectURL(featureId0Blob);
|
|
775
|
+
}
|
|
314
776
|
|
|
315
|
-
|
|
777
|
+
// Feature index property table
|
|
778
|
+
// This table has no practical use, but at least one property table is required to build a feature table
|
|
779
|
+
const meshPropertyTable0 = defined(featureIndexArray)
|
|
780
|
+
? new Float32Array(featureCount)
|
|
781
|
+
: undefined;
|
|
782
|
+
let propertyTable0URL;
|
|
783
|
+
if (defined(meshPropertyTable0)) {
|
|
784
|
+
// This table just maps the feature index to itself
|
|
785
|
+
for (let index = 0; index < meshPropertyTable0.length; ++index) {
|
|
786
|
+
meshPropertyTable0[index] = index;
|
|
787
|
+
}
|
|
788
|
+
const propertyTable0Blob = new Blob([meshPropertyTable0], {
|
|
789
|
+
type: "application/binary",
|
|
790
|
+
});
|
|
791
|
+
propertyTable0URL = URL.createObjectURL(propertyTable0Blob);
|
|
792
|
+
}
|
|
316
793
|
|
|
317
794
|
const attributes = {};
|
|
795
|
+
const extensions = {};
|
|
318
796
|
|
|
319
797
|
// POSITIONS
|
|
320
|
-
attributes.POSITION =
|
|
798
|
+
attributes.POSITION = accessors.length;
|
|
321
799
|
buffers.push({
|
|
322
800
|
uri: positionsURL,
|
|
323
801
|
byteLength: meshPositions.byteLength,
|
|
324
802
|
});
|
|
325
803
|
bufferViews.push({
|
|
326
|
-
buffer:
|
|
804
|
+
buffer: buffers.length - 1,
|
|
327
805
|
byteOffset: 0,
|
|
328
806
|
byteLength: meshPositions.byteLength,
|
|
329
807
|
target: 34962,
|
|
330
808
|
});
|
|
331
809
|
accessors.push({
|
|
332
|
-
bufferView:
|
|
810
|
+
bufferView: bufferViews.length - 1,
|
|
333
811
|
byteOffset: 0,
|
|
334
812
|
componentType: 5126,
|
|
335
|
-
count:
|
|
813
|
+
count: meshPositions.length / 3,
|
|
336
814
|
type: "VEC3",
|
|
337
815
|
max: [minX, minY, minZ],
|
|
338
816
|
min: [maxX, maxY, maxZ],
|
|
@@ -340,107 +818,230 @@ function generateGltfBuffer(
|
|
|
340
818
|
|
|
341
819
|
// NORMALS
|
|
342
820
|
if (defined(normalsURL)) {
|
|
343
|
-
|
|
344
|
-
normalIndex = currentIndex;
|
|
345
|
-
attributes.NORMAL = normalIndex;
|
|
821
|
+
attributes.NORMAL = accessors.length;
|
|
346
822
|
buffers.push({
|
|
347
823
|
uri: normalsURL,
|
|
348
824
|
byteLength: meshNormals.byteLength,
|
|
349
825
|
});
|
|
350
826
|
bufferViews.push({
|
|
351
|
-
buffer:
|
|
827
|
+
buffer: buffers.length - 1,
|
|
352
828
|
byteOffset: 0,
|
|
353
829
|
byteLength: meshNormals.byteLength,
|
|
354
830
|
target: 34962,
|
|
355
831
|
});
|
|
356
832
|
accessors.push({
|
|
357
|
-
bufferView:
|
|
833
|
+
bufferView: bufferViews.length - 1,
|
|
358
834
|
byteOffset: 0,
|
|
359
835
|
componentType: 5126,
|
|
360
|
-
count:
|
|
836
|
+
count: meshNormals.length / 3,
|
|
361
837
|
type: "VEC3",
|
|
362
838
|
});
|
|
363
839
|
}
|
|
364
840
|
|
|
365
841
|
// UV0
|
|
366
842
|
if (defined(uv0URL)) {
|
|
367
|
-
|
|
368
|
-
uv0Index = currentIndex;
|
|
369
|
-
attributes.TEXCOORD_0 = uv0Index;
|
|
843
|
+
attributes.TEXCOORD_0 = accessors.length;
|
|
370
844
|
buffers.push({
|
|
371
845
|
uri: uv0URL,
|
|
372
846
|
byteLength: meshUv0s.byteLength,
|
|
373
847
|
});
|
|
374
848
|
bufferViews.push({
|
|
375
|
-
buffer:
|
|
849
|
+
buffer: buffers.length - 1,
|
|
376
850
|
byteOffset: 0,
|
|
377
851
|
byteLength: meshUv0s.byteLength,
|
|
378
852
|
target: 34962,
|
|
379
853
|
});
|
|
380
854
|
accessors.push({
|
|
381
|
-
bufferView:
|
|
855
|
+
bufferView: bufferViews.length - 1,
|
|
382
856
|
byteOffset: 0,
|
|
383
857
|
componentType: 5126,
|
|
384
|
-
count:
|
|
858
|
+
count: meshUv0s.length / 2,
|
|
385
859
|
type: "VEC2",
|
|
386
860
|
});
|
|
387
861
|
}
|
|
388
862
|
|
|
389
863
|
// COLORS
|
|
390
864
|
if (defined(colorsURL)) {
|
|
391
|
-
|
|
392
|
-
colorIndex = currentIndex;
|
|
393
|
-
attributes.COLOR_0 = colorIndex;
|
|
865
|
+
attributes.COLOR_0 = accessors.length;
|
|
394
866
|
buffers.push({
|
|
395
867
|
uri: colorsURL,
|
|
396
868
|
byteLength: meshColorsInBytes.byteLength,
|
|
397
869
|
});
|
|
398
870
|
bufferViews.push({
|
|
399
|
-
buffer:
|
|
871
|
+
buffer: buffers.length - 1,
|
|
400
872
|
byteOffset: 0,
|
|
401
873
|
byteLength: meshColorsInBytes.byteLength,
|
|
402
874
|
target: 34962,
|
|
403
875
|
});
|
|
404
876
|
accessors.push({
|
|
405
|
-
bufferView:
|
|
877
|
+
bufferView: bufferViews.length - 1,
|
|
406
878
|
byteOffset: 0,
|
|
407
|
-
componentType:
|
|
408
|
-
|
|
409
|
-
count: vertexCount,
|
|
879
|
+
componentType: 5126,
|
|
880
|
+
count: meshColorsInBytes.length / 4,
|
|
410
881
|
type: "VEC4",
|
|
411
882
|
});
|
|
412
883
|
}
|
|
413
884
|
|
|
885
|
+
// _FEATURE_ID_0
|
|
886
|
+
if (defined(featureId0URL)) {
|
|
887
|
+
attributes._FEATURE_ID_0 = accessors.length;
|
|
888
|
+
buffers.push({
|
|
889
|
+
uri: featureId0URL,
|
|
890
|
+
byteLength: meshFeatureId0.byteLength,
|
|
891
|
+
});
|
|
892
|
+
bufferViews.push({
|
|
893
|
+
buffer: buffers.length - 1,
|
|
894
|
+
byteOffset: 0,
|
|
895
|
+
byteLength: meshFeatureId0.byteLength,
|
|
896
|
+
target: 34963,
|
|
897
|
+
});
|
|
898
|
+
accessors.push({
|
|
899
|
+
bufferView: bufferViews.length - 1,
|
|
900
|
+
byteOffset: 0,
|
|
901
|
+
componentType: 5126,
|
|
902
|
+
count: meshFeatureId0.length,
|
|
903
|
+
type: "SCALAR",
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
// Mesh features extension associates feature ids by vertex
|
|
907
|
+
extensions.EXT_mesh_features = {
|
|
908
|
+
featureIds: [
|
|
909
|
+
{
|
|
910
|
+
attribute: 0,
|
|
911
|
+
propertyTable: 0,
|
|
912
|
+
featureCount: featureCount,
|
|
913
|
+
},
|
|
914
|
+
],
|
|
915
|
+
};
|
|
916
|
+
extensionsUsed.push("EXT_mesh_features");
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// Feature index property table
|
|
920
|
+
if (defined(propertyTable0URL)) {
|
|
921
|
+
buffers.push({
|
|
922
|
+
uri: propertyTable0URL,
|
|
923
|
+
byteLength: meshPropertyTable0.byteLength,
|
|
924
|
+
});
|
|
925
|
+
bufferViews.push({
|
|
926
|
+
buffer: buffers.length - 1,
|
|
927
|
+
byteOffset: 0,
|
|
928
|
+
byteLength: meshPropertyTable0.byteLength,
|
|
929
|
+
target: 34963,
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
rootExtensions.EXT_structural_metadata = {
|
|
933
|
+
schema: {
|
|
934
|
+
id: "i3s-metadata-schema-001",
|
|
935
|
+
name: "I3S metadata schema 001",
|
|
936
|
+
description: "The schema for I3S metadata",
|
|
937
|
+
version: "1.0",
|
|
938
|
+
classes: {
|
|
939
|
+
feature: {
|
|
940
|
+
name: "feature",
|
|
941
|
+
description: "Feature metadata",
|
|
942
|
+
properties: {
|
|
943
|
+
index: {
|
|
944
|
+
description: "The feature index",
|
|
945
|
+
type: "SCALAR",
|
|
946
|
+
componentType: "FLOAT32",
|
|
947
|
+
required: true,
|
|
948
|
+
},
|
|
949
|
+
},
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
},
|
|
953
|
+
propertyTables: [
|
|
954
|
+
{
|
|
955
|
+
name: "feature-indices-mapping",
|
|
956
|
+
class: "feature",
|
|
957
|
+
count: featureCount,
|
|
958
|
+
properties: {
|
|
959
|
+
index: {
|
|
960
|
+
values: bufferViews.length - 1,
|
|
961
|
+
},
|
|
962
|
+
},
|
|
963
|
+
},
|
|
964
|
+
],
|
|
965
|
+
};
|
|
966
|
+
extensionsUsed.push("EXT_structural_metadata");
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// Outlines indices
|
|
970
|
+
if (defined(outlinesIndicesURL)) {
|
|
971
|
+
buffers.push({
|
|
972
|
+
uri: outlinesIndicesURL,
|
|
973
|
+
byteLength: outlinesIndexArray.byteLength,
|
|
974
|
+
});
|
|
975
|
+
bufferViews.push({
|
|
976
|
+
buffer: buffers.length - 1,
|
|
977
|
+
byteOffset: 0,
|
|
978
|
+
byteLength: outlinesIndexArray.byteLength,
|
|
979
|
+
target: 34963,
|
|
980
|
+
});
|
|
981
|
+
accessors.push({
|
|
982
|
+
bufferView: bufferViews.length - 1,
|
|
983
|
+
byteOffset: 0,
|
|
984
|
+
componentType: 5125,
|
|
985
|
+
count: outlinesIndexArray.length,
|
|
986
|
+
type: "SCALAR",
|
|
987
|
+
});
|
|
988
|
+
extensions.CESIUM_primitive_outline = {
|
|
989
|
+
indices: accessors.length - 1,
|
|
990
|
+
};
|
|
991
|
+
extensionsUsed.push("CESIUM_primitive_outline");
|
|
992
|
+
}
|
|
993
|
+
|
|
414
994
|
// INDICES
|
|
415
|
-
++currentIndex;
|
|
416
|
-
indicesIndex = currentIndex;
|
|
417
995
|
buffers.push({
|
|
418
996
|
uri: indicesURL,
|
|
419
997
|
byteLength: indexArray.byteLength,
|
|
420
998
|
});
|
|
421
999
|
bufferViews.push({
|
|
422
|
-
buffer:
|
|
1000
|
+
buffer: buffers.length - 1,
|
|
423
1001
|
byteOffset: 0,
|
|
424
1002
|
byteLength: indexArray.byteLength,
|
|
425
1003
|
target: 34963,
|
|
426
1004
|
});
|
|
427
|
-
accessors.push({
|
|
428
|
-
bufferView: indicesIndex,
|
|
429
|
-
byteOffset: 0,
|
|
430
|
-
componentType: 5125,
|
|
431
|
-
count: vertexCount,
|
|
432
|
-
type: "SCALAR",
|
|
433
|
-
});
|
|
434
1005
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
1006
|
+
const meshPrimitives = [];
|
|
1007
|
+
if (transparentVertexOffset > 0) {
|
|
1008
|
+
// Add opaque mesh primitive
|
|
1009
|
+
accessors.push({
|
|
1010
|
+
bufferView: bufferViews.length - 1,
|
|
1011
|
+
byteOffset: 0,
|
|
1012
|
+
componentType: 5125,
|
|
1013
|
+
count: transparentVertexOffset,
|
|
1014
|
+
type: "SCALAR",
|
|
1015
|
+
});
|
|
1016
|
+
meshPrimitives.push({
|
|
1017
|
+
attributes: attributes,
|
|
1018
|
+
indices: accessors.length - 1,
|
|
1019
|
+
material: meshPrimitives.length,
|
|
1020
|
+
extensions: extensions,
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
if (transparentVertexOffset < vertexCount) {
|
|
1024
|
+
// Add transparent mesh primitive
|
|
1025
|
+
accessors.push({
|
|
1026
|
+
bufferView: bufferViews.length - 1,
|
|
1027
|
+
byteOffset: 4 * transparentVertexOffset, // skip 4 bytes for each opaque vertex
|
|
1028
|
+
componentType: 5125,
|
|
1029
|
+
count: vertexCount - transparentVertexOffset,
|
|
1030
|
+
type: "SCALAR",
|
|
1031
|
+
});
|
|
1032
|
+
// Indicate the vertices transparancy for the mesh primitive
|
|
1033
|
+
meshPrimitives.push({
|
|
1034
|
+
attributes: attributes,
|
|
1035
|
+
indices: accessors.length - 1,
|
|
1036
|
+
material: meshPrimitives.length,
|
|
1037
|
+
extensions: extensions,
|
|
1038
|
+
extra: {
|
|
1039
|
+
isTransparent: true,
|
|
442
1040
|
},
|
|
443
|
-
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
meshes.push({
|
|
1044
|
+
primitives: meshPrimitives,
|
|
444
1045
|
});
|
|
445
1046
|
nodesInScene.push(0);
|
|
446
1047
|
nodes.push({ mesh: 0 });
|
|
@@ -452,6 +1053,8 @@ function generateGltfBuffer(
|
|
|
452
1053
|
meshes: meshes,
|
|
453
1054
|
nodes: nodes,
|
|
454
1055
|
nodesInScene: nodesInScene,
|
|
1056
|
+
rootExtensions: rootExtensions,
|
|
1057
|
+
extensionsUsed: extensionsUsed,
|
|
455
1058
|
};
|
|
456
1059
|
}
|
|
457
1060
|
|
|
@@ -954,32 +1557,12 @@ function decodeAndCreateGltf(parameters) {
|
|
|
954
1557
|
);
|
|
955
1558
|
}
|
|
956
1559
|
|
|
957
|
-
|
|
958
|
-
const meshData = generateGltfBuffer(
|
|
959
|
-
geometryData.vertexCount,
|
|
960
|
-
geometryData.indices,
|
|
961
|
-
geometryData.positions,
|
|
962
|
-
geometryData.normals,
|
|
963
|
-
geometryData.uv0s,
|
|
964
|
-
geometryData.colors
|
|
965
|
-
);
|
|
966
|
-
|
|
967
|
-
const customAttributes = {};
|
|
1560
|
+
let featureIndex;
|
|
968
1561
|
if (defined(geometryData["feature-index"])) {
|
|
969
|
-
|
|
970
|
-
customAttributes.indices = geometryData.indices;
|
|
971
|
-
customAttributes.featureIndex = geometryData["feature-index"];
|
|
972
|
-
customAttributes.cartesianCenter = parameters.cartesianCenter;
|
|
973
|
-
customAttributes.parentRotation = parameters.parentRotation;
|
|
1562
|
+
featureIndex = geometryData["feature-index"];
|
|
974
1563
|
} else if (defined(geometryData["faceRange"])) {
|
|
975
|
-
customAttributes.positions = geometryData.positions;
|
|
976
|
-
customAttributes.indices = geometryData.indices;
|
|
977
|
-
customAttributes.sourceURL = parameters.url;
|
|
978
|
-
customAttributes.cartesianCenter = parameters.cartesianCenter;
|
|
979
|
-
customAttributes.parentRotation = parameters.parentRotation;
|
|
980
|
-
|
|
981
1564
|
// Build the feature index array from the faceRange.
|
|
982
|
-
|
|
1565
|
+
featureIndex = new Array(geometryData.vertexCount);
|
|
983
1566
|
for (
|
|
984
1567
|
let range = 0;
|
|
985
1568
|
range < geometryData["faceRange"].length - 1;
|
|
@@ -989,13 +1572,56 @@ function decodeAndCreateGltf(parameters) {
|
|
|
989
1572
|
const rangeStart = geometryData["faceRange"][range];
|
|
990
1573
|
const rangeEnd = geometryData["faceRange"][range + 1];
|
|
991
1574
|
for (let i = rangeStart; i <= rangeEnd; i++) {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1575
|
+
featureIndex[i * 3] = curIndex;
|
|
1576
|
+
featureIndex[i * 3 + 1] = curIndex;
|
|
1577
|
+
featureIndex[i * 3 + 2] = curIndex;
|
|
995
1578
|
}
|
|
996
1579
|
}
|
|
997
1580
|
}
|
|
998
1581
|
|
|
1582
|
+
if (parameters.calculateNormals) {
|
|
1583
|
+
const data = generateNormals(
|
|
1584
|
+
geometryData.vertexCount,
|
|
1585
|
+
geometryData.indices,
|
|
1586
|
+
geometryData.positions,
|
|
1587
|
+
geometryData.normals,
|
|
1588
|
+
geometryData.uv0s,
|
|
1589
|
+
geometryData.colors,
|
|
1590
|
+
featureIndex
|
|
1591
|
+
);
|
|
1592
|
+
if (defined(data.normals)) {
|
|
1593
|
+
geometryData.normals = data.normals;
|
|
1594
|
+
if (defined(data.vertexCount)) {
|
|
1595
|
+
geometryData.vertexCount = data.vertexCount;
|
|
1596
|
+
geometryData.indices = data.indices;
|
|
1597
|
+
geometryData.positions = data.positions;
|
|
1598
|
+
geometryData.uv0s = data.uv0s;
|
|
1599
|
+
geometryData.colors = data.colors;
|
|
1600
|
+
featureIndex = data.featureIndex;
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
// Create the final buffer
|
|
1606
|
+
const meshData = generateGltfBuffer(
|
|
1607
|
+
geometryData.vertexCount,
|
|
1608
|
+
geometryData.indices,
|
|
1609
|
+
geometryData.positions,
|
|
1610
|
+
geometryData.normals,
|
|
1611
|
+
geometryData.uv0s,
|
|
1612
|
+
geometryData.colors,
|
|
1613
|
+
featureIndex,
|
|
1614
|
+
parameters
|
|
1615
|
+
);
|
|
1616
|
+
|
|
1617
|
+
const customAttributes = {
|
|
1618
|
+
positions: geometryData.positions,
|
|
1619
|
+
indices: geometryData.indices,
|
|
1620
|
+
featureIndex: featureIndex,
|
|
1621
|
+
sourceURL: parameters.url,
|
|
1622
|
+
cartesianCenter: parameters.cartesianCenter,
|
|
1623
|
+
parentRotation: parameters.parentRotation,
|
|
1624
|
+
};
|
|
999
1625
|
meshData._customAttributes = customAttributes;
|
|
1000
1626
|
|
|
1001
1627
|
const results = {
|