313 lines
14 KiB
JavaScript
313 lines
14 KiB
JavaScript
|
|
defineSuite([
|
||
|
|
'Core/Occluder',
|
||
|
|
'Core/BoundingSphere',
|
||
|
|
'Core/Cartesian3',
|
||
|
|
'Core/Ellipsoid',
|
||
|
|
'Core/Math',
|
||
|
|
'Core/Rectangle',
|
||
|
|
'Core/Visibility'
|
||
|
|
], function(
|
||
|
|
Occluder,
|
||
|
|
BoundingSphere,
|
||
|
|
Cartesian3,
|
||
|
|
Ellipsoid,
|
||
|
|
CesiumMath,
|
||
|
|
Rectangle,
|
||
|
|
Visibility) {
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
it('throws an exception during construction (1 of 3)', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new Occluder();
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws an exception during construction (2 of 3)', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new Occluder(new BoundingSphere(new Cartesian3(0, 0, 0)));
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws an exception during construction (3 of 3)', function() {
|
||
|
|
expect(function() {
|
||
|
|
return new Occluder(new Cartesian3(0, 0, 0));
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can entirely eclipse a smaller occludee', function() {
|
||
|
|
var giantSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5);
|
||
|
|
var littleSphere = new BoundingSphere(new Cartesian3(0, 0, -2.75), 0.25);
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluder = new Occluder(giantSphere, cameraPosition);
|
||
|
|
expect(occluder.isBoundingSphereVisible(littleSphere)).toEqual(false);
|
||
|
|
expect(occluder.computeVisibility(littleSphere)).toEqual(Visibility.NONE);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can have a fully visible occludee', function() {
|
||
|
|
var bigSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5);
|
||
|
|
var littleSphere = new BoundingSphere(new Cartesian3(0, 0, -2.75), 0.25);
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluder = new Occluder(littleSphere, cameraPosition);
|
||
|
|
expect(occluder.radius).toBeLessThan(bigSphere.radius);
|
||
|
|
expect(occluder.isBoundingSphereVisible(bigSphere)).toEqual(true);
|
||
|
|
expect(occluder.computeVisibility(bigSphere)).toEqual(Visibility.FULL);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('blocks the occludee when both are aligned and the same size', function() {
|
||
|
|
var sphere1 = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5);
|
||
|
|
var sphere2 = new BoundingSphere(new Cartesian3(0, 0, -2.5), 0.5);
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluder = new Occluder(sphere1, cameraPosition);
|
||
|
|
expect(occluder.isBoundingSphereVisible(sphere2)).toEqual(false);
|
||
|
|
expect(occluder.computeVisibility(sphere2)).toEqual(Visibility.NONE);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can have a fully visible occludee', function() {
|
||
|
|
var sphere1 = new BoundingSphere(new Cartesian3(-1.25, 0, -1.5), 0.5);
|
||
|
|
var sphere2 = new BoundingSphere(new Cartesian3(1.25, 0, -1.5), 0.5);
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluder = new Occluder(sphere1, cameraPosition);
|
||
|
|
expect(occluder.computeVisibility(sphere2)).toEqual(Visibility.FULL);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can partially block an occludee without intersecting', function() {
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -2), 1);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var occludeeBS = new BoundingSphere(new Cartesian3(0.5, 0.5, -3), 1);
|
||
|
|
expect(occluder.computeVisibility(occludeeBS)).toEqual(Visibility.PARTIAL);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can partially block an occludee when it intersects laterally', function() {
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(-0.5, 0, -1), 1);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var occludeeBS = new BoundingSphere(new Cartesian3(0.5, 0, -1), 1);
|
||
|
|
expect(occluder.computeVisibility(occludeeBS)).toEqual(Visibility.PARTIAL);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can partially block an occludee when it intersects vertically', function() {
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -2), 1);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var occludeeBS = new BoundingSphere(new Cartesian3(0, 0.5, -2.5), 1);
|
||
|
|
expect(occluder.computeVisibility(occludeeBS)).toEqual(Visibility.PARTIAL);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('reports full visibility when occludee is larger than occluder', function() {
|
||
|
|
var littleSphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5);
|
||
|
|
var bigSphere = new BoundingSphere(new Cartesian3(0, 0, -3), 1);
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluder = new Occluder(littleSphere, cameraPosition);
|
||
|
|
expect(occluder.computeVisibility(bigSphere)).toEqual(Visibility.FULL);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('computeVisibility throws without a bounding sphere', function() {
|
||
|
|
var sphere = new BoundingSphere(new Cartesian3(0, 0, -1.5), 0.5);
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluder = new Occluder(sphere, cameraPosition);
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
occluder.computeVisibility();
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can throw errors during computeOccludeePoint (1 of 5)', function() {
|
||
|
|
expect(function() {
|
||
|
|
Occluder.computeOccludeePoint();
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can throw errors during computeOccludeePoint (2 of 5)', function() {
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1);
|
||
|
|
var occludeePosition = new Cartesian3(0, 0, -5);
|
||
|
|
var positions = [];
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
Occluder.computeOccludeePoint(occluderBS, occludeePosition, positions);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can throw errors during computeOccludeePoint (3 of 5)', function() {
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1);
|
||
|
|
var positions = [];
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
Occluder.computeOccludeePoint(occluderBS, new Cartesian3(0, 0, -3), positions);
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can throw errors during computeOccludeePoint (4 of 5)', function() {
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1);
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
Occluder.computeOccludeePoint(occluderBS, new Cartesian3(0, 0, -3));
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can throw errors during computeOccludeePoint (5 of 5)', function() {
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -5), 1);
|
||
|
|
|
||
|
|
expect(function() {
|
||
|
|
Occluder.computeOccludeePoint(occluderBS, new Cartesian3(0, 0, -5), new Cartesian3(0, 0, -3));
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can compute an occludee point', function() {
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2);
|
||
|
|
var positions = [new Cartesian3(-1.085, 0, -6.221), new Cartesian3(1.085, 0, -6.221)];
|
||
|
|
var tileOccluderSphere = BoundingSphere.fromPoints(positions);
|
||
|
|
var occludeePosition = tileOccluderSphere.center;
|
||
|
|
var result = Occluder.computeOccludeePoint(occluderBS, occludeePosition, positions);
|
||
|
|
expect(result).toEqualEpsilon(new Cartesian3(0, 0, -5), CesiumMath.EPSILON1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can compute a rotation vector (major axis = 0)', function() {
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(5, 0, 0), 2);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var occludeeBS = new BoundingSphere(new Cartesian3(8, 0, 0), 1);
|
||
|
|
var occludee = new Occluder(occludeeBS, cameraPosition);
|
||
|
|
|
||
|
|
var occluderPosition = occluder.position;
|
||
|
|
var occludeePosition = occludee.position;
|
||
|
|
var occluderPlaneNormal = Cartesian3.normalize(Cartesian3.subtract(occludeePosition, occluderPosition, new Cartesian3()), new Cartesian3());
|
||
|
|
var occluderPlaneD = -(Cartesian3.dot(occluderPlaneNormal, occluderPosition));
|
||
|
|
|
||
|
|
var tempVec0 = Cartesian3.abs(Cartesian3.clone(occluderPlaneNormal), new Cartesian3());
|
||
|
|
var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1;
|
||
|
|
if (((majorAxis === 0) && (tempVec0.z > tempVec0.x)) || ((majorAxis === 1) && (tempVec0.z > tempVec0.y))) {
|
||
|
|
majorAxis = 2;
|
||
|
|
}
|
||
|
|
expect(majorAxis).toEqual(0);
|
||
|
|
var aRotationVector = Occluder._anyRotationVector(occluderPosition, occluderPlaneNormal, occluderPlaneD);
|
||
|
|
expect(aRotationVector).toBeTruthy();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can compute a rotation vector (major axis = 1)', function() {
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(5, 0, 0), 2);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var occludeeBS = new BoundingSphere(new Cartesian3(7, 2, 0), 1);
|
||
|
|
var occludee = new Occluder(occludeeBS, cameraPosition);
|
||
|
|
|
||
|
|
var occluderPosition = occluder.position;
|
||
|
|
var occludeePosition = occludee.position;
|
||
|
|
var occluderPlaneNormal = Cartesian3.normalize(Cartesian3.subtract(occludeePosition, occluderPosition, new Cartesian3()), new Cartesian3());
|
||
|
|
var occluderPlaneD = -(Cartesian3.dot(occluderPlaneNormal, occluderPosition));
|
||
|
|
|
||
|
|
var tempVec0 = Cartesian3.abs(Cartesian3.clone(occluderPlaneNormal), new Cartesian3());
|
||
|
|
var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1;
|
||
|
|
if (((majorAxis === 0) && (tempVec0.z > tempVec0.x)) || ((majorAxis === 1) && (tempVec0.z > tempVec0.y))) {
|
||
|
|
majorAxis = 2;
|
||
|
|
}
|
||
|
|
expect(majorAxis).toEqual(1);
|
||
|
|
var aRotationVector = Occluder._anyRotationVector(occluderPosition, occluderPlaneNormal, occluderPlaneD);
|
||
|
|
expect(aRotationVector).toBeTruthy();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can compute a rotation vector (major axis = 2)', function() {
|
||
|
|
var cameraPosition = Cartesian3.ZERO;
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(5, 0, 0), 2);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var occludeeBS = new BoundingSphere(new Cartesian3(6, 0, 2), 1);
|
||
|
|
var occludee = new Occluder(occludeeBS, cameraPosition);
|
||
|
|
|
||
|
|
var occluderPosition = occluder.position;
|
||
|
|
var occludeePosition = occludee.position;
|
||
|
|
var occluderPlaneNormal = Cartesian3.normalize(Cartesian3.subtract(occludeePosition, occluderPosition, new Cartesian3()), new Cartesian3());
|
||
|
|
var occluderPlaneD = -(Cartesian3.dot(occluderPlaneNormal, occluderPosition));
|
||
|
|
|
||
|
|
var tempVec0 = Cartesian3.abs(Cartesian3.clone(occluderPlaneNormal), new Cartesian3());
|
||
|
|
var majorAxis = tempVec0.x > tempVec0.y ? 0 : 1;
|
||
|
|
if (((majorAxis === 0) && (tempVec0.z > tempVec0.x)) || ((majorAxis === 1) && (tempVec0.z > tempVec0.y))) {
|
||
|
|
majorAxis = 2;
|
||
|
|
}
|
||
|
|
expect(majorAxis).toEqual(2);
|
||
|
|
var aRotationVector = Occluder._anyRotationVector(occluderPosition, occluderPlaneNormal, occluderPlaneD);
|
||
|
|
expect(aRotationVector).toBeTruthy();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can have an invisible occludee point', function() {
|
||
|
|
var cameraPosition = new Cartesian3(0, 0, -8);
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var positions = [new Cartesian3(-0.25, 0, -5.3), new Cartesian3(0.25, 0, -5.3)];
|
||
|
|
var tileOccluderSphere = BoundingSphere.fromPoints(positions);
|
||
|
|
var occludeePosition = tileOccluderSphere.center;
|
||
|
|
var result = Occluder.computeOccludeePoint(occluderBS, occludeePosition, positions);
|
||
|
|
|
||
|
|
var bs = new BoundingSphere(result, 0.0);
|
||
|
|
|
||
|
|
expect(occluder.isBoundingSphereVisible(bs)).toEqual(false);
|
||
|
|
expect(occluder.computeVisibility(bs)).toEqual(Visibility.NONE);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can have a visible occludee point', function() {
|
||
|
|
var cameraPosition = new Cartesian3(3, 0, -8);
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2);
|
||
|
|
var occluder = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var positions = [new Cartesian3(-0.25, 0, -5.3), new Cartesian3(0.25, 0, -5.3)];
|
||
|
|
var tileOccluderSphere = BoundingSphere.fromPoints(positions);
|
||
|
|
var occludeePosition = tileOccluderSphere.center;
|
||
|
|
var result = Occluder.computeOccludeePoint(occluderBS, occludeePosition, positions);
|
||
|
|
expect(occluder.isBoundingSphereVisible(new BoundingSphere(result, 0.0))).toEqual(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('compute occludee point from rectangle throws without a rectangle', function() {
|
||
|
|
expect(function() {
|
||
|
|
return Occluder.computeOccludeePointFromRectangle();
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('compute invalid occludee point from rectangle', function() {
|
||
|
|
var rectangle = Rectangle.MAX_VALUE;
|
||
|
|
expect(Occluder.computeOccludeePointFromRectangle(rectangle)).toEqual(undefined);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('compute valid occludee point from rectangle', function() {
|
||
|
|
var edge = Math.PI / 32.0;
|
||
|
|
var rectangle = new Rectangle(-edge, -edge, edge, edge);
|
||
|
|
var ellipsoid = Ellipsoid.WGS84;
|
||
|
|
var positions = Rectangle.subsample(rectangle, ellipsoid);
|
||
|
|
var bs = BoundingSphere.fromPoints(positions);
|
||
|
|
var point = Occluder.computeOccludeePoint(new BoundingSphere(Cartesian3.ZERO, ellipsoid.minimumRadius), bs.center, positions);
|
||
|
|
var actual = Occluder.computeOccludeePointFromRectangle(rectangle);
|
||
|
|
expect(actual).toEqual(point);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('fromBoundingSphere throws without a bounding sphere', function() {
|
||
|
|
expect(function() {
|
||
|
|
Occluder.fromBoundingSphere();
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('fromBoundingSphere throws without camera position', function() {
|
||
|
|
expect(function() {
|
||
|
|
Occluder.fromBoundingSphere(new BoundingSphere());
|
||
|
|
}).toThrowDeveloperError();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('fromBoundingSphere without result parameter', function() {
|
||
|
|
var cameraPosition = new Cartesian3(3, 0, -8);
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2);
|
||
|
|
var occluder0 = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var occluder1 = Occluder.fromBoundingSphere(occluderBS, cameraPosition);
|
||
|
|
|
||
|
|
expect(occluder1.position).toEqual(occluder0.position);
|
||
|
|
expect(occluder1.radius).toEqual(occluder0.radius);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('fromBoundingSphere with result parameter', function() {
|
||
|
|
var cameraPosition = new Cartesian3(3, 0, -8);
|
||
|
|
var occluderBS = new BoundingSphere(new Cartesian3(0, 0, -8), 2);
|
||
|
|
var occluder0 = new Occluder(occluderBS, cameraPosition);
|
||
|
|
var result = new Occluder(occluderBS, Cartesian3.ZERO);
|
||
|
|
var occluder1 = Occluder.fromBoundingSphere(occluderBS, cameraPosition, result);
|
||
|
|
|
||
|
|
expect(occluder1).toBe(result);
|
||
|
|
expect(occluder1.position).toEqual(occluder0.position);
|
||
|
|
expect(occluder1.radius).toEqual(occluder0.radius);
|
||
|
|
});
|
||
|
|
});
|