Skip to content

Commit f66452f

Browse files
authored
Merge pull request #8390 from AnalyticalGraphicsInc/tilePickFix
Fixed tile triangle picking
2 parents c6fde0d + b72732b commit f66452f

File tree

3 files changed

+37
-7
lines changed

3 files changed

+37
-7
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Change Log
88
* Fixed terrain tile culling problems when under ellipsoid. [#8397](https://github.com/AnalyticalGraphicsInc/cesium/pull/8397)
99
* Fixed primitive culling when below the ellipsoid but above terrain. [#8398](https://github.com/AnalyticalGraphicsInc/cesium/pull/8398)
1010
* Improved the translucency calculation for the Water material type. [#8455](https://github.com/AnalyticalGraphicsInc/cesium/pull/8455)
11+
* Fixed globe picking so that it returns the closest intersecting triangle instead of the first intersecting triangle. [#8390](https://github.com/AnalyticalGraphicsInc/cesium/pull/8390)
1112

1213
##### Additions :tada:
1314
* Added `Globe.backFaceCulling` to support viewing terrain from below the surface. [#8470](https://github.com/AnalyticalGraphicsInc/cesium/pull/8470)

Source/Scene/GlobeSurfaceTile.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import IndexDatatype from '../Core/IndexDatatype.js';
77
import IntersectionTests from '../Core/IntersectionTests.js';
88
import OrientedBoundingBox from '../Core/OrientedBoundingBox.js';
99
import PixelFormat from '../Core/PixelFormat.js';
10+
import Ray from '../Core/Ray.js';
1011
import Request from '../Core/Request.js';
1112
import RequestState from '../Core/RequestState.js';
1213
import RequestType from '../Core/RequestType.js';
@@ -139,7 +140,6 @@ import TerrainState from './TerrainState.js';
139140
var scratchV0 = new Cartesian3();
140141
var scratchV1 = new Cartesian3();
141142
var scratchV2 = new Cartesian3();
142-
var scratchResult = new Cartesian3();
143143

144144
GlobeSurfaceTile.prototype.pick = function(ray, mode, projection, cullBackFaces, result) {
145145
var mesh = this.renderedMesh;
@@ -150,9 +150,11 @@ import TerrainState from './TerrainState.js';
150150
var vertices = mesh.vertices;
151151
var indices = mesh.indices;
152152
var encoding = mesh.encoding;
153+
var indicesLength = indices.length;
153154

154-
var length = indices.length;
155-
for (var i = 0; i < length; i += 3) {
155+
var minT = Number.MAX_VALUE;
156+
157+
for (var i = 0; i < indicesLength; i += 3) {
156158
var i0 = indices[i];
157159
var i1 = indices[i + 1];
158160
var i2 = indices[i + 2];
@@ -161,13 +163,13 @@ import TerrainState from './TerrainState.js';
161163
var v1 = getPosition(encoding, mode, projection, vertices, i1, scratchV1);
162164
var v2 = getPosition(encoding, mode, projection, vertices, i2, scratchV2);
163165

164-
var intersection = IntersectionTests.rayTriangle(ray, v0, v1, v2, cullBackFaces, scratchResult);
165-
if (defined(intersection)) {
166-
return Cartesian3.clone(intersection, result);
166+
var t = IntersectionTests.rayTriangleParametric(ray, v0, v1, v2, cullBackFaces);
167+
if (defined(t) && t < minT) {
168+
minT = t;
167169
}
168170
}
169171

170-
return undefined;
172+
return minT < Number.MAX_VALUE ? Ray.getPoint(ray, minT, result) : undefined;
171173
};
172174

173175
GlobeSurfaceTile.prototype.freeResources = function() {

Specs/Scene/GlobeSurfaceTileSpec.js

+27
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Cartesian3 } from '../../Source/Cesium.js';
55
import { Cartesian4 } from '../../Source/Cesium.js';
66
import { createWorldTerrain } from '../../Source/Cesium.js';
77
import { Ellipsoid } from '../../Source/Cesium.js';
8+
import { EllipsoidTerrainProvider } from '../../Source/Cesium.js';
89
import { GeographicTilingScheme } from '../../Source/Cesium.js';
910
import { Ray } from '../../Source/Cesium.js';
1011
import { GlobeSurfaceTile } from '../../Source/Cesium.js';
@@ -308,6 +309,32 @@ describe('Scene/GlobeSurfaceTile', function() {
308309
expect(cartographic.height).toBeGreaterThan(-500.0);
309310
});
310311
});
312+
313+
it('gets correct result when a closer triangle is processed after a farther triangle', function() {
314+
// Pick root tile (0,0). It will intersect a triangle on the east and the west side.
315+
// The east triangle is closer and should be the pick result even though the west triangle is checked first.
316+
var terrainProvider = new EllipsoidTerrainProvider();
317+
318+
var tile = new QuadtreeTile({
319+
tilingScheme : new GeographicTilingScheme(),
320+
level : 0,
321+
x : 0,
322+
y : 0
323+
});
324+
325+
processor.frameState = scene.frameState;
326+
processor.terrainProvider = terrainProvider;
327+
328+
return processor.process([tile]).then(function() {
329+
var ray = new Ray(
330+
new Cartesian3(50000000.0, 0.0, 0.0),
331+
// nudge the direction to be pointing at the (0,0) tile
332+
new Cartesian3(-0.9999422718925407, -0.007344489332226594, -0.007842917749982258));
333+
var cullBackFaces = false;
334+
var pickResult = tile.data.pick(ray, undefined, undefined, cullBackFaces);
335+
expect(pickResult.x).toBeGreaterThan(0.0);
336+
});
337+
});
311338
}, 'WebGL');
312339

313340
describe('eligibleForUnloading', function() {

0 commit comments

Comments
 (0)