-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tileset traversal with clipping planes #5966
Tileset traversal with clipping planes #5966
Conversation
@ggetz, thanks for the pull request! Maintainers, we have a signed CLA from @ggetz, so you can review this at any time.
I am a bot who helps you make Cesium awesome! Contributions to my configuration are welcome. 🌍 🌎 🌏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to work well when running in Sandcastle. I have some general architecture comments.
Source/Scene/Cesium3DTile.js
Outdated
@@ -940,7 +966,7 @@ define([ | |||
var showVolume = tileset.debugShowBoundingVolume || (tileset.debugShowContentBoundingVolume && !hasContentBoundingVolume); | |||
if (showVolume) { | |||
if (!defined(tile._debugBoundingVolume)) { | |||
var color = tile._finalResolution ? (hasContentBoundingVolume ? Color.WHITE : Color.RED) : Color.YELLOW; | |||
var color = tile._finalResolution ? (hasContentBoundingVolume ? (tile._debugClipped ? Color.CYAN : Color.WHITE) : Color.RED) : Color.YELLOW; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the tile is clipped won't its debug bounding volume not be visible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, I was using this for my own debugging purposes, I'll remove this and the _debugClipped
property.
Cartesian3.multiplyByScalar(plane.normal, plane.distance, scratchCartesian); | ||
Matrix4.multiplyByPoint(context.uniformState.modelView3D, scratchCartesian, scratchCartesian); | ||
packedPlane.w = Cartesian3.dot(packedPlane, scratchCartesian); | ||
Matrix4.multiply(context.uniformState.view3D, content._modelMatrix, scratchMatrix); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following Model
, computing the scratch matrix could go outside the for loop as well.
Source/Scene/Cesium3DTile.js
Outdated
var length = planes.length; | ||
for (var i = 0; i < length; ++i) { | ||
var plane = planes[i]; | ||
Plane.transformPlane(plane, tile._tileset._root.computedTransform, scratchPlane); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be tile._computedTransform
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this should definitely be the root transform. The plane is defined relative to the tileset, not each individual tile.
I tested both on the NY tileset as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But let me know if there is a cleaner way to get this value
Source/Core/CullingVolume.js
Outdated
* @returns {Number} A plane mask as described above (which can be applied to this boundingVolume's children). | ||
* | ||
* @private | ||
*/ | ||
CullingVolume.prototype.computeVisibilityWithPlaneMask = function(boundingVolume, parentPlaneMask) { | ||
CullingVolume.prototype.computeVisibilityWithPlaneMask = function(boundingVolume, parentPlaneMask, checkClipped) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This callback doesn't really belong in CullingVolume
. The logic of whether to proceed with checking the clipping planes should exist in Cesium3DTile
.
Source/Core/Plane.js
Outdated
* @param {Plane} [result] The object into which to store the result. | ||
* @returns {Plane} The plane transformed by the given transformation matrix. | ||
*/ | ||
Plane.transformPlane = function(plane, transform, result) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to write tests for this once you start writing tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also since this is a new thing it should be added to CHANGES.md
, unless this is better off private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just name this transform
since Plane
is the class name?
Source/Core/Plane.js
Outdated
if (!defined(transform)) { | ||
throw new DeveloperError('transform is required.'); | ||
} | ||
//>>includeEnd('debug'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything in this file should move over to the Check
syntax.
Source/Scene/Cesium3DTile.js
Outdated
var plane = planes[i]; | ||
Plane.transformPlane(plane, tile._tileset._root.computedTransform, scratchPlane); | ||
if (boundingVolume.intersectPlane(scratchPlane) === Intersect.INSIDE) { | ||
tile._debugClipped = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this works... Is Intersect.INSIDE
the result if the contents are completely on the opposite side of the clipping plane? Does this mean the normal is reverse what it should be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the tileset should contain a culling volume built from its clipping planes. The check here should be functionally the same as CullingVolume.computeVisibility
, so it would be better to reuse that code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this works... Is Intersect.INSIDE the result if the contents are completely on the opposite side of the clipping plane? Does this mean the normal is reverse what it should be?
I think I assumed we wanted to clip what was on the "inside" of the plane. If we want the "outside" to be clipped, it should be fairly easy to update the shader to clip the opposite of what we are now, and check for outside intersections instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the tileset should contain a culling volume built from its clipping planes. The check here should be functionally the same as CullingVolume.computeVisibility, so it would be better to reuse that code.
I think the only difference is that we only care if the volume is inside (or outside after the above changes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, another difference is that CullingVolume
uses the Cartesian4
representation for the coefficients of the plane equation to calculate intersections, rather than a Plane
object with normal/distance. So I'm going to go with no clipping volume unless we want to convert the planes to their equations everytime we update.
@lilleyse Thanks for taking a look! Updated. |
Source/Scene/Cesium3DTile.js
Outdated
var length = planes.length; | ||
for (var i = 0; i < length; ++i) { | ||
var plane = planes[i]; | ||
Plane.transformPlane(plane, tile._tileset._root.computedTransform, scratchPlane); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outside of the loop:
var rootTransform = tile._tileset._root.computedTransform;
Source/Scene/Cesium3DTile.js
Outdated
@@ -747,6 +768,11 @@ define([ | |||
Cesium3DTile.prototype.visibility = function(frameState, parentVisibilityPlaneMask) { | |||
var cullingVolume = frameState.cullingVolume; | |||
var boundingVolume = getBoundingVolume(this, frameState); | |||
|
|||
if (checkTileClipped(this, boundingVolume)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of this optimization is to use the original shader when the tile is not clipped. Does this PR do that?
Updated to include the additional optimization. Also included fixes from discussion in my previous PR: #5913 (comment) |
@lilleyse Can you take a look at this? I have a successive branch with all the additional changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll review the second branch more closely. It's also possible some of the issues I'm seeing have been fixed there.
Source/Scene/Model.js
Outdated
|
||
var scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); | ||
function createClippingPlanesFunction(model, context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
context
isn't used any more.
@@ -44,25 +44,27 @@ | |||
<tr> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fixed in the next branch.
@@ -44,25 +44,27 @@ | |||
<tr> | |||
<td>x</td> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point cloud tileset doesn't seem to show up for me, even after playing around with the sliders.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noted, but I think it will be easier to fix this in the next branch as I have added easier ways to handle this.
Source/Scene/Cesium3DTileset.js
Outdated
* Optimization option. If set to false, the tileset will not perform clipping operations. | ||
* | ||
* @type {Boolean} | ||
* @default {undefined} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default is true
Source/Scene/Model.js
Outdated
* | ||
* @default [] | ||
* @default false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default is true
Thanks @lilleyse, updated! |
visibility
andcontentVisibility
Plane
classPlane
Part of #5765
@lilleyse