Skip to content

Commit

Permalink
Merge pull request #8499 from AnalyticalGraphicsInc/negativePickFix
Browse files Browse the repository at this point in the history
Made GlobeSurfaceTile.pick not pick triangles behind the ray
  • Loading branch information
lilleyse authored Dec 30, 2019
2 parents 6b42340 + 5082e42 commit 2bc678a
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 10 deletions.
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Change Log
==========

### 1.65.0 - 2020-01-02
### 1.65.0 - 2020-01-06

##### Fixes :wrench:
* Fixed Geocoder auto-complete suggestions when hosted inside Web Components. [#8425](https://github.com/AnalyticalGraphicsInc/cesium/pull/8425)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/IntersectionTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ import Ray from './Ray.js';
var scratchQVec = new Cartesian3();

/**
* Computes the intersection of a ray and a triangle as a parametric distance along the input ray.
* Computes the intersection of a ray and a triangle as a parametric distance along the input ray. The result is negative when the triangle is behind the ray.
*
* Implements {@link https://cadxfem.org/inf/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf|
* Fast Minimum Storage Ray/Triangle Intersection} by Tomas Moller and Ben Trumbore.
Expand Down
4 changes: 2 additions & 2 deletions Source/Scene/GlobeSurfaceTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,12 @@ import TerrainState from './TerrainState.js';
var v2 = getPosition(encoding, mode, projection, vertices, i2, scratchV2);

var t = IntersectionTests.rayTriangleParametric(ray, v0, v1, v2, cullBackFaces);
if (defined(t) && t < minT) {
if (defined(t) && t < minT && t >= 0.0) {
minT = t;
}
}

return minT < Number.MAX_VALUE ? Ray.getPoint(ray, minT, result) : undefined;
return minT !== Number.MAX_VALUE ? Ray.getPoint(ray, minT, result) : undefined;
};

GlobeSurfaceTile.prototype.freeResources = function() {
Expand Down
36 changes: 30 additions & 6 deletions Specs/Scene/GlobeSurfaceTileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,9 @@ describe('Scene/GlobeSurfaceTile', function() {
});

it('gets correct result when a closer triangle is processed after a farther triangle', function() {
// Pick root tile (0,0). It will intersect a triangle on the east and the west side.
// The east triangle is closer and should be the pick result even though the west triangle is checked first.
// Pick root tile (level=0, x=0, y=0) from the east side towards the west.
// Based on heightmap triangle processing order the west triangle will be tested first, followed
// by the east triangle. But since the east triangle is closer we expect it to be the pick result.
var terrainProvider = new EllipsoidTerrainProvider();

var tile = new QuadtreeTile({
Expand All @@ -326,10 +327,33 @@ describe('Scene/GlobeSurfaceTile', function() {
processor.terrainProvider = terrainProvider;

return processor.process([tile]).then(function() {
var ray = new Ray(
new Cartesian3(50000000.0, 0.0, 0.0),
// nudge the direction to be pointing at the (0,0) tile
new Cartesian3(-0.9999422718925407, -0.007344489332226594, -0.007842917749982258));
var origin = new Cartesian3(50000000.0, -1.0, 0.0);
var direction = new Cartesian3(-1.0, 0.0, 0.0);
var ray = new Ray(origin, direction);
var cullBackFaces = false;
var pickResult = tile.data.pick(ray, undefined, undefined, cullBackFaces);
expect(pickResult.x).toBeGreaterThan(0.0);
});
});

it('ignores triangles that are behind the ray', function() {
// Pick root tile (level=0, x=0, y=0) from the center towards the east side (+X).
var terrainProvider = new EllipsoidTerrainProvider();

var tile = new QuadtreeTile({
tilingScheme : new GeographicTilingScheme(),
level : 0,
x : 0,
y : 0
});

processor.frameState = scene.frameState;
processor.terrainProvider = terrainProvider;

return processor.process([tile]).then(function() {
var origin = new Cartesian3(0.0, -1.0, 0.0);
var direction = new Cartesian3(1.0, 0.0, 0.0);
var ray = new Ray(origin, direction);
var cullBackFaces = false;
var pickResult = tile.data.pick(ray, undefined, undefined, cullBackFaces);
expect(pickResult.x).toBeGreaterThan(0.0);
Expand Down

0 comments on commit 2bc678a

Please sign in to comment.