Skip to content

Commit

Permalink
enableCameraCollision option
Browse files Browse the repository at this point in the history
  • Loading branch information
ggetz committed Dec 6, 2023
1 parent e206e8b commit c95f426
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 46 deletions.
2 changes: 1 addition & 1 deletion Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@
// MAXAR OWT WFF 1.2 Base Globe
tileset = await Cesium.Cesium3DTileset.fromIonAssetId(691510, {
maximumScreenSpaceError: 4,
enableCameraCollision: true,
});
scene.primitives.add(tileset);
scene.enableCollisionDetectionForTileset(tileset);
} catch (error) {
console.log(`Error loading tileset: ${error}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
try {
const googleTileset = await Cesium.createGooglePhotorealistic3DTileset();
viewer.scene.primitives.add(googleTileset);
viewer.scene.enableCollisionDetectionForTileset(googleTileset);
} catch (error) {
console.log(`Error loading Photorealistic 3D Tiles tileset.
${error}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
try {
const tileset = await Cesium.createGooglePhotorealistic3DTileset();
viewer.scene.primitives.add(tileset);
viewer.scene.enableCollisionDetectionForTileset(tileset);
} catch (error) {
console.log(`Error loading Photorealistic 3D Tiles tileset.
${error}`);
Expand Down
39 changes: 29 additions & 10 deletions packages/engine/Source/Scene/Cesium3DTileset.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,13 @@ import Ray from "../Core/Ray.js";
* @property {string|number} [instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority.
* @property {boolean} [showCreditsOnScreen=false] Whether to display the credits of this tileset on screen.
* @property {SplitDirection} [splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this tileset.
* @property {boolean} [projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has loaded.
* @property {boolean} [options.enablePick=false] Whether to allow with CPU picking with <code>pick</code> when not using WebGL 2 or above. If using WebGL 2 or above, this option will be ignored. If using WebGL 1 and this is true, the <code>pick</code> operation will work correctly, but it will use more memory to do so. If running with WebGL 1 and this is false, the model will use less memory, but <code>pick</code> will always return <code>undefined</code>. This cannot be set after the tileset has loaded.
* @property {boolean} [enableCameraCollision=false] When {@link ScreenSpaceCameraController#enableCollisionDetection} is true, prevents the camera from going below the tileset surface.
* @property {boolean} [projectTo2D=false] Whether to accurately project the tileset to 2D. If this is true, the tileset will be projected accurately to 2D, but it will use more memory to do so. If this is false, the tileset will use less memory and will still render in 2D / CV mode, but its projected positions may be inaccurate. This cannot be set after the tileset has been created.
* @property {boolean} [enablePick=false] Whether to allow with CPU picking with <code>pick</code> when not using WebGL 2 or above. If using WebGL 2 or above, this option will be ignored. If using WebGL 1 and this is true, the <code>pick</code> operation will work correctly, but it will use more memory to do so. If running with WebGL 1 and this is false, the model will use less memory, but <code>pick</code> will always return <code>undefined</code>. This cannot be set after the tileset has loaded.
* @property {string} [debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value.
* @property {boolean} [debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering.
* @property {boolean} [debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile.
* @property {boolean} [enableDebugWireframe] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has loaded.
* @property {boolean} [enableDebugWireframe=false] For debugging only. This must be true for debugWireframe to work in WebGL1. This cannot be set after the tileset has been created.
* @property {boolean} [debugWireframe=false] For debugging only. When true, render's each tile's content as a wireframe.
* @property {boolean} [debugShowBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile.
* @property {boolean} [debugShowContentBoundingVolume=false] For debugging only. When true, renders the bounding volume for each tile's content.
Expand Down Expand Up @@ -826,8 +827,23 @@ function Cesium3DTileset(options) {
SplitDirection.NONE
);

/**
* When {@link ScreenSpaceCameraController#enableCollisionDetection} is true, prevents the camera from going below the tileset surface.
* If using WebGL 1, {@link Cesium3DTileset#ConstructorOptions} <code>enablePick</code> must be true for this behavior to work.
*
* @type {boolean}
* @default false
*/
this.enableCameraCollision = defaultValue(
options.enableCameraCollision,
false
);

this._projectTo2D = defaultValue(options.projectTo2D, false);
this._enablePick = defaultValue(options.enablePick, false);
this._enablePick = defaultValue(
options.enablePick,
this.enableCameraCollision
);

/**
* This property is for debugging only; it is not optimized for production use.
Expand Down Expand Up @@ -3407,17 +3423,20 @@ Cesium3DTileset.prototype.getHeight = function (cartographic, scene) {
}

const ray = scratchGetHeightRay;
ray.direction = ellipsoid.geodeticSurfaceNormalCartographic(
const position = ellipsoid.cartographicToCartesian(
cartographic,
ray.direction
);

const intersection = this.pick(
ray,
scene.frameState,
false,
scratchIntersection
ray.direction = Cartesian3.normalize(position, ray.direction);
ray.direction = Cartesian3.negate(position, ray.direction);
ray.origin = Cartesian3.multiplyByScalar(
ray.direction,
-2 * ellipsoid.maximumRadius,
ray.origin
);

const intersection = this.pick(ray, scene.frameState, scratchIntersection);
if (!defined(intersection)) {
return;
}
Expand Down
1 change: 1 addition & 0 deletions packages/engine/Source/Scene/Model/I3dmLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const Instances = ModelComponents.Instances;
* @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model.
* @param {Axis} [options.forwardAxis=Axis.X] The forward-axis of the glTF model.
* @param {boolean} [options.loadAttributesAsTypedArray=false] Load all attributes as typed arrays instead of GPU buffers. If the attributes are interleaved in the glTF they will be de-interleaved in the typed array.
* @param {boolean} [options.enablePick=false] If <code>true</code>, load the positions buffer, any instanced attribute buffers, and index buffer as typed arrays for CPU-enabled picking in WebGL1.
* @param {boolean} [options.loadIndicesForWireframe=false] Load the index buffer as a typed array so wireframe indices can be created for WebGL1.
* @param {boolean} [options.loadPrimitiveOutline=true] If true, load outlines from the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time.
*/
Expand Down
42 changes: 9 additions & 33 deletions packages/engine/Source/Scene/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ function Scene(options) {
this._globeTranslucencyState = new GlobeTranslucencyState();
this._primitives = new PrimitiveCollection();
this._groundPrimitives = new PrimitiveCollection();
this._terrainTilesets = [];

this._globeHeight = undefined;
this._cameraUnderground = false;
Expand Down Expand Up @@ -3576,44 +3575,21 @@ function callAfterRenderFunctions(scene) {
functions.length = 0;
}

/**
* Allow camera collisions, if enabled for the camera, on a tileset surface
* @param {Cesium3DTileset} tileset Tileset fo which to enable collision.
*/
Scene.prototype.enableCollisionDetectionForTileset = function (tileset) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("tileset", tileset);
//>>includeEnd('debug');

this._terrainTilesets.push(tileset);
};

/**
* Disallow camera collisions on a tileset surface
* @param {Cesium3DTileset} tileset Tileset for which to disable collision.
*/
Scene.prototype.disableCollisionDetectionForTileset = function (tileset) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object("tileset", tileset);
//>>includeEnd('debug');

const i = this._terrainTilesets.indexOf(tileset);
if (i === -1) {
return;
}

this._terrainTilesets.splice(i, 1);
};

function getGlobeHeight(scene) {
const globe = scene._globe;
const camera = scene.camera;
const cartographic = camera.positionCartographic;

let maxHeight = Number.NEGATIVE_INFINITY;
for (const tileset of scene._terrainTilesets) {
const result = tileset.getHeight(cartographic, scene);
if (result > maxHeight) {
const length = scene.primitives.length;
for (let i = 0; i < length; ++i) {
const primitive = scene.primitives.get(i);
if (!primitive.isCesium3DTileset || !primitive.enableCameraCollision) {
continue;
}

const result = primitive.getHeight(cartographic, scene);
if (defined(result) && result > maxHeight) {
maxHeight = result;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ async function createGooglePhotorealistic3DTileset(key, options) {
options.maximumCacheOverflowBytes,
1024 * 1024 * 1024
);
options.enableCameraCollision = defaultValue(
options.enableCameraCollision,
true
);

key = defaultValue(key, GoogleMaps.defaultApiKey);
if (!defined(key)) {
Expand Down

0 comments on commit c95f426

Please sign in to comment.