cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Allow users to define clipping regions with polygons

Open ggetz opened this issue 1 year ago • 14 comments

Description

The PR implements a new API for clipping that allows user to define a collection of polygonal areas rather than defining individual clipping planes.

This allows:

  • An easier-to-use API for clipping regions more inline with how clipping is implemented in Cesium for Unreal
    • Users now specify polygon positions rather than planes with transforms
    • In particular clipping for global tilesets such as Google's Photogrammetric 3D Tiles becomes much simpler
  • Users can now define multiple regions instead of just one
  • Users can now define concave regions
  • Users can toggle an inverse property to isolate regions instead of clipping them

Out of scope for this PR:

  • Holes: It'd be possible to integrate holes into the existing implementation. In particular the inside/outside and distance algorithm would support holes as-is. The sticking point is mainly scope – Our existing PolygonHierarchy (what would really should use to keep the API cohesive) definition supports an unlimited recursive list of holes, and how we pack that into the texture used for the compute command would need some work to support holes. It's also totally feasible to add a hierarchy option at a later date. Given all that, I would suggest keeping it out of the scope of this PR and see if the feature is requested.
  • Shadows: Currently, clipping polygons are not taken into account for shadows. They are not implemented for clipping planes either, so it may make sense to tackle this together outside of this PR.

image

With building inset Without building inset
image image

Sandcastle Example

Concave clipping region Inverted clipping regions
image image

Sandcastle Example

This is implemented very similar to clipping planes, where we:

  • Add a new ClippingPolygon, defined by a list of three or more positions, and ClippingPolygonCollection for managing the list and state
  • This collection can be applied one or more tilesets, or a model
  • Use intersections with 3D tiles bounding volumes to determine if a tile is being clipped or not
  • Pack the details of the clipping area into a texture
  • Add a new model pipeline stage and modifications to GlobeFS which add lines the fragment shader to discard the area within the polygon

To avoid doing inside/outside checks for each fragment, we instead use a ComputeCommand to generate a texture containing the signed distance from the polygons' edges, and the fragment shader instead samples the results from this pre-computed texture. Additionally, the spherical approximation method is borrowed from our implementation of texture mapping for groundPrimitives, and should be enough precision for most cases.

Issue number and link

Fixes https://github.com/CesiumGS/cesium/issues/8751

Testing plan

For both 3D Tiles and the globe (this sandcastle allows you to toggle between the two):

  1. Verify multiple polygons can be clipped at once.
  2. Verify polygons far away clip.
  3. Verify polygons intersecting one another clip.
  4. Verify inverse clipping for multiple polygons.
  5. Verify concave polygons clip correctly.
  6. Verify concave polygons inverse clip correctly.
  7. Verify removing polygons from a collection.
  8. Verify performance (FPS) is comparable for a polygon with many positions, using: viewer.scene.debugShowFramesPerSecond = true;
  9. Verify clipping resolution when zoomed in

Author checklist

  • [x] I have submitted a Contributor License Agreement
  • [x] I have added my name to CONTRIBUTORS.md
  • [x] I have updated CHANGES.md with a short summary of my change
  • [x] I have added or updated unit tests to ensure consistent code coverage
  • [x] I have update the inline documentation, and included code examples where relevant
  • [x] I have performed a self-review of my code
  • [x] Performance testing
  • [ ] ~Exclude clipped areas from shadows~
  • [x] Testing plan
  • [x] Polished Sandcastle
  • [x] Jagged edges on large polygons
  • [x] Move AEC tileset into the CesiumJS ion account
  • [ ] Squash commits

ggetz avatar Jan 09 '24 17:01 ggetz

Hi @ggetz Massive thank you for this PR. Your work represents a significant step forward in improving asset integration capabilities, and we are incredibly excited about the potential it unlocks for us and community.

Your implementation could greatly enhance the way users interact with external 3D integration into 3Dtileset. This is why your contribution is viewed as a key feature for us and the community.

We found a glitch with shadows where the hidden part always casts shadows, which is quite annoying when we want to do a shadow analysis of an integrated CAD or BIM model.

Looking forward to your thoughts and any further actions you deem necessary to bring this PR to completion. Let's make this amazing feature available to everyone in the CesiumJS community!

tbenazzi avatar Feb 09 '24 10:02 tbenazzi

Very interesting tool! @cesiumgs-admin do you know when will be avalaible?

Masty88 avatar Feb 14 '24 12:02 Masty88

Thanks @tbenazzi and @Masty88 for the interest!

We are reviewing some performance impact of this feature currently, and I'm aiming to get it into the March 1 release.

We found a glitch with shadows where the hidden part always casts shadows, which is quite annoying when we want to do a shadow analysis of an integrated CAD or BIM model.

This is a good point. We will evaluate whether its possible to include in this iteration. If not, we will certainly open a feature request for it. Thanks for the idea!

ggetz avatar Feb 14 '24 14:02 ggetz

Hi, Any idea when this feature will get released?

saadatali48 avatar Mar 08 '24 05:03 saadatali48

@saadatali48 Sorry for the delay. This PR is next on my list, and ideally will go out with the next release. Thanks for the interest!

ggetz avatar Mar 12 '24 13:03 ggetz

@jjhembd This should be ready for a first pass. ~Please note the remaining TODO's include finishing up the unit tests~ ~and jagged edges on large polygons which corresponds with the one TODO comment in the code~.

ggetz avatar Mar 25 '24 17:03 ggetz

I'm getting some strange results with large polygons on terrain. image The polygon has just 4 points.

The same polygon on 3D Tiles doesn't seem to clip anything.

jjhembd avatar Apr 11 '24 23:04 jjhembd

I'm getting some strange results with large polygons on terrain.

@jjhembd Thanks for pointing this out. Was this the only polygon in the scene or were there multiple?

ggetz avatar Apr 12 '24 12:04 ggetz

Was this the only polygon in the scene or were there multiple?

Good question. I can only trigger the problem if there are multiple polygons. Here is the result with only one large polygon (looks fine): image

And here is the result if I first draw a smaller polygon in the NW corner, then a large one in the center: image

jjhembd avatar Apr 12 '24 13:04 jjhembd

I'm getting some strange results with large polygons on terrain.

Thanks for pointing this out @jjhembd. I think this should be resolved now.

The same polygon on 3D Tiles doesn't seem to clip anything.

Something seems to be very different about the behavior of root tiles on Google P3DT. I'm looking into that now.

ggetz avatar Apr 15 '24 21:04 ggetz

Thanks for the thorough review @jjhembd! I believe I've addressed all of you feedback and this is ready for another look.

ggetz avatar Apr 17 '24 18:04 ggetz

Thanks @ggetz, the code is looking good, and the issue with large polygons is fixed.

I have two more smaller comments on the Sandcastles.

AEC Clipping Sandcastle

This one works well, and it's a very interesting demo! A minor nitpick: the initial camera position is awkward for me. The region of interest is mostly out of view, below the camera. image

Clipping Regions Sandcastle

The clipping polygon seems to lose resolution when zooming out to a lower LOD in the underlying data. For example, here I clipped out part of Michigan: image

But when I zoom out, one point in the polygon appears to be lost: image

Zooming out further leaves only 4 points in the polygon, and the original shape is gone: image

This aggressive polygon simplification is similar in both Terrain and 3D Tiles.

jjhembd avatar Apr 22 '24 21:04 jjhembd

Thanks @jjhembd! I believe I've addressed your feedback. You can now see 1) a better view of the AEC clipping region, and 2) Michigan at scale.

ggetz avatar Apr 23 '24 21:04 ggetz

@jjhembd I've made some additional adjustments based on your feedback.

  1. There was a bug with removing then adding polygons with the same number of positions, which was a simple fix in the update function.
  2. To remove artifacts, I increased the amount of padding defining the polygon extents. My concern was this would affect performance, but when measuring I could not detect any effect on the framerate.

ggetz avatar Apr 26 '24 15:04 ggetz

Super thank you!

Masty88 avatar May 02 '24 08:05 Masty88

Is clippingPolygon supported for VoxelPrimitive?

catnuko avatar Jul 11 '24 03:07 catnuko

@catnuko Not presently, but we can open a feature request for this. Would you mind giving us a few details about your use case?

ggetz avatar Jul 11 '24 13:07 ggetz