-
Notifications
You must be signed in to change notification settings - Fork 167
fix(view): Implement state for user controlled camera to properly distinguish between scripted and user camera #2363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -527,9 +527,6 @@ void W3DView::setCameraTransform() | |
| if (TheGlobalData->m_headless) | ||
| return; | ||
|
|
||
| if (m_viewLockedUntilFrame > TheGameClient->getFrame()) | ||
| return; | ||
|
|
||
| m_cameraHasMovedSinceRequest = true; | ||
| Matrix3D cameraTransform; | ||
|
|
||
|
|
@@ -627,7 +624,7 @@ void W3DView::init() | |
|
|
||
| m_cameraAreaConstraintsValid = false; | ||
|
|
||
| m_scrollAmountCutoff = TheGlobalData->m_scrollAmountCutoff; | ||
| m_scrollAmountCutoffSqr = sqr(TheGlobalData->m_scrollAmountCutoff); | ||
|
|
||
| m_recalcCamera = true; | ||
| } | ||
|
|
@@ -650,10 +647,15 @@ void W3DView::reset() | |
| // Just in case... | ||
| setTimeMultiplier(1); // Set time rate back to 1. | ||
|
|
||
| stopDoingScriptedCamera(); | ||
| setUserControlled(true); | ||
|
|
||
| // Just move the camera to zero. It'll get repositioned at the beginning of the next game anyways. | ||
| Coord3D arbitraryPos = { 0, 0, 0 }; | ||
| // Just move the camera to 0, 0, 0. It'll get repositioned at the beginning of the next game | ||
| // anyways. | ||
| resetCamera(&arbitraryPos, 1, 0.0f, 0.0f); | ||
| setPosition(&arbitraryPos); | ||
| setAngleToDefault(); | ||
| setPitchToDefault(); | ||
| setZoomToDefault(); | ||
|
|
||
| setViewFilter(FT_VIEW_DEFAULT); | ||
|
|
||
|
|
@@ -1281,6 +1283,12 @@ void W3DView::update() | |
| didScriptedMovement = true; // don't mess up the scripted movement | ||
| } | ||
| } | ||
|
|
||
| if (!m_isUserControlled) | ||
| { | ||
| didScriptedMovement = true; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This means that the scripted camera state will prevail even if no script camera action is currently running, for as long as the user did no camera inputs. I cannot recall why this was necessary, but there are definitely gaps in Mission cutscenes where no scripted camera movements happen and it makes sense to keep the scripted state active for as long as the user is not controlling the camera. |
||
| } | ||
|
|
||
| // | ||
| // Process camera shake | ||
| // | ||
|
|
@@ -1320,8 +1328,9 @@ void W3DView::update() | |
| m_heightAboveGround = m_currentHeightAboveGround; | ||
| } | ||
|
|
||
| const Bool isScrolling = TheInGameUI && TheInGameUI->isScrolling(); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I have decoupled the scrolling condition from TheInGameUI. This is necessary, because we cannot trust that the mouse input equals the actual camera scrolling, if the camera is allowed to block user input, like we do for the Replay Player Camera for every full logic frame. |
||
| const Bool isScrollingTooFast = m_scrollAmount.length() >= m_scrollAmountCutoff; | ||
| const Real scrollLenSqr = m_scrollAmount.lengthSqr(); | ||
| const Bool isScrolling = scrollLenSqr > FLT_EPSILON; | ||
| const Bool isScrollingTooFast = scrollLenSqr >= m_scrollAmountCutoffSqr; | ||
| const Bool isWithinHeightConstraints = isWithinCameraHeightConstraints(); | ||
|
|
||
| // if scrolling, only adjust if we're too close or too far | ||
|
|
@@ -1766,9 +1775,8 @@ void W3DView::setSnapMode( CameraLockType lockType, Real lockDist ) | |
| // TheSuperHackers @bugfix Now rotates the view plane on the Z axis only to properly discard the | ||
| // camera pitch. The aspect ratio also no longer modifies the vertical scroll speed. | ||
| //------------------------------------------------------------------------------------------------- | ||
| void W3DView::scrollBy( Coord2D *delta ) | ||
| void W3DView::scrollBy( const Coord2D *delta ) | ||
| { | ||
| // if we haven't moved, ignore | ||
| if( delta && (delta->x != 0 || delta->y != 0) ) | ||
| { | ||
| constexpr const Real SCROLL_RESOLUTION = 250.0f; | ||
|
|
@@ -1808,7 +1816,11 @@ void W3DView::scrollBy( Coord2D *delta ) | |
| removeScriptedState(Scripted_Rotate); | ||
| m_recalcCamera = true; | ||
| } | ||
|
|
||
| else | ||
| { | ||
| m_scrollAmount.x = 0; | ||
| m_scrollAmount.y = 0; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This now allows to set zero scroll speed, to signal that it is no longer scrolling. Previously it would just leave the last value and we relied on |
||
| } | ||
| } | ||
|
|
||
| //------------------------------------------------------------------------------------------------- | ||
|
|
@@ -1902,7 +1914,8 @@ void W3DView::setHeightAboveGround(Real z) | |
| // the camera height. | ||
| void W3DView::setZoom(Real z) | ||
| { | ||
| View::setZoom(z); | ||
| m_heightAboveGround = m_maxHeightAboveGround * z; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is necessary, because the |
||
| m_zoom = z; | ||
|
|
||
| stopDoingScriptedCamera(); | ||
| m_CameraArrivedAtWaypointOnPathFlag = false; | ||
|
|
@@ -2248,7 +2261,6 @@ void W3DView::lookAt( const Coord3D *o ) | |
| { | ||
| Coord3D pos = *o; | ||
|
|
||
|
|
||
| // no, don't call the super-lookAt, since it will munge our coords | ||
| // as for a 2d view. just call setPosition. | ||
| //View::lookAt(&pos); | ||
|
|
@@ -3034,6 +3046,15 @@ void W3DView::pitchCameraOneFrame() | |
| } | ||
| } | ||
|
|
||
| //------------------------------------------------------------------------------------------------- | ||
| void W3DView::setUserControlled(Bool value) | ||
| { | ||
| if (m_isUserControlled != value) | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This condition does not make much sense right now but will do later because more code is added in the conditional body. |
||
| { | ||
| m_isUserControlled = value; | ||
| } | ||
| } | ||
|
|
||
| // ------------------------------------------------------------------------------------------------ | ||
| Bool W3DView::isDoingScriptedCamera() | ||
| { | ||
|
|
@@ -3056,6 +3077,7 @@ Bool W3DView::hasScriptedState(ScriptedState state) const | |
| void W3DView::addScriptedState(ScriptedState state) | ||
| { | ||
| m_scriptedState |= state; | ||
| setUserControlled(false); | ||
| } | ||
|
|
||
| // ------------------------------------------------------------------------------------------------ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -211,6 +211,7 @@ struct Coord2D | |
| Real x, y; | ||
|
|
||
| Real length() const { return (Real)sqrt( x*x + y*y ); } | ||
| Real lengthSqr() const { return x*x + y*y; } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor length to return (Real)sqrt(lengthSqr())maybe?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is fine to have them independent of each other. Their code will never change. |
||
|
|
||
| void normalize() | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed from
resetCameratosetfunction, becauseresetCamerais meant to be used by scripted actions and would set the user controlled flag to false, which we do not want here.