-
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
Changes from 4 commits
271dade
5bd4ad6
ad4f9e5
02bdf52
072400c
8330177
45a48d0
a7fe4db
f1197cd
e161b31
32b01c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,25 +44,26 @@ | |
<tr> | ||
<td>x</td> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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. |
||
<td> | ||
<input type="range" min="-100" max="100" step="1" data-bind="value: xOffset, valueUpdate: 'input'"> | ||
<input type="range" min="-150" max="150" step="1" data-bind="value: xOffset, valueUpdate: 'input'"> | ||
<input type="text" size="2" data-bind="value: xOffset"> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>y</td> | ||
<td> | ||
<input type="range" min="-100" max="100" step="1" data-bind="value: yOffset, valueUpdate: 'input'"> | ||
<input type="range" min="-150" max="150" step="1" data-bind="value: yOffset, valueUpdate: 'input'"> | ||
<input type="text" size="2" data-bind="value: yOffset"> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>z</td> | ||
<td> | ||
<input type="range" min="-100" max="100" step="1" data-bind="value: zOffset, valueUpdate: 'input'"> | ||
<input type="range" min="-150" max="150" step="1" data-bind="value: zOffset, valueUpdate: 'input'"> | ||
<input type="text" size="2" data-bind="value: zOffset"> | ||
</td> | ||
</tr> | ||
</tbody></table> | ||
<input type="checkbox" value="false" data-bind="checked: debugBoundingVolumesEnabled, valueUpdate: 'input'"> Show debug <code>boundingVolume</code> | ||
</div> | ||
|
||
<script id="cesium_sandcastle_script"> | ||
|
@@ -72,15 +73,25 @@ | |
var viewer = new Cesium.Viewer('cesiumContainer'); | ||
|
||
var defaultClippingPlanes = [ | ||
new Cesium.Plane(new Cesium.Cartesian3(-1, 0, 0), 0.0), | ||
new Cesium.Plane(new Cesium.Cartesian3(0, -1, 0), 100.0), | ||
new Cesium.Plane(new Cesium.Cartesian3(0, 0, 1), 100.0) | ||
new Cesium.Plane(new Cesium.Cartesian3(1, 0, 0), 0.0), | ||
new Cesium.Plane(new Cesium.Cartesian3(0, 1, 0), -100.0), | ||
new Cesium.Plane(new Cesium.Cartesian3(0, 0, -1), -100.0) | ||
]; | ||
|
||
function loadTileset (url) { | ||
var viewModel = { | ||
exampleType : 'BIM', | ||
exampleTypes : ['BIM', 'Model', 'Point Cloud'], | ||
xOffset : 0.0, | ||
yOffset: -100.0, | ||
zOffset: -100.0, | ||
debugBoundingVolumesEnabled: false | ||
}; | ||
|
||
var tileset; | ||
function loadTileset (url, offeset) { | ||
reset(); | ||
|
||
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ | ||
tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ | ||
url : url | ||
})); | ||
|
||
|
@@ -92,6 +103,7 @@ | |
throw(error); | ||
}); | ||
|
||
tileset.debugShowBoundingVolume = viewModel.debugBoundingVolumesEnabled; | ||
tileset.clippingPlanes = defaultClippingPlanes; | ||
return tileset.clippingPlanes; | ||
} | ||
|
@@ -131,14 +143,6 @@ | |
var clippingPlanes = loadTileset(bimUrl); | ||
|
||
// Track and create the bindings for the view model | ||
|
||
var viewModel = { | ||
exampleType : 'BIM', | ||
exampleTypes : ['BIM', 'Model', 'Point Cloud'], | ||
xOffset : 0.0, | ||
yOffset: 100.0, | ||
zOffset: 100.0 | ||
}; | ||
var toolbar = document.getElementById('toolbar'); | ||
Cesium.knockout.track(viewModel); | ||
Cesium.knockout.applyBindings(viewModel, toolbar); | ||
|
@@ -155,6 +159,10 @@ | |
clippingPlanes[2].distance = parseFloat(newValue); | ||
}); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'debugBoundingVolumesEnabled').subscribe(function(newValue) { | ||
tileset.debugShowBoundingVolume = newValue; | ||
}); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'exampleType').subscribe( | ||
function(newValue) { | ||
if (newValue === 'BIM') { | ||
|
@@ -173,8 +181,8 @@ | |
|
||
if (Cesium.defined(viewModel)) { | ||
viewModel.xOffset = 0.0; | ||
viewModel.yOffset = 100.0; | ||
viewModel.zOffset = 100.0; | ||
viewModel.yOffset = -100.0; | ||
viewModel.zOffset = -100.0; | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,20 @@ | ||
define([ | ||
'./Cartesian3', | ||
'./Check', | ||
'./defined', | ||
'./DeveloperError', | ||
'./freezeObject', | ||
'./Math' | ||
'./Math', | ||
'./Matrix4' | ||
], function( | ||
Cartesian3, | ||
Check, | ||
defined, | ||
DeveloperError, | ||
freezeObject, | ||
CesiumMath) { | ||
CesiumMath, | ||
Matrix4 | ||
) { | ||
'use strict'; | ||
|
||
/** | ||
|
@@ -39,15 +44,11 @@ define([ | |
*/ | ||
function Plane(normal, distance) { | ||
//>>includeStart('debug', pragmas.debug); | ||
if (!defined(normal)) { | ||
throw new DeveloperError('normal is required.'); | ||
} | ||
Check.typeOf.object('normal', normal); | ||
if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { | ||
throw new DeveloperError('normal must be normalized.'); | ||
} | ||
if (!defined(distance)) { | ||
throw new DeveloperError('distance is required.'); | ||
} | ||
Check.typeOf.number('distance', distance); | ||
//>>includeEnd('debug'); | ||
|
||
/** | ||
|
@@ -86,12 +87,8 @@ define([ | |
*/ | ||
Plane.fromPointNormal = function(point, normal, result) { | ||
//>>includeStart('debug', pragmas.debug); | ||
if (!defined(point)) { | ||
throw new DeveloperError('point is required.'); | ||
} | ||
if (!defined(normal)) { | ||
throw new DeveloperError('normal is required.'); | ||
} | ||
Check.typeOf.object('point', point); | ||
Check.typeOf.object('normal', normal); | ||
if (!CesiumMath.equalsEpsilon(Cartesian3.magnitude(normal), 1.0, CesiumMath.EPSILON6)) { | ||
throw new DeveloperError('normal must be normalized.'); | ||
} | ||
|
@@ -120,9 +117,7 @@ define([ | |
*/ | ||
Plane.fromCartesian4 = function(coefficients, result) { | ||
//>>includeStart('debug', pragmas.debug); | ||
if (!defined(coefficients)) { | ||
throw new DeveloperError('coefficients is required.'); | ||
} | ||
Check.typeOf.object('coefficients', coefficients); | ||
//>>includeEnd('debug'); | ||
|
||
var normal = Cartesian3.fromCartesian4(coefficients, scratchNormal); | ||
|
@@ -155,17 +150,37 @@ define([ | |
*/ | ||
Plane.getPointDistance = function(plane, point) { | ||
//>>includeStart('debug', pragmas.debug); | ||
if (!defined(plane)) { | ||
throw new DeveloperError('plane is required.'); | ||
} | ||
if (!defined(point)) { | ||
throw new DeveloperError('point is required.'); | ||
} | ||
Check.typeOf.object('plane', plane); | ||
Check.typeOf.object('point', point); | ||
//>>includeEnd('debug'); | ||
|
||
return Cartesian3.dot(plane.normal, point) + plane.distance; | ||
}; | ||
|
||
var scratchPosition = new Cartesian3(); | ||
/** | ||
* Transforms the plane by the given transformation matrix. | ||
* | ||
* @param {Plane} plane The plane. | ||
* @param {Matrix4} transform The transformation matrix. | ||
* @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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Also since this is a new thing it should be added to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just name this |
||
//>>includeStart('debug', pragmas.debug); | ||
Check.typeOf.object('plane', plane); | ||
Check.typeOf.object('transform', transform); | ||
//>>includeEnd('debug'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Everything in this file should move over to the |
||
|
||
Matrix4.multiplyByPointAsVector(transform, plane.normal, scratchNormal); | ||
Cartesian3.normalize(scratchNormal, scratchNormal); | ||
|
||
Cartesian3.multiplyByScalar(plane.normal, plane.distance, scratchPosition); | ||
Matrix4.multiplyByPoint(transform, scratchPosition, scratchPosition); | ||
|
||
return Plane.fromPointNormal(scratchPosition, scratchNormal, result); | ||
}; | ||
|
||
/** | ||
* A constant initialized to the XY plane passing through the origin, with normal in positive Z. | ||
* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ define([ | |
'../Core/BoundingSphere', | ||
'../Core/Cartesian3', | ||
'../Core/Color', | ||
'../Core/CullingVolume', | ||
'../Core/defaultValue', | ||
'../Core/defined', | ||
'../Core/defineProperties', | ||
|
@@ -14,6 +15,7 @@ define([ | |
'../Core/loadArrayBuffer', | ||
'../Core/Matrix3', | ||
'../Core/Matrix4', | ||
'../Core/Plane', | ||
'../Core/Rectangle', | ||
'../Core/Request', | ||
'../Core/RequestScheduler', | ||
|
@@ -35,6 +37,7 @@ define([ | |
BoundingSphere, | ||
Cartesian3, | ||
Color, | ||
CullingVolume, | ||
defaultValue, | ||
defined, | ||
defineProperties, | ||
|
@@ -47,6 +50,7 @@ define([ | |
loadArrayBuffer, | ||
Matrix3, | ||
Matrix4, | ||
Plane, | ||
Rectangle, | ||
Request, | ||
RequestScheduler, | ||
|
@@ -735,6 +739,23 @@ define([ | |
return frameState.mode !== SceneMode.SCENE3D ? tile._contentBoundingVolume2D : tile._contentBoundingVolume; | ||
} | ||
|
||
|
||
var scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); | ||
function checkTileClipped(tile, boundingVolume) { | ||
var planes = tile._tileset.clippingPlanes; | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. Outside of the loop:
|
||
if (boundingVolume.intersectPlane(scratchPlane) === Intersect.OUTSIDE) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
|
||
/** | ||
* Determines whether the tile's bounding volume intersects the culling volume. | ||
* | ||
|
@@ -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 commentThe 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? |
||
return CullingVolume.MASK_OUTSIDE; | ||
} | ||
|
||
return cullingVolume.computeVisibilityWithPlaneMask(boundingVolume, parentVisibilityPlaneMask); | ||
}; | ||
|
||
|
@@ -770,6 +796,11 @@ define([ | |
// tile's (not the content's) bounding volume intersects the culling volume? | ||
var cullingVolume = frameState.cullingVolume; | ||
var boundingVolume = getContentBoundingVolume(this, frameState); | ||
|
||
if (checkTileClipped(this, boundingVolume)) { | ||
return Intersect.OUTSIDE; | ||
} | ||
|
||
return cullingVolume.computeVisibility(boundingVolume); | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ define([ | |
'../Core/Matrix3', | ||
'../Core/Matrix4', | ||
'../Core/PixelFormat', | ||
'../Core/Plane', | ||
'../Core/PrimitiveType', | ||
'../Core/Quaternion', | ||
'../Core/Queue', | ||
|
@@ -108,6 +109,7 @@ define([ | |
Matrix3, | ||
Matrix4, | ||
PixelFormat, | ||
Plane, | ||
PrimitiveType, | ||
Quaternion, | ||
Queue, | ||
|
@@ -3312,7 +3314,7 @@ define([ | |
}; | ||
} | ||
|
||
var scratchCartesian = new Cartesian3(); | ||
var scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); | ||
var scratchMatrix = new Matrix4(); | ||
|
||
function createClippingPlanesFunction(model, context) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
@@ -3327,11 +3329,11 @@ define([ | |
for (var i = 0; i < length; ++i) { | ||
var plane = planes[i]; | ||
var packedPlane = packedPlanes[i]; | ||
Matrix4.multiplyByPointAsVector(scratchMatrix, plane.normal, packedPlane); | ||
Cartesian3.normalize(packedPlane, packedPlane); | ||
Cartesian3.multiplyByScalar(plane.normal, plane.distance, scratchCartesian); | ||
Matrix4.multiplyByPoint(scratchMatrix, scratchCartesian, scratchCartesian); | ||
packedPlane.w = Cartesian3.dot(packedPlane, scratchCartesian); | ||
|
||
Plane.transformPlane(plane, scratchMatrix, scratchPlane); | ||
|
||
Cartesian3.clone(scratchPlane.normal, packedPlane); | ||
packedPlane.w = scratchPlane.distance; | ||
} | ||
return packedPlanes; | ||
}; | ||
|
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 seeing a crash when zooming into the BIM tileset.
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.