Hier sind einige Tipps zum Drehen der Kamera (Mausblick). Nachdem ich eine Kameraklasse von Grund auf neu implementiert hatte, musste ich ein paar zusätzliche Änderungen vornehmen, um ein gutes Drehverhalten zu erzielen:
Setzen Sie die Mauskoordinaten in jedem Frame auf die Bildschirmmitte zurück, damit die Maus nicht an den Bildschirmrändern hängen bleibt
Behalten Sie den Aufwärtsvektor der Kamera bei (Rollverbot) und berechnen Sie den Seitwärtsvektor neu
Blick nach oben über die vertikale + y-Achse oder nach unten über die -y-Achse nicht zulassen (zu weit oben / unten)
Richtige Reihenfolge der Umdrehungen (zuerst hoch / runter, dann links / rechts)
Renormieren Sie die Vektoren "up", "aim" und "sideways" für jeden Frame
Hoffentlich können Sie einen Teil dieses Codes zu Ihrem Vorteil nutzen:
const int mouseDeltaX = mouseAxisX * (input.GetMouseX() - int(app.GetWidth()/2));
const int mouseDeltaY = -mouseAxisY * (input.GetMouseY() - int(app.GetHeight()/2)); // mouse y-offsets are upside-down!
// HACK: reset the cursor pos.:
app.SetCursorPosition(app.GetWidth()/2, app.GetHeight()/2);
float lookRightRads = mouseDeltaX * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
float lookUpRads = mouseDeltaY * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
// Limit the aim vector in such a way that the 'up' vector never drops below the horizon:
static const float zenithMinDeclination = DEG_TO_RAD * MIN_UPWARDS_TILT_DEG;
static const float zenithMaxDeclination = DEG_TO_RAD * (180.0f - MIN_UPWARDS_TILT_DEG);
const float currentDeclination = std::acosf(camera.aim_.y_); ///< declination from vertical y-axis
const float requestedDeclination = currentDeclination - lookUpRads;
// Clamp the up/down rotation to at most the min/max zenith:
if(requestedDeclination < zenithMinDeclination)
lookUpRads = currentDeclination - zenithMinDeclination;
else if(requestedDeclination > zenithMaxDeclination)
lookUpRads = currentDeclination - zenithMaxDeclination;
// Rotate both the "aim" vector and the "up" vector ccw by
// lookUpRads radians within their common plane -- which should
// also contain the y-axis: (i.e. no diagonal tilt allowed!)
camera.aim_.rotateAboutAxis(camera.right_, lookUpRads);
camera.up_.rotateAboutAxis(camera.right_, lookUpRads);
ASSERT_ORTHONORMAL(camera.aim_, camera.up_, camera.right_);
// Rotate both the "aim" and the "up" vector ccw about the vertical y-axis:
// (again, this keeps the y-axis in their common plane, and disallows diagonal tilt)
camera.aim_.rotateAboutAxis(Y_AXIS, -lookRightRads);
camera.up_.rotateAboutAxis(Y_AXIS, -lookRightRads);
camera.updateRightAxis();
Beachten Sie, dass:
mouseAxisX und mouseAxisY sind mit +/- 1 definiert, abhängig davon, ob die X- oder Y-Achse des Mauszeigers invertiert werden soll. Normalerweise bieten Spiele diese Option zumindest für die vertikale Achse an.
MIN_UPWARDS_TILT_DEG ist mit 1,0 Grad definiert (der Betrachter darf also von -89 Grad nach unten bis +89 Grad nach oben schauen, was ziemlich überzeugend wie ein voller vertikaler 180-Grad-Bereich aussieht - die fehlenden 2 Grad an den Extremen sind vernachlässigbar). .
camera.aim_, camera.right_ und camera.up_ sind natürlich 3D-Vektoren und die rotateAboutAxis () -Methode, die Sie aus Wikipedia und einer beliebigen Anzahl von Online-Quellen zusammenfügen können. Y_AXIS ist ein Vektor mit fester Konstante (0,1,0).
ASSERT_ORTHONORMAL () ist eine reine Fehlerprüfung im Debug-Modus, die niemals im optimierten / Release-Modus kompiliert wird.
Entschuldigen Sie sich im Voraus für den C-Style-Code ... aber auch hier werden Sie von einem Typen namens Mediocritus beraten! ; ^)