@cesium/engine 17.0.0 → 18.0.1-splats.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/ThirdParty/Workers/z-worker-pako.js +1 -1
- package/Build/Workers/{chunk-UC7KH56Y.js → chunk-2AXKROJA.js} +5 -5
- package/Build/Workers/{chunk-IKDQX7DY.js → chunk-2J5ZZ7CY.js} +4 -4
- package/Build/Workers/{chunk-4TIR5UPL.js → chunk-2SYY3UBI.js} +1 -1
- package/Build/Workers/{chunk-CC2WKHIW.js → chunk-2WKW3BEB.js} +6 -6
- package/Build/Workers/{chunk-CBFJVM6I.js → chunk-2ZO6BCHN.js} +11 -11
- package/Build/Workers/{chunk-7PHT4JHA.js → chunk-3UKG5X7F.js} +12 -12
- package/Build/Workers/{chunk-PM4Q36WX.js → chunk-4GYIDPXP.js} +9 -9
- package/Build/Workers/{chunk-QUFN3GEO.js → chunk-6EP7ED36.js} +3 -3
- package/Build/Workers/{chunk-QJTIOB2Z.js → chunk-6QOBORNG.js} +6 -6
- package/Build/Workers/{chunk-YE6MDFDA.js → chunk-6WWHK2ER.js} +14 -14
- package/Build/Workers/{chunk-RX65FA7X.js → chunk-6Y6TVYHS.js} +7 -7
- package/Build/Workers/{chunk-P2N5IDWU.js → chunk-744VWE2U.js} +13 -13
- package/Build/Workers/{chunk-LVGYWPEX.js → chunk-7PQ52XCW.js} +4 -4
- package/Build/Workers/{chunk-PS3OKVOQ.js → chunk-A5UFJW2M.js} +12 -12
- package/Build/Workers/{chunk-CAKU6ZPR.js → chunk-AQKVFTWV.js} +8 -8
- package/Build/Workers/{chunk-236N6BJN.js → chunk-BKTEHJFD.js} +2 -2
- package/Build/Workers/{chunk-5PC577K7.js → chunk-CQXYKPAW.js} +16 -16
- package/Build/Workers/{chunk-DRMXU674.js → chunk-DI7PHKC6.js} +5 -5
- package/Build/Workers/{chunk-CQMXZF4A.js → chunk-DKKIQS6F.js} +6 -6
- package/Build/Workers/{chunk-J2HTPGC7.js → chunk-DTVWE5YL.js} +2 -2
- package/Build/Workers/{chunk-SSLK4U3V.js → chunk-ERPS2WZC.js} +4 -4
- package/Build/Workers/chunk-EYMZ5FSQ.js +280 -0
- package/Build/Workers/{chunk-LPGOAMYH.js → chunk-F43TQW5B.js} +2 -2
- package/Build/Workers/{chunk-5RPUEFSA.js → chunk-FOMRN6II.js} +6 -6
- package/Build/Workers/{chunk-2BJXFXD7.js → chunk-FOTXJYKS.js} +4 -4
- package/Build/Workers/{chunk-VXAKU6EV.js → chunk-G2Y7EA4W.js} +5 -5
- package/Build/Workers/{chunk-KE45DUDH.js → chunk-GY4E4ZP6.js} +10 -10
- package/Build/Workers/{chunk-NZSBSY5K.js → chunk-HDG3VHYL.js} +2 -2
- package/Build/Workers/{chunk-WP3IJYLC.js → chunk-HOEUXPBL.js} +9 -9
- package/Build/Workers/{chunk-5YEFZMMM.js → chunk-IWDYVJ56.js} +12 -12
- package/Build/Workers/{chunk-SQKTLDSD.js → chunk-JA4KPQJL.js} +12 -12
- package/Build/Workers/{chunk-MAIKDIBS.js → chunk-JZZQEZMA.js} +6 -6
- package/Build/Workers/{chunk-77MDEA47.js → chunk-KPLU3WDY.js} +5 -5
- package/Build/Workers/{chunk-E7SMO47Q.js → chunk-LHM6V4D6.js} +5 -5
- package/Build/Workers/{chunk-HBNWBMAM.js → chunk-LMTGCD6P.js} +1 -1
- package/Build/Workers/{chunk-XYGBWBD5.js → chunk-LWZOYSSF.js} +1 -1
- package/Build/Workers/{chunk-OBHLT34A.js → chunk-M6U7SV4T.js} +7 -7
- package/Build/Workers/{chunk-MS5NWDHH.js → chunk-O25M56DO.js} +2 -2
- package/Build/Workers/{chunk-UX5JWAC7.js → chunk-OE2WXO2Z.js} +10 -10
- package/Build/Workers/{chunk-C5DCX2YQ.js → chunk-PFD462OE.js} +6 -6
- package/Build/Workers/{chunk-37PA7GZW.js → chunk-PPI33PXH.js} +7 -7
- package/Build/Workers/{chunk-4BGKMM7J.js → chunk-PRQQHLUB.js} +1 -1
- package/Build/Workers/{chunk-IFIS4CVK.js → chunk-RTUZ7MJB.js} +2 -2
- package/Build/Workers/{chunk-G6JUXZUO.js → chunk-S6QBTP5U.js} +4 -4
- package/Build/Workers/{chunk-UFV3YUIN.js → chunk-SMFCIGM3.js} +5 -5
- package/Build/Workers/{chunk-P57PR3WM.js → chunk-TC3LEKFJ.js} +5 -5
- package/Build/Workers/{chunk-7IIMO7ZZ.js → chunk-UTLYCPFY.js} +16 -16
- package/Build/Workers/{chunk-HGEGZ67N.js → chunk-V7LEBY53.js} +6 -6
- package/Build/Workers/{chunk-GO3RZX2R.js → chunk-VE3UKRDB.js} +9 -9
- package/Build/Workers/{chunk-ZTBZMRQT.js → chunk-W3FBD4FE.js} +8 -8
- package/Build/Workers/{chunk-K5JTWJPE.js → chunk-YRR6CJGG.js} +4 -4
- package/Build/Workers/{chunk-UZ6KXWCA.js → chunk-ZVTKMLU6.js} +4 -4
- package/Build/Workers/combineGeometry.js +21 -21
- package/Build/Workers/createBoxGeometry.js +15 -15
- package/Build/Workers/createBoxOutlineGeometry.js +13 -13
- package/Build/Workers/createCircleGeometry.js +23 -23
- package/Build/Workers/createCircleOutlineGeometry.js +16 -16
- package/Build/Workers/createCoplanarPolygonGeometry.js +30 -30
- package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +28 -28
- package/Build/Workers/createCorridorGeometry.js +26 -26
- package/Build/Workers/createCorridorOutlineGeometry.js +25 -25
- package/Build/Workers/createCylinderGeometry.js +17 -17
- package/Build/Workers/createCylinderOutlineGeometry.js +15 -15
- package/Build/Workers/createEllipseGeometry.js +23 -23
- package/Build/Workers/createEllipseOutlineGeometry.js +16 -16
- package/Build/Workers/createEllipsoidGeometry.js +16 -16
- package/Build/Workers/createEllipsoidOutlineGeometry.js +15 -15
- package/Build/Workers/createFrustumGeometry.js +15 -15
- package/Build/Workers/createFrustumOutlineGeometry.js +15 -15
- package/Build/Workers/createGeometry.js +23 -21
- package/Build/Workers/createGroundPolylineGeometry.js +19 -19
- package/Build/Workers/createPlaneGeometry.js +13 -13
- package/Build/Workers/createPlaneOutlineGeometry.js +12 -12
- package/Build/Workers/createPolygonGeometry.js +29 -29
- package/Build/Workers/createPolygonOutlineGeometry.js +27 -27
- package/Build/Workers/createPolylineGeometry.js +22 -22
- package/Build/Workers/createPolylineVolumeGeometry.js +28 -28
- package/Build/Workers/createPolylineVolumeOutlineGeometry.js +24 -24
- package/Build/Workers/createRectangleGeometry.js +24 -24
- package/Build/Workers/createRectangleOutlineGeometry.js +17 -17
- package/Build/Workers/createSimplePolylineGeometry.js +20 -20
- package/Build/Workers/createSphereGeometry.js +16 -16
- package/Build/Workers/createSphereOutlineGeometry.js +15 -15
- package/Build/Workers/createTaskProcessorWorker.js +3 -3
- package/Build/Workers/createVectorTileClampedPolylines.js +12 -12
- package/Build/Workers/createVectorTileGeometries.js +21 -21
- package/Build/Workers/createVectorTilePoints.js +11 -11
- package/Build/Workers/createVectorTilePolygons.js +19 -19
- package/Build/Workers/createVectorTilePolylines.js +12 -12
- package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +19 -19
- package/Build/Workers/createVerticesFromHeightmap.js +19 -19
- package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +16 -16
- package/Build/Workers/createWallGeometry.js +21 -21
- package/Build/Workers/createWallOutlineGeometry.js +20 -20
- package/Build/Workers/decodeDraco.js +10 -10
- package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
- package/Build/Workers/decodeI3S.js +9 -9
- package/Build/Workers/gaussianSplatSorter.js +62 -0
- package/Build/Workers/gaussianSplatTextureGenerator.js +68 -0
- package/Build/Workers/transcodeKTX2.js +78 -7
- package/Build/Workers/transferTypedArrayTest.js +1 -1
- package/Build/Workers/upsampleQuantizedTerrainMesh.js +19 -19
- package/Source/Core/Ion.js +1 -1
- package/Source/Core/PixelFormat.js +98 -0
- package/Source/Renderer/Context.js +2 -0
- package/Source/Renderer/Pass.js +3 -2
- package/Source/Renderer/Texture.js +1 -0
- package/Source/Renderer/Texture3D.js +568 -0
- package/Source/Renderer/VertexArray.js +33 -8
- package/Source/Renderer/createUniform.js +3 -0
- package/Source/Renderer/createUniformArray.js +1 -0
- package/Source/Scene/ArcGisMapService.js +1 -1
- package/Source/Scene/Cesium3DTileContentFactory.js +23 -0
- package/Source/Scene/Cesium3DTileset.js +197 -2
- package/Source/Scene/GaussianSplat3DTileContent.js +504 -0
- package/Source/Scene/GaussianSplatPrimitive.js +932 -0
- package/Source/Scene/GaussianSplatRenderResources.js +81 -0
- package/Source/Scene/GaussianSplatSorter.js +73 -0
- package/Source/Scene/GaussianSplatTextureGenerator.js +64 -0
- package/Source/Scene/GlobeSurfaceShaderSet.js +4 -5
- package/Source/Scene/GltfLoader.js +82 -4
- package/Source/Scene/GltfSpzLoader.js +222 -0
- package/Source/Scene/GltfVertexBufferLoader.js +98 -3
- package/Source/Scene/ImageryLayer.js +19 -4
- package/Source/Scene/ImageryLayerCollection.js +3 -2
- package/Source/Scene/Model/CartesianRectangle.js +108 -0
- package/Source/Scene/Model/ImageryConfiguration.js +25 -0
- package/Source/Scene/Model/ImageryCoverage.js +488 -0
- package/Source/Scene/Model/ImageryFlags.js +31 -0
- package/Source/Scene/Model/ImageryInput.js +60 -0
- package/Source/Scene/Model/ImageryPipelineStage.js +1040 -0
- package/Source/Scene/Model/MappedPositions.js +84 -0
- package/Source/Scene/Model/Model.js +38 -0
- package/Source/Scene/Model/ModelImagery.js +403 -0
- package/Source/Scene/Model/ModelImageryMapping.js +489 -0
- package/Source/Scene/Model/ModelPrimitiveImagery.js +972 -0
- package/Source/Scene/Model/ModelReader.js +810 -0
- package/Source/Scene/Model/ModelRenderResources.js +13 -0
- package/Source/Scene/Model/ModelRuntimePrimitive.js +20 -0
- package/Source/Scene/Model/ModelSceneGraph.js +133 -27
- package/Source/Scene/Model/ModelUtility.js +2 -0
- package/Source/Scene/Model/NodeRenderResources.js +10 -0
- package/Source/Scene/ModelComponents.js +10 -0
- package/Source/Scene/PrimitiveLoadPlan.js +59 -0
- package/Source/Scene/ResourceCache.js +60 -3
- package/Source/Scene/ResourceCacheKey.js +39 -1
- package/Source/Scene/Scene.js +32 -1
- package/Source/Scene/VertexAttributeSemantic.js +30 -0
- package/Source/Scene/VoxelPrimitive.js +22 -37
- package/Source/Scene/VoxelRenderResources.js +1 -1
- package/Source/Scene/processVoxelProperties.js +41 -100
- package/Source/Shaders/Builtin/Constants/passGaussianSplats.glsl +9 -0
- package/Source/Shaders/Builtin/Constants/passGaussianSplats.js +11 -0
- package/Source/Shaders/Builtin/Constants/passOverlay.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passOverlay.js +1 -1
- package/Source/Shaders/Builtin/CzmBuiltins.js +2 -0
- package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl +0 -1
- package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.js +0 -1
- package/Source/Shaders/GlobeFS.glsl +22 -0
- package/Source/Shaders/GlobeFS.js +22 -0
- package/Source/Shaders/Model/MaterialStageFS.glsl +4 -0
- package/Source/Shaders/Model/MaterialStageFS.js +4 -0
- package/Source/Shaders/Model/ModelFS.glsl +3 -1
- package/Source/Shaders/Model/ModelFS.js +3 -1
- package/Source/Shaders/Model/ModelVS.glsl +5 -1
- package/Source/Shaders/Model/ModelVS.js +5 -1
- package/Source/Shaders/Model/PointCloudStylingStageVS.glsl +1 -1
- package/Source/Shaders/Model/PointCloudStylingStageVS.js +2 -1
- package/Source/Shaders/PrimitiveGaussianSplatFS.glsl +18 -0
- package/Source/Shaders/PrimitiveGaussianSplatFS.js +20 -0
- package/Source/Shaders/PrimitiveGaussianSplatVS.glsl +108 -0
- package/Source/Shaders/PrimitiveGaussianSplatVS.js +109 -0
- package/Source/Shaders/Voxels/IntersectDepth.glsl +10 -3
- package/Source/Shaders/Voxels/IntersectDepth.js +10 -3
- package/Source/Shaders/Voxels/Intersection.glsl +1 -3
- package/Source/Shaders/Voxels/Intersection.js +1 -3
- package/Source/Shaders/Voxels/IntersectionUtils.glsl +1 -0
- package/Source/Shaders/Voxels/IntersectionUtils.js +1 -0
- package/Source/Shaders/Voxels/VoxelFS.glsl +37 -24
- package/Source/Shaders/Voxels/VoxelFS.js +37 -24
- package/Source/ThirdParty/Workers/z-worker-pako.js +1 -1
- package/Source/ThirdParty/wasm_splats_bg.wasm +0 -0
- package/Source/Workers/gaussianSplatSorter.js +34 -0
- package/Source/Workers/gaussianSplatTextureGenerator.js +39 -0
- package/index.d.ts +66 -2
- package/index.js +101 -80
- package/package.json +6 -4
|
@@ -101,6 +101,19 @@ function ModelRenderResources(model) {
|
|
|
101
101
|
* @private
|
|
102
102
|
*/
|
|
103
103
|
this.hasSkipLevelOfDetail = false;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The NodeRenderResources for the nodes of the scene graph.
|
|
107
|
+
*
|
|
108
|
+
* Note that elements of this array may be <code>undefined</code> when
|
|
109
|
+
* there was no runtime node for a certain node.
|
|
110
|
+
*
|
|
111
|
+
* @type {NodeRenderResources[]}
|
|
112
|
+
* @default []
|
|
113
|
+
*
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
this.nodeRenderResources = [];
|
|
104
117
|
}
|
|
105
118
|
|
|
106
119
|
export default ModelRenderResources;
|
|
@@ -12,6 +12,7 @@ import CustomShaderPipelineStage from "./CustomShaderPipelineStage.js";
|
|
|
12
12
|
import DequantizationPipelineStage from "./DequantizationPipelineStage.js";
|
|
13
13
|
import FeatureIdPipelineStage from "./FeatureIdPipelineStage.js";
|
|
14
14
|
import GeometryPipelineStage from "./GeometryPipelineStage.js";
|
|
15
|
+
import ImageryPipelineStage from "./ImageryPipelineStage.js";
|
|
15
16
|
import LightingPipelineStage from "./LightingPipelineStage.js";
|
|
16
17
|
import MaterialPipelineStage from "./MaterialPipelineStage.js";
|
|
17
18
|
import MetadataPickingPipelineStage from "./MetadataPickingPipelineStage.js";
|
|
@@ -27,6 +28,7 @@ import SelectedFeatureIdPipelineStage from "./SelectedFeatureIdPipelineStage.js"
|
|
|
27
28
|
import SkinningPipelineStage from "./SkinningPipelineStage.js";
|
|
28
29
|
import VerticalExaggerationPipelineStage from "./VerticalExaggerationPipelineStage.js";
|
|
29
30
|
import WireframePipelineStage from "./WireframePipelineStage.js";
|
|
31
|
+
import oneTimeWarning from "../../Core/oneTimeWarning.js";
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* In memory representation of a single primitive, that is, a primitive
|
|
@@ -206,6 +208,12 @@ ModelRuntimePrimitive.prototype.configurePipeline = function (frameState) {
|
|
|
206
208
|
const hasMorphTargets =
|
|
207
209
|
defined(primitive.morphTargets) && primitive.morphTargets.length > 0;
|
|
208
210
|
const hasSkinning = defined(node.skin);
|
|
211
|
+
|
|
212
|
+
// Check whether the model is part of a `Model3DTileContent` that
|
|
213
|
+
// belongs to a tileset that has imagery layers. If this is the
|
|
214
|
+
// case, then the `ImageryPipelineStage` will be required.
|
|
215
|
+
const hasImageryLayers = defined(model.imageryLayers);
|
|
216
|
+
|
|
209
217
|
const hasCustomShader = defined(customShader);
|
|
210
218
|
const hasCustomFragmentShader =
|
|
211
219
|
hasCustomShader && defined(customShader.fragmentShaderText);
|
|
@@ -215,6 +223,7 @@ ModelRuntimePrimitive.prototype.configurePipeline = function (frameState) {
|
|
|
215
223
|
const hasQuantization = ModelUtility.hasQuantizedAttributes(
|
|
216
224
|
primitive.attributes,
|
|
217
225
|
);
|
|
226
|
+
|
|
218
227
|
const generateWireframeIndices =
|
|
219
228
|
model.debugWireframe &&
|
|
220
229
|
PrimitiveType.isTriangles(primitive.primitiveType) &&
|
|
@@ -270,6 +279,17 @@ ModelRuntimePrimitive.prototype.configurePipeline = function (frameState) {
|
|
|
270
279
|
pipelineStages.push(DequantizationPipelineStage);
|
|
271
280
|
}
|
|
272
281
|
|
|
282
|
+
if (hasImageryLayers) {
|
|
283
|
+
if (hasOutlines) {
|
|
284
|
+
oneTimeWarning(
|
|
285
|
+
"outlines-and-draping",
|
|
286
|
+
"Primitive outlines disable imagery draping",
|
|
287
|
+
);
|
|
288
|
+
} else {
|
|
289
|
+
pipelineStages.push(ImageryPipelineStage);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
273
293
|
if (materialsEnabled) {
|
|
274
294
|
pipelineStages.push(MaterialPipelineStage);
|
|
275
295
|
}
|
|
@@ -445,6 +445,7 @@ const scratchModelPositionMin = new Cartesian3();
|
|
|
445
445
|
const scratchModelPositionMax = new Cartesian3();
|
|
446
446
|
const scratchPrimitivePositionMin = new Cartesian3();
|
|
447
447
|
const scratchPrimitivePositionMax = new Cartesian3();
|
|
448
|
+
|
|
448
449
|
/**
|
|
449
450
|
* Generates the {@link ModelDrawCommand} for each primitive in the model.
|
|
450
451
|
* If the model is used for classification, a {@link ClassificationModelDrawCommand}
|
|
@@ -456,6 +457,30 @@ const scratchPrimitivePositionMax = new Cartesian3();
|
|
|
456
457
|
* @private
|
|
457
458
|
*/
|
|
458
459
|
ModelSceneGraph.prototype.buildDrawCommands = function (frameState) {
|
|
460
|
+
const modelRenderResources = this.buildRenderResources(frameState);
|
|
461
|
+
this.computeBoundingVolumes(modelRenderResources);
|
|
462
|
+
this.createDrawCommands(modelRenderResources, frameState);
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Generates the {@link ModelRenderResources} for the model.
|
|
467
|
+
*
|
|
468
|
+
* This will traverse the model, nodes and primitives of the scene graph,
|
|
469
|
+
* and perform the following tasks:
|
|
470
|
+
*
|
|
471
|
+
* - configure the pipeline stages by calling `configurePipeline`,
|
|
472
|
+
* `runtimeNode.configurePipeline`, and `runtimePrimitive.configurePipeline`
|
|
473
|
+
* - create the `ModelRenderResources`, `NodeRenderResources`, and
|
|
474
|
+
* `PrimitiveRenderResources`
|
|
475
|
+
* - Process the render resources with the respective pipelines
|
|
476
|
+
*
|
|
477
|
+
* @param {FrameState} frameState The current frame state. This is needed to
|
|
478
|
+
* allocate GPU resources as needed.
|
|
479
|
+
* @returns {ModelRenderResources} The model render resources
|
|
480
|
+
*
|
|
481
|
+
* @private
|
|
482
|
+
*/
|
|
483
|
+
ModelSceneGraph.prototype.buildRenderResources = function (frameState) {
|
|
459
484
|
const model = this._model;
|
|
460
485
|
const modelRenderResources = new ModelRenderResources(model);
|
|
461
486
|
|
|
@@ -465,26 +490,12 @@ ModelSceneGraph.prototype.buildDrawCommands = function (frameState) {
|
|
|
465
490
|
this.configurePipeline(frameState);
|
|
466
491
|
const modelPipelineStages = this.modelPipelineStages;
|
|
467
492
|
|
|
468
|
-
let i
|
|
469
|
-
for (i = 0; i < modelPipelineStages.length; i++) {
|
|
493
|
+
for (let i = 0; i < modelPipelineStages.length; i++) {
|
|
470
494
|
const modelPipelineStage = modelPipelineStages[i];
|
|
471
495
|
modelPipelineStage.process(modelRenderResources, model, frameState);
|
|
472
496
|
}
|
|
473
497
|
|
|
474
|
-
|
|
475
|
-
Number.MAX_VALUE,
|
|
476
|
-
Number.MAX_VALUE,
|
|
477
|
-
Number.MAX_VALUE,
|
|
478
|
-
scratchModelPositionMin,
|
|
479
|
-
);
|
|
480
|
-
const modelPositionMax = Cartesian3.fromElements(
|
|
481
|
-
-Number.MAX_VALUE,
|
|
482
|
-
-Number.MAX_VALUE,
|
|
483
|
-
-Number.MAX_VALUE,
|
|
484
|
-
scratchModelPositionMax,
|
|
485
|
-
);
|
|
486
|
-
|
|
487
|
-
for (i = 0; i < this._runtimeNodes.length; i++) {
|
|
498
|
+
for (let i = 0; i < this._runtimeNodes.length; i++) {
|
|
488
499
|
const runtimeNode = this._runtimeNodes[i];
|
|
489
500
|
|
|
490
501
|
// If a node in the model was unreachable from the scene graph, there will
|
|
@@ -500,8 +511,9 @@ ModelSceneGraph.prototype.buildDrawCommands = function (frameState) {
|
|
|
500
511
|
modelRenderResources,
|
|
501
512
|
runtimeNode,
|
|
502
513
|
);
|
|
514
|
+
modelRenderResources.nodeRenderResources[i] = nodeRenderResources;
|
|
503
515
|
|
|
504
|
-
for (j = 0; j < nodePipelineStages.length; j++) {
|
|
516
|
+
for (let j = 0; j < nodePipelineStages.length; j++) {
|
|
505
517
|
const nodePipelineStage = nodePipelineStages[j];
|
|
506
518
|
|
|
507
519
|
nodePipelineStage.process(
|
|
@@ -511,8 +523,7 @@ ModelSceneGraph.prototype.buildDrawCommands = function (frameState) {
|
|
|
511
523
|
);
|
|
512
524
|
}
|
|
513
525
|
|
|
514
|
-
|
|
515
|
-
for (j = 0; j < runtimeNode.runtimePrimitives.length; j++) {
|
|
526
|
+
for (let j = 0; j < runtimeNode.runtimePrimitives.length; j++) {
|
|
516
527
|
const runtimePrimitive = runtimeNode.runtimePrimitives[j];
|
|
517
528
|
|
|
518
529
|
runtimePrimitive.configurePipeline(frameState);
|
|
@@ -522,16 +533,76 @@ ModelSceneGraph.prototype.buildDrawCommands = function (frameState) {
|
|
|
522
533
|
nodeRenderResources,
|
|
523
534
|
runtimePrimitive,
|
|
524
535
|
);
|
|
536
|
+
nodeRenderResources.primitiveRenderResources[j] =
|
|
537
|
+
primitiveRenderResources;
|
|
525
538
|
|
|
526
|
-
for (k = 0; k < primitivePipelineStages.length; k++) {
|
|
539
|
+
for (let k = 0; k < primitivePipelineStages.length; k++) {
|
|
527
540
|
const primitivePipelineStage = primitivePipelineStages[k];
|
|
528
|
-
|
|
529
541
|
primitivePipelineStage.process(
|
|
530
542
|
primitiveRenderResources,
|
|
531
543
|
runtimePrimitive.primitive,
|
|
532
544
|
frameState,
|
|
533
545
|
);
|
|
534
546
|
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return modelRenderResources;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Computes the bounding volumes for the scene graph and the model.
|
|
554
|
+
*
|
|
555
|
+
* This will traverse the model, nodes and primitives of the scene graph,
|
|
556
|
+
* and compute the bounding volumes. Specifically, it will compute
|
|
557
|
+
*
|
|
558
|
+
* - this._boundingSphere
|
|
559
|
+
* - model._boundingSphere
|
|
560
|
+
*
|
|
561
|
+
* With the latter being modified as of
|
|
562
|
+
*
|
|
563
|
+
* - model._initialRadius = model._boundingSphere.radius;
|
|
564
|
+
* - model._boundingSphere.radius *= model._clampedScale;
|
|
565
|
+
*
|
|
566
|
+
* NOTE: This contains some bugs. See https://github.com/CesiumGS/cesium/issues/12108
|
|
567
|
+
*
|
|
568
|
+
* @param {ModelRenderResources} modelRenderResources The model render resources
|
|
569
|
+
*
|
|
570
|
+
* @private
|
|
571
|
+
*/
|
|
572
|
+
ModelSceneGraph.prototype.computeBoundingVolumes = function (
|
|
573
|
+
modelRenderResources,
|
|
574
|
+
) {
|
|
575
|
+
const model = this._model;
|
|
576
|
+
|
|
577
|
+
const modelPositionMin = Cartesian3.fromElements(
|
|
578
|
+
Number.MAX_VALUE,
|
|
579
|
+
Number.MAX_VALUE,
|
|
580
|
+
Number.MAX_VALUE,
|
|
581
|
+
scratchModelPositionMin,
|
|
582
|
+
);
|
|
583
|
+
const modelPositionMax = Cartesian3.fromElements(
|
|
584
|
+
-Number.MAX_VALUE,
|
|
585
|
+
-Number.MAX_VALUE,
|
|
586
|
+
-Number.MAX_VALUE,
|
|
587
|
+
scratchModelPositionMax,
|
|
588
|
+
);
|
|
589
|
+
|
|
590
|
+
for (let i = 0; i < this._runtimeNodes.length; i++) {
|
|
591
|
+
const runtimeNode = this._runtimeNodes[i];
|
|
592
|
+
|
|
593
|
+
// If a node in the model was unreachable from the scene graph, there will
|
|
594
|
+
// be no corresponding runtime node and therefore should be skipped.
|
|
595
|
+
if (!defined(runtimeNode)) {
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
const nodeRenderResources = modelRenderResources.nodeRenderResources[i];
|
|
600
|
+
const nodeTransform = runtimeNode.computedTransform;
|
|
601
|
+
for (let j = 0; j < runtimeNode.runtimePrimitives.length; j++) {
|
|
602
|
+
const runtimePrimitive = runtimeNode.runtimePrimitives[j];
|
|
603
|
+
|
|
604
|
+
const primitiveRenderResources =
|
|
605
|
+
nodeRenderResources.primitiveRenderResources[j];
|
|
535
606
|
|
|
536
607
|
runtimePrimitive.boundingSphere = BoundingSphere.clone(
|
|
537
608
|
primitiveRenderResources.boundingSphere,
|
|
@@ -559,12 +630,6 @@ ModelSceneGraph.prototype.buildDrawCommands = function (frameState) {
|
|
|
559
630
|
primitivePositionMax,
|
|
560
631
|
modelPositionMax,
|
|
561
632
|
);
|
|
562
|
-
|
|
563
|
-
const drawCommand = ModelDrawCommands.buildModelDrawCommand(
|
|
564
|
-
primitiveRenderResources,
|
|
565
|
-
frameState,
|
|
566
|
-
);
|
|
567
|
-
runtimePrimitive.drawCommand = drawCommand;
|
|
568
633
|
}
|
|
569
634
|
}
|
|
570
635
|
|
|
@@ -596,6 +661,47 @@ ModelSceneGraph.prototype.buildDrawCommands = function (frameState) {
|
|
|
596
661
|
model._boundingSphere.radius *= model._clampedScale;
|
|
597
662
|
};
|
|
598
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Creates the draw commands for the primitives in the scene graph.
|
|
666
|
+
*
|
|
667
|
+
* This will traverse the model, nodes and primitives of the scene graph,
|
|
668
|
+
* and create the respective draw commands for the primitives, storing
|
|
669
|
+
* them as the `runtimePrimitive.drawCommand`, respectively.
|
|
670
|
+
*
|
|
671
|
+
* @param {ModelRenderResources} modelRenderResources The model render resources
|
|
672
|
+
*
|
|
673
|
+
* @private
|
|
674
|
+
*/
|
|
675
|
+
ModelSceneGraph.prototype.createDrawCommands = function (
|
|
676
|
+
modelRenderResources,
|
|
677
|
+
frameState,
|
|
678
|
+
) {
|
|
679
|
+
for (let i = 0; i < this._runtimeNodes.length; i++) {
|
|
680
|
+
const runtimeNode = this._runtimeNodes[i];
|
|
681
|
+
|
|
682
|
+
// If a node in the model was unreachable from the scene graph, there will
|
|
683
|
+
// be no corresponding runtime node and therefore should be skipped.
|
|
684
|
+
if (!defined(runtimeNode)) {
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
const nodeRenderResources = modelRenderResources.nodeRenderResources[i];
|
|
689
|
+
|
|
690
|
+
for (let j = 0; j < runtimeNode.runtimePrimitives.length; j++) {
|
|
691
|
+
const runtimePrimitive = runtimeNode.runtimePrimitives[j];
|
|
692
|
+
|
|
693
|
+
const primitiveRenderResources =
|
|
694
|
+
nodeRenderResources.primitiveRenderResources[j];
|
|
695
|
+
|
|
696
|
+
const drawCommand = ModelDrawCommands.buildModelDrawCommand(
|
|
697
|
+
primitiveRenderResources,
|
|
698
|
+
frameState,
|
|
699
|
+
);
|
|
700
|
+
runtimePrimitive.drawCommand = drawCommand;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
|
|
599
705
|
/**
|
|
600
706
|
* Configure the model pipeline stages. If the pipeline needs to be re-run, call
|
|
601
707
|
* this method again to ensure the correct sequence of pipeline stages are
|
|
@@ -368,6 +368,8 @@ ModelUtility.supportedExtensions = {
|
|
|
368
368
|
KHR_techniques_webgl: true,
|
|
369
369
|
KHR_texture_basisu: true,
|
|
370
370
|
KHR_texture_transform: true,
|
|
371
|
+
KHR_gaussian_splatting: true,
|
|
372
|
+
KHR_spz_gaussian_splats_compression: true,
|
|
371
373
|
WEB3D_quantized_attributes: true,
|
|
372
374
|
};
|
|
373
375
|
|
|
@@ -155,6 +155,16 @@ function NodeRenderResources(modelRenderResources, runtimeNode) {
|
|
|
155
155
|
* @private
|
|
156
156
|
*/
|
|
157
157
|
this.instanceCount = 0;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The PrimitiveRenderResources for the primitives of the node.
|
|
161
|
+
*
|
|
162
|
+
* @type {PrimitiveRenderResources[]}
|
|
163
|
+
* @default []
|
|
164
|
+
*
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
this.primitiveRenderResources = [];
|
|
158
168
|
}
|
|
159
169
|
|
|
160
170
|
export default NodeRenderResources;
|
|
@@ -620,6 +620,16 @@ function Primitive() {
|
|
|
620
620
|
* @private
|
|
621
621
|
*/
|
|
622
622
|
this.outlineCoordinates = undefined;
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* If the model is part of a Model3DTileContent of a Cesium3DTileset that
|
|
626
|
+
* has 'imageryLayers', then this will represent the information that is
|
|
627
|
+
* required for draping the imagery over this primitive.
|
|
628
|
+
*
|
|
629
|
+
* @type {ModelPrimitiveImagery|undefined}
|
|
630
|
+
* @private
|
|
631
|
+
*/
|
|
632
|
+
this.modelPrimitiveImagery = undefined;
|
|
623
633
|
}
|
|
624
634
|
|
|
625
635
|
/**
|
|
@@ -7,6 +7,8 @@ import BufferUsage from "../Renderer/BufferUsage.js";
|
|
|
7
7
|
import AttributeType from "./AttributeType.js";
|
|
8
8
|
import ModelComponents from "./ModelComponents.js";
|
|
9
9
|
import PrimitiveOutlineGenerator from "./Model/PrimitiveOutlineGenerator.js";
|
|
10
|
+
import VertexAttributeSemantic from "./VertexAttributeSemantic.js";
|
|
11
|
+
import ModelUtility from "./Model/ModelUtility.js";
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Simple struct for tracking whether an attribute will be loaded as a buffer
|
|
@@ -157,6 +159,15 @@ function PrimitiveLoadPlan(primitive) {
|
|
|
157
159
|
* @private
|
|
158
160
|
*/
|
|
159
161
|
this.outlineIndices = undefined;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Set this true to indicate that the primitive has the
|
|
165
|
+
* KHR_gaussian_splatting extension and needs to be post-processed
|
|
166
|
+
*
|
|
167
|
+
* @type {boolean}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
this.needsGaussianSplats = false;
|
|
160
171
|
}
|
|
161
172
|
|
|
162
173
|
/**
|
|
@@ -174,6 +185,11 @@ PrimitiveLoadPlan.prototype.postProcess = function (context) {
|
|
|
174
185
|
generateOutlines(this);
|
|
175
186
|
generateBuffers(this, context);
|
|
176
187
|
}
|
|
188
|
+
|
|
189
|
+
if (this.needsGaussianSplats) {
|
|
190
|
+
prepareSpzData(this, context);
|
|
191
|
+
setupGaussianSplatBuffers(this, context);
|
|
192
|
+
}
|
|
177
193
|
};
|
|
178
194
|
|
|
179
195
|
function generateOutlines(loadPlan) {
|
|
@@ -226,6 +242,49 @@ function makeOutlineCoordinatesAttribute(outlineCoordinatesTypedArray) {
|
|
|
226
242
|
return attribute;
|
|
227
243
|
}
|
|
228
244
|
|
|
245
|
+
function prepareSpzData(loadPlan, context) {
|
|
246
|
+
const position = ModelUtility.getAttributeBySemantic(
|
|
247
|
+
loadPlan.primitive,
|
|
248
|
+
VertexAttributeSemantic.POSITION,
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
for (let i = 0; i < position.typedArray.length; i += 3) {
|
|
252
|
+
position.typedArray[i + 1] = -position.typedArray[i + 1];
|
|
253
|
+
position.typedArray[i + 2] = -position.typedArray[i + 2];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const rotations = ModelUtility.getAttributeBySemantic(
|
|
257
|
+
loadPlan.primitive,
|
|
258
|
+
VertexAttributeSemantic.ROTATION,
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
//180* rotation around X.
|
|
262
|
+
//Temporary until we can get SPZ supporting Z-up assets natively
|
|
263
|
+
const rots = rotations.typedArray;
|
|
264
|
+
for (let q = 0; q < rots.length; q += 4) {
|
|
265
|
+
const w = rots[q];
|
|
266
|
+
const x = -rots[q + 3];
|
|
267
|
+
const y = rots[q + 2];
|
|
268
|
+
const z = -rots[q + 1];
|
|
269
|
+
|
|
270
|
+
rots[q] = y;
|
|
271
|
+
rots[q + 1] = -x;
|
|
272
|
+
rots[q + 2] = w;
|
|
273
|
+
rots[q + 3] = -z;
|
|
274
|
+
}
|
|
275
|
+
rotations.typedArray = rots;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function setupGaussianSplatBuffers(loadPlan, context) {
|
|
279
|
+
const attributePlans = loadPlan.attributePlans;
|
|
280
|
+
const attrLen = attributePlans.length;
|
|
281
|
+
for (let i = 0; i < attrLen; i++) {
|
|
282
|
+
const attributePlan = attributePlans[i];
|
|
283
|
+
attributePlan.loadBuffer = false;
|
|
284
|
+
attributePlan.loadTypedArray = true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
229
288
|
function generateBuffers(loadPlan, context) {
|
|
230
289
|
generateAttributeBuffers(loadPlan.attributePlans, context);
|
|
231
290
|
|
|
@@ -10,6 +10,7 @@ import GltfIndexBufferLoader from "./GltfIndexBufferLoader.js";
|
|
|
10
10
|
import GltfJsonLoader from "./GltfJsonLoader.js";
|
|
11
11
|
import GltfTextureLoader from "./GltfTextureLoader.js";
|
|
12
12
|
import GltfVertexBufferLoader from "./GltfVertexBufferLoader.js";
|
|
13
|
+
import GltfSpzLoader from "./GltfSpzLoader.js";
|
|
13
14
|
import MetadataSchemaLoader from "./MetadataSchemaLoader.js";
|
|
14
15
|
import ResourceCacheKey from "./ResourceCacheKey.js";
|
|
15
16
|
import ResourceCacheStatistics from "./ResourceCacheStatistics.js";
|
|
@@ -390,6 +391,57 @@ ResourceCache.getDracoLoader = function (options) {
|
|
|
390
391
|
return ResourceCache.add(dracoLoader);
|
|
391
392
|
};
|
|
392
393
|
|
|
394
|
+
/**
|
|
395
|
+
* Gets an existing SPZ loader from the cache, or creates a new loader if one does not already exist.
|
|
396
|
+
* This loader is used to decode SPZ (Splat Point Cloud) data in glTF.
|
|
397
|
+
*
|
|
398
|
+
* @param {object} options Object with the following properties:
|
|
399
|
+
* @param {object} options.gltf The glTF JSON.
|
|
400
|
+
* @param {object} options.primitive The primitive containing the SPZ extension.
|
|
401
|
+
* @param {object} options.spz The SPZ extension object.
|
|
402
|
+
* @param {Resource} options.gltfResource The {@link Resource} containing the glTF.
|
|
403
|
+
* @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to.
|
|
404
|
+
*
|
|
405
|
+
* @return {GltfSpzLoader} The cached SPZ loader.
|
|
406
|
+
@private
|
|
407
|
+
* */
|
|
408
|
+
ResourceCache.getSpzLoader = function (options) {
|
|
409
|
+
options = options ?? Frozen.EMPTY_OBJECT;
|
|
410
|
+
const { gltf, primitive, spz, gltfResource, baseResource } = options;
|
|
411
|
+
|
|
412
|
+
//>>includeStart('debug', pragmas.debug);
|
|
413
|
+
Check.typeOf.object("options.gltf", gltf);
|
|
414
|
+
Check.typeOf.object("options.primitive", primitive);
|
|
415
|
+
Check.typeOf.object("options.spz", spz);
|
|
416
|
+
Check.typeOf.object("options.gltfResource", gltfResource);
|
|
417
|
+
Check.typeOf.object("options.baseResource", baseResource);
|
|
418
|
+
//>>includeEnd('debug');
|
|
419
|
+
|
|
420
|
+
const cacheKey = ResourceCacheKey.getSpzCacheKey({
|
|
421
|
+
gltf: gltf,
|
|
422
|
+
primitive: primitive,
|
|
423
|
+
gltfResource: gltfResource,
|
|
424
|
+
baseResource: baseResource,
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
let spzLoader = ResourceCache.get(cacheKey);
|
|
428
|
+
if (defined(spzLoader)) {
|
|
429
|
+
return spzLoader;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
spzLoader = new GltfSpzLoader({
|
|
433
|
+
resourceCache: ResourceCache,
|
|
434
|
+
gltf: gltf,
|
|
435
|
+
primitive: primitive,
|
|
436
|
+
spz: spz,
|
|
437
|
+
gltfResource: gltfResource,
|
|
438
|
+
baseResource: baseResource,
|
|
439
|
+
cacheKey: cacheKey,
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
return ResourceCache.add(spzLoader);
|
|
443
|
+
};
|
|
444
|
+
|
|
393
445
|
/**
|
|
394
446
|
* Gets an existing glTF vertex buffer from the cache, or creates a new loader if one does not already exist.
|
|
395
447
|
*
|
|
@@ -424,6 +476,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
|
|
|
424
476
|
bufferViewId,
|
|
425
477
|
primitive,
|
|
426
478
|
draco,
|
|
479
|
+
spz,
|
|
427
480
|
attributeSemantic,
|
|
428
481
|
accessorId,
|
|
429
482
|
asynchronous = true,
|
|
@@ -448,10 +501,11 @@ ResourceCache.getVertexBufferLoader = function (options) {
|
|
|
448
501
|
const hasDraco = hasDracoCompression(draco, attributeSemantic);
|
|
449
502
|
const hasAttributeSemantic = defined(attributeSemantic);
|
|
450
503
|
const hasAccessorId = defined(accessorId);
|
|
504
|
+
const hasSpz = defined(spz);
|
|
451
505
|
|
|
452
|
-
if (hasBufferViewId === hasDraco) {
|
|
506
|
+
if (hasBufferViewId === (hasDraco !== hasSpz)) {
|
|
453
507
|
throw new DeveloperError(
|
|
454
|
-
"One of options.bufferViewId
|
|
508
|
+
"One of options.bufferViewId, options.draco, or options.spz must be defined.",
|
|
455
509
|
);
|
|
456
510
|
}
|
|
457
511
|
|
|
@@ -463,7 +517,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
|
|
|
463
517
|
|
|
464
518
|
if (hasDraco && !hasAccessorId) {
|
|
465
519
|
throw new DeveloperError(
|
|
466
|
-
"When options.draco is defined options.
|
|
520
|
+
"When options.draco is defined options.hasAccessorId must also be defined.",
|
|
467
521
|
);
|
|
468
522
|
}
|
|
469
523
|
|
|
@@ -478,6 +532,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
|
|
|
478
532
|
Check.typeOf.string("options.attributeSemantic", attributeSemantic);
|
|
479
533
|
Check.typeOf.number("options.accessorId", accessorId);
|
|
480
534
|
}
|
|
535
|
+
|
|
481
536
|
//>>includeEnd('debug');
|
|
482
537
|
|
|
483
538
|
const cacheKey = ResourceCacheKey.getVertexBufferCacheKey({
|
|
@@ -487,6 +542,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
|
|
|
487
542
|
frameState: frameState,
|
|
488
543
|
bufferViewId: bufferViewId,
|
|
489
544
|
draco: draco,
|
|
545
|
+
spz: spz,
|
|
490
546
|
attributeSemantic: attributeSemantic,
|
|
491
547
|
dequantize: dequantize,
|
|
492
548
|
loadBuffer: loadBuffer,
|
|
@@ -506,6 +562,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
|
|
|
506
562
|
bufferViewId: bufferViewId,
|
|
507
563
|
primitive: primitive,
|
|
508
564
|
draco: draco,
|
|
565
|
+
spz: spz,
|
|
509
566
|
attributeSemantic: attributeSemantic,
|
|
510
567
|
accessorId: accessorId,
|
|
511
568
|
cacheKey: cacheKey,
|
|
@@ -71,6 +71,24 @@ function getDracoCacheKey(gltf, draco, gltfResource, baseResource) {
|
|
|
71
71
|
return `${bufferCacheKey}-range-${bufferViewCacheKey}`;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
function getSpzCacheKey(gltf, primitive, gltfResource, baseResource) {
|
|
75
|
+
const bufferViewId = 0;
|
|
76
|
+
const bufferView = gltf.bufferViews[bufferViewId];
|
|
77
|
+
const bufferId = bufferView.buffer;
|
|
78
|
+
const buffer = gltf.buffers[bufferId];
|
|
79
|
+
|
|
80
|
+
const bufferCacheKey = getBufferCacheKey(
|
|
81
|
+
buffer,
|
|
82
|
+
bufferId,
|
|
83
|
+
gltfResource,
|
|
84
|
+
baseResource,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const bufferViewCacheKey = getBufferViewCacheKey(bufferView);
|
|
88
|
+
|
|
89
|
+
return `${bufferCacheKey}-range-${bufferViewCacheKey}`;
|
|
90
|
+
}
|
|
91
|
+
|
|
74
92
|
function getImageCacheKey(gltf, imageId, gltfResource, baseResource) {
|
|
75
93
|
const image = gltf.images[imageId];
|
|
76
94
|
const bufferViewId = image.bufferView;
|
|
@@ -272,6 +290,19 @@ ResourceCacheKey.getDracoCacheKey = function (options) {
|
|
|
272
290
|
return `draco:${getDracoCacheKey(gltf, draco, gltfResource, baseResource)}`;
|
|
273
291
|
};
|
|
274
292
|
|
|
293
|
+
ResourceCacheKey.getSpzCacheKey = function (options) {
|
|
294
|
+
options = options ?? Frozen.EMPTY_OBJECT;
|
|
295
|
+
const { gltf, primitive, gltfResource, baseResource } = options;
|
|
296
|
+
|
|
297
|
+
//>>includeStart('debug', pragmas.debug);
|
|
298
|
+
Check.typeOf.object("options.gltf", gltf);
|
|
299
|
+
Check.typeOf.object("options.primitive", primitive);
|
|
300
|
+
Check.typeOf.object("options.gltfResource", gltfResource);
|
|
301
|
+
Check.typeOf.object("options.baseResource", baseResource);
|
|
302
|
+
//>>includeEnd('debug');
|
|
303
|
+
|
|
304
|
+
return `spz:${getSpzCacheKey(gltf, primitive, gltfResource, baseResource)}`;
|
|
305
|
+
};
|
|
275
306
|
/**
|
|
276
307
|
* Gets the vertex buffer cache key.
|
|
277
308
|
*
|
|
@@ -301,6 +332,7 @@ ResourceCacheKey.getVertexBufferCacheKey = function (options) {
|
|
|
301
332
|
frameState,
|
|
302
333
|
bufferViewId,
|
|
303
334
|
draco,
|
|
335
|
+
spz,
|
|
304
336
|
attributeSemantic,
|
|
305
337
|
dequantize = false,
|
|
306
338
|
loadBuffer = false,
|
|
@@ -316,8 +348,9 @@ ResourceCacheKey.getVertexBufferCacheKey = function (options) {
|
|
|
316
348
|
const hasBufferViewId = defined(bufferViewId);
|
|
317
349
|
const hasDraco = hasDracoCompression(draco, attributeSemantic);
|
|
318
350
|
const hasAttributeSemantic = defined(attributeSemantic);
|
|
351
|
+
const hasSpz = defined(spz);
|
|
319
352
|
|
|
320
|
-
if (hasBufferViewId === hasDraco) {
|
|
353
|
+
if (hasBufferViewId === (hasDraco !== hasSpz)) {
|
|
321
354
|
throw new DeveloperError(
|
|
322
355
|
"One of options.bufferViewId and options.draco must be defined.",
|
|
323
356
|
);
|
|
@@ -365,6 +398,11 @@ ResourceCacheKey.getVertexBufferCacheKey = function (options) {
|
|
|
365
398
|
return `vertex-buffer:${dracoCacheKey}-draco-${attributeSemantic}${cacheKeySuffix}`;
|
|
366
399
|
}
|
|
367
400
|
|
|
401
|
+
if (spz) {
|
|
402
|
+
const spzCacheKey = getSpzCacheKey(gltf, spz, gltfResource, baseResource);
|
|
403
|
+
return `vertex-buffer:${spzCacheKey}-spz-${attributeSemantic}${cacheKeySuffix}`;
|
|
404
|
+
}
|
|
405
|
+
|
|
368
406
|
const bufferView = gltf.bufferViews[bufferViewId];
|
|
369
407
|
const bufferId = bufferView.buffer;
|
|
370
408
|
const buffer = gltf.buffers[bufferId];
|
package/Source/Scene/Scene.js
CHANGED
|
@@ -2318,6 +2318,23 @@ function backToFront(a, b, position) {
|
|
|
2318
2318
|
);
|
|
2319
2319
|
}
|
|
2320
2320
|
|
|
2321
|
+
const scratchCart3 = new Cartesian3();
|
|
2322
|
+
function distanceSquaredToCenter(center, position) {
|
|
2323
|
+
const diff = Cartesian3.subtract(center, position, scratchCart3);
|
|
2324
|
+
const distance = Math.max(0.0, Cartesian3.magnitude(diff));
|
|
2325
|
+
return distance * distance;
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
function backToFrontSplats(a, b, position) {
|
|
2329
|
+
const boxA = a.boundingVolume;
|
|
2330
|
+
const boxB = b.boundingVolume;
|
|
2331
|
+
|
|
2332
|
+
return (
|
|
2333
|
+
distanceSquaredToCenter(boxB.center, position) -
|
|
2334
|
+
distanceSquaredToCenter(boxA.center, position)
|
|
2335
|
+
);
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2321
2338
|
function frontToBack(a, b, position) {
|
|
2322
2339
|
// When distances are equal equal favor sorting b before a. This gives render priority to commands later in the list.
|
|
2323
2340
|
return (
|
|
@@ -2362,7 +2379,6 @@ function executeTranslucentCommandsFrontToBack(
|
|
|
2362
2379
|
executeFunction(commands[i], scene, passState);
|
|
2363
2380
|
}
|
|
2364
2381
|
}
|
|
2365
|
-
|
|
2366
2382
|
/**
|
|
2367
2383
|
* Execute commands to render voxels in the scene.
|
|
2368
2384
|
*
|
|
@@ -2385,6 +2401,19 @@ function performVoxelsPass(scene, passState, frustumCommands) {
|
|
|
2385
2401
|
}
|
|
2386
2402
|
}
|
|
2387
2403
|
|
|
2404
|
+
function performGaussianSplatPass(scene, passState, frustumCommands) {
|
|
2405
|
+
scene.context.uniformState.updatePass(Pass.GAUSSIAN_SPLATS);
|
|
2406
|
+
|
|
2407
|
+
const commands = frustumCommands.commands[Pass.GAUSSIAN_SPLATS];
|
|
2408
|
+
commands.length = frustumCommands.indices[Pass.GAUSSIAN_SPLATS];
|
|
2409
|
+
|
|
2410
|
+
mergeSort(commands, backToFrontSplats, scene.camera.positionWC);
|
|
2411
|
+
|
|
2412
|
+
for (let i = 0; i < commands.length; ++i) {
|
|
2413
|
+
executeCommand(commands[i], scene, passState);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2388
2417
|
const scratchPerspectiveFrustum = new PerspectiveFrustum();
|
|
2389
2418
|
const scratchPerspectiveOffCenterFrustum = new PerspectiveOffCenterFrustum();
|
|
2390
2419
|
const scratchOrthographicFrustum = new OrthographicFrustum();
|
|
@@ -2782,6 +2811,8 @@ function executeCommands(scene, passState) {
|
|
|
2782
2811
|
|
|
2783
2812
|
performPass(frustumCommands, Pass.OPAQUE);
|
|
2784
2813
|
|
|
2814
|
+
performGaussianSplatPass(scene, passState, frustumCommands);
|
|
2815
|
+
|
|
2785
2816
|
if (index !== 0 && scene.mode !== SceneMode.SCENE2D) {
|
|
2786
2817
|
// Do not overlap frustums in the translucent pass to avoid blending artifacts
|
|
2787
2818
|
frustum.near = frustumCommands.near;
|