298 lines
14 KiB
JavaScript
298 lines
14 KiB
JavaScript
defineSuite([
|
|
'Core/EllipsoidalOccluder',
|
|
'Core/BoundingSphere',
|
|
'Core/Cartesian3',
|
|
'Core/Ellipsoid',
|
|
'Core/IntersectionTests',
|
|
'Core/Math',
|
|
'Core/Ray',
|
|
'Core/Rectangle'
|
|
], function(
|
|
EllipsoidalOccluder,
|
|
BoundingSphere,
|
|
Cartesian3,
|
|
Ellipsoid,
|
|
IntersectionTests,
|
|
CesiumMath,
|
|
Ray,
|
|
Rectangle) {
|
|
'use strict';
|
|
|
|
it('uses ellipsoid', function() {
|
|
var ellipsoid = new Ellipsoid(2.0, 3.0, 4.0);
|
|
var occluder = new EllipsoidalOccluder(ellipsoid);
|
|
expect(occluder.ellipsoid).toEqual(ellipsoid);
|
|
});
|
|
|
|
it('throws if ellipsoid is not provided to constructor', function() {
|
|
function createOccluderWithoutEllipsoid() {
|
|
return new EllipsoidalOccluder(undefined, new Cartesian3(1.0, 2.0, 3.0));
|
|
}
|
|
expect(createOccluderWithoutEllipsoid).toThrowDeveloperError();
|
|
});
|
|
|
|
it('isPointVisible example works as claimed', function() {
|
|
var cameraPosition = new Cartesian3(0, 0, 2.5);
|
|
var ellipsoid = new Ellipsoid(1.0, 1.1, 0.9);
|
|
var occluder = new EllipsoidalOccluder(ellipsoid, cameraPosition);
|
|
var point = new Cartesian3(0, -3, -3);
|
|
expect(occluder.isPointVisible(point)).toEqual(true);
|
|
});
|
|
|
|
it('isScaledSpacePointVisible example works as claimed', function() {
|
|
var cameraPosition = new Cartesian3(0, 0, 2.5);
|
|
var ellipsoid = new Ellipsoid(1.0, 1.1, 0.9);
|
|
var occluder = new EllipsoidalOccluder(ellipsoid, cameraPosition);
|
|
var point = new Cartesian3(0, -3, -3);
|
|
var scaledSpacePoint = ellipsoid.transformPositionToScaledSpace(point);
|
|
expect(occluder.isScaledSpacePointVisible(scaledSpacePoint)).toEqual(true);
|
|
});
|
|
|
|
it('reports not visible when point is directly behind ellipsoid', function() {
|
|
var ellipsoid = Ellipsoid.WGS84;
|
|
var occluder = new EllipsoidalOccluder(ellipsoid);
|
|
occluder.cameraPosition = new Cartesian3(7000000.0, 0.0, 0.0);
|
|
|
|
var point = new Cartesian3(-7000000, 0.0, 0.0);
|
|
expect(occluder.isPointVisible(point)).toEqual(false);
|
|
});
|
|
|
|
it('reports not visible when point is directly behind ellipsoid and camera is inside the ellispoid', function() {
|
|
var ellipsoid = Ellipsoid.WGS84;
|
|
var occluder = new EllipsoidalOccluder(ellipsoid);
|
|
occluder.cameraPosition = new Cartesian3(ellipsoid.minimumRadius - 100, 0.0, 0.0);
|
|
|
|
var point = new Cartesian3(-7000000, 0.0, 0.0);
|
|
expect(occluder.isPointVisible(point)).toEqual(false);
|
|
});
|
|
|
|
it('reports visible when point is in front of ellipsoid', function() {
|
|
var ellipsoid = Ellipsoid.WGS84;
|
|
var occluder = new EllipsoidalOccluder(ellipsoid);
|
|
occluder.cameraPosition = new Cartesian3(7000000.0, 0.0, 0.0);
|
|
|
|
var point = new Cartesian3(6900000.0, 0.0, 0.0);
|
|
expect(occluder.isPointVisible(point)).toEqual(true);
|
|
});
|
|
|
|
it('reports visible when point is in opposite direction from ellipsoid', function() {
|
|
var ellipsoid = Ellipsoid.WGS84;
|
|
var occluder = new EllipsoidalOccluder(ellipsoid);
|
|
occluder.cameraPosition = new Cartesian3(7000000.0, 0.0, 0.0);
|
|
|
|
var point = new Cartesian3(7100000.0, 0.0, 0.0);
|
|
expect(occluder.isPointVisible(point)).toEqual(true);
|
|
});
|
|
|
|
it('reports not visible when point is over horizon', function() {
|
|
var ellipsoid = Ellipsoid.WGS84;
|
|
var occluder = new EllipsoidalOccluder(ellipsoid);
|
|
occluder.cameraPosition = new Cartesian3(7000000.0, 0.0, 0.0);
|
|
|
|
var point = new Cartesian3(4510635.0, 4510635.0, 0.0);
|
|
expect(occluder.isPointVisible(point)).toEqual(false);
|
|
});
|
|
|
|
describe('computeHorizonCullingPoint', function() {
|
|
it('requires directionToPoint and positions', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 12345.0, 12345.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
var positions = [new Cartesian3(-12345.0, 12345.0, 12345.0)];
|
|
var directionToPoint = BoundingSphere.fromPoints(positions).center;
|
|
|
|
expect(function() {
|
|
ellipsoidalOccluder.computeHorizonCullingPoint(undefined, positions);
|
|
}).toThrowDeveloperError();
|
|
|
|
expect(function() {
|
|
ellipsoidalOccluder.computeHorizonCullingPoint(directionToPoint, undefined);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it('returns point on ellipsoid when single position is on center line', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 4567.0, 8910.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
var positions = [new Cartesian3(12345.0, 0.0, 0.0)];
|
|
var directionToPoint = new Cartesian3(1.0, 0.0, 0.0);
|
|
|
|
var result = ellipsoidalOccluder.computeHorizonCullingPoint(directionToPoint, positions);
|
|
|
|
expect(result.x).toEqualEpsilon(1.0, CesiumMath.EPSILON14);
|
|
expect(result.y).toEqualEpsilon(0.0, CesiumMath.EPSILON14);
|
|
expect(result.z).toEqualEpsilon(0.0, CesiumMath.EPSILON14);
|
|
});
|
|
|
|
it('returns undefined when horizon of single point is parallel to center line', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 4567.0, 8910.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
var positions = [new Cartesian3(0.0, 4567.0, 0.0)];
|
|
var directionToPoint = new Cartesian3(1.0, 0.0, 0.0);
|
|
|
|
var result = ellipsoidalOccluder.computeHorizonCullingPoint(directionToPoint, positions);
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it('returns undefined when single point is in the opposite direction of the center line', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 4567.0, 8910.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
var positions = [new Cartesian3(-14000.0, -1000.0, 0.0)];
|
|
var directionToPoint = new Cartesian3(1.0, 0.0, 0.0);
|
|
|
|
var result = ellipsoidalOccluder.computeHorizonCullingPoint(directionToPoint, positions);
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it('computes a point from a single position with a grazing altitude close to zero', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 12345.0, 12345.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
|
|
var positions = [new Cartesian3(-12345.0, 12345.0, 12345.0), new Cartesian3(-12346.0, 12345.0, 12345.0)];
|
|
var boundingSphere = BoundingSphere.fromPoints(positions);
|
|
|
|
var firstPositionArray = [positions[0]];
|
|
var result = ellipsoidalOccluder.computeHorizonCullingPoint(boundingSphere.center, firstPositionArray);
|
|
var unscaledResult = Cartesian3.multiplyComponents(result, ellipsoid.radii, new Cartesian3());
|
|
|
|
// The grazing altitude of the ray from the horizon culling point to the
|
|
// position used to compute it should be very nearly zero.
|
|
var direction = Cartesian3.normalize(Cartesian3.subtract(positions[0], unscaledResult, new Cartesian3()), new Cartesian3());
|
|
var nearest = IntersectionTests.grazingAltitudeLocation(new Ray(unscaledResult, direction), ellipsoid);
|
|
var nearestCartographic = ellipsoid.cartesianToCartographic(nearest);
|
|
expect(nearestCartographic.height).toEqualEpsilon(0.0, CesiumMath.EPSILON5);
|
|
});
|
|
|
|
it('computes a point from multiple positions with a grazing altitude close to zero for one of the positions and less than zero for the others', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 12345.0, 12345.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
|
|
var positions = [new Cartesian3(-12345.0, 12345.0, 12345.0), new Cartesian3(-12346.0, 12345.0, 12345.0), new Cartesian3(-12446.0, 12445.0, 12445.0)];
|
|
var boundingSphere = BoundingSphere.fromPoints(positions);
|
|
|
|
var result = ellipsoidalOccluder.computeHorizonCullingPoint(boundingSphere.center, positions);
|
|
var unscaledResult = Cartesian3.multiplyComponents(result, ellipsoid.radii, new Cartesian3());
|
|
|
|
// The grazing altitude of the ray from the horizon culling point to the
|
|
// position used to compute it should be very nearly zero.
|
|
var foundOneNearZero = false;
|
|
for (var i = 0; i < positions.length; ++i) {
|
|
var direction = Cartesian3.normalize(Cartesian3.subtract(positions[i], unscaledResult, new Cartesian3()), new Cartesian3());
|
|
var nearest = IntersectionTests.grazingAltitudeLocation(new Ray(unscaledResult, direction), ellipsoid);
|
|
var nearestCartographic = ellipsoid.cartesianToCartographic(nearest);
|
|
if (Math.abs(nearestCartographic.height) < CesiumMath.EPSILON5) {
|
|
foundOneNearZero = true;
|
|
} else {
|
|
expect(nearestCartographic.height).toBeLessThan(0.0);
|
|
}
|
|
}
|
|
|
|
expect(foundOneNearZero).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('computeHorizonCullingPointFromVertices', function() {
|
|
it('requires directionToPoint, vertices, and stride', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 12345.0, 12345.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
|
|
var positions = [new Cartesian3(-12345.0, 12345.0, 12345.0), new Cartesian3(-12346.0, 12345.0, 12345.0), new Cartesian3(-12446.0, 12445.0, 12445.0)];
|
|
var boundingSphere = BoundingSphere.fromPoints(positions);
|
|
|
|
var vertices = [];
|
|
for (var i = 0; i < positions.length; ++i) {
|
|
var position = positions[i];
|
|
vertices.push(position.x);
|
|
vertices.push(position.y);
|
|
vertices.push(position.z);
|
|
vertices.push(1.0);
|
|
vertices.push(2.0);
|
|
vertices.push(3.0);
|
|
vertices.push(4.0);
|
|
}
|
|
|
|
ellipsoidalOccluder.computeHorizonCullingPointFromVertices(boundingSphere.center, vertices, 7);
|
|
|
|
expect(function() {
|
|
ellipsoidalOccluder.computeHorizonCullingPointFromVertices(undefined, vertices, 7);
|
|
}).toThrowDeveloperError();
|
|
|
|
expect(function() {
|
|
ellipsoidalOccluder.computeHorizonCullingPointFromVertices(boundingSphere.center, undefined, 7);
|
|
}).toThrowDeveloperError();
|
|
|
|
expect(function() {
|
|
ellipsoidalOccluder.computeHorizonCullingPointFromVertices(boundingSphere.center, vertices, undefined);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it('produces same answers as computeHorizonCullingPoint', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 12345.0, 12345.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
|
|
var positions = [new Cartesian3(-12345.0, 12345.0, 12345.0), new Cartesian3(-12346.0, 12345.0, 12345.0), new Cartesian3(-12446.0, 12445.0, 12445.0)];
|
|
var boundingSphere = BoundingSphere.fromPoints(positions);
|
|
|
|
var center = new Cartesian3(-12000.0, 12000.0, 12000.0);
|
|
|
|
var vertices = [];
|
|
for (var i = 0; i < positions.length; ++i) {
|
|
var position = positions[i];
|
|
vertices.push(position.x - center.x);
|
|
vertices.push(position.y - center.y);
|
|
vertices.push(position.z - center.z);
|
|
vertices.push(1.0);
|
|
vertices.push(2.0);
|
|
vertices.push(3.0);
|
|
vertices.push(4.0);
|
|
}
|
|
|
|
var result1 = ellipsoidalOccluder.computeHorizonCullingPoint(boundingSphere.center, positions);
|
|
var result2 = ellipsoidalOccluder.computeHorizonCullingPointFromVertices(boundingSphere.center, vertices, 7, center);
|
|
|
|
expect(result1.x).toEqualEpsilon(result2.x, CesiumMath.EPSILON14);
|
|
expect(result1.y).toEqualEpsilon(result2.y, CesiumMath.EPSILON14);
|
|
expect(result1.z).toEqualEpsilon(result2.z, CesiumMath.EPSILON14);
|
|
});
|
|
});
|
|
|
|
describe('computeHorizonCullingPointFromRectangle', function() {
|
|
it('returns undefined for global rectangle', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 12345.0, 12345.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
var rectangle = Rectangle.MAX_VALUE;
|
|
var result = ellipsoidalOccluder.computeHorizonCullingPointFromRectangle(rectangle, ellipsoid);
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it('computes a point with a grazing altitude close to zero for one of the rectangle corners and less than or equal to zero for the others', function() {
|
|
var ellipsoid = new Ellipsoid(12345.0, 12345.0, 12345.0);
|
|
var ellipsoidalOccluder = new EllipsoidalOccluder(ellipsoid);
|
|
|
|
var rectangle = new Rectangle(0.1, 0.2, 0.3, 0.4);
|
|
var result = ellipsoidalOccluder.computeHorizonCullingPointFromRectangle(rectangle, ellipsoid);
|
|
expect(result).toBeDefined();
|
|
var unscaledResult = Cartesian3.multiplyComponents(result, ellipsoid.radii, new Cartesian3());
|
|
|
|
// The grazing altitude of the ray from the horizon culling point to the
|
|
// position used to compute it should be very nearly zero.
|
|
var positions = [ellipsoid.cartographicToCartesian(Rectangle.southwest(rectangle)),
|
|
ellipsoid.cartographicToCartesian(Rectangle.southeast(rectangle)),
|
|
ellipsoid.cartographicToCartesian(Rectangle.northwest(rectangle)),
|
|
ellipsoid.cartographicToCartesian(Rectangle.northeast(rectangle))];
|
|
|
|
var foundOneNearZero = false;
|
|
for (var i = 0; i < positions.length; ++i) {
|
|
var direction = Cartesian3.normalize(Cartesian3.subtract(positions[i], unscaledResult, new Cartesian3()), new Cartesian3());
|
|
var nearest = IntersectionTests.grazingAltitudeLocation(new Ray(unscaledResult, direction), ellipsoid);
|
|
var nearestCartographic = ellipsoid.cartesianToCartographic(nearest);
|
|
if (Math.abs(nearestCartographic.height) < CesiumMath.EPSILON5) {
|
|
foundOneNearZero = true;
|
|
} else {
|
|
expect(nearestCartographic.height).toBeLessThanOrEqualTo(0.0);
|
|
}
|
|
}
|
|
|
|
expect(foundOneNearZero).toBe(true);
|
|
});
|
|
});
|
|
});
|