Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// C
// The near plane calculus is quite straight forward and works the same as for planar
// projections. We simply search for the closest point of the ground just above
// the camera, then we apply margin (elevation) to it along the sphere surface normal:
const cameraAltitude = this.getCameraAltitude(camera, projection);
nearPlane = cameraAltitude - this.maxElevation;
// The far plane distance calculus requires finding the sphere tangent line that is
// co-linear with (goes thru) camera position, such tangent creates right angle
// with sphere diameter where it touches its surface (point T). Given that sphere is
// always at world orgin and camera orbits around it we have:
// angle(OTC) = 90
// sin(OCT) = sin(alpha) = r / d
// alpha = asin(r / d)
const r = EarthConstants.EQUATORIAL_RADIUS;
let d = camera.position.length();
d = d === 0 ? epsilon : d;
const alpha = Math.asin(r / d);
// The distance to tangent point may be described as:
// t = sqrt(d^2 - r^2)
const t = Math.sqrt(d * d - r * r);
// Because we would like to see elevated geometry that may be visible beyond the tangent
// point on ground surface, we need to extend viewing distance along the tangent line
// by te (see graph above). Knowing that OTE forms right angle, we have:
// (r+e)^2 = r^2 + te^2
// te = sqrt((r+e)^2 - r^2)
// This reduces to:
// te = sqrt(r^2 + 2*r*e + e^2 - r^2)
// te = sqrt(2*r*e + e^2)
// There may be situations when maximum elevation still remains below sea level (< 0) or
// it is neglible, in such cases tangent extension (te) is not required.
const worldOrigin = new THREE.Vector3(0, 0, 0);
// Acquire camera to origin vector.
const cameraToOrigin = worldOrigin.sub(camera.position);
// Extract camera X, Y, Z orientation axes into tmp vectors array.
camera.matrixWorld.extractBasis(
this.m_tmpVectors[0],
this.m_tmpVectors[1],
this.m_tmpVectors[2]
);
const xaxis = this.m_tmpVectors[0];
const yaxis = this.m_tmpVectors[1];
// Extend the far plane by the margin along the shpere normal (radius).
// In order to calculate far plane distance we need to find sphere tangent
// line that passes thru camera position, method explanation may be found in
// AltitudeBasedClipPlanesEvaluator.evaluateDistanceSphericalProj() method.
const r = EarthConstants.EQUATORIAL_RADIUS;
const d = cameraToOrigin.length();
const dNorm = this.m_tmpVectors[2].copy(cameraToOrigin).multiplyScalar(1 / d);
const sinAlpha = r / d;
const alpha = Math.asin(sinAlpha);
const cosAlpha = Math.sqrt(1 - sinAlpha * sinAlpha);
// Apply tangent vector length onto camera to origin vector.
let td: THREE.Vector3;
// There may be situations when maximum elevation remains below sea level (< 0), or
// is neglible, in such cases simply apply tangent distance to camera to origin vector.
if (this.maxElevation < epsilon) {
// This may be calculated by several methods, firstly:
// t_d = d_norm * |t|,
// where:
// |t| = sqrt(|d|^2 - |r|^2), or