Mond-3D: Pan und Zoom ohne Blickwinkelveraenderung umsetzen

Verschieben nutzt jetzt camera.setViewOffset() statt Kameraposition/-ziel
zu bewegen, und Zoom erfolgt ueber camera.zoom (Brennweite) statt ueber
Annaeherung der Kamera. So bleibt der Blickwinkel auf den Mond in der
Standardansicht immer wie von der Erde aus - nur der freie Kamera-Modus
darf ihn aendern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-13 13:38:15 +02:00
co-authored by Claude Sonnet 5
parent efb2d8ed04
commit 4c6fe6faeb
+33 -4
View File
@@ -596,18 +596,47 @@ function applyMoonZoom() {
return;
}
const r = MOON_CAMERA_BASE_Z / getMoonZoomFactor();
if (freeCameraMode) {
const r = MOON_CAMERA_BASE_Z / getMoonZoomFactor();
moonSceneState.camera.position.set(
r * Math.sin(cameraOrbitPhi) * Math.sin(cameraOrbitTheta),
r * Math.cos(cameraOrbitPhi),
r * Math.sin(cameraOrbitPhi) * Math.cos(cameraOrbitTheta)
);
moonSceneState.camera.lookAt(0, 0, 0);
moonSceneState.camera.zoom = 1;
moonSceneState.camera.clearViewOffset();
} else {
moonSceneState.camera.position.set(moonPanX, moonPanY, r);
moonSceneState.camera.lookAt(moonPanX, moonPanY, 0);
// Kamera bleibt IMMER exakt auf den Mond ausgerichtet UND auf fester
// Distanz ("Blickwinkel wie von der Erde aus" darf sich weder beim
// Verschieben noch beim Zoomen aendern - genau wie ein Teleskop, das den
// Mond vergroessert, ohne dass sich die Erde-Mond-Distanz aendert). Zoom
// wird deshalb NICHT durch Annaehern der Kamera simuliert (das wuerde
// durch die perspektivische Projektion echte Parallaxe/Verzerrung
// erzeugen, die bei einer realen Fernbeobachtung so nicht auftritt),
// sondern rein optisch ueber camera.zoom (Brennweiten-Vergroesserung
// ohne Positionsaenderung). Das Verschieben passiert ebenfalls ohne
// Positionsaenderung, rein als Bildausschnitt-Versatz (Shift-Objektiv-
// Prinzip via camera.setViewOffset).
moonSceneState.camera.position.set(0, 0, MOON_CAMERA_BASE_Z);
moonSceneState.camera.lookAt(0, 0, 0);
moonSceneState.camera.zoom = getMoonZoomFactor();
const fullWidth = Math.max(1, moonCanvas.clientWidth || 900);
const fullHeight = Math.max(1, moonCanvas.clientHeight || 900);
// Der Bildwinkel-Versatz muss mit dem Zoom mitwachsen: die scheinbare
// Mondgroesse auf dem Bildschirm skaliert mit dem Zoomfaktor, sonst reicht
// der Pan-Bereich bei starkem Zoom nicht mehr aus, um den Mond bis an den
// Rand zu ziehen.
const panPixelScale = Math.min(fullWidth, fullHeight) * 0.18 * getMoonZoomFactor();
const offsetX = moonPanX * panPixelScale;
const offsetY = -moonPanY * panPixelScale;
if (offsetX === 0 && offsetY === 0) {
moonSceneState.camera.clearViewOffset();
} else {
moonSceneState.camera.setViewOffset(fullWidth, fullHeight, offsetX, offsetY, fullWidth, fullHeight);
}
}
moonSceneState.camera.updateProjectionMatrix();