Skip to content

Commit

Permalink
Merge pull request #12255 from p-skakun/fix-collinear-lines-corners
Browse files Browse the repository at this point in the history
Fix for possible normalization issue for line corner points
  • Loading branch information
ggetz authored Oct 30, 2024
2 parents 192ab06 + 3af8393 commit 6e6ed43
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
- Fix flickering issue caused by bounding sphere retrieval being blocked by the bounding sphere of another entity. [#12230](https://github.com/CesiumGS/cesium/pull/12230)
- Fixed `ImageBasedLighting.imageBasedLightingFactor` not affecting lighting. [#12129](https://github.com/CesiumGS/cesium/pull/12129)

- Fix error with normalization of corner points for lines and corridors with collinear points. [#12255](https://github.com/CesiumGS/cesium/pull/12255)

### 1.122 - 2024-10-01

#### @cesium/engine
Expand Down
8 changes: 4 additions & 4 deletions packages/engine/Source/Core/CorridorGeometryLibrary.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,6 @@ CorridorGeometryLibrary.computePositions = function (params) {
Cartesian3.subtract(nextPosition, position, forward),
forward,
);
cornerDirection = Cartesian3.normalize(
Cartesian3.add(forward, backward, cornerDirection),
cornerDirection,
);

const forwardProjection = Cartesian3.multiplyByScalar(
normal,
Expand All @@ -284,6 +280,10 @@ CorridorGeometryLibrary.computePositions = function (params) {
);

if (doCorner) {
cornerDirection = Cartesian3.normalize(
Cartesian3.add(forward, backward, cornerDirection),
cornerDirection,
);
cornerDirection = Cartesian3.cross(
cornerDirection,
normal,
Expand Down
4 changes: 2 additions & 2 deletions packages/engine/Source/Core/PolylineVolumeGeometryLibrary.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,6 @@ PolylineVolumeGeometryLibrary.computePositions = function (
}
forward = Cartesian3.subtract(nextPosition, position, forward);
forward = Cartesian3.normalize(forward, forward);
cornerDirection = Cartesian3.add(forward, backward, cornerDirection);
cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection);
surfaceNormal = ellipsoid.geodeticSurfaceNormal(position, surfaceNormal);

const forwardProjection = Cartesian3.multiplyByScalar(
Expand All @@ -461,6 +459,8 @@ PolylineVolumeGeometryLibrary.computePositions = function (
);

if (doCorner) {
cornerDirection = Cartesian3.add(forward, backward, cornerDirection);
cornerDirection = Cartesian3.normalize(cornerDirection, cornerDirection);
cornerDirection = Cartesian3.cross(
cornerDirection,
surfaceNormal,
Expand Down
38 changes: 38 additions & 0 deletions packages/engine/Specs/Core/CorridorGeometryLibrarySpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { CorridorGeometryLibrary, Ellipsoid } from "../../index.js";

describe("Core/CorridorGeometryLibrary", () => {
describe("computePositions", () => {
it("should not compute corners for collinear points", () => {
const options = {
positions: [
{ x: 1, y: 1, z: 1 },
{ x: 2, y: 2, z: 2 },
{ x: 3, y: 3, z: 3 },
{ x: 4, y: 4, z: 4 },
],
width: 0.15,
ellipsoid: Ellipsoid.WGS84,
};

// The fact it doesn't throw an error also verifies the fix #12255
const result = CorridorGeometryLibrary.computePositions(options);
expect(result.corners.length).toEqual(0);
});

it("should compute corners for non-collinear points", () => {
const options = {
positions: [
{ x: 0, y: 0, z: 1 },
{ x: 1, y: 0, z: 2 },
{ x: 1, y: 1, z: 3 },
{ x: 0, y: 1, z: 4 },
],
width: 0.15,
ellipsoid: Ellipsoid.WGS84,
};

const result = CorridorGeometryLibrary.computePositions(options);
expect(result.corners.length).toEqual(2);
});
});
});
56 changes: 56 additions & 0 deletions packages/engine/Specs/Core/PolylineVolumeGeometryLibrarySpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
Cartesian3,
Cartesian2,
BoundingRectangle,
PolylineVolumeGeometry,
Ellipsoid,
PolylineVolumeGeometryLibrary,
} from "../../index.js";

describe("Core/PolylineVolumeGeometryLibrary", () => {
describe("computePositions", () => {
// Tests the fix #12255
it("should not throw error if positions are collinear after scaling to geodetic surface", () => {
const positions = [
new Cartesian3(1, 1, 1),
new Cartesian3(2, 2, 2),
new Cartesian3(3, 3, 3),
new Cartesian3(4, 4, 4),
];

const shape = [
new Cartesian2(-0.15, -0.15),
new Cartesian2(0.15, -0.15),
new Cartesian2(0.15, 0.15),
new Cartesian2(-0.15, 0.15),
];

const ellipsoidStub = new Ellipsoid(
6378137.0,
6378137.0,
6356752.3142451793,
);
// It's easier to stub the function than to predict the values to be collinear after calling the function
ellipsoidStub.scaleToGeodeticSurface = function (cartesian, result) {
return Cartesian3.clone(cartesian, result);
};

const boundingRectangle = new BoundingRectangle(-0.15, -0.15, 0.3, 0.3);
const geometry = new PolylineVolumeGeometry({
polylinePositions: positions,
shapePositions: shape,
});
geometry._ellipsoid = ellipsoidStub;

expect(() =>
PolylineVolumeGeometryLibrary.computePositions(
positions,
shape,
boundingRectangle,
geometry,
true,
),
).not.toThrowDeveloperError();
});
});
});

0 comments on commit 6e6ed43

Please sign in to comment.