diff --git a/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h index 7e03f3e3fe4..e4603a3970b 100644 --- a/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h +++ b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h @@ -303,7 +303,7 @@ class W3DView : public View, public SubsystemInterface Bool movePivotToGround(); void updateCameraAreaConstraints(); void calcCameraAreaConstraints(); ///< Recalculates the camera area constraints - Real calcCameraAreaOffset(Real maxEdgeZ, Bool isLookingDown); + Real calcCameraAreaOffset(Real maxEdgeZ); void clipCameraIntoAreaConstraints(); Bool isWithinCameraAreaConstraints() const; Bool isWithinCameraHeightConstraints() const; diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp index 98175b6a75b..b286c20e2d9 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp @@ -539,9 +539,9 @@ void W3DView::calcCameraAreaConstraints() Matrix3D prevCameraTransform = m_3DCamera->Get_Transform(); m_3DCamera->Set_Transform(cameraTransform); - const Vector3 cameraForward = -cameraTransform.Get_Z_Vector(); - const Bool isLookingDown = cameraForward.Z <= 0.0f; - Real offset = calcCameraAreaOffset(m_groundLevel, isLookingDown); + Real offset = calcCameraAreaOffset(m_groundLevel); + offset = std::min(offset, (mapRegion.hi.x - mapRegion.lo.x) / 2); + offset = std::min(offset, (mapRegion.hi.y - mapRegion.lo.y) / 2); // Revert the 3D camera transform. m_3DCamera->Set_Transform(prevCameraTransform); @@ -556,21 +556,26 @@ void W3DView::calcCameraAreaConstraints() } //------------------------------------------------------------------------------------------------- -Real W3DView::calcCameraAreaOffset(Real maxEdgeZ, Bool isLookingDown) +Real W3DView::calcCameraAreaOffset(Real maxEdgeZ) { Coord2D center; ICoord2D screen; Vector3 rayStart; Vector3 rayEnd; - //Pick at the center + // Pick at the center screen.x = 0.5f * getWidth() + m_originX; screen.y = 0.5f * getHeight() + m_originY; getPickRay(&screen, &rayStart, &rayEnd); + // Looking at the horizon would yield infinite numbers. + if (fabs(rayStart.Z - rayEnd.Z) < 1.0f) + return 1e+6f; + center.x = Vector3::Find_X_At_Z(maxEdgeZ, rayStart, rayEnd); center.y = Vector3::Find_Y_At_Z(maxEdgeZ, rayStart, rayEnd); + const Bool isLookingDown = rayStart.Z >= rayEnd.Z; const Real height = isLookingDown ? getHeight() : 0.0f; screen.y = height + m_originY; getPickRay(&screen, &rayStart, &rayEnd); @@ -1555,7 +1560,10 @@ void W3DView::update() return; // don't draw - makes it faster :) jba. } - updateCameraAreaConstraints(); + if (!didScriptedMovement) + { + updateCameraAreaConstraints(); + } // (gth) C&C3 if m_isCameraSlaved then force the camera to update each frame if (m_recalcCamera || m_isCameraSlaved)