From 81313f56c79a86b44e4eb20002b3d89696fa8906 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Thu, 26 Feb 2026 21:42:50 +0100 Subject: [PATCH] refactor(view): Change scripted state booleans to enum flags in W3DView --- Core/GameEngine/Include/GameClient/View.h | 3 + .../Include/W3DDevice/GameClient/W3DView.h | 29 ++- .../Source/W3DDevice/GameClient/W3DView.cpp | 212 +++++++++++------- .../Code/Tools/WorldBuilder/src/wbview3d.cpp | 3 + .../Code/Tools/WorldBuilder/src/wbview3d.cpp | 3 + 5 files changed, 153 insertions(+), 97 deletions(-) diff --git a/Core/GameEngine/Include/GameClient/View.h b/Core/GameEngine/Include/GameClient/View.h index 251bfe42019..53502580bb3 100644 --- a/Core/GameEngine/Include/GameClient/View.h +++ b/Core/GameEngine/Include/GameClient/View.h @@ -172,6 +172,9 @@ class View : public Snapshot virtual void zoomCamera( Real finalZoom, Int milliseconds, Real easeIn=0.0f, Real easeOut=0.0f ) {}; virtual void pitchCamera( Real finalPitch, Int milliseconds, Real easeIn=0.0f, Real easeOut=0.0f ) {}; + virtual Bool isDoingScriptedCamera() = 0; + virtual void stopDoingScriptedCamera() = 0; + virtual void setAngle( Real radians ); ///< Rotate the view around the vertical axis to the given angle (yaw) virtual Real getAngle() { return m_angle; } ///< Return current camera angle virtual void setPitch( Real radians ); ///< Rotate the view around the horizontal axis to the given angle (pitch) diff --git a/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h index b4cc9f3f8e2..c5e2e221be7 100644 --- a/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h +++ b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h @@ -128,6 +128,15 @@ typedef struct // ------------------------------------------------------------------------------------------------ class W3DView : public View, public SubsystemInterface { + enum Scripted + { + Scripted_Rotate = 1<<0, // Set when rotating the camera + Scripted_Pitch = 1<<1, // Set when pitching the camera + Scripted_Zoom = 1<<2, // Set when zooming the camera + Scripted_CameraLock = 1<<3, // Set when following a unit via script + Scripted_MoveOnWaypointPath = 1<<4, // Set when moving camera along waypoint path + }; + typedef UnsignedInt ScriptedState; public: W3DView(); @@ -157,6 +166,9 @@ class W3DView : public View, public SubsystemInterface virtual void forceRedraw(); + virtual Bool isDoingScriptedCamera(); + virtual void stopDoingScriptedCamera(); + virtual void setAngle( Real radians ); ///< Rotate the view around the vertical axis to the given angle (yaw) virtual void setPitch( Real radians ); ///< Rotate the view around the horizontal axis to the given angle (pitch) virtual void setAngleToDefault(); ///< Set the view angle back to default @@ -246,22 +258,16 @@ class W3DView : public View, public SubsystemInterface Real m_shakeIntensity; ///< the intensity of the oscillation Vector3 m_shakerAngles; //WST 11/12/2002 new multiple instance camera shaker system - TRotateCameraInfo m_rcInfo; - Bool m_doingRotateCamera; ///< True if we are doing a camera rotate. + ScriptedState m_scriptedState; ///< Flags for scripted camera movements. Use functions addScriptedState, removeScriptedState for write. + TRotateCameraInfo m_rcInfo; TPitchCameraInfo m_pcInfo; - Bool m_doingPitchCamera; TZoomCameraInfo m_zcInfo; - Bool m_doingZoomCamera; - - Bool m_doingScriptedCameraLock; ///< True if we are following a unit via script + TMoveAlongWaypointPathInfo m_mcwpInfo; ///< Move camera along waypoint path info. + Bool m_CameraArrivedAtWaypointOnPathFlag; Real m_FXPitch; ///< Camera effects pitch. 0 = flat, infinite = look down, 1 = normal. - TMoveAlongWaypointPathInfo m_mcwpInfo; ///< Move camera along waypoint path info. - Bool m_doingMoveCameraOnWaypointPath; ///< If true, moving camera along waypoint path. - Bool m_CameraArrivedAtWaypointOnPathFlag; - Bool m_freezeTimeForCameraMovement; Int m_timeMultiplier; ///< Time speedup multiplier. @@ -283,6 +289,9 @@ class W3DView : public View, public SubsystemInterface void buildCameraTransform(Matrix3D *transform); ///< calculate (but do not set) the transform matrix of m_3DCamera, based on m_pos & m_angle void calcCameraAreaConstraints(); ///< Recalculates the camera area constraints Bool isWithinCameraHeightConstraints() const; + Bool hasScriptedState(ScriptedState state) const; + void addScriptedState(ScriptedState state); + void removeScriptedState(ScriptedState state); void moveAlongWaypointPath(Real milliseconds); ///< Move camera along path. void getPickRay(const ICoord2D *screen, Vector3 *rayStart, Vector3 *rayEnd); ///getLogicTimeStepMilliseconds(FramePacer::IgnoreFrozenTime)); didUpdate = true; } - if (m_doingScriptedCameraLock) + if (hasScriptedState(Scripted_CameraLock)) { didUpdate = true; } @@ -1108,7 +1112,7 @@ void W3DView::update() } if (cameraLock != INVALID_ID) { - m_doingMoveCameraOnWaypointPath = false; + removeScriptedState(Scripted_MoveOnWaypointPath); m_CameraArrivedAtWaypointOnPathFlag = false; Object* cameraLockObj = TheGameLogic->findObjectByID(cameraLock); @@ -1273,7 +1277,7 @@ void W3DView::update() m_recalcCamera = true; } } else { - if (m_doingRotateCamera || m_doingMoveCameraOnWaypointPath || m_doingPitchCamera || m_doingZoomCamera || m_doingScriptedCameraLock) { + if (isDoingScriptedCamera()) { didScriptedMovement = true; // don't mess up the scripted movement } } @@ -1310,13 +1314,11 @@ void W3DView::update() Real desiredHeight = (m_terrainHeightAtPivot + m_heightAboveGround); Real desiredZoom = desiredHeight / m_cameraOffset.z; - if (didScriptedMovement) - { - // if we are in a scripted camera movement, take its height above ground as our desired height. - m_heightAboveGround = m_currentHeightAboveGround; - //DEBUG_LOG(("Frame %d: height above ground: %g %g %g %g", TheGameLogic->getFrame(), m_heightAboveGround, - // m_cameraOffset.z, m_zoom, m_terrainHeightUnderCamera)); - } + if (didScriptedMovement) + { + // if we are in a scripted camera movement, take its height above ground as our desired height. + m_heightAboveGround = m_currentHeightAboveGround; + } const Bool isScrolling = TheInGameUI && TheInGameUI->isScrolling(); const Bool isScrollingTooFast = m_scrollAmount.length() >= m_scrollAmountCutoff; @@ -1746,7 +1748,7 @@ void W3DView::setCameraLock(ObjectID id) return; } View::setCameraLock(id); - m_doingScriptedCameraLock = FALSE; + removeScriptedState(Scripted_CameraLock); } // ------------------------------------------------------------------------------------------------ @@ -1754,7 +1756,7 @@ void W3DView::setCameraLock(ObjectID id) void W3DView::setSnapMode( CameraLockType lockType, Real lockDist ) { View::setSnapMode(lockType, lockDist); - m_doingScriptedCameraLock = TRUE; + addScriptedState(Scripted_CameraLock); } //------------------------------------------------------------------------------------------------- @@ -1803,7 +1805,7 @@ void W3DView::scrollBy( Coord2D *delta ) //m_cameraConstraintValid = false; // pos change does NOT invalidate cam constraints - m_doingRotateCamera = false; + removeScriptedState(Scripted_Rotate); m_recalcCamera = true; } @@ -1824,13 +1826,8 @@ void W3DView::setAngle( Real radians ) { View::setAngle( radians ); - m_doingMoveCameraOnWaypointPath = false; + stopDoingScriptedCamera(); m_CameraArrivedAtWaypointOnPathFlag = false; - - m_doingRotateCamera = false; - m_doingPitchCamera = false; - m_doingZoomCamera = false; - m_doingScriptedCameraLock = false; m_recalcCamera = true; } @@ -1841,11 +1838,7 @@ void W3DView::setPitch( Real radians ) { View::setPitch( radians ); - m_doingMoveCameraOnWaypointPath = false; - m_doingRotateCamera = false; - m_doingPitchCamera = false; - m_doingZoomCamera = false; - m_doingScriptedCameraLock = false; + stopDoingScriptedCamera(); // TheSuperHackers @fix Now recalculates the camera constraints because // the camera pitch can change the camera distance towards the map border. m_cameraAreaConstraintsValid = false; @@ -1895,12 +1888,8 @@ void W3DView::setHeightAboveGround(Real z) { View::setHeightAboveGround(z); - m_doingMoveCameraOnWaypointPath = false; + stopDoingScriptedCamera(); m_CameraArrivedAtWaypointOnPathFlag = false; - m_doingRotateCamera = false; - m_doingPitchCamera = false; - m_doingZoomCamera = false; - m_doingScriptedCameraLock = false; m_cameraAreaConstraintsValid = false; m_recalcCamera = true; } @@ -1915,12 +1904,8 @@ void W3DView::setZoom(Real z) { View::setZoom(z); - m_doingMoveCameraOnWaypointPath = false; + stopDoingScriptedCamera(); m_CameraArrivedAtWaypointOnPathFlag = false; - m_doingRotateCamera = false; - m_doingPitchCamera = false; - m_doingZoomCamera = false; - m_doingScriptedCameraLock = false; m_cameraAreaConstraintsValid = false; m_recalcCamera = true; } @@ -1943,12 +1928,8 @@ void W3DView::setZoomToDefault() m_zoom = desiredZoom; m_heightAboveGround = m_maxHeightAboveGround; - m_doingMoveCameraOnWaypointPath = false; + stopDoingScriptedCamera(); m_CameraArrivedAtWaypointOnPathFlag = false; - m_doingRotateCamera = false; - m_doingPitchCamera = false; - m_doingZoomCamera = false; - m_doingScriptedCameraLock = false; m_cameraAreaConstraintsValid = false; m_recalcCamera = true; } @@ -2302,10 +2283,9 @@ void W3DView::lookAt( const Coord3D *o ) } pos.z = 0; setPosition(&pos); - m_doingRotateCamera = false; - m_doingMoveCameraOnWaypointPath = false; + + removeScriptedState(Scripted_Rotate | Scripted_CameraLock | Scripted_MoveOnWaypointPath); m_CameraArrivedAtWaypointOnPathFlag = false; - m_doingScriptedCameraLock = false; m_recalcCamera = true; } @@ -2356,7 +2336,7 @@ void W3DView::moveCameraTo(const Coord3D *o, Int milliseconds, Int shutter, Bool if (m_mcwpInfo.totalTimeMilliseconds==1) { // do it instantly. moveAlongWaypointPath(1); - m_doingMoveCameraOnWaypointPath = true; + addScriptedState(Scripted_MoveOnWaypointPath); m_CameraArrivedAtWaypointOnPathFlag = false; } } @@ -2375,14 +2355,14 @@ void W3DView::rotateCamera(Real rotations, Int milliseconds, Real easeIn, Real e m_rcInfo.numFrames = 1; } m_rcInfo.curFrame = 0; - m_doingRotateCamera = true; + addScriptedState(Scripted_Rotate); m_rcInfo.angle.startAngle = m_angle; m_rcInfo.angle.endAngle = m_angle + 2*PI*rotations; m_rcInfo.startTimeMultiplier = m_timeMultiplier; m_rcInfo.endTimeMultiplier = m_timeMultiplier; m_rcInfo.ease.setEaseTimes(easeIn/milliseconds, easeOut/milliseconds); - m_doingMoveCameraOnWaypointPath = false; + removeScriptedState(Scripted_MoveOnWaypointPath); m_CameraArrivedAtWaypointOnPathFlag = false; } @@ -2404,13 +2384,13 @@ void W3DView::rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMi m_rcInfo.numFrames = 1; } m_rcInfo.curFrame = 0; - m_doingRotateCamera = true; + addScriptedState(Scripted_Rotate); m_rcInfo.target.targetObjectID = id; m_rcInfo.startTimeMultiplier = m_timeMultiplier; m_rcInfo.endTimeMultiplier = m_timeMultiplier; m_rcInfo.ease.setEaseTimes(easeIn/milliseconds, easeOut/milliseconds); - m_doingMoveCameraOnWaypointPath = false; + removeScriptedState(Scripted_MoveOnWaypointPath); m_CameraArrivedAtWaypointOnPathFlag = false; } @@ -2448,7 +2428,7 @@ void W3DView::rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds, } m_rcInfo.curFrame = 0; - m_doingRotateCamera = true; + addScriptedState(Scripted_Rotate); m_rcInfo.angle.startAngle = m_angle; // TheSuperHackers @todo Investigate if the non Generals code is correct for Zero Hour. // It certainly is incorrect for Generals: Seen in GLA mission 1 opening cut scene. @@ -2461,7 +2441,7 @@ void W3DView::rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds, m_rcInfo.endTimeMultiplier = m_timeMultiplier; m_rcInfo.ease.setEaseTimes(easeIn/milliseconds, easeOut/milliseconds); - m_doingMoveCameraOnWaypointPath = false; + removeScriptedState(Scripted_MoveOnWaypointPath); m_CameraArrivedAtWaypointOnPathFlag = false; } @@ -2475,7 +2455,7 @@ void W3DView::zoomCamera( Real finalZoom, Int milliseconds, Real easeIn, Real ea m_zcInfo.numFrames = 1; } m_zcInfo.curFrame = 0; - m_doingZoomCamera = TRUE; + addScriptedState(Scripted_Zoom); m_zcInfo.startZoom = m_zoom; m_zcInfo.endZoom = finalZoom; m_zcInfo.ease.setEaseTimes(easeIn/milliseconds, easeOut/milliseconds); @@ -2491,7 +2471,7 @@ void W3DView::pitchCamera( Real finalPitch, Int milliseconds, Real easeIn, Real m_pcInfo.numFrames = 1; } m_pcInfo.curFrame = 0; - m_doingPitchCamera = TRUE; + addScriptedState(Scripted_Pitch); m_pcInfo.startPitch = m_FXPitch; m_pcInfo.endPitch = finalPitch; m_pcInfo.ease.setEaseTimes(easeIn/milliseconds, easeOut/milliseconds); @@ -2502,8 +2482,7 @@ void W3DView::pitchCamera( Real finalPitch, Int milliseconds, Real easeIn, Real //------------------------------------------------------------------------------------------------- void W3DView::cameraModFinalZoom( Real finalZoom, Real easeIn, Real easeOut ) { - - if (m_doingRotateCamera) + if (hasScriptedState(Scripted_Rotate)) { Real terrainHeightMax = getHeightAroundPos(m_pos.x, m_pos.y); Real maxHeight = (terrainHeightMax + m_maxHeightAboveGround); @@ -2512,7 +2491,7 @@ void W3DView::cameraModFinalZoom( Real finalZoom, Real easeIn, Real easeOut ) Real time = (m_rcInfo.numFrames + m_rcInfo.numHoldFrames - m_rcInfo.curFrame)*TheW3DFrameLengthInMsec; zoomCamera( finalZoom*maxZoom, time, time*easeIn, time*easeOut ); } - if (m_doingMoveCameraOnWaypointPath) + if (hasScriptedState(Scripted_MoveOnWaypointPath)) { Coord3D pos = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints]; Real terrainHeightMax = getHeightAroundPos(pos.x, pos.y); @@ -2529,14 +2508,16 @@ void W3DView::cameraModFinalZoom( Real finalZoom, Real easeIn, Real easeOut ) //------------------------------------------------------------------------------------------------- void W3DView::cameraModFreezeAngle() { - if (m_doingRotateCamera) { + if (hasScriptedState(Scripted_Rotate)) + { if (m_rcInfo.trackObject) { m_rcInfo.target.targetObjectID = INVALID_ID; } else { m_rcInfo.angle.startAngle = m_rcInfo.angle.endAngle = m_angle; // Silly, but consistent. } } - if (m_doingMoveCameraOnWaypointPath) { + if (hasScriptedState(Scripted_MoveOnWaypointPath)) + { Int i; // Real curDistance = 0; for (i=0; i1; + if (m_mcwpInfo.numWaypoints>1) + { + addScriptedState(Scripted_MoveOnWaypointPath); + } + else + { + removeScriptedState(Scripted_MoveOnWaypointPath); + } + m_CameraArrivedAtWaypointOnPathFlag = false; - m_doingRotateCamera = false; + removeScriptedState(Scripted_Rotate); m_mcwpInfo.elapsedTimeMilliseconds = 0; m_mcwpInfo.curShutter = m_mcwpInfo.shutter; @@ -2912,7 +2920,7 @@ void W3DView::rotateCameraOneFrame() m_rcInfo.curFrame++; if (TheGlobalData->m_disableCameraMovement) { if (m_rcInfo.curFrame >= m_rcInfo.numFrames + m_rcInfo.numHoldFrames) { - m_doingRotateCamera = false; + removeScriptedState(Scripted_Rotate); m_freezeTimeForCameraMovement = false; } return; @@ -2967,7 +2975,7 @@ void W3DView::rotateCameraOneFrame() if (m_rcInfo.curFrame >= m_rcInfo.numFrames + m_rcInfo.numHoldFrames) { - m_doingRotateCamera = false; + removeScriptedState(Scripted_Rotate); m_freezeTimeForCameraMovement = false; if (! m_rcInfo.trackObject) { @@ -2983,7 +2991,7 @@ void W3DView::zoomCameraOneFrame() m_zcInfo.curFrame++; if (TheGlobalData->m_disableCameraMovement) { if (m_zcInfo.curFrame >= m_zcInfo.numFrames) { - m_doingZoomCamera = false; + removeScriptedState(Scripted_Zoom); } return; } @@ -2995,7 +3003,7 @@ void W3DView::zoomCameraOneFrame() } if (m_zcInfo.curFrame >= m_zcInfo.numFrames) { - m_doingZoomCamera = false; + removeScriptedState(Scripted_Zoom); m_zoom = m_zcInfo.endZoom; } @@ -3009,7 +3017,7 @@ void W3DView::pitchCameraOneFrame() m_pcInfo.curFrame++; if (TheGlobalData->m_disableCameraMovement) { if (m_pcInfo.curFrame >= m_pcInfo.numFrames) { - m_doingPitchCamera = false; + removeScriptedState(Scripted_Pitch); } return; } @@ -3021,11 +3029,41 @@ void W3DView::pitchCameraOneFrame() } if (m_pcInfo.curFrame >= m_pcInfo.numFrames) { - m_doingPitchCamera = false; + removeScriptedState(Scripted_Pitch); m_FXPitch = m_pcInfo.endPitch; } } +// ------------------------------------------------------------------------------------------------ +Bool W3DView::isDoingScriptedCamera() +{ + return m_scriptedState != 0; +} + +// ------------------------------------------------------------------------------------------------ +void W3DView::stopDoingScriptedCamera() +{ + m_scriptedState = 0; +} + +// ------------------------------------------------------------------------------------------------ +Bool W3DView::hasScriptedState(ScriptedState state) const +{ + return (m_scriptedState & state) != 0; +} + +// ------------------------------------------------------------------------------------------------ +void W3DView::addScriptedState(ScriptedState state) +{ + m_scriptedState |= state; +} + +// ------------------------------------------------------------------------------------------------ +void W3DView::removeScriptedState(ScriptedState state) +{ + m_scriptedState &= ~state; +} + // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void W3DView::moveAlongWaypointPath(Real milliseconds) @@ -3033,13 +3071,13 @@ void W3DView::moveAlongWaypointPath(Real milliseconds) m_mcwpInfo.elapsedTimeMilliseconds += milliseconds; if (TheGlobalData->m_disableCameraMovement) { if (m_mcwpInfo.elapsedTimeMilliseconds>m_mcwpInfo.totalTimeMilliseconds) { - m_doingMoveCameraOnWaypointPath = false; + removeScriptedState(Scripted_MoveOnWaypointPath); m_freezeTimeForCameraMovement = false; } return; } if (m_mcwpInfo.elapsedTimeMilliseconds>m_mcwpInfo.totalTimeMilliseconds) { - m_doingMoveCameraOnWaypointPath = false; + removeScriptedState(Scripted_MoveOnWaypointPath); m_CameraArrivedAtWaypointOnPathFlag = false; m_freezeTimeForCameraMovement = false; @@ -3074,7 +3112,7 @@ void W3DView::moveAlongWaypointPath(Real milliseconds) while (m_mcwpInfo.curSegDistance >= m_mcwpInfo.waySegLength[m_mcwpInfo.curSegment]) #endif { - if ( m_doingMoveCameraOnWaypointPath ) + if (hasScriptedState(Scripted_MoveOnWaypointPath)) { //WWDEBUG_SAY(( "MBL TEST: Camera waypoint along path reached!" )); m_CameraArrivedAtWaypointOnPathFlag = true; diff --git a/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp b/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp index f53dfe2492e..e1cc4e6c97d 100644 --- a/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/wbview3d.cpp @@ -196,6 +196,9 @@ class PlaceholderView : public View virtual void forceRedraw() { } + virtual Bool isDoingScriptedCamera() { return false; } + virtual void stopDoingScriptedCamera() {} + virtual void lookAt( const Coord3D *o ){}; ///< Center the view on the given coordinate virtual void initHeightForMap( void ) {}; ///< Init the camera height for the map at the current position. virtual void scrollBy( Coord2D *delta ){}; ///< Shift the view by the given delta diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp index 3abebcc0823..242597a55cd 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/wbview3d.cpp @@ -197,6 +197,9 @@ class PlaceholderView : public View virtual void forceRedraw() { } + virtual Bool isDoingScriptedCamera() { return false; } + virtual void stopDoingScriptedCamera() {} + virtual void lookAt( const Coord3D *o ){}; ///< Center the view on the given coordinate virtual void initHeightForMap( void ) {}; ///< Init the camera height for the map at the current position. virtual void scrollBy( Coord2D *delta ){}; ///< Shift the view by the given delta