Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// and takes the current rotation of the camera into account.
cache.matrix4[1].multiplyMatrices(
cache.matrix4[0],
cache.matrix4[1].getInverse(mapView.camera.projectionMatrix)
);
// Unproject the point via the unprojection matrix.
const pointInCameraSpace = pointInNDCPosition.applyMatrix4(cache.matrix4[1]);
// Use the point in camera space as the vector towards this point.
rayCaster.set(cache.vector3[1], pointInCameraSpace.normalize());
if (elevation !== undefined) {
groundPlane.constant = -elevation;
}
const worldPosition = new THREE.Vector3();
const result =
mapView.projection.type === ProjectionType.Planar
? rayCaster.ray.intersectPlane(groundPlane, worldPosition)
: rayCaster.ray.intersectSphere(groundSphere, worldPosition);
groundPlane.constant = 0;
return result;
}
pt.sub(this.center);
this.geometry.vertices.push(pt);
middlePoint.add(pt);
});
middlePoint.divideScalar(geoCoordinates.length);
const lineObject = new THREE.Line(this.geometry, debugMaterial);
lineObject.renderOrder = PRIORITY_ALWAYS;
this.objects.push(lineObject);
this.m_labelPositions.setXYZ(0, 0, 0, 0);
const textPosition = new THREE.Vector3();
if (this.projection.type === ProjectionType.Planar) {
// place the text position at north/west for planar projections.
textPosition.copy(this.geometry.vertices[3]);
textPosition.multiplyScalar(0.95);
this.m_textLayoutStyle = new TextLayoutStyle({
verticalAlignment: VerticalAlignment.Below,
horizontalAlignment: HorizontalAlignment.Left
});
} else {
textPosition.copy(middlePoint);
this.m_textLayoutStyle = new TextLayoutStyle({
verticalAlignment: VerticalAlignment.Center,
horizontalAlignment: HorizontalAlignment.Center
});
}
this.m_tmpVectors[1],
this.m_tmpVectors[2]
);
// Setup quaternion based on X axis.
this.m_tmpQuaternion.setFromAxisAngle(this.m_tmpVectors[0], alpha);
// Aquire forward vector based on Z axis reversed (keep it in tmpVectors[2]).
const fwd = this.m_tmpVectors[2].negate();
// Apply quaternion rotation to forward vector, store it in tmpVectors[1].
const fwdRot = this.m_tmpVectors[1].copy(fwd).applyQuaternion(this.m_tmpQuaternion);
// Store camera position tmpVectors[0] and reference it with p.
const p = this.m_tmpVectors[0].copy(camera.position);
p.addScaledVector(fwdRot, Math.sqrt(d * d - r * r));
farPlane = p.sub(camera.position).dot(fwd);
const bias = 2000; // TODO: generalize.
nearPlane = Math.max(this.nearMin, projection.groundDistance(camera.position) - bias);
} else if (projection.type === ProjectionType.Planar) {
const groundDistance = projection.groundDistance(camera.position);
nearPlane = Math.max(this.nearMin, groundDistance * this.nearMultiplier);
// Will be already clamped to minFar due to clamping above.
farPlane = nearPlane * this.nearFarMultiplier + this.farOffset;
} else {
assert(false, "Unsuported projection type");
}
const viewRanges: ViewRanges = { near: nearPlane, far: farPlane, maximum: farPlane };
return viewRanges;
}
}
}
}
}
// Get new target position after the zoom
const newTargetPosition = rayCastWorldCoordinates(
mapView,
targetPositionOnScreenXinNDC,
targetPositionOnScreenYinNDC
);
if (!targetPosition || !newTargetPosition) {
return;
}
if (mapView.projection.type === ProjectionType.Planar) {
// Calculate the difference and pan the map to maintain the map relative to the target
// position.
targetPosition.sub(newTargetPosition);
panCameraAboveFlatMap(mapView, targetPosition.x, targetPosition.y);
} else if (mapView.projection.type === ProjectionType.Spherical) {
panCameraAroundGlobe(mapView, targetPosition, newTargetPosition);
}
}
private computeRequiredInitialRootTileKeys(worldCenter: THREE.Vector3) {
this.m_rootTileKeys = [];
const rootTileKey = TileKey.fromRowColumnLevel(0, 0, 0);
const tileWrappingEnabled = this.mapView.projection.type === ProjectionType.Planar;
if (!tileWrappingEnabled || !this.m_tileWrappingEnabled) {
this.m_rootTileKeys.push(new TileKeyEntry(rootTileKey, 0, 0, 0));
return;
}
const worldGeoPoint = this.mapView.projection.unprojectPoint(worldCenter);
const startOffset = Math.round(worldGeoPoint.longitude / 360.0);
// This algorithm computes the number of offsets we need to test. The following diagram may
// help explain the algorithm below.
//
// |🎥
// |.\ .
// | . \ .
// z | . \ .c2
isSolidLineTechnique(technique) && technique.secondaryWidth !== undefined;
const object = new ObjectCtor(bufferGeometry, material);
object.renderOrder = technique.renderOrder!;
if (group.renderOrderOffset !== undefined) {
object.renderOrder += group.renderOrderOffset;
}
if (srcGeometry.uuid !== undefined) {
object.userData.geometryId = srcGeometry.uuid;
}
if (
isFillTechnique(technique) &&
mapView.projection.type === ProjectionType.Planar
) {
object.onBeforeRender = chainCallbacks(
object.onBeforeRender,
(_renderer, _scene, _camera, _geometry, _material) => {
if (_material.clippingPlanes === null) {
_material.clippingPlanes = this.clippingPlanes;
// TODO: Add clipping for Spherical projection.
}
const worldOffsetX =
mapView.projection.worldExtent(0, 0).max.x * tile.offset;
// This prevents aliasing issues in the pixel shader, there are artifacts
// at low zoom levels, so we increase the factor by 10 to 1%.
const expandFactor = mapView.zoomLevel <= 2 ? 1.01 : 1.001;
const planes = _material.clippingPlanes;
const rightConstant =
tile.center.x -
update(camera: THREE.Camera) {
if (this.m_projectionType === ProjectionType.Planar) {
this.setHorizonPosition(camera);
this.updateTexturePosition();
}
}
constructor(
sky: GradientSky,
private m_projectionType: ProjectionType,
private m_height: number = DEFAULT_TEXTURE_SIZE
) {
const topColor = new Color(sky.topColor);
const bottomColor = new Color(sky.bottomColor);
const groundColor = new Color(sky.groundColor);
this.m_width = this.m_projectionType === ProjectionType.Planar ? 1.0 : this.m_height;
this.m_faceCount = this.m_projectionType === ProjectionType.Planar ? 1.0 : 6.0;
this.m_faces = [];
for (let i = 0; i < this.m_faceCount; ++i) {
const data = new Uint8Array(3 * this.m_width * this.m_height);
this.fillTextureData(data, i, topColor, bottomColor, groundColor, sky.monomialPower);
const texture = new DataTexture(data, this.m_width, this.m_height, RGBFormat);
texture.needsUpdate = true;
texture.unpackAlignment = 1;
this.m_faces.push(texture);
}
if (this.m_projectionType === ProjectionType.Spherical) {
this.m_skybox = new CubeTexture(this.m_faces);
this.m_skybox.needsUpdate = true;
} else {
this.m_farClipPlaneDividedVertically = new Line3();