Skip to content

Commit 036bf12

Browse files
authored
Merge pull request #8571 from AnalyticalGraphicsInc/lookToOriginFix
Handling zero origin for localFrameToFixedFrame
2 parents 8648a46 + 929dcaa commit 036bf12

File tree

4 files changed

+82
-5
lines changed

4 files changed

+82
-5
lines changed

CHANGES.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,21 @@ Change Log
3030
* Added `Globe.showSkirts` to support the ability to hide terrain skirts when viewing terrain from below the surface. [#8489](https://github.com/AnalyticalGraphicsInc/cesium/pull/8489)
3131
* Fixed `BoundingSphere.projectTo2D` when the bounding sphere’s center is at the origin. [#8482](https://github.com/AnalyticalGraphicsInc/cesium/pull/8482)
3232
* Added `minificationFilter` and `magnificationFilter` options to `Material` to control texture filtering. [#8473](https://github.com/AnalyticalGraphicsInc/cesium/pull/8473)
33-
* Update [earcut](https://github.com/mapbox/earcut) to 2.2.1 [#8528](https://github.com/AnalyticalGraphicsInc/cesium/pull/8528)
33+
* Update [earcut](https://github.com/mapbox/earcut) to 2.2.1. [#8528](https://github.com/AnalyticalGraphicsInc/cesium/pull/8528)
3434

3535
##### Fixes :wrench:
3636
* Fixed issue where `RequestScheduler` double-counted image requests made via `createImageBitmap`. [#8162](https://github.com/AnalyticalGraphicsInc/cesium/issues/8162)
3737
* Fixed a bug where the camera could go underground during mouse navigation. [#8504](https://github.com/AnalyticalGraphicsInc/cesium/pull/8504)
3838
* Fixed a bug where files with backslashes were not loaded in KMZ files. [#8533](https://github.com/AnalyticalGraphicsInc/cesium/pull/8533)
39-
* Reduced Cesium bundle size by avoiding unnecessarily importing `Cesium3DTileset` in `Picking.js` [#8532](https://github.com/AnalyticalGraphicsInc/cesium/pull/8532)
39+
* Reduced Cesium bundle size by avoiding unnecessarily importing `Cesium3DTileset` in `Picking.js`. [#8532](https://github.com/AnalyticalGraphicsInc/cesium/pull/8532)
4040
* Fixed WebGL warning message about `EXT_float_blend` being implicitly enabled. [#8534](https://github.com/AnalyticalGraphicsInc/cesium/pull/8534)
4141
* Updated SampleData models to glTF 2.0. [#7802](https://github.com/AnalyticalGraphicsInc/cesium/issues/7802)
42-
* Fixed a bug where toggling point cloud classification visibility would result in a grey screen on Linux / Nvidia [#8538](https://github.com/AnalyticalGraphicsInc/cesium/pull/8538)
42+
* Fixed a bug where toggling point cloud classification visibility would result in a grey screen on Linux / Nvidia. [#8538](https://github.com/AnalyticalGraphicsInc/cesium/pull/8538)
4343
* Fixed a bug where a point in a `PointPrimitiveCollection` is rendered in the middle of the screen instead of being clipped. [#8542](https://github.com/AnalyticalGraphicsInc/cesium/pull/8542)
4444
* Fixed a crash when deleting and re-creating polylines from CZML. `ReferenceProperty` now returns undefined when the target entity or property does not exist, instead of throwing. [#8544](https://github.com/AnalyticalGraphicsInc/cesium/pull/8544)
4545
* Fixed a bug where rapidly updating a `PolylineCollection` could result in an instanceIndex is out of range error. [#8546](https://github.com/AnalyticalGraphicsInc/cesium/pull/8546)
4646
* Fixed a crash that could occur when an entity was deleted while the corresponding `Primitive` was being created asynchronously. [#8569](https://github.com/AnalyticalGraphicsInc/cesium/pull/8569)
47+
* Fixed a crash when calling `camera.lookAt` with the origin as the target. This could happen when looking at a tileset with the origin as its center. [#8571](https://github.com/AnalyticalGraphicsInc/cesium/pull/8571)
4748

4849
### 1.65.0 - 2020-01-06
4950

Source/Core/Transforms.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,13 @@ import TimeConstants from './TimeConstants.js';
128128
if (!defined(result)) {
129129
result = new Matrix4();
130130
}
131-
// If x and y are zero, assume origin is at a pole, which is a special case.
132-
if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) {
131+
if (Cartesian3.equalsEpsilon(origin, Cartesian3.ZERO, CesiumMath.EPSILON14)) {
132+
// If x, y, and z are zero, use the degenerate local frame, which is a special case
133+
Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, scratchFirstCartesian);
134+
Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, scratchSecondCartesian);
135+
Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, scratchThirdCartesian);
136+
} else if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) {
137+
// If x and y are zero, assume origin is at a pole, which is a special case.
133138
var sign = CesiumMath.sign(origin.z);
134139

135140
Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, scratchFirstCartesian);

Specs/Core/TransformsSpec.js

+44
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ describe('Core/Transforms', function() {
6969
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
7070
});
7171

72+
it('eastNorthUpToFixedFrame works at the origin', function() {
73+
var origin = Cartesian3.ZERO;
74+
var expectedTranslation = new Cartesian4(0.0, 0.0, 0.0, 1.0);
75+
76+
var returnedResult = Transforms.eastNorthUpToFixedFrame(origin, Ellipsoid.WGS84);
77+
expect(Matrix4.getColumn(returnedResult, 0, new Cartesian4())).toEqual(Cartesian4.UNIT_Y); // east
78+
expect(Matrix4.getColumn(returnedResult, 1, new Cartesian4())).toEqual(negativeX); // north
79+
expect(Matrix4.getColumn(returnedResult, 2, new Cartesian4())).toEqual(Cartesian4.UNIT_Z); // up
80+
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
81+
});
82+
7283
it('northEastDownToFixedFrame works without a result parameter', function() {
7384
var origin = new Cartesian3(1.0, 0.0, 0.0);
7485
var expectedTranslation = new Cartesian4(origin.x, origin.y, origin.z, 1.0);
@@ -117,6 +128,17 @@ describe('Core/Transforms', function() {
117128
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
118129
});
119130

131+
it('northEastDownToFixedFrame works at the origin', function() {
132+
var origin = Cartesian3.ZERO;
133+
var expectedTranslation = new Cartesian4(0.0, 0.0, 0.0, 1.0);
134+
135+
var returnedResult = Transforms.northEastDownToFixedFrame(origin, Ellipsoid.UNIT_SPHERE);
136+
expect(Matrix4.getColumn(returnedResult, 0, new Cartesian4())).toEqual(negativeX); // north
137+
expect(Matrix4.getColumn(returnedResult, 1, new Cartesian4())).toEqual(Cartesian4.UNIT_Y); // east
138+
expect(Matrix4.getColumn(returnedResult, 2, new Cartesian4())).toEqual(negativeZ); // down
139+
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
140+
});
141+
120142
it('northUpEastToFixedFrame works without a result parameter', function() {
121143
var origin = new Cartesian3(1.0, 0.0, 0.0);
122144
var expectedTranslation = new Cartesian4(origin.x, origin.y, origin.z, 1.0);
@@ -165,6 +187,17 @@ describe('Core/Transforms', function() {
165187
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
166188
});
167189

190+
it('northUpEastToFixedFrame works at the origin', function() {
191+
var origin = Cartesian3.ZERO;
192+
var expectedTranslation = new Cartesian4(0.0, 0.0, 0.0, 1.0);
193+
194+
var returnedResult = Transforms.northUpEastToFixedFrame(origin, Ellipsoid.UNIT_SPHERE);
195+
expect(Matrix4.getColumn(returnedResult, 0, new Cartesian4())).toEqual(negativeX); // north
196+
expect(Matrix4.getColumn(returnedResult, 1, new Cartesian4())).toEqual(Cartesian4.UNIT_Z); // up
197+
expect(Matrix4.getColumn(returnedResult, 2, new Cartesian4())).toEqual(Cartesian4.UNIT_Y); // east
198+
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
199+
});
200+
168201
it('northWestUpToFixedFrame works without a result parameter', function() {
169202
var origin = new Cartesian3(1.0, 0.0, 0.0);
170203
var expectedTranslation = new Cartesian4(origin.x, origin.y, origin.z, 1.0);
@@ -213,6 +246,17 @@ describe('Core/Transforms', function() {
213246
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
214247
});
215248

249+
it('northWestUpToFixedFrame works at the origin', function() {
250+
var origin = Cartesian3.ZERO;
251+
var expectedTranslation = new Cartesian4(0.0, 0.0, 0.0, 1.0);
252+
253+
var returnedResult = Transforms.northWestUpToFixedFrame(origin, Ellipsoid.UNIT_SPHERE);
254+
expect(Matrix4.getColumn(returnedResult, 0, new Cartesian4())).toEqual(negativeX); // north
255+
expect(Matrix4.getColumn(returnedResult, 1, new Cartesian4())).toEqual(negativeY); // west
256+
expect(Matrix4.getColumn(returnedResult, 2, new Cartesian4())).toEqual(Cartesian4.UNIT_Z); // up
257+
expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation
258+
});
259+
216260
it('normal use of localFrameToFixedFrameGenerator', function() {
217261
var cartesianTab = [
218262
new Cartesian3(0.0, 0.0, 1.0),

Specs/Scene/CameraSpec.js

+27
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,33 @@ describe('Scene/Camera', function() {
14991499
expect(1.0 - Cartesian3.magnitude(tempCamera.right)).toBeLessThan(CesiumMath.EPSILON14);
15001500
});
15011501

1502+
it('lookAt when target is zero', function() {
1503+
var target = Cartesian3.clone(Cartesian3.ZERO);
1504+
var offset = new Cartesian3(0.0, -1.0, 0.0);
1505+
1506+
var tempCamera = Camera.clone(camera);
1507+
tempCamera.lookAt(target, offset);
1508+
1509+
expect(tempCamera.position).toEqualEpsilon(offset, CesiumMath.EPSILON11);
1510+
expect(tempCamera.direction).toEqualEpsilon(Cartesian3.negate(Cartesian3.normalize(offset, new Cartesian3()), new Cartesian3()), CesiumMath.EPSILON11);
1511+
expect(tempCamera.right).toEqualEpsilon(Cartesian3.cross(tempCamera.direction, Cartesian3.UNIT_Z, new Cartesian3()), CesiumMath.EPSILON11);
1512+
expect(tempCamera.up).toEqualEpsilon(Cartesian3.cross(tempCamera.right, tempCamera.direction, new Cartesian3()), CesiumMath.EPSILON11);
1513+
});
1514+
1515+
it('lookAt when target and camera are zero', function() {
1516+
var target = Cartesian3.clone(Cartesian3.ZERO);
1517+
var offset = new Cartesian3(0.0, -1.0, 0.0);
1518+
1519+
var tempCamera = Camera.clone(camera);
1520+
tempCamera.position = Cartesian3.clone(Cartesian3.ZERO);
1521+
tempCamera.lookAt(target, offset);
1522+
1523+
expect(tempCamera.position).toEqualEpsilon(offset, CesiumMath.EPSILON11);
1524+
expect(tempCamera.direction).toEqualEpsilon(Cartesian3.negate(Cartesian3.normalize(offset, new Cartesian3()), new Cartesian3()), CesiumMath.EPSILON11);
1525+
expect(tempCamera.right).toEqualEpsilon(Cartesian3.cross(tempCamera.direction, Cartesian3.UNIT_Z, new Cartesian3()), CesiumMath.EPSILON11);
1526+
expect(tempCamera.up).toEqualEpsilon(Cartesian3.cross(tempCamera.right, tempCamera.direction, new Cartesian3()), CesiumMath.EPSILON11);
1527+
});
1528+
15021529
it('lookAt throws with no target parameter', function() {
15031530
expect(function() {
15041531
camera.lookAt(undefined, Cartesian3.ZERO);

0 commit comments

Comments
 (0)