@cesium/engine 1.0.0 → 1.1.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/{AttributeCompression-4589338a.js → AttributeCompression-b646d393.js} +1 -1
- package/Build/Workers/{AxisAlignedBoundingBox-bfb1234f.js → AxisAlignedBoundingBox-a4321399.js} +1 -1
- package/Build/Workers/{BoundingRectangle-7ffc2153.js → BoundingRectangle-80d8801f.js} +1 -1
- package/Build/Workers/{BoxGeometry-93f344a3.js → BoxGeometry-33c10a4f.js} +1 -1
- package/Build/Workers/{Color-0c5aaf47.js → Color-1bf9a6e0.js} +1 -1
- package/Build/Workers/{CoplanarPolygonGeometryLibrary-6597982a.js → CoplanarPolygonGeometryLibrary-5c5b981b.js} +1 -1
- package/Build/Workers/{CorridorGeometryLibrary-2119580e.js → CorridorGeometryLibrary-7cbae7a0.js} +1 -1
- package/Build/Workers/{CylinderGeometry-f9503c6d.js → CylinderGeometry-42740df0.js} +1 -1
- package/Build/Workers/{EllipseGeometry-fedf72d5.js → EllipseGeometry-49a3ac21.js} +1 -1
- package/Build/Workers/{EllipseGeometryLibrary-4ea68687.js → EllipseGeometryLibrary-b891b2f8.js} +1 -1
- package/Build/Workers/{EllipseOutlineGeometry-e2ae6a35.js → EllipseOutlineGeometry-fbd72e07.js} +1 -1
- package/Build/Workers/{EllipsoidGeodesic-16de63ea.js → EllipsoidGeodesic-98c62a56.js} +1 -1
- package/Build/Workers/{EllipsoidGeometry-95c0330e.js → EllipsoidGeometry-a351dba8.js} +1 -1
- package/Build/Workers/{EllipsoidOutlineGeometry-d6d2ceec.js → EllipsoidOutlineGeometry-3e8779bf.js} +1 -1
- package/Build/Workers/{EllipsoidRhumbLine-ae5e65e0.js → EllipsoidRhumbLine-19756602.js} +1 -1
- package/Build/Workers/{EllipsoidTangentPlane-bfc674bf.js → EllipsoidTangentPlane-cfb50678.js} +1 -1
- package/Build/Workers/{EncodedCartesian3-f473ea18.js → EncodedCartesian3-81f70735.js} +1 -1
- package/Build/Workers/{FrustumGeometry-3bf2e4eb.js → FrustumGeometry-c5754412.js} +1 -1
- package/Build/Workers/{GeometryAttribute-df5f473e.js → GeometryAttribute-0bfd05e8.js} +1 -1
- package/Build/Workers/{GeometryInstance-aa75b4cf.js → GeometryInstance-451dc1cd.js} +1 -1
- package/Build/Workers/{GeometryPipeline-f0e46c42.js → GeometryPipeline-0166905d.js} +1 -1
- package/Build/Workers/{IntersectionTests-9de29d51.js → IntersectionTests-a93d3de9.js} +1 -1
- package/Build/Workers/{Matrix2-ce637455.js → Matrix2-13178034.js} +4 -2
- package/Build/Workers/{Matrix3-4f4df527.js → Matrix3-315394f6.js} +2 -1
- package/Build/Workers/{OrientedBoundingBox-d3ff3d4d.js → OrientedBoundingBox-b450cb61.js} +5 -5
- package/Build/Workers/{Plane-b81241c2.js → Plane-900aa728.js} +1 -1
- package/Build/Workers/{PolygonGeometryLibrary-6f4937bb.js → PolygonGeometryLibrary-f918ac26.js} +1 -1
- package/Build/Workers/PolygonPipeline-f59a8f0a.js +1345 -0
- package/Build/Workers/{PolylinePipeline-2e2b015c.js → PolylinePipeline-d8e6bd9b.js} +1 -1
- package/Build/Workers/{PolylineVolumeGeometryLibrary-7ee1d449.js → PolylineVolumeGeometryLibrary-125d2edf.js} +1 -1
- package/Build/Workers/{PrimitivePipeline-a9b7aae0.js → PrimitivePipeline-0d7b5ed4.js} +1 -1
- package/Build/Workers/{RectangleGeometryLibrary-9aa6c8f6.js → RectangleGeometryLibrary-0768db63.js} +1 -1
- package/Build/Workers/{TerrainEncoding-b52dcfc5.js → TerrainEncoding-06470d7f.js} +1 -1
- package/Build/Workers/{Transforms-2f755df8.js → Transforms-26539bce.js} +97 -83
- package/Build/Workers/{WallGeometryLibrary-ab19a93d.js → WallGeometryLibrary-6167b0fc.js} +1 -1
- package/Build/Workers/{WebMercatorProjection-9f25de49.js → WebMercatorProjection-13a90d41.js} +1 -1
- package/Build/Workers/cesiumWorkerBootstrapper.js +25 -1
- package/Build/Workers/combineGeometry.js +1 -1
- package/Build/Workers/createBoxGeometry.js +1 -1
- package/Build/Workers/createBoxOutlineGeometry.js +1 -1
- package/Build/Workers/createCircleGeometry.js +1 -1
- package/Build/Workers/createCircleOutlineGeometry.js +1 -1
- package/Build/Workers/createCoplanarPolygonGeometry.js +1 -1
- package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +1 -1
- package/Build/Workers/createCorridorGeometry.js +1 -1
- package/Build/Workers/createCorridorOutlineGeometry.js +1 -1
- package/Build/Workers/createCylinderGeometry.js +1 -1
- package/Build/Workers/createCylinderOutlineGeometry.js +1 -1
- package/Build/Workers/createEllipseGeometry.js +1 -1
- package/Build/Workers/createEllipseOutlineGeometry.js +1 -1
- package/Build/Workers/createEllipsoidGeometry.js +1 -1
- package/Build/Workers/createEllipsoidOutlineGeometry.js +1 -1
- package/Build/Workers/createFrustumGeometry.js +1 -1
- package/Build/Workers/createFrustumOutlineGeometry.js +1 -1
- package/Build/Workers/createGeometry.js +1 -1
- package/Build/Workers/createGroundPolylineGeometry.js +1 -1
- package/Build/Workers/createPlaneGeometry.js +1 -1
- package/Build/Workers/createPlaneOutlineGeometry.js +1 -1
- package/Build/Workers/createPolygonGeometry.js +1 -1
- package/Build/Workers/createPolygonOutlineGeometry.js +1 -1
- package/Build/Workers/createPolylineGeometry.js +1 -1
- package/Build/Workers/createPolylineVolumeGeometry.js +1 -1
- package/Build/Workers/createPolylineVolumeOutlineGeometry.js +1 -1
- package/Build/Workers/createRectangleGeometry.js +1 -1
- package/Build/Workers/createRectangleOutlineGeometry.js +1 -1
- package/Build/Workers/createSimplePolylineGeometry.js +1 -1
- package/Build/Workers/createSphereGeometry.js +1 -1
- package/Build/Workers/createSphereOutlineGeometry.js +1 -1
- package/Build/Workers/createVectorTileClampedPolylines.js +1 -1
- package/Build/Workers/createVectorTileGeometries.js +1 -1
- package/Build/Workers/createVectorTilePoints.js +1 -1
- package/Build/Workers/createVectorTilePolygons.js +1 -1
- package/Build/Workers/createVectorTilePolylines.js +1 -1
- package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +1 -1
- package/Build/Workers/createVerticesFromHeightmap.js +7 -3
- package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +1 -1
- package/Build/Workers/createWallGeometry.js +1 -1
- package/Build/Workers/createWallOutlineGeometry.js +1 -1
- package/Build/Workers/decodeI3S.js +1 -1
- package/Build/Workers/package.js +25 -1
- package/Build/Workers/transferTypedArrayTest.js +25 -1
- package/Build/Workers/upsampleQuantizedTerrainMesh.js +1 -1
- package/Source/Core/EarthOrientationParameters.js +67 -63
- package/Source/Core/Ion.js +1 -1
- package/Source/Core/Matrix2.js +2 -1
- package/Source/Core/Matrix3.js +2 -1
- package/Source/Core/Matrix4.js +1 -0
- package/Source/Core/OrientedBoundingBox.js +4 -4
- package/Source/Core/S2Cell.js +3 -3
- package/Source/Core/Transforms.js +3 -7
- package/Source/DataSources/GpxDataSource.js +4 -6
- package/Source/DataSources/KmlDataSource.js +3 -5
- package/Source/Renderer/Context.js +27 -9
- package/Source/Renderer/Pass.js +3 -2
- package/Source/Scene/Cesium3DTileContentType.js +19 -0
- package/Source/Scene/Cesium3DTilesVoxelProvider.js +482 -0
- package/Source/Scene/Cesium3DTilesetMetadata.js +2 -2
- package/Source/Scene/ContentMetadata.js +2 -2
- package/Source/Scene/DerivedCommand.js +7 -0
- package/Source/Scene/Expression.js +1 -1
- package/Source/Scene/Globe.js +10 -0
- package/Source/Scene/GlobeSurfaceTileProvider.js +7 -0
- package/Source/Scene/GltfImageLoader.js +1 -1
- package/Source/Scene/GltfVertexBufferLoader.js +10 -2
- package/Source/Scene/GroupMetadata.js +2 -2
- package/Source/Scene/ImplicitMetadataView.js +2 -2
- package/Source/Scene/ImplicitSubtreeCache.js +127 -0
- package/Source/Scene/ImplicitSubtreeMetadata.js +2 -2
- package/Source/Scene/ImplicitTileset.js +3 -2
- package/Source/Scene/KeyframeNode.js +47 -0
- package/Source/Scene/Megatexture.js +490 -0
- package/Source/Scene/MetadataClass.js +60 -25
- package/Source/Scene/MetadataClassProperty.js +132 -68
- package/Source/Scene/MetadataComponentType.js +78 -57
- package/Source/Scene/MetadataEnum.js +59 -23
- package/Source/Scene/MetadataEnumValue.js +49 -15
- package/Source/Scene/MetadataSchema.js +53 -24
- package/Source/Scene/MetadataSchemaLoader.js +2 -2
- package/Source/Scene/MetadataTableProperty.js +2 -2
- package/Source/Scene/MetadataType.js +6 -14
- package/Source/Scene/Model/GeoJsonLoader.js +1 -1
- package/Source/Scene/Model/Model.js +2 -3
- package/Source/Scene/Model/buildDrawCommand.js +19 -11
- package/Source/Scene/PointCloud.js +1 -1
- package/Source/Scene/PropertyAttribute.js +2 -2
- package/Source/Scene/PropertyAttributeProperty.js +2 -2
- package/Source/Scene/PropertyTable.js +2 -2
- package/Source/Scene/PropertyTexture.js +2 -2
- package/Source/Scene/PropertyTextureProperty.js +2 -2
- package/Source/Scene/ResourceCache.js +9 -1
- package/Source/Scene/ResourceCacheKey.js +9 -1
- package/Source/Scene/Scene.js +17 -0
- package/Source/Scene/SpatialNode.js +375 -0
- package/Source/Scene/StructuralMetadata.js +2 -2
- package/Source/Scene/TileMetadata.js +2 -2
- package/Source/Scene/TilesetMetadata.js +2 -2
- package/Source/Scene/VoxelBoxShape.js +527 -0
- package/Source/Scene/VoxelContent.js +169 -0
- package/Source/Scene/VoxelCylinderShape.js +937 -0
- package/Source/Scene/VoxelEllipsoidShape.js +937 -0
- package/Source/Scene/VoxelPrimitive.js +1919 -0
- package/Source/Scene/VoxelProvider.js +255 -0
- package/Source/Scene/VoxelRenderResources.js +224 -0
- package/Source/Scene/VoxelShape.js +152 -0
- package/Source/Scene/VoxelShapeType.js +105 -0
- package/Source/Scene/VoxelTraversal.js +1144 -0
- package/Source/Scene/buildVoxelDrawCommands.js +116 -0
- package/Source/Scene/parseBatchTable.js +18 -2
- package/Source/Scene/preprocess3DTileContent.js +8 -0
- package/Source/Scene/processVoxelProperties.js +455 -0
- package/Source/Shaders/BillboardCollectionVS.glsl +1 -1
- package/Source/Shaders/BillboardCollectionVS.js +1 -1
- package/Source/Shaders/Builtin/Constants/passOverlay.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passOverlay.js +1 -1
- package/Source/Shaders/Builtin/Constants/passVoxels.glsl +9 -0
- package/Source/Shaders/Builtin/Constants/passVoxels.js +11 -0
- package/Source/Shaders/Builtin/CzmBuiltins.js +17 -15
- package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.glsl +55 -43
- package/Source/Shaders/Builtin/Functions/windowToEyeCoordinates.js +55 -43
- package/Source/Shaders/GlobeFS.glsl +2 -1
- package/Source/Shaders/GlobeFS.js +2 -1
- package/Source/Shaders/PointPrimitiveCollectionVS.glsl +5 -2
- package/Source/Shaders/PointPrimitiveCollectionVS.js +5 -2
- package/Source/Shaders/Voxels/IntersectBox.glsl +79 -0
- package/Source/Shaders/Voxels/IntersectBox.js +81 -0
- package/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +70 -0
- package/Source/Shaders/Voxels/IntersectClippingPlanes.js +72 -0
- package/Source/Shaders/Voxels/IntersectCylinder.glsl +273 -0
- package/Source/Shaders/Voxels/IntersectCylinder.js +275 -0
- package/Source/Shaders/Voxels/IntersectDepth.glsl +23 -0
- package/Source/Shaders/Voxels/IntersectDepth.js +25 -0
- package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +337 -0
- package/Source/Shaders/Voxels/IntersectEllipsoid.js +339 -0
- package/Source/Shaders/Voxels/Intersection.glsl +54 -0
- package/Source/Shaders/Voxels/Intersection.js +56 -0
- package/Source/Shaders/Voxels/IntersectionUtils.glsl +151 -0
- package/Source/Shaders/Voxels/IntersectionUtils.js +153 -0
- package/Source/Shaders/Voxels/Megatexture.glsl +136 -0
- package/Source/Shaders/Voxels/Megatexture.js +138 -0
- package/Source/Shaders/Voxels/Octree.glsl +221 -0
- package/Source/Shaders/Voxels/Octree.js +223 -0
- package/Source/Shaders/Voxels/VoxelFS.glsl +150 -0
- package/Source/Shaders/Voxels/VoxelFS.js +152 -0
- package/Source/Shaders/Voxels/VoxelVS.glsl +11 -0
- package/Source/Shaders/Voxels/VoxelVS.js +13 -0
- package/Source/Shaders/Voxels/convertUvToBox.glsl +16 -0
- package/Source/Shaders/Voxels/convertUvToBox.js +18 -0
- package/Source/Shaders/Voxels/convertUvToCylinder.glsl +79 -0
- package/Source/Shaders/Voxels/convertUvToCylinder.js +81 -0
- package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +133 -0
- package/Source/Shaders/Voxels/convertUvToEllipsoid.js +135 -0
- package/Source/ThirdParty/Workers/z-worker-pako.js +0 -0
- package/index.d.ts +3124 -2287
- package/index.js +1117 -1085
- package/package.json +3 -4
- package/Build/Workers/PolygonPipeline-774a8aaf.js +0 -1341
|
@@ -0,0 +1,1144 @@
|
|
|
1
|
+
import Cartesian2 from "../Core/Cartesian2.js";
|
|
2
|
+
import CesiumMath from "../Core/Math.js";
|
|
3
|
+
import CullingVolume from "../Core/CullingVolume.js";
|
|
4
|
+
import defined from "../Core/defined.js";
|
|
5
|
+
import destroyObject from "../Core/destroyObject.js";
|
|
6
|
+
import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js";
|
|
7
|
+
import getTimestamp from "../Core/getTimestamp.js";
|
|
8
|
+
import KeyframeNode from "./KeyframeNode.js";
|
|
9
|
+
import MetadataType from "./MetadataType.js";
|
|
10
|
+
import Megatexture from "./Megatexture.js";
|
|
11
|
+
import PixelFormat from "../Core/PixelFormat.js";
|
|
12
|
+
import PixelDatatype from "../Renderer/PixelDatatype.js";
|
|
13
|
+
import Sampler from "../Renderer/Sampler.js";
|
|
14
|
+
import SpatialNode from "./SpatialNode.js";
|
|
15
|
+
import Texture from "../Renderer/Texture.js";
|
|
16
|
+
import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.js";
|
|
17
|
+
import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Handles tileset traversal, tile requests, and GPU resources. Intended to be
|
|
21
|
+
* private and paired with a {@link VoxelPrimitive}, which has a user-facing API.
|
|
22
|
+
*
|
|
23
|
+
* @alias VoxelTraversal
|
|
24
|
+
* @constructor
|
|
25
|
+
*
|
|
26
|
+
* @param {VoxelPrimitive} primitive
|
|
27
|
+
* @param {Context} context
|
|
28
|
+
* @param {Cartesian3} dimensions
|
|
29
|
+
* @param {MetadataType[]} types
|
|
30
|
+
* @param {MetadataComponentType[]} componentTypes
|
|
31
|
+
* @param {Number} keyframeCount
|
|
32
|
+
* @param {Number} [maximumTextureMemoryByteLength]
|
|
33
|
+
*
|
|
34
|
+
* @private
|
|
35
|
+
*/
|
|
36
|
+
function VoxelTraversal(
|
|
37
|
+
primitive,
|
|
38
|
+
context,
|
|
39
|
+
dimensions,
|
|
40
|
+
types,
|
|
41
|
+
componentTypes,
|
|
42
|
+
keyframeCount,
|
|
43
|
+
maximumTextureMemoryByteLength
|
|
44
|
+
) {
|
|
45
|
+
/**
|
|
46
|
+
* TODO: maybe this shouldn't be stored or passed into update function?
|
|
47
|
+
* @type {VoxelPrimitive}
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
this._primitive = primitive;
|
|
51
|
+
|
|
52
|
+
const length = types.length;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @type {Megatexture[]}
|
|
56
|
+
* @readonly
|
|
57
|
+
*/
|
|
58
|
+
this.megatextures = new Array(length);
|
|
59
|
+
|
|
60
|
+
// TODO make sure to split the maximumTextureMemoryByteLength across all the megatextures
|
|
61
|
+
for (let i = 0; i < length; i++) {
|
|
62
|
+
const type = types[i];
|
|
63
|
+
const componentCount = MetadataType.getComponentCount(type);
|
|
64
|
+
const componentType = componentTypes[i];
|
|
65
|
+
|
|
66
|
+
this.megatextures[i] = new Megatexture(
|
|
67
|
+
context,
|
|
68
|
+
dimensions,
|
|
69
|
+
componentCount,
|
|
70
|
+
componentType,
|
|
71
|
+
maximumTextureMemoryByteLength
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const maximumTileCount = this.megatextures[0].maximumTileCount;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @type {Number}
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
this._simultaneousRequestCount = 0;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @type {Boolean}
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
this._debugPrint = false;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @type {Number}
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
this._frameNumber = 0;
|
|
94
|
+
|
|
95
|
+
const shape = primitive._shape;
|
|
96
|
+
const rootLevel = 0;
|
|
97
|
+
const rootX = 0;
|
|
98
|
+
const rootY = 0;
|
|
99
|
+
const rootZ = 0;
|
|
100
|
+
const rootParent = undefined;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @type {SpatialNode}
|
|
104
|
+
* @readonly
|
|
105
|
+
*/
|
|
106
|
+
this.rootNode = new SpatialNode(
|
|
107
|
+
rootLevel,
|
|
108
|
+
rootX,
|
|
109
|
+
rootY,
|
|
110
|
+
rootZ,
|
|
111
|
+
rootParent,
|
|
112
|
+
shape,
|
|
113
|
+
dimensions
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @type {DoubleEndedPriorityQueue}
|
|
118
|
+
* @private
|
|
119
|
+
*/
|
|
120
|
+
this._priorityQueue = new DoubleEndedPriorityQueue({
|
|
121
|
+
maximumLength: maximumTileCount,
|
|
122
|
+
comparator: KeyframeNode.priorityComparator,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @type {KeyframeNode[]}
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
this._highPriorityKeyframeNodes = new Array(maximumTileCount);
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @type {KeyframeNode[]}
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
this._keyframeNodesInMegatexture = new Array(maximumTileCount);
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @type {Number}
|
|
139
|
+
* @private
|
|
140
|
+
*/
|
|
141
|
+
this._keyframeCount = keyframeCount;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @type {Number}
|
|
145
|
+
* @private
|
|
146
|
+
*/
|
|
147
|
+
this._sampleCount = undefined;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @type {Number}
|
|
151
|
+
* @private
|
|
152
|
+
*/
|
|
153
|
+
this._keyframeLocation = 0;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @type {Number[]}
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
this._binaryTreeKeyframeWeighting = new Array(keyframeCount);
|
|
160
|
+
|
|
161
|
+
function binaryTreeWeightingRecursive(arr, start, end, depth) {
|
|
162
|
+
if (start > end) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const mid = Math.floor((start + end) / 2);
|
|
166
|
+
arr[mid] = depth;
|
|
167
|
+
binaryTreeWeightingRecursive(arr, start, mid - 1, depth + 1);
|
|
168
|
+
binaryTreeWeightingRecursive(arr, mid + 1, end, depth + 1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const binaryTreeKeyframeWeighting = this._binaryTreeKeyframeWeighting;
|
|
172
|
+
binaryTreeKeyframeWeighting[0] = 0;
|
|
173
|
+
binaryTreeKeyframeWeighting[keyframeCount - 1] = 0;
|
|
174
|
+
binaryTreeWeightingRecursive(
|
|
175
|
+
binaryTreeKeyframeWeighting,
|
|
176
|
+
1,
|
|
177
|
+
keyframeCount - 2,
|
|
178
|
+
0
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const internalNodeTexelCount = 9;
|
|
182
|
+
const internalNodeTextureDimensionX = 2048;
|
|
183
|
+
const internalNodeTilesPerRow = Math.floor(
|
|
184
|
+
internalNodeTextureDimensionX / internalNodeTexelCount
|
|
185
|
+
);
|
|
186
|
+
const internalNodeTextureDimensionY = Math.ceil(
|
|
187
|
+
maximumTileCount / internalNodeTilesPerRow
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @type {Texture}
|
|
192
|
+
* @readonly
|
|
193
|
+
*/
|
|
194
|
+
this.internalNodeTexture = new Texture({
|
|
195
|
+
context: context,
|
|
196
|
+
pixelFormat: PixelFormat.RGBA,
|
|
197
|
+
pixelDatatype: PixelDatatype.UNSIGNED_BYTE,
|
|
198
|
+
flipY: false,
|
|
199
|
+
width: internalNodeTextureDimensionX,
|
|
200
|
+
height: internalNodeTextureDimensionY,
|
|
201
|
+
sampler: new Sampler({
|
|
202
|
+
minificationFilter: TextureMinificationFilter.NEAREST,
|
|
203
|
+
magnificationFilter: TextureMagnificationFilter.NEAREST,
|
|
204
|
+
}),
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @type {Number}
|
|
209
|
+
* @readonly
|
|
210
|
+
*/
|
|
211
|
+
this.internalNodeTilesPerRow = internalNodeTilesPerRow;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* @type {Cartesian2}
|
|
215
|
+
* @readonly
|
|
216
|
+
*/
|
|
217
|
+
this.internalNodeTexelSizeUv = new Cartesian2(
|
|
218
|
+
1.0 / internalNodeTextureDimensionX,
|
|
219
|
+
1.0 / internalNodeTextureDimensionY
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Only generated when there are two or more samples.
|
|
224
|
+
* @type {Texture}
|
|
225
|
+
* @readonly
|
|
226
|
+
*/
|
|
227
|
+
this.leafNodeTexture = undefined;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Only generated when there are two or more samples.
|
|
231
|
+
* @type {Number}
|
|
232
|
+
* @readonly
|
|
233
|
+
*/
|
|
234
|
+
this.leafNodeTilesPerRow = undefined;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Only generated when there are two or more samples.
|
|
238
|
+
* @type {Cartesian2}
|
|
239
|
+
* @readonly
|
|
240
|
+
*/
|
|
241
|
+
this.leafNodeTexelSizeUv = new Cartesian2();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
VoxelTraversal.simultaneousRequestCountMaximum = 50;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @param {FrameState} frameState
|
|
248
|
+
* @param {Number} keyframeLocation
|
|
249
|
+
* @param {Boolean} recomputeBoundingVolumes
|
|
250
|
+
* @param {Boolean} pauseUpdate
|
|
251
|
+
*/
|
|
252
|
+
VoxelTraversal.prototype.update = function (
|
|
253
|
+
frameState,
|
|
254
|
+
keyframeLocation,
|
|
255
|
+
recomputeBoundingVolumes,
|
|
256
|
+
pauseUpdate
|
|
257
|
+
) {
|
|
258
|
+
const primitive = this._primitive;
|
|
259
|
+
const context = frameState.context;
|
|
260
|
+
const maximumTileCount = this.megatextures[0].maximumTileCount;
|
|
261
|
+
const keyframeCount = this._keyframeCount;
|
|
262
|
+
|
|
263
|
+
const levelBlendFactor = primitive._levelBlendFactor;
|
|
264
|
+
const hasLevelBlendFactor = levelBlendFactor > 0.0;
|
|
265
|
+
const hasKeyframes = keyframeCount > 1;
|
|
266
|
+
const sampleCount = (hasLevelBlendFactor ? 2 : 1) * (hasKeyframes ? 2 : 1);
|
|
267
|
+
this._sampleCount = sampleCount;
|
|
268
|
+
|
|
269
|
+
const useLeafNodes = sampleCount >= 2;
|
|
270
|
+
if (useLeafNodes && !defined(this.leafNodeTexture)) {
|
|
271
|
+
const leafNodeTexelCount = 2;
|
|
272
|
+
const leafNodeTextureDimensionX = 1024;
|
|
273
|
+
const leafNodeTilesPerRow = Math.floor(
|
|
274
|
+
leafNodeTextureDimensionX / leafNodeTexelCount
|
|
275
|
+
);
|
|
276
|
+
const leafNodeTextureDimensionY = Math.ceil(
|
|
277
|
+
maximumTileCount / leafNodeTilesPerRow
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
this.leafNodeTexture = new Texture({
|
|
281
|
+
context: context,
|
|
282
|
+
pixelFormat: PixelFormat.RGBA,
|
|
283
|
+
pixelDatatype: PixelDatatype.UNSIGNED_BYTE,
|
|
284
|
+
flipY: false,
|
|
285
|
+
width: leafNodeTextureDimensionX,
|
|
286
|
+
height: leafNodeTextureDimensionY,
|
|
287
|
+
sampler: new Sampler({
|
|
288
|
+
minificationFilter: TextureMinificationFilter.NEAREST,
|
|
289
|
+
magnificationFilter: TextureMagnificationFilter.NEAREST,
|
|
290
|
+
}),
|
|
291
|
+
});
|
|
292
|
+
this.leafNodeTexelSizeUv = Cartesian2.fromElements(
|
|
293
|
+
1.0 / leafNodeTextureDimensionX,
|
|
294
|
+
1.0 / leafNodeTextureDimensionY,
|
|
295
|
+
this.leafNodeTexelSizeUv
|
|
296
|
+
);
|
|
297
|
+
this.leafNodeTilesPerRow = leafNodeTilesPerRow;
|
|
298
|
+
} else if (!useLeafNodes && defined(this.leafNodeTexture)) {
|
|
299
|
+
this.leafNodeTexture = this.leafNodeTexture.destroy();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
this._keyframeLocation = CesiumMath.clamp(
|
|
303
|
+
keyframeLocation,
|
|
304
|
+
0.0,
|
|
305
|
+
keyframeCount - 1
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
if (recomputeBoundingVolumes) {
|
|
309
|
+
recomputeBoundingVolumesRecursive(this, this.rootNode);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (pauseUpdate) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
this._frameNumber = frameState.frameNumber;
|
|
317
|
+
const timestamp0 = getTimestamp();
|
|
318
|
+
loadAndUnload(this, frameState);
|
|
319
|
+
const timestamp1 = getTimestamp();
|
|
320
|
+
generateOctree(this, sampleCount, levelBlendFactor);
|
|
321
|
+
const timestamp2 = getTimestamp();
|
|
322
|
+
|
|
323
|
+
if (this._debugPrint) {
|
|
324
|
+
const loadAndUnloadTimeMs = timestamp1 - timestamp0;
|
|
325
|
+
const generateOctreeTimeMs = timestamp2 - timestamp1;
|
|
326
|
+
const totalTimeMs = timestamp2 - timestamp0;
|
|
327
|
+
printDebugInformation(
|
|
328
|
+
this,
|
|
329
|
+
loadAndUnloadTimeMs,
|
|
330
|
+
generateOctreeTimeMs,
|
|
331
|
+
totalTimeMs
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Check if a node is renderable.
|
|
338
|
+
* @param {SpatialNode} tile
|
|
339
|
+
* @returns {Boolean}
|
|
340
|
+
*/
|
|
341
|
+
VoxelTraversal.prototype.isRenderable = function (tile) {
|
|
342
|
+
return tile.isRenderable(this._frameNumber);
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Returns true if this object was destroyed; otherwise, false.
|
|
347
|
+
* <br /><br />
|
|
348
|
+
* If this object was destroyed, it should not be used; calling any function other than
|
|
349
|
+
* <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
|
|
350
|
+
*
|
|
351
|
+
* @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
|
|
352
|
+
*
|
|
353
|
+
* @see VoxelTraversal#destroy
|
|
354
|
+
*/
|
|
355
|
+
VoxelTraversal.prototype.isDestroyed = function () {
|
|
356
|
+
return false;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
|
|
361
|
+
* release of WebGL resources, instead of relying on the garbage collector to destroy this object.
|
|
362
|
+
* <br /><br />
|
|
363
|
+
* Once an object is destroyed, it should not be used; calling any function other than
|
|
364
|
+
* <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
|
|
365
|
+
* assign the return value (<code>undefined</code>) to the object as done in the example.
|
|
366
|
+
*
|
|
367
|
+
* @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
|
|
368
|
+
*
|
|
369
|
+
* @see VoxelTraversal#isDestroyed
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* voxelTraversal = voxelTraversal && voxelTraversal.destroy();
|
|
373
|
+
*/
|
|
374
|
+
VoxelTraversal.prototype.destroy = function () {
|
|
375
|
+
const megatextures = this.megatextures;
|
|
376
|
+
const megatextureLength = megatextures.length;
|
|
377
|
+
for (let i = 0; i < megatextureLength; i++) {
|
|
378
|
+
megatextures[i] = megatextures[i] && megatextures[i].destroy();
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
this.internalNodeTexture =
|
|
382
|
+
this.internalNodeTexture && this.internalNodeTexture.destroy();
|
|
383
|
+
|
|
384
|
+
this.leafNodeTexture = this.leafNodeTexture && this.leafNodeTexture.destroy();
|
|
385
|
+
|
|
386
|
+
return destroyObject(this);
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* @function
|
|
391
|
+
*
|
|
392
|
+
* @param {VoxelTraversal} that
|
|
393
|
+
* @param {SpatialNode} node
|
|
394
|
+
*
|
|
395
|
+
* @private
|
|
396
|
+
*/
|
|
397
|
+
function recomputeBoundingVolumesRecursive(that, node) {
|
|
398
|
+
const primitive = that._primitive;
|
|
399
|
+
const shape = primitive._shape;
|
|
400
|
+
const dimensions = primitive._provider.dimensions;
|
|
401
|
+
node.computeBoundingVolumes(shape, dimensions);
|
|
402
|
+
if (defined(node.children)) {
|
|
403
|
+
for (let i = 0; i < 8; i++) {
|
|
404
|
+
const child = node.children[i];
|
|
405
|
+
recomputeBoundingVolumesRecursive(that, child);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* @function
|
|
412
|
+
*
|
|
413
|
+
* @param {VoxelTraversal} that
|
|
414
|
+
* @param {KeyframeNode} keyframeNode
|
|
415
|
+
*
|
|
416
|
+
* @private
|
|
417
|
+
*/
|
|
418
|
+
function requestData(that, keyframeNode) {
|
|
419
|
+
if (
|
|
420
|
+
that._simultaneousRequestCount >=
|
|
421
|
+
VoxelTraversal.simultaneousRequestCountMaximum
|
|
422
|
+
) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const primitive = that._primitive;
|
|
427
|
+
const provider = primitive._provider;
|
|
428
|
+
const keyframe = keyframeNode.keyframe;
|
|
429
|
+
const spatialNode = keyframeNode.spatialNode;
|
|
430
|
+
const tileLevel = spatialNode.level;
|
|
431
|
+
const tileX = spatialNode.x;
|
|
432
|
+
const tileY = spatialNode.y;
|
|
433
|
+
const tileZ = spatialNode.z;
|
|
434
|
+
|
|
435
|
+
function postRequestSuccess(result) {
|
|
436
|
+
that._simultaneousRequestCount--;
|
|
437
|
+
const length = primitive._provider.types.length;
|
|
438
|
+
|
|
439
|
+
if (!defined(result)) {
|
|
440
|
+
keyframeNode.state = KeyframeNode.LoadState.UNAVAILABLE;
|
|
441
|
+
} else if (result === KeyframeNode.LoadState.FAILED) {
|
|
442
|
+
keyframeNode.state = KeyframeNode.LoadState.FAILED;
|
|
443
|
+
} else if (!Array.isArray(result) || result.length !== length) {
|
|
444
|
+
// TODO should this throw runtime error?
|
|
445
|
+
keyframeNode.state = KeyframeNode.LoadState.FAILED;
|
|
446
|
+
} else {
|
|
447
|
+
const megatextures = that.megatextures;
|
|
448
|
+
for (let i = 0; i < length; i++) {
|
|
449
|
+
const { voxelCountPerTile, channelCount } = megatextures[i];
|
|
450
|
+
const { x, y, z } = voxelCountPerTile;
|
|
451
|
+
const tileVoxelCount = x * y * z;
|
|
452
|
+
|
|
453
|
+
const data = result[i];
|
|
454
|
+
const expectedLength = tileVoxelCount * channelCount;
|
|
455
|
+
if (data.length === expectedLength) {
|
|
456
|
+
keyframeNode.metadatas[i] = data;
|
|
457
|
+
// State is received only when all metadata requests have been received
|
|
458
|
+
keyframeNode.state = KeyframeNode.LoadState.RECEIVED;
|
|
459
|
+
} else {
|
|
460
|
+
keyframeNode.state = KeyframeNode.LoadState.FAILED;
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function postRequestFailure() {
|
|
468
|
+
that._simultaneousRequestCount--;
|
|
469
|
+
keyframeNode.state = KeyframeNode.LoadState.FAILED;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const promise = provider.requestData({
|
|
473
|
+
tileLevel: tileLevel,
|
|
474
|
+
tileX: tileX,
|
|
475
|
+
tileY: tileY,
|
|
476
|
+
tileZ: tileZ,
|
|
477
|
+
keyframe: keyframe,
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
if (defined(promise)) {
|
|
481
|
+
that._simultaneousRequestCount++;
|
|
482
|
+
keyframeNode.state = KeyframeNode.LoadState.RECEIVING;
|
|
483
|
+
promise.then(postRequestSuccess).catch(postRequestFailure);
|
|
484
|
+
} else {
|
|
485
|
+
keyframeNode.state = KeyframeNode.LoadState.FAILED;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* @function
|
|
491
|
+
*
|
|
492
|
+
* @param {Number} x
|
|
493
|
+
* @returns {Number}
|
|
494
|
+
*
|
|
495
|
+
* @private
|
|
496
|
+
*/
|
|
497
|
+
function mapInfiniteRangeToZeroOne(x) {
|
|
498
|
+
return x / (1.0 + x);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* @function
|
|
503
|
+
*
|
|
504
|
+
* @param {VoxelTraversal} that
|
|
505
|
+
* @param {FrameState} frameState
|
|
506
|
+
*
|
|
507
|
+
* @private
|
|
508
|
+
*/
|
|
509
|
+
function loadAndUnload(that, frameState) {
|
|
510
|
+
const frameNumber = that._frameNumber;
|
|
511
|
+
const primitive = that._primitive;
|
|
512
|
+
const shape = primitive._shape;
|
|
513
|
+
const voxelDimensions = primitive._provider.dimensions;
|
|
514
|
+
const targetScreenSpaceError = primitive._screenSpaceError;
|
|
515
|
+
const priorityQueue = that._priorityQueue;
|
|
516
|
+
const keyframeLocation = that._keyframeLocation;
|
|
517
|
+
const keyframeCount = that._keyframeCount;
|
|
518
|
+
const rootNode = that.rootNode;
|
|
519
|
+
|
|
520
|
+
const cameraPosition = frameState.camera.positionWC;
|
|
521
|
+
const screenSpaceErrorDenominator = frameState.camera.frustum.sseDenominator;
|
|
522
|
+
const screenHeight =
|
|
523
|
+
frameState.context.drawingBufferHeight / frameState.pixelRatio;
|
|
524
|
+
const screenSpaceErrorMultiplier = screenHeight / screenSpaceErrorDenominator;
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @ignore
|
|
528
|
+
* @param {SpatialNode} spatialNode
|
|
529
|
+
* @param {Number} visibilityPlaneMask
|
|
530
|
+
*/
|
|
531
|
+
function addToQueueRecursive(spatialNode, visibilityPlaneMask) {
|
|
532
|
+
spatialNode.computeScreenSpaceError(
|
|
533
|
+
cameraPosition,
|
|
534
|
+
screenSpaceErrorMultiplier
|
|
535
|
+
);
|
|
536
|
+
|
|
537
|
+
visibilityPlaneMask = spatialNode.visibility(
|
|
538
|
+
frameState,
|
|
539
|
+
visibilityPlaneMask
|
|
540
|
+
);
|
|
541
|
+
if (visibilityPlaneMask === CullingVolume.MASK_OUTSIDE) {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
spatialNode.visitedFrameNumber = frameNumber;
|
|
545
|
+
|
|
546
|
+
const previousKeyframe = CesiumMath.clamp(
|
|
547
|
+
Math.floor(keyframeLocation),
|
|
548
|
+
0,
|
|
549
|
+
keyframeCount - 2
|
|
550
|
+
);
|
|
551
|
+
const nextKeyframe = previousKeyframe + 1;
|
|
552
|
+
|
|
553
|
+
// Create keyframe nodes at the playhead.
|
|
554
|
+
// If they already exist, nothing will be created.
|
|
555
|
+
if (keyframeCount === 1) {
|
|
556
|
+
spatialNode.createKeyframeNode(0);
|
|
557
|
+
} else if (spatialNode.keyframeNodes.length !== keyframeCount) {
|
|
558
|
+
for (let k = 0; k < keyframeCount; k++) {
|
|
559
|
+
spatialNode.createKeyframeNode(k);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
const ssePriority = mapInfiniteRangeToZeroOne(spatialNode.screenSpaceError);
|
|
563
|
+
|
|
564
|
+
let hasLoadedKeyframe = false;
|
|
565
|
+
const keyframeNodes = spatialNode.keyframeNodes;
|
|
566
|
+
for (let i = 0; i < keyframeNodes.length; i++) {
|
|
567
|
+
const keyframeNode = keyframeNodes[i];
|
|
568
|
+
const keyframe = keyframeNode.keyframe;
|
|
569
|
+
|
|
570
|
+
// Balanced prioritization
|
|
571
|
+
const keyframeDifference = Math.min(
|
|
572
|
+
Math.abs(keyframe - previousKeyframe),
|
|
573
|
+
Math.abs(keyframe - nextKeyframe)
|
|
574
|
+
);
|
|
575
|
+
const maxKeyframeDifference = Math.max(
|
|
576
|
+
previousKeyframe,
|
|
577
|
+
keyframeCount - nextKeyframe - 1,
|
|
578
|
+
1
|
|
579
|
+
);
|
|
580
|
+
const keyframeFactor = Math.pow(
|
|
581
|
+
1.0 - keyframeDifference / maxKeyframeDifference,
|
|
582
|
+
4.0
|
|
583
|
+
);
|
|
584
|
+
const binaryTreeFactor = Math.exp(
|
|
585
|
+
-that._binaryTreeKeyframeWeighting[keyframe]
|
|
586
|
+
);
|
|
587
|
+
keyframeNode.priority = 10.0 * ssePriority;
|
|
588
|
+
keyframeNode.priority += CesiumMath.lerp(
|
|
589
|
+
binaryTreeFactor,
|
|
590
|
+
keyframeFactor,
|
|
591
|
+
0.15 + 0.85 * keyframeFactor
|
|
592
|
+
);
|
|
593
|
+
|
|
594
|
+
if (
|
|
595
|
+
keyframeNode.state !== KeyframeNode.LoadState.UNAVAILABLE &&
|
|
596
|
+
keyframeNode.state !== KeyframeNode.LoadState.FAILED &&
|
|
597
|
+
keyframeNode.priority !== -Number.MAX_VALUE
|
|
598
|
+
) {
|
|
599
|
+
priorityQueue.insert(keyframeNode);
|
|
600
|
+
}
|
|
601
|
+
if (keyframeNode.state === KeyframeNode.LoadState.LOADED) {
|
|
602
|
+
hasLoadedKeyframe = true;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const meetsScreenSpaceError =
|
|
607
|
+
spatialNode.screenSpaceError < targetScreenSpaceError;
|
|
608
|
+
if (meetsScreenSpaceError || !hasLoadedKeyframe) {
|
|
609
|
+
// Free up memory
|
|
610
|
+
spatialNode.children = undefined;
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
if (!defined(spatialNode.children)) {
|
|
615
|
+
const childCoords = getChildCoords(spatialNode);
|
|
616
|
+
const childLevel = spatialNode.level + 1;
|
|
617
|
+
spatialNode.children = childCoords.map(([x, y, z]) => {
|
|
618
|
+
return new SpatialNode(
|
|
619
|
+
childLevel,
|
|
620
|
+
x,
|
|
621
|
+
y,
|
|
622
|
+
z,
|
|
623
|
+
spatialNode,
|
|
624
|
+
shape,
|
|
625
|
+
voxelDimensions
|
|
626
|
+
);
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
for (let childIndex = 0; childIndex < 8; childIndex++) {
|
|
630
|
+
const child = spatialNode.children[childIndex];
|
|
631
|
+
addToQueueRecursive(child, visibilityPlaneMask);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
priorityQueue.reset();
|
|
636
|
+
addToQueueRecursive(rootNode, CullingVolume.MASK_INDETERMINATE);
|
|
637
|
+
|
|
638
|
+
const highPriorityKeyframeNodes = that._highPriorityKeyframeNodes;
|
|
639
|
+
let highPriorityKeyframeNodeCount = 0;
|
|
640
|
+
let highPriorityKeyframeNode;
|
|
641
|
+
while (priorityQueue.length > 0) {
|
|
642
|
+
highPriorityKeyframeNode = priorityQueue.removeMaximum();
|
|
643
|
+
highPriorityKeyframeNode.highPriorityFrameNumber = frameNumber;
|
|
644
|
+
highPriorityKeyframeNodes[
|
|
645
|
+
highPriorityKeyframeNodeCount
|
|
646
|
+
] = highPriorityKeyframeNode;
|
|
647
|
+
highPriorityKeyframeNodeCount++;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const keyframeNodesInMegatexture = that._keyframeNodesInMegatexture;
|
|
651
|
+
// TODO: some of the megatexture state should be stored once, not duplicate for each megatexture
|
|
652
|
+
const megatexture = that.megatextures[0];
|
|
653
|
+
const keyframeNodesInMegatextureCount = megatexture.occupiedCount;
|
|
654
|
+
keyframeNodesInMegatexture.length = keyframeNodesInMegatextureCount;
|
|
655
|
+
keyframeNodesInMegatexture.sort(function (a, b) {
|
|
656
|
+
if (a.highPriorityFrameNumber === b.highPriorityFrameNumber) {
|
|
657
|
+
return b.priority - a.priority;
|
|
658
|
+
}
|
|
659
|
+
return b.highPriorityFrameNumber - a.highPriorityFrameNumber;
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
let destroyedCount = 0;
|
|
663
|
+
let addedCount = 0;
|
|
664
|
+
|
|
665
|
+
for (
|
|
666
|
+
let highPriorityKeyframeNodeIndex = 0;
|
|
667
|
+
highPriorityKeyframeNodeIndex < highPriorityKeyframeNodeCount;
|
|
668
|
+
highPriorityKeyframeNodeIndex++
|
|
669
|
+
) {
|
|
670
|
+
highPriorityKeyframeNode =
|
|
671
|
+
highPriorityKeyframeNodes[highPriorityKeyframeNodeIndex];
|
|
672
|
+
|
|
673
|
+
if (
|
|
674
|
+
highPriorityKeyframeNode.state === KeyframeNode.LoadState.LOADED ||
|
|
675
|
+
highPriorityKeyframeNode.spatialNode === undefined
|
|
676
|
+
) {
|
|
677
|
+
// Already loaded, so nothing to do.
|
|
678
|
+
// Or destroyed when adding a higher priority node
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
if (highPriorityKeyframeNode.state === KeyframeNode.LoadState.UNLOADED) {
|
|
682
|
+
requestData(that, highPriorityKeyframeNode);
|
|
683
|
+
}
|
|
684
|
+
if (highPriorityKeyframeNode.state === KeyframeNode.LoadState.RECEIVED) {
|
|
685
|
+
let addNodeIndex = 0;
|
|
686
|
+
if (megatexture.isFull()) {
|
|
687
|
+
// If the megatexture is full, try removing a discardable node with the lowest priority.
|
|
688
|
+
addNodeIndex = keyframeNodesInMegatextureCount - 1 - destroyedCount;
|
|
689
|
+
destroyedCount++;
|
|
690
|
+
|
|
691
|
+
const discardNode = keyframeNodesInMegatexture[addNodeIndex];
|
|
692
|
+
discardNode.spatialNode.destroyKeyframeNode(
|
|
693
|
+
discardNode,
|
|
694
|
+
that.megatextures
|
|
695
|
+
);
|
|
696
|
+
} else {
|
|
697
|
+
addNodeIndex = keyframeNodesInMegatextureCount + addedCount;
|
|
698
|
+
addedCount++;
|
|
699
|
+
}
|
|
700
|
+
highPriorityKeyframeNode.spatialNode.addKeyframeNodeToMegatextures(
|
|
701
|
+
highPriorityKeyframeNode,
|
|
702
|
+
that.megatextures
|
|
703
|
+
);
|
|
704
|
+
keyframeNodesInMegatexture[addNodeIndex] = highPriorityKeyframeNode;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Compute the X, Y, Z coordinates of the children of a node
|
|
711
|
+
* @param {SpatialNode} spatialNode The parent node
|
|
712
|
+
* @returns {Array[]} Child coordinate arrays
|
|
713
|
+
* @private
|
|
714
|
+
*/
|
|
715
|
+
function getChildCoords(spatialNode) {
|
|
716
|
+
const { x, y, z } = spatialNode;
|
|
717
|
+
const xMin = x * 2;
|
|
718
|
+
const yMin = y * 2;
|
|
719
|
+
const zMin = z * 2;
|
|
720
|
+
const yMax = yMin + 1;
|
|
721
|
+
const xMax = xMin + 1;
|
|
722
|
+
const zMax = zMin + 1;
|
|
723
|
+
|
|
724
|
+
return [
|
|
725
|
+
[xMin, yMin, zMin],
|
|
726
|
+
[xMax, yMin, zMin],
|
|
727
|
+
[xMin, yMax, zMin],
|
|
728
|
+
[xMax, yMax, zMin],
|
|
729
|
+
[xMin, yMin, zMax],
|
|
730
|
+
[xMax, yMin, zMax],
|
|
731
|
+
[xMin, yMax, zMax],
|
|
732
|
+
[xMax, yMax, zMax],
|
|
733
|
+
];
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* @function
|
|
738
|
+
*
|
|
739
|
+
* @param {VoxelTraversal} that
|
|
740
|
+
*
|
|
741
|
+
* @private
|
|
742
|
+
*/
|
|
743
|
+
function printDebugInformation(
|
|
744
|
+
that,
|
|
745
|
+
loadAndUnloadTimeMs,
|
|
746
|
+
generateOctreeTimeMs,
|
|
747
|
+
totalTimeMs
|
|
748
|
+
) {
|
|
749
|
+
const keyframeCount = that._keyframeCount;
|
|
750
|
+
const rootNode = that.rootNode;
|
|
751
|
+
|
|
752
|
+
const loadStateCount = Object.keys(KeyframeNode.LoadState).length;
|
|
753
|
+
const loadStatesByKeyframe = new Array(loadStateCount);
|
|
754
|
+
const loadStateByCount = new Array(loadStateCount);
|
|
755
|
+
let nodeCountTotal = 0;
|
|
756
|
+
|
|
757
|
+
for (
|
|
758
|
+
let loadStateIndex = 0;
|
|
759
|
+
loadStateIndex < loadStateCount;
|
|
760
|
+
loadStateIndex++
|
|
761
|
+
) {
|
|
762
|
+
const keyframeArray = new Array(keyframeCount);
|
|
763
|
+
loadStatesByKeyframe[loadStateIndex] = keyframeArray;
|
|
764
|
+
for (let i = 0; i < keyframeCount; i++) {
|
|
765
|
+
keyframeArray[i] = 0;
|
|
766
|
+
}
|
|
767
|
+
loadStateByCount[loadStateIndex] = 0;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* @ignore
|
|
772
|
+
* @param {SpatialNode} node
|
|
773
|
+
*/
|
|
774
|
+
function traverseRecursive(node) {
|
|
775
|
+
const keyframeNodes = node.keyframeNodes;
|
|
776
|
+
for (
|
|
777
|
+
let keyframeIndex = 0;
|
|
778
|
+
keyframeIndex < keyframeNodes.length;
|
|
779
|
+
keyframeIndex++
|
|
780
|
+
) {
|
|
781
|
+
const keyframeNode = keyframeNodes[keyframeIndex];
|
|
782
|
+
const keyframe = keyframeNode.keyframe;
|
|
783
|
+
const state = keyframeNode.state;
|
|
784
|
+
loadStatesByKeyframe[state][keyframe] += 1;
|
|
785
|
+
loadStateByCount[state] += 1;
|
|
786
|
+
nodeCountTotal++;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
if (defined(node.children)) {
|
|
790
|
+
for (let childIndex = 0; childIndex < 8; childIndex++) {
|
|
791
|
+
const child = node.children[childIndex];
|
|
792
|
+
traverseRecursive(child);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
traverseRecursive(rootNode);
|
|
797
|
+
|
|
798
|
+
const loadedKeyframeStatistics = `KEYFRAMES: ${
|
|
799
|
+
loadStatesByKeyframe[KeyframeNode.LoadState.LOADED]
|
|
800
|
+
}`;
|
|
801
|
+
const loadStateStatistics =
|
|
802
|
+
`UNLOADED: ${loadStateByCount[KeyframeNode.LoadState.UNLOADED]} | ` +
|
|
803
|
+
`RECEIVING: ${loadStateByCount[KeyframeNode.LoadState.RECEIVING]} | ` +
|
|
804
|
+
`RECEIVED: ${loadStateByCount[KeyframeNode.LoadState.RECEIVED]} | ` +
|
|
805
|
+
`LOADED: ${loadStateByCount[KeyframeNode.LoadState.LOADED]} | ` +
|
|
806
|
+
`FAILED: ${loadStateByCount[KeyframeNode.LoadState.FAILED]} | ` +
|
|
807
|
+
`UNAVAILABLE: ${loadStateByCount[KeyframeNode.LoadState.UNAVAILABLE]} | ` +
|
|
808
|
+
`TOTAL: ${nodeCountTotal}`;
|
|
809
|
+
|
|
810
|
+
const loadAndUnloadTimeMsRounded =
|
|
811
|
+
Math.round(loadAndUnloadTimeMs * 100) / 100;
|
|
812
|
+
const generateOctreeTimeMsRounded =
|
|
813
|
+
Math.round(generateOctreeTimeMs * 100) / 100;
|
|
814
|
+
const totalTimeMsRounded = Math.round(totalTimeMs * 100) / 100;
|
|
815
|
+
|
|
816
|
+
const timerStatistics =
|
|
817
|
+
`LOAD: ${loadAndUnloadTimeMsRounded} | ` +
|
|
818
|
+
`OCT: ${generateOctreeTimeMsRounded} | ` +
|
|
819
|
+
`ALL: ${totalTimeMsRounded}`;
|
|
820
|
+
|
|
821
|
+
console.log(
|
|
822
|
+
`${loadedKeyframeStatistics} || ${loadStateStatistics} || ${timerStatistics}`
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// GPU Octree Layout
|
|
827
|
+
// (shown as binary tree instead of octree for demonstration purposes)
|
|
828
|
+
//
|
|
829
|
+
// Tree representation:
|
|
830
|
+
// 0
|
|
831
|
+
// / \
|
|
832
|
+
// / \
|
|
833
|
+
// / \
|
|
834
|
+
// 1 3
|
|
835
|
+
// / \ / \
|
|
836
|
+
// L0 2 L3 L4
|
|
837
|
+
// / \
|
|
838
|
+
// L1 L2
|
|
839
|
+
//
|
|
840
|
+
//
|
|
841
|
+
// Array representation:
|
|
842
|
+
// L = leaf index
|
|
843
|
+
// * = index to parent node
|
|
844
|
+
// index: 0_______ 1________ 2________ 3_________
|
|
845
|
+
// array: [*0, 1, 3, *0, L0, 2, *1 L1, L2, *0, L3, L4]
|
|
846
|
+
//
|
|
847
|
+
// The array is generated from a depth-first traversal. The end result could be an unbalanced tree,
|
|
848
|
+
// so the parent index is stored at each node to make it possible to traverse upwards.
|
|
849
|
+
|
|
850
|
+
const GpuOctreeFlag = {
|
|
851
|
+
// Data is an octree index.
|
|
852
|
+
INTERNAL: 0,
|
|
853
|
+
// Data is a leaf node.
|
|
854
|
+
LEAF: 1,
|
|
855
|
+
// When leaf data is packed in the octree and there's a node that is forced to
|
|
856
|
+
// render but has no data of its own (such as when its siblings are renderable but it
|
|
857
|
+
// is not), signal that it's using its parent's data.
|
|
858
|
+
PACKED_LEAF_FROM_PARENT: 2,
|
|
859
|
+
};
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* @function
|
|
863
|
+
*
|
|
864
|
+
* @param {VoxelTraversal} that
|
|
865
|
+
* @param {FrameState} frameState
|
|
866
|
+
* @param {Number} sampleCount
|
|
867
|
+
* @param {Number} levelBlendFactor
|
|
868
|
+
* @private
|
|
869
|
+
*/
|
|
870
|
+
function generateOctree(that, sampleCount, levelBlendFactor) {
|
|
871
|
+
const targetSse = that._primitive._screenSpaceError;
|
|
872
|
+
const keyframeLocation = that._keyframeLocation;
|
|
873
|
+
const frameNumber = that._frameNumber;
|
|
874
|
+
const useLeafNodes = sampleCount >= 2;
|
|
875
|
+
|
|
876
|
+
let internalNodeCount = 0;
|
|
877
|
+
let leafNodeCount = 0;
|
|
878
|
+
const internalNodeOctreeData = [];
|
|
879
|
+
const leafNodeOctreeData = [];
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* @ignore
|
|
883
|
+
* @param {SpatialNode} node
|
|
884
|
+
* @param {Number} childOctreeIndex
|
|
885
|
+
* @param {Number} childEntryIndex
|
|
886
|
+
* @param {Number} parentOctreeIndex
|
|
887
|
+
* @param {Number} parentEntryIndex
|
|
888
|
+
*/
|
|
889
|
+
function buildOctree(
|
|
890
|
+
node,
|
|
891
|
+
childOctreeIndex,
|
|
892
|
+
childEntryIndex,
|
|
893
|
+
parentOctreeIndex,
|
|
894
|
+
parentEntryIndex
|
|
895
|
+
) {
|
|
896
|
+
let hasRenderableChildren = false;
|
|
897
|
+
if (defined(node.children)) {
|
|
898
|
+
for (let c = 0; c < 8; c++) {
|
|
899
|
+
const childNode = node.children[c];
|
|
900
|
+
childNode.computeSurroundingRenderableKeyframeNodes(keyframeLocation);
|
|
901
|
+
if (childNode.isRenderable(frameNumber)) {
|
|
902
|
+
hasRenderableChildren = true;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
if (hasRenderableChildren) {
|
|
908
|
+
// Point the parent and child octree indexes at each other
|
|
909
|
+
internalNodeOctreeData[parentEntryIndex] =
|
|
910
|
+
(GpuOctreeFlag.INTERNAL << 16) | childOctreeIndex;
|
|
911
|
+
internalNodeOctreeData[childEntryIndex] = parentOctreeIndex;
|
|
912
|
+
internalNodeCount++;
|
|
913
|
+
|
|
914
|
+
// Recurse over children
|
|
915
|
+
parentOctreeIndex = childOctreeIndex;
|
|
916
|
+
parentEntryIndex = parentOctreeIndex * 9 + 1;
|
|
917
|
+
for (let cc = 0; cc < 8; cc++) {
|
|
918
|
+
const child = node.children[cc];
|
|
919
|
+
childOctreeIndex = internalNodeCount;
|
|
920
|
+
childEntryIndex = childOctreeIndex * 9 + 0;
|
|
921
|
+
buildOctree(
|
|
922
|
+
child,
|
|
923
|
+
childOctreeIndex,
|
|
924
|
+
childEntryIndex,
|
|
925
|
+
parentOctreeIndex,
|
|
926
|
+
parentEntryIndex + cc
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
} else {
|
|
930
|
+
// Store the leaf node information instead
|
|
931
|
+
// Recursion stops here because there are no renderable children
|
|
932
|
+
if (useLeafNodes) {
|
|
933
|
+
const baseIdx = leafNodeCount * 5;
|
|
934
|
+
const keyframeNode = node.renderableKeyframeNodePrevious;
|
|
935
|
+
const levelDifference = node.level - keyframeNode.spatialNode.level;
|
|
936
|
+
|
|
937
|
+
const parentNode = keyframeNode.spatialNode.parent;
|
|
938
|
+
const parentKeyframeNode = defined(parentNode)
|
|
939
|
+
? parentNode.renderableKeyframeNodePrevious
|
|
940
|
+
: keyframeNode;
|
|
941
|
+
|
|
942
|
+
const lodLerp = getLodLerp(node, targetSse, levelBlendFactor);
|
|
943
|
+
const levelDifferenceChild = levelDifference;
|
|
944
|
+
const levelDifferenceParent = 1;
|
|
945
|
+
const megatextureIndexChild = keyframeNode.megatextureIndex;
|
|
946
|
+
const megatextureIndexParent = parentKeyframeNode.megatextureIndex;
|
|
947
|
+
|
|
948
|
+
leafNodeOctreeData[baseIdx + 0] = lodLerp;
|
|
949
|
+
leafNodeOctreeData[baseIdx + 1] = levelDifferenceChild;
|
|
950
|
+
leafNodeOctreeData[baseIdx + 2] = levelDifferenceParent;
|
|
951
|
+
leafNodeOctreeData[baseIdx + 3] = megatextureIndexChild;
|
|
952
|
+
leafNodeOctreeData[baseIdx + 4] = megatextureIndexParent;
|
|
953
|
+
|
|
954
|
+
internalNodeOctreeData[parentEntryIndex] =
|
|
955
|
+
(GpuOctreeFlag.LEAF << 16) | leafNodeCount;
|
|
956
|
+
} else {
|
|
957
|
+
const keyframeNode = node.renderableKeyframeNodePrevious;
|
|
958
|
+
const levelDifference = node.level - keyframeNode.spatialNode.level;
|
|
959
|
+
const flag =
|
|
960
|
+
levelDifference === 0
|
|
961
|
+
? GpuOctreeFlag.LEAF
|
|
962
|
+
: GpuOctreeFlag.PACKED_LEAF_FROM_PARENT;
|
|
963
|
+
internalNodeOctreeData[parentEntryIndex] =
|
|
964
|
+
(flag << 16) | keyframeNode.megatextureIndex;
|
|
965
|
+
}
|
|
966
|
+
leafNodeCount++;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
const rootNode = that.rootNode;
|
|
971
|
+
rootNode.computeSurroundingRenderableKeyframeNodes(keyframeLocation);
|
|
972
|
+
if (rootNode.isRenderable(frameNumber)) {
|
|
973
|
+
buildOctree(rootNode, 0, 0, 0, 0);
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
copyToInternalNodeTexture(
|
|
977
|
+
internalNodeOctreeData,
|
|
978
|
+
9,
|
|
979
|
+
that.internalNodeTilesPerRow,
|
|
980
|
+
that.internalNodeTexture
|
|
981
|
+
);
|
|
982
|
+
if (useLeafNodes) {
|
|
983
|
+
copyToLeafNodeTexture(
|
|
984
|
+
leafNodeOctreeData,
|
|
985
|
+
2,
|
|
986
|
+
that.leafNodeTilesPerRow,
|
|
987
|
+
that.leafNodeTexture
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* Compute an interpolation factor between a node and its parent
|
|
994
|
+
* @param {SpatialNode} node
|
|
995
|
+
* @param {Number} targetSse
|
|
996
|
+
* @param {Number} levelBlendFactor
|
|
997
|
+
* @returns {Number}
|
|
998
|
+
* @private
|
|
999
|
+
*/
|
|
1000
|
+
function getLodLerp(node, targetSse, levelBlendFactor) {
|
|
1001
|
+
if (node.parent === undefined) {
|
|
1002
|
+
return 0.0;
|
|
1003
|
+
}
|
|
1004
|
+
const sse = node.screenSpaceError;
|
|
1005
|
+
const parentSse = node.parent.screenSpaceError;
|
|
1006
|
+
const lodLerp = (targetSse - sse) / (parentSse - sse);
|
|
1007
|
+
const blended = (lodLerp + levelBlendFactor - 1.0) / levelBlendFactor;
|
|
1008
|
+
|
|
1009
|
+
return CesiumMath.clamp(blended, 0.0, 1.0);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
*
|
|
1014
|
+
* @param {Number[]} data
|
|
1015
|
+
* @param {Number} texelsPerTile
|
|
1016
|
+
* @param {Number} tilesPerRow
|
|
1017
|
+
* @param {Texture} texture
|
|
1018
|
+
* @private
|
|
1019
|
+
*/
|
|
1020
|
+
function copyToInternalNodeTexture(data, texelsPerTile, tilesPerRow, texture) {
|
|
1021
|
+
const channelCount = PixelFormat.componentsLength(texture.pixelFormat);
|
|
1022
|
+
const tileCount = Math.ceil(data.length / texelsPerTile);
|
|
1023
|
+
const copyWidth = Math.max(
|
|
1024
|
+
1,
|
|
1025
|
+
texelsPerTile * Math.min(tileCount, tilesPerRow)
|
|
1026
|
+
);
|
|
1027
|
+
const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow));
|
|
1028
|
+
|
|
1029
|
+
const textureData = new Uint8Array(copyWidth * copyHeight * channelCount);
|
|
1030
|
+
for (let i = 0; i < data.length; i++) {
|
|
1031
|
+
const val = data[i];
|
|
1032
|
+
const startIndex = i * channelCount;
|
|
1033
|
+
for (let j = 0; j < channelCount; j++) {
|
|
1034
|
+
textureData[startIndex + j] = (val >>> (j * 8)) & 0xff;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
const source = {
|
|
1039
|
+
arrayBufferView: textureData,
|
|
1040
|
+
width: copyWidth,
|
|
1041
|
+
height: copyHeight,
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
const copyOptions = {
|
|
1045
|
+
source: source,
|
|
1046
|
+
xOffset: 0,
|
|
1047
|
+
yOffset: 0,
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
texture.copyFrom(copyOptions);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
*
|
|
1055
|
+
* @param {Number[]} data
|
|
1056
|
+
* @param {Number} texelsPerTile
|
|
1057
|
+
* @param {Number} tilesPerRow
|
|
1058
|
+
* @param {Texture} texture
|
|
1059
|
+
* @private
|
|
1060
|
+
*/
|
|
1061
|
+
function copyToLeafNodeTexture(data, texelsPerTile, tilesPerRow, texture) {
|
|
1062
|
+
const channelCount = PixelFormat.componentsLength(texture.pixelFormat);
|
|
1063
|
+
const datasPerTile = 5;
|
|
1064
|
+
const tileCount = Math.ceil(data.length / datasPerTile);
|
|
1065
|
+
const copyWidth = Math.max(
|
|
1066
|
+
1,
|
|
1067
|
+
texelsPerTile * Math.min(tileCount, tilesPerRow)
|
|
1068
|
+
);
|
|
1069
|
+
const copyHeight = Math.max(1, Math.ceil(tileCount / tilesPerRow));
|
|
1070
|
+
|
|
1071
|
+
const textureData = new Uint8Array(copyWidth * copyHeight * channelCount);
|
|
1072
|
+
for (let tileIndex = 0; tileIndex < tileCount; tileIndex++) {
|
|
1073
|
+
const timeLerp = data[tileIndex * datasPerTile + 0];
|
|
1074
|
+
const previousKeyframeLevelsAbove = data[tileIndex * datasPerTile + 1];
|
|
1075
|
+
const nextKeyframeLevelsAbove = data[tileIndex * datasPerTile + 2];
|
|
1076
|
+
const previousKeyframeMegatextureIndex = data[tileIndex * datasPerTile + 3];
|
|
1077
|
+
const nextKeyframeMegatextureIndex = data[tileIndex * datasPerTile + 4];
|
|
1078
|
+
|
|
1079
|
+
const timeLerpCompressed = CesiumMath.clamp(
|
|
1080
|
+
Math.floor(65536 * timeLerp),
|
|
1081
|
+
0,
|
|
1082
|
+
65535
|
|
1083
|
+
);
|
|
1084
|
+
textureData[tileIndex * 8 + 0] = (timeLerpCompressed >>> 0) & 0xff;
|
|
1085
|
+
textureData[tileIndex * 8 + 1] = (timeLerpCompressed >>> 8) & 0xff;
|
|
1086
|
+
textureData[tileIndex * 8 + 2] = previousKeyframeLevelsAbove & 0xff;
|
|
1087
|
+
textureData[tileIndex * 8 + 3] = nextKeyframeLevelsAbove & 0xff;
|
|
1088
|
+
textureData[tileIndex * 8 + 4] =
|
|
1089
|
+
(previousKeyframeMegatextureIndex >>> 0) & 0xff;
|
|
1090
|
+
textureData[tileIndex * 8 + 5] =
|
|
1091
|
+
(previousKeyframeMegatextureIndex >>> 8) & 0xff;
|
|
1092
|
+
textureData[tileIndex * 8 + 6] =
|
|
1093
|
+
(nextKeyframeMegatextureIndex >>> 0) & 0xff;
|
|
1094
|
+
textureData[tileIndex * 8 + 7] =
|
|
1095
|
+
(nextKeyframeMegatextureIndex >>> 8) & 0xff;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
const source = {
|
|
1099
|
+
arrayBufferView: textureData,
|
|
1100
|
+
width: copyWidth,
|
|
1101
|
+
height: copyHeight,
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1104
|
+
const copyOptions = {
|
|
1105
|
+
source: source,
|
|
1106
|
+
xOffset: 0,
|
|
1107
|
+
yOffset: 0,
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
texture.copyFrom(copyOptions);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* @param {Number} tileCount
|
|
1115
|
+
* @param {Cartesian3} dimensions
|
|
1116
|
+
* @param {MetadataType[]} types
|
|
1117
|
+
* @param {MetadataComponentType[]} componentTypes
|
|
1118
|
+
*/
|
|
1119
|
+
VoxelTraversal.getApproximateTextureMemoryByteLength = function (
|
|
1120
|
+
tileCount,
|
|
1121
|
+
dimensions,
|
|
1122
|
+
types,
|
|
1123
|
+
componentTypes
|
|
1124
|
+
) {
|
|
1125
|
+
let textureMemoryByteLength = 0;
|
|
1126
|
+
|
|
1127
|
+
const length = types.length;
|
|
1128
|
+
for (let i = 0; i < length; i++) {
|
|
1129
|
+
const type = types[i];
|
|
1130
|
+
const componentType = componentTypes[i];
|
|
1131
|
+
const componentCount = MetadataType.getComponentCount(type);
|
|
1132
|
+
|
|
1133
|
+
textureMemoryByteLength += Megatexture.getApproximateTextureMemoryByteLength(
|
|
1134
|
+
tileCount,
|
|
1135
|
+
dimensions,
|
|
1136
|
+
componentCount,
|
|
1137
|
+
componentType
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
return textureMemoryByteLength;
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
export default VoxelTraversal;
|