diff --git a/packages/engine/Source/Core/Credit.js b/packages/engine/Source/Core/Credit.js
index 98525c04c79..23b9caea8ed 100644
--- a/packages/engine/Source/Core/Credit.js
+++ b/packages/engine/Source/Core/Credit.js
@@ -166,7 +166,8 @@ Credit.getIonCredit = function (attribution) {
*/
Credit.clone = function (credit) {
if (defined(credit)) {
- return new Credit(credit.html, credit.showOnScreen);
+ return credit;
+ // return new Credit(credit.html, credit.showOnScreen);
}
};
export default Credit;
diff --git a/packages/engine/Source/Core/Matrix3.js b/packages/engine/Source/Core/Matrix3.js
index 7a7ab6c3213..7887f3c53ba 100644
--- a/packages/engine/Source/Core/Matrix3.js
+++ b/packages/engine/Source/Core/Matrix3.js
@@ -35,28 +35,30 @@ import CesiumMath from "./Math.js";
* @see Matrix2
* @see Matrix4
*/
-function Matrix3(
- column0Row0,
- column1Row0,
- column2Row0,
- column0Row1,
- column1Row1,
- column2Row1,
- column0Row2,
- column1Row2,
- column2Row2,
-) {
- this[0] = column0Row0 ?? 0.0;
- this[1] = column0Row1 ?? 0.0;
- this[2] = column0Row2 ?? 0.0;
- this[3] = column1Row0 ?? 0.0;
- this[4] = column1Row1 ?? 0.0;
- this[5] = column1Row2 ?? 0.0;
- this[6] = column2Row0 ?? 0.0;
- this[7] = column2Row1 ?? 0.0;
- this[8] = column2Row2 ?? 0.0;
+class Matrix3 extends Float64Array {
+ constructor(
+ column0Row0,
+ column1Row0,
+ column2Row0,
+ column0Row1,
+ column1Row1,
+ column2Row1,
+ column0Row2,
+ column1Row2,
+ column2Row2,
+ ) {
+ super(9);
+ this[0] = column0Row0 ?? 0.0;
+ this[1] = column0Row1 ?? 0.0;
+ this[2] = column0Row2 ?? 0.0;
+ this[3] = column1Row0 ?? 0.0;
+ this[4] = column1Row1 ?? 0.0;
+ this[5] = column1Row2 ?? 0.0;
+ this[6] = column2Row0 ?? 0.0;
+ this[7] = column2Row1 ?? 0.0;
+ this[8] = column2Row2 ?? 0.0;
+ }
}
-
/**
* The number of elements used to pack the object into an array.
* @type {number}
@@ -1671,9 +1673,7 @@ Matrix3.equalsEpsilon = function (left, right, epsilon) {
* @type {Matrix3}
* @constant
*/
-Matrix3.IDENTITY = Object.freeze(
- new Matrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0),
-);
+Matrix3.IDENTITY = new Matrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
/**
* An immutable Matrix3 instance initialized to the zero matrix.
@@ -1681,9 +1681,7 @@ Matrix3.IDENTITY = Object.freeze(
* @type {Matrix3}
* @constant
*/
-Matrix3.ZERO = Object.freeze(
- new Matrix3(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
-);
+Matrix3.ZERO = new Matrix3(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
/**
* The index into Matrix3 for column 0, row 0.
diff --git a/packages/engine/Source/Core/Matrix4.js b/packages/engine/Source/Core/Matrix4.js
index f30b8a73390..80e0afeea83 100644
--- a/packages/engine/Source/Core/Matrix4.js
+++ b/packages/engine/Source/Core/Matrix4.js
@@ -53,40 +53,43 @@ import RuntimeError from "./RuntimeError.js";
* @see Matrix3
* @see Packable
*/
-function Matrix4(
- column0Row0,
- column1Row0,
- column2Row0,
- column3Row0,
- column0Row1,
- column1Row1,
- column2Row1,
- column3Row1,
- column0Row2,
- column1Row2,
- column2Row2,
- column3Row2,
- column0Row3,
- column1Row3,
- column2Row3,
- column3Row3,
-) {
- this[0] = column0Row0 ?? 0.0;
- this[1] = column0Row1 ?? 0.0;
- this[2] = column0Row2 ?? 0.0;
- this[3] = column0Row3 ?? 0.0;
- this[4] = column1Row0 ?? 0.0;
- this[5] = column1Row1 ?? 0.0;
- this[6] = column1Row2 ?? 0.0;
- this[7] = column1Row3 ?? 0.0;
- this[8] = column2Row0 ?? 0.0;
- this[9] = column2Row1 ?? 0.0;
- this[10] = column2Row2 ?? 0.0;
- this[11] = column2Row3 ?? 0.0;
- this[12] = column3Row0 ?? 0.0;
- this[13] = column3Row1 ?? 0.0;
- this[14] = column3Row2 ?? 0.0;
- this[15] = column3Row3 ?? 0.0;
+class Matrix4 extends Float64Array {
+ constructor(
+ column0Row0,
+ column1Row0,
+ column2Row0,
+ column3Row0,
+ column0Row1,
+ column1Row1,
+ column2Row1,
+ column3Row1,
+ column0Row2,
+ column1Row2,
+ column2Row2,
+ column3Row2,
+ column0Row3,
+ column1Row3,
+ column2Row3,
+ column3Row3,
+ ) {
+ super(16);
+ this[0] = column0Row0 ?? 0.0;
+ this[1] = column0Row1 ?? 0.0;
+ this[2] = column0Row2 ?? 0.0;
+ this[3] = column0Row3 ?? 0.0;
+ this[4] = column1Row0 ?? 0.0;
+ this[5] = column1Row1 ?? 0.0;
+ this[6] = column1Row2 ?? 0.0;
+ this[7] = column1Row3 ?? 0.0;
+ this[8] = column2Row0 ?? 0.0;
+ this[9] = column2Row1 ?? 0.0;
+ this[10] = column2Row2 ?? 0.0;
+ this[11] = column2Row3 ?? 0.0;
+ this[12] = column3Row0 ?? 0.0;
+ this[13] = column3Row1 ?? 0.0;
+ this[14] = column3Row2 ?? 0.0;
+ this[15] = column3Row3 ?? 0.0;
+ }
}
/**
@@ -1929,41 +1932,23 @@ Matrix4.multiplyTransformation = function (left, right, result) {
const right13 = right[13];
const right14 = right[14];
- const column0Row0 = left0 * right0 + left4 * right1 + left8 * right2;
- const column0Row1 = left1 * right0 + left5 * right1 + left9 * right2;
- const column0Row2 = left2 * right0 + left6 * right1 + left10 * right2;
-
- const column1Row0 = left0 * right4 + left4 * right5 + left8 * right6;
- const column1Row1 = left1 * right4 + left5 * right5 + left9 * right6;
- const column1Row2 = left2 * right4 + left6 * right5 + left10 * right6;
-
- const column2Row0 = left0 * right8 + left4 * right9 + left8 * right10;
- const column2Row1 = left1 * right8 + left5 * right9 + left9 * right10;
- const column2Row2 = left2 * right8 + left6 * right9 + left10 * right10;
-
- const column3Row0 =
- left0 * right12 + left4 * right13 + left8 * right14 + left12;
- const column3Row1 =
- left1 * right12 + left5 * right13 + left9 * right14 + left13;
- const column3Row2 =
- left2 * right12 + left6 * right13 + left10 * right14 + left14;
-
- result[0] = column0Row0;
- result[1] = column0Row1;
- result[2] = column0Row2;
+ result[0] = left0 * right0 + left4 * right1 + left8 * right2;
+ result[1] = left1 * right0 + left5 * right1 + left9 * right2;
+ result[2] = left2 * right0 + left6 * right1 + left10 * right2;
result[3] = 0.0;
- result[4] = column1Row0;
- result[5] = column1Row1;
- result[6] = column1Row2;
+ result[4] = left0 * right4 + left4 * right5 + left8 * right6;
+ result[5] = left1 * right4 + left5 * right5 + left9 * right6;
+ result[6] = left2 * right4 + left6 * right5 + left10 * right6;
result[7] = 0.0;
- result[8] = column2Row0;
- result[9] = column2Row1;
- result[10] = column2Row2;
+ result[8] = left0 * right8 + left4 * right9 + left8 * right10;
+ result[9] = left1 * right8 + left5 * right9 + left9 * right10;
+ result[10] = left2 * right8 + left6 * right9 + left10 * right10;
result[11] = 0.0;
- result[12] = column3Row0;
- result[13] = column3Row1;
- result[14] = column3Row2;
+ result[12] = left0 * right12 + left4 * right13 + left8 * right14 + left12;
+ result[13] = left1 * right12 + left5 * right13 + left9 * right14 + left13;
+ result[14] = left2 * right12 + left6 * right13 + left10 * right14 + left14;
result[15] = 1.0;
+
return result;
};
@@ -2968,25 +2953,23 @@ Matrix4.inverseTranspose = function (matrix, result) {
* @type {Matrix4}
* @constant
*/
-Matrix4.IDENTITY = Object.freeze(
- new Matrix4(
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
- ),
+Matrix4.IDENTITY = new Matrix4(
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
);
/**
@@ -2995,25 +2978,23 @@ Matrix4.IDENTITY = Object.freeze(
* @type {Matrix4}
* @constant
*/
-Matrix4.ZERO = Object.freeze(
- new Matrix4(
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ),
+Matrix4.ZERO = new Matrix4(
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
);
/**
diff --git a/packages/engine/Source/Scene/Cesium3DTilesetStatistics.js b/packages/engine/Source/Scene/Cesium3DTilesetStatistics.js
index 17b094f33ad..c70b1c40aca 100644
--- a/packages/engine/Source/Scene/Cesium3DTilesetStatistics.js
+++ b/packages/engine/Source/Scene/Cesium3DTilesetStatistics.js
@@ -30,7 +30,7 @@ function Cesium3DTilesetStatistics() {
// Memory statistics
this.geometryByteLength = 0;
this.texturesByteLength = 0;
- this.texturesReferenceCounterById = {};
+ this.texturesReferenceCounterById = new Map();
this.batchTableByteLength = 0; // batch textures and any binary metadata properties not otherwise accounted for
}
@@ -100,12 +100,12 @@ Cesium3DTilesetStatistics.prototype.incrementLoadCounts = function (content) {
const textureIds = content.getTextureIds();
for (const textureId of textureIds) {
const referenceCounter =
- this.texturesReferenceCounterById[textureId] ?? 0;
+ this.texturesReferenceCounterById.get(textureId) ?? 0;
if (referenceCounter === 0) {
const textureByteLength = content.getTextureByteLengthById(textureId);
this.texturesByteLength += textureByteLength;
}
- this.texturesReferenceCounterById[textureId] = referenceCounter + 1;
+ this.texturesReferenceCounterById.set(textureId, referenceCounter + 1);
}
}
@@ -146,13 +146,13 @@ Cesium3DTilesetStatistics.prototype.decrementLoadCounts = function (content) {
// total textures byte length
const textureIds = content.getTextureIds();
for (const textureId of textureIds) {
- const referenceCounter = this.texturesReferenceCounterById[textureId];
+ const referenceCounter = this.texturesReferenceCounterById.get(textureId);
if (referenceCounter === 1) {
- delete this.texturesReferenceCounterById[textureId];
+ this.texturesReferenceCounterById.delete(textureId);
const textureByteLength = content.getTextureByteLengthById(textureId);
this.texturesByteLength -= textureByteLength;
} else {
- this.texturesReferenceCounterById[textureId] = referenceCounter - 1;
+ this.texturesReferenceCounterById.set(textureId, referenceCounter - 1);
}
}
}
@@ -187,9 +187,7 @@ Cesium3DTilesetStatistics.clone = function (statistics, result) {
statistics.numberOfTilesCulledWithChildrenUnion;
result.geometryByteLength = statistics.geometryByteLength;
result.texturesByteLength = statistics.texturesByteLength;
- result.texturesReferenceCounterById = {
- ...statistics.texturesReferenceCounterById,
- };
+ result.texturesReferenceCounterById = statistics.texturesReferenceCounterById;
result.batchTableByteLength = statistics.batchTableByteLength;
};
export default Cesium3DTilesetStatistics;
diff --git a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js
index fd13b76d9d4..7ecc0681303 100644
--- a/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js
+++ b/packages/engine/Source/Scene/Cesium3DTilesetTraversal.js
@@ -188,6 +188,11 @@ function isOnScreenLongEnough(tile, frameState) {
* @param {FrameState} frameState
*/
Cesium3DTilesetTraversal.updateTile = function (tile, frameState) {
+ if (tile._visitedFrame === frameState.frameNumber) {
+ // Prevents another pass from visiting the frame again
+ return;
+ }
+ Cesium3DTilesetTraversal.visitTile(tile, frameState);
updateTileVisibility(tile, frameState);
tile.updateExpiration();
@@ -279,6 +284,9 @@ function anyChildrenVisible(tile, frameState) {
const child = children[i];
child.updateVisibility(frameState);
anyVisible = anyVisible || child.isVisible;
+ if (anyVisible) {
+ break;
+ }
}
return anyVisible;
}
diff --git a/packages/engine/Source/Scene/Scene.js b/packages/engine/Source/Scene/Scene.js
index 16149ca8b23..4cc389eb629 100644
--- a/packages/engine/Source/Scene/Scene.js
+++ b/packages/engine/Source/Scene/Scene.js
@@ -3831,12 +3831,23 @@ function callAfterRenderFunctions(scene) {
functions.length = 0;
}
+/**
+ * @param {Scene} scene
+ * @returns {Number|undefined} The height of the globe at the camera position, or undefined if the height cannot be determined.
+ */
function getGlobeHeight(scene) {
- if (scene.mode === SceneMode.MORPHING) {
+ if (
+ scene.mode === SceneMode.MORPHING ||
+ scene._screenSpaceCameraController.collisionHeightReference ===
+ HeightReference.NONE
+ ) {
return;
}
const cartographic = scene.camera.positionCartographic;
- return scene.getHeight(cartographic);
+ return scene.getHeight(
+ cartographic,
+ scene._screenSpaceCameraController.collisionHeightReference,
+ );
}
function getMaxPrimitiveHeight(primitive, cartographic, scene) {
diff --git a/packages/engine/Source/Scene/ScreenSpaceCameraController.js b/packages/engine/Source/Scene/ScreenSpaceCameraController.js
index d4864da3e04..ccf9e788962 100644
--- a/packages/engine/Source/Scene/ScreenSpaceCameraController.js
+++ b/packages/engine/Source/Scene/ScreenSpaceCameraController.js
@@ -24,6 +24,7 @@ import MapMode2D from "./MapMode2D.js";
import SceneMode from "./SceneMode.js";
import SceneTransforms from "./SceneTransforms.js";
import TweenCollection from "./TweenCollection.js";
+import HeightReference from "./HeightReference.js";
/**
* Modifies the camera position and orientation based on mouse input to a canvas.
@@ -265,13 +266,13 @@ function ScreenSpaceCameraController(scene) {
: ellipsoid.minimumRadius * 1.175;
this._minimumTrackBallHeight = this.minimumTrackBallHeight;
/**
- * When disabled, the values of maximumZoomDistance and minimumZoomDistance are ignored.
- * Also used in conjunction with {@link Cesium3DTileset#enableCollision} to prevent the camera from moving through or below a 3D Tileset surface.
- * This may also affect clamping behavior when using {@link HeightReference.CLAMP_TO_GROUND} on 3D Tiles.
- * @type {boolean}
- * @default true
+ * This value controls the height reference for the {@link ScreenSpaceCameraController} collision, which is used to limit the camera minimum and maximum zoom.
+ * When set to {@link HeightReference.NONE}, the camera can go underground, and the values of maximumZoomDistance and minimumZoomDistance are ignored.
+ * For all other values, the camera is constrained to be above the terrain and/or 3D Tiles (depending on {@link Cesium3DTileset#enableCollision}).
+ * @type {HeightReference}
+ * @default HeightReference.CLAMP_TO_GROUND
*/
- this.enableCollisionDetection = true;
+ this.collisionHeightReference = HeightReference.CLAMP_TO_GROUND;
/**
* The angle, relative to the ellipsoid normal, restricting the maximum amount that the user can tilt the camera. If undefined, the angle of the camera tilt is unrestricted.
* @type {number|undefined}
@@ -353,6 +354,27 @@ function ScreenSpaceCameraController(scene) {
this._maximumUndergroundPickDistance = 10000.0;
}
+Object.defineProperties(ScreenSpaceCameraController.prototype, {
+ /**
+ * When disabled, the values of maximumZoomDistance and minimumZoomDistance are ignored.
+ * Also used in conjunction with {@link Cesium3DTileset#enableCollision} to prevent the camera from moving through or below a 3D Tileset surface.
+ * This may also affect clamping behavior when using {@link HeightReference.CLAMP_TO_GROUND} on 3D Tiles.
+ * @type {boolean}
+ * @default true
+ * @deprecated Use {@link ScreenSpaceCameraController#collisionHeightReference} instead.
+ */
+ enableCollisionDetection: {
+ get: function () {
+ return this.collisionHeightReference !== HeightReference.NONE;
+ },
+ set: function (value) {
+ this.collisionHeightReference = value
+ ? HeightReference.CLAMP_TO_GROUND
+ : HeightReference.NONE;
+ },
+ },
+});
+
function decay(time, coefficient) {
if (time < 0) {
return 0.0;
@@ -556,6 +578,16 @@ const scratchZoomViewOptions = {
orientation: new HeadingPitchRoll(),
};
+/**
+ *
+ * @param {ScreenSpaceCameraController} object
+ * @param {*} startPosition
+ * @param {*} movement
+ * @param {*} zoomFactor
+ * @param {*} distanceMeasure
+ * @param {*} unitPositionDotDirection
+ * @returns
+ */
function handleZoom(
object,
startPosition,