Skip to content

Commit

Permalink
Merge pull request #9175 from CesiumGS/barycentric-divide-check
Browse files Browse the repository at this point in the history
Improved degenerate barycentric check
  • Loading branch information
lilleyse committed Dec 12, 2021
2 parents 554baa1 + fb28273 commit 7f64b05
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Removed `Scene.debugShowGlobeDepth`. [#9965](https://github.com/CesiumGS/cesium/pull/9965)
- Removed `CesiumInspectorViewModel.globeDepth` and `CesiumInspectorViewModel.pickDepth`. [#9965](https://github.com/CesiumGS/cesium/pull/9965)
- `barycentricCoordinates` returns `undefined` when the input triangle is degenerate. [#9175](https://github.com/CesiumGS/cesium/pull/9175)

##### Additions :tada:

Expand Down
3 changes: 3 additions & 0 deletions Source/Core/GeometryPipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -2211,6 +2211,9 @@ function computeTriangleAttributes(
var p1 = Cartesian3.fromArray(positions, i1 * 3, p1Scratch);
var p2 = Cartesian3.fromArray(positions, i2 * 3, p2Scratch);
var coords = barycentricCoordinates(point, p0, p1, p2, barycentricScratch);
if (!defined(coords)) {
return;
}

if (defined(normals)) {
interpolateAndPackCartesian3(
Expand Down
13 changes: 6 additions & 7 deletions Source/Core/barycentricCoordinates.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var scratchCartesian3 = new Cartesian3();
* @param {Cartesian2|Cartesian3} p1 The second point of the triangle, corresponding to the barycentric y-axis.
* @param {Cartesian2|Cartesian3} p2 The third point of the triangle, corresponding to the barycentric z-axis.
* @param {Cartesian3} [result] The object onto which to store the result.
* @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided.
* @returns {Cartesian3|undefined} The modified result parameter or a new Cartesian3 instance if one was not provided. If the triangle is degenerate the function will return undefined.
*
* @example
* // Returns Cartesian3.UNIT_X
Expand Down Expand Up @@ -96,14 +96,13 @@ function barycentricCoordinates(point, p0, p1, p2, result) {
result.z = dot00 * dot12 - dot01 * dot02;
var q = dot00 * dot11 - dot01 * dot01;

// This is done to avoid dividing by infinity causing a NaN
if (result.y !== 0) {
result.y /= q;
}
if (result.z !== 0) {
result.z /= q;
// Triangle is degenerate
if (q === 0) {
return undefined;
}

result.y /= q;
result.z /= q;
result.x = 1.0 - result.y - result.z;
return result;
}
Expand Down
14 changes: 12 additions & 2 deletions Source/Core/pointInsideTriangle.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import barycentricCoordinates from "./barycentricCoordinates.js";
import Cartesian3 from "./Cartesian3.js";
import defined from "./defined.js";

var coords = new Cartesian3();
var scratchBarycentricCoords = new Cartesian3();

/**
* Determines if a point is inside a triangle.
Expand All @@ -23,7 +24,16 @@ var coords = new Cartesian3();
* new Cesium.Cartesian2(0.0, 1.0));
*/
function pointInsideTriangle(point, p0, p1, p2) {
barycentricCoordinates(point, p0, p1, p2, coords);
var coords = barycentricCoordinates(
point,
p0,
p1,
p2,
scratchBarycentricCoords
);
if (!defined(coords)) {
return false;
}
return coords.x > 0.0 && coords.y > 0.0 && coords.z > 0;
}
export default pointInsideTriangle;
13 changes: 6 additions & 7 deletions Specs/Core/barycentricCoordinatesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,13 @@ describe("Core/barycentricCoordinates", function () {
);
});

it("evaluates without throwing a NaN", function () {
var point = Cartesian3.multiplyByScalar(
Cartesian3.add(p1, p1, p1),
0.5,
new Cartesian3()
);
it("returns undefined for colinear points", function () {
var p0 = new Cartesian3(-1.0, -1.0, 0.0);
var p1 = new Cartesian3(0.0, 0.0, 0.0);
var p2 = new Cartesian3(1.0, 1.0, 0.0);
var point = new Cartesian3(0.5, 0.5, 0.0);
var coord = barycentricCoordinates(point, p0, p1, p2);
expect(coord.z).not.toBeNaN();
expect(coord).toBeUndefined();
});

it("evaluates with equal length sides", function () {
Expand Down

0 comments on commit 7f64b05

Please sign in to comment.