diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt
index d1af9c1e69..1c2ca6c6b1 100644
--- a/Core/GameEngine/CMakeLists.txt
+++ b/Core/GameEngine/CMakeLists.txt
@@ -210,7 +210,7 @@ set(GAMEENGINE_SRC
# Include/GameClient/Module/BeaconClientUpdate.h
# Include/GameClient/Module/SwayClientUpdate.h
# Include/GameClient/Mouse.h
-# Include/GameClient/ParabolicEase.h
+ Include/GameClient/ParabolicEase.h
# Include/GameClient/ParticleSys.h
# Include/GameClient/PlaceEventTranslator.h
# Include/GameClient/ProcessAnimateWindow.h
@@ -228,7 +228,7 @@ set(GAMEENGINE_SRC
# Include/GameClient/TerrainRoads.h
# Include/GameClient/TerrainVisual.h
Include/GameClient/VideoPlayer.h
-# Include/GameClient/View.h
+ Include/GameClient/View.h
# Include/GameClient/Water.h
# Include/GameClient/WindowLayout.h
Include/GameClient/WindowVideoManager.h
@@ -815,7 +815,7 @@ set(GAMEENGINE_SRC
# Source/GameClient/MessageStream/PlaceEventTranslator.cpp
# Source/GameClient/MessageStream/SelectionXlat.cpp
# Source/GameClient/MessageStream/WindowXlat.cpp
-# Source/GameClient/ParabolicEase.cpp
+ Source/GameClient/ParabolicEase.cpp
# Source/GameClient/RadiusDecal.cpp
# Source/GameClient/SelectionInfo.cpp
# Source/GameClient/Snow.cpp
@@ -832,7 +832,7 @@ set(GAMEENGINE_SRC
# Source/GameClient/Terrain/TerrainVisual.cpp
Source/GameClient/VideoPlayer.cpp
Source/GameClient/VideoStream.cpp
-# Source/GameClient/View.cpp
+ Source/GameClient/View.cpp
# Source/GameClient/Water.cpp
# Source/GameLogic/AI/AI.cpp
# Source/GameLogic/AI/AIDock.cpp
diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/ParabolicEase.h b/Core/GameEngine/Include/GameClient/ParabolicEase.h
similarity index 100%
rename from GeneralsMD/Code/GameEngine/Include/GameClient/ParabolicEase.h
rename to Core/GameEngine/Include/GameClient/ParabolicEase.h
diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/View.h b/Core/GameEngine/Include/GameClient/View.h
similarity index 94%
rename from GeneralsMD/Code/GameEngine/Include/GameClient/View.h
rename to Core/GameEngine/Include/GameClient/View.h
index 1e0f72fbae..f61a1db60d 100644
--- a/GeneralsMD/Code/GameEngine/Include/GameClient/View.h
+++ b/Core/GameEngine/Include/GameClient/View.h
@@ -135,13 +135,13 @@ class View : public Snapshot
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
- virtual void moveCameraTo(const Coord3D *o, Int frames, Int shutter, Bool orient, Real easeIn, Real easeOut) { lookAt( o ); }
- virtual void moveCameraAlongWaypointPath(Waypoint *way, Int frames, Int shutter, Bool orient, Real easeIn, Real easeOut) { }
+ virtual void moveCameraTo(const Coord3D *o, Int frames, Int shutter, Bool orient, Real easeIn=0.0f, Real easeOut=0.0f) { lookAt( o ); }
+ virtual void moveCameraAlongWaypointPath(Waypoint *way, Int frames, Int shutter, Bool orient, Real easeIn=0.0f, Real easeOut=0.0f) { }
virtual Bool isCameraMovementFinished( void ) { return TRUE; }
- virtual void cameraModFinalZoom(Real finalZoom, Real easeIn, Real easeOut){}; ///< Final zoom for current camera movement.
+ virtual void cameraModFinalZoom(Real finalZoom, Real easeIn=0.0f, Real easeOut=0.0f){}; ///< Final zoom for current camera movement.
virtual void cameraModRollingAverage(Int framesToAverage){}; ///< Number of frames to average movement for current camera movement.
virtual void cameraModFinalTimeMultiplier(Int finalMultiplier){}; ///< Final time multiplier for current camera movement.
- virtual void cameraModFinalPitch(Real finalPitch, Real easeIn, Real easeOut){}; ///< Final pitch for current camera movement.
+ virtual void cameraModFinalPitch(Real finalPitch, Real easeIn=0.0f, Real easeOut=0.0f){}; ///< Final pitch for current camera movement.
virtual void cameraModFreezeTime(void){ } ///< Freezes time during the next camera movement.
virtual void cameraModFreezeAngle(void){ } ///< Freezes time during the next camera movement.
virtual void cameraModLookToward(Coord3D *pLoc){} ///< Sets a look at point during camera movement.
@@ -161,16 +161,16 @@ class View : public Snapshot
virtual void setFadeParameters(Int fadeFrames, Int direction) { };
virtual void set3DWireFrameMode(Bool enable) { };
- virtual void resetCamera(const Coord3D *location, Int frames, Real easeIn, Real easeOut) {}; ///< Move camera to location, and reset to default angle & zoom.
- virtual void rotateCamera(Real rotations, Int frames, Real easeIn, Real easeOut) {}; ///< Rotate camera about current viewpoint.
- virtual void rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds, Real easeIn, Real easeOut) {}; ///< Rotate camera to face an object, and hold on it
- virtual void rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds, Real easeIn, Real easeOut, Bool reverseRotation) {}; ///< Rotate camera to face a location.
+ virtual void resetCamera(const Coord3D *location, Int frames, Real easeIn=0.0f, Real easeOut=0.0f) {}; ///< Move camera to location, and reset to default angle & zoom.
+ virtual void rotateCamera(Real rotations, Int frames, Real easeIn=0.0f, Real easeOut=0.0f) {}; ///< Rotate camera about current viewpoint.
+ virtual void rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds, Real easeIn=0.0f, Real easeOut=0.0f) {}; ///< Rotate camera to face an object, and hold on it
+ virtual void rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds, Real easeIn=0.0f, Real easeOut=0.0f, Bool reverseRotation=FALSE) {}; ///< Rotate camera to face a location.
virtual Bool isTimeFrozen(void){ return false;} ///< Freezes time during the next camera movement.
virtual Int getTimeMultiplier(void) {return 1;}; ///< Get the time multiplier.
virtual void setTimeMultiplier(Int multiple) {}; ///< Set the time multiplier.
virtual void setDefaultView(Real pitch, Real angle, Real maxHeight) {};
- virtual void zoomCamera( Real finalZoom, Int milliseconds, Real easeIn, Real easeOut ) {};
- virtual void pitchCamera( Real finalPitch, Int milliseconds, Real easeIn, Real easeOut ) {};
+ 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 void setAngle( Real angle ); ///< Rotate the view around the up axis to the given angle
virtual Real getAngle( void ) { return m_angle; }
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/ParabolicEase.cpp b/Core/GameEngine/Source/GameClient/ParabolicEase.cpp
similarity index 100%
rename from GeneralsMD/Code/GameEngine/Source/GameClient/ParabolicEase.cpp
rename to Core/GameEngine/Source/GameClient/ParabolicEase.cpp
diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp b/Core/GameEngine/Source/GameClient/View.cpp
similarity index 100%
rename from GeneralsMD/Code/GameEngine/Source/GameClient/View.cpp
rename to Core/GameEngine/Source/GameClient/View.cpp
diff --git a/Core/GameEngineDevice/CMakeLists.txt b/Core/GameEngineDevice/CMakeLists.txt
index 6c390f7d84..c53c29220f 100644
--- a/Core/GameEngineDevice/CMakeLists.txt
+++ b/Core/GameEngineDevice/CMakeLists.txt
@@ -71,7 +71,7 @@ set(GAMEENGINEDEVICE_SRC
# Include/W3DDevice/GameClient/W3DTerrainVisual.h
# Include/W3DDevice/GameClient/W3DTreeBuffer.h
Include/W3DDevice/GameClient/W3DVideoBuffer.h
-# Include/W3DDevice/GameClient/W3DView.h
+ Include/W3DDevice/GameClient/W3DView.h
# Include/W3DDevice/GameClient/W3DVolumetricShadow.h
# Include/W3DDevice/GameClient/W3DWater.h
# Include/W3DDevice/GameClient/W3DWaterTracks.h
@@ -98,7 +98,7 @@ set(GAMEENGINEDEVICE_SRC
# Source/W3DDevice/Common/Thing/W3DThingFactory.cpp
# Source/W3DDevice/Common/W3DConvert.cpp
# Source/W3DDevice/GameClient/BaseHeightMap.cpp
-# Source/W3DDevice/GameClient/camerashakesystem.cpp
+ Source/W3DDevice/GameClient/CameraShakeSystem.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DDebrisDraw.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DDefaultDraw.cpp
# Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp
@@ -173,7 +173,7 @@ set(GAMEENGINEDEVICE_SRC
# Source/W3DDevice/GameClient/W3DTerrainVisual.cpp
# Source/W3DDevice/GameClient/W3DTreeBuffer.cpp
Source/W3DDevice/GameClient/W3DVideoBuffer.cpp
-# Source/W3DDevice/GameClient/W3DView.cpp
+ Source/W3DDevice/GameClient/W3DView.cpp
# Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp
# Source/W3DDevice/GameClient/W3DWebBrowser.cpp
# Source/W3DDevice/GameClient/Water/W3DWater.cpp
diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/camerashakesystem.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/CameraShakeSystem.h
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/camerashakesystem.h
rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/CameraShakeSystem.h
diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h
similarity index 100%
rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h
rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/camerashakesystem.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/CameraShakeSystem.cpp
similarity index 99%
rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/camerashakesystem.cpp
rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/CameraShakeSystem.cpp
index 32922d8514..71d7124a47 100644
--- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/camerashakesystem.cpp
+++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/CameraShakeSystem.cpp
@@ -75,7 +75,7 @@
#include "W3DDevice/GameClient/W3DPoly.h"
#include "W3DDevice/GameClient/W3DCustomScene.h"
-#include "W3DDevice/GameClient/camerashakesystem.h"
+#include "W3DDevice/GameClient/CameraShakeSystem.h"
#include "WW3D2/camera.h"
//#include "W3DDevice/GameClient/camera.h"
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
similarity index 99%
rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
index a9009cdc70..704f000e25 100644
--- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
+++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
@@ -93,7 +93,7 @@
#include "WW3D2/predlod.h"
#include "WW3D2/ww3d.h"
-#include "W3DDevice/GameClient/camerashakesystem.h"
+#include "W3DDevice/GameClient/CameraShakeSystem.h"
#include "WinMain.h" /** @todo Remove this, it's only here because we
are using timeGetTime, but we can remove that
@@ -377,6 +377,14 @@ void W3DView::buildCameraTransform( Matrix3D *transform )
}
else
{
+ // TheSuperHackers @todo Investigate whether the non Generals code is correct for Zero Hour.
+ // It certainly is incorrect for Generals when m_FXPitch goes above 1:
+ // Seen in USA mission 1 second cut scene with SCUD Storm.
+#if RTS_GENERALS
+ Real height = sourcePos.Z - targetPos.Z;
+ height *= m_FXPitch;
+ targetPos.Z = sourcePos.Z - height;
+#else
if (m_FXPitch <= 1.0f)
{
Real height = sourcePos.Z - targetPos.Z;
@@ -388,6 +396,7 @@ void W3DView::buildCameraTransform( Matrix3D *transform )
sourcePos.X = targetPos.X + ((sourcePos.X - targetPos.X) / m_FXPitch);
sourcePos.Y = targetPos.Y + ((sourcePos.Y - targetPos.Y) / m_FXPitch);
}
+#endif
}
//m_3DCamera->Set_View_Plane(DEG_TO_RADF(50.0f));
@@ -2512,7 +2521,13 @@ void W3DView::rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds,
m_rcInfo.curFrame = 0;
m_doingRotateCamera = true;
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.
+#if RTS_GENERALS
+ m_rcInfo.angle.endAngle = m_angle + angle;
+#else
m_rcInfo.angle.endAngle = angle;
+#endif
m_rcInfo.startTimeMultiplier = m_timeMultiplier;
m_rcInfo.endTimeMultiplier = m_timeMultiplier;
m_rcInfo.ease.setEaseTimes(easeIn/milliseconds, easeOut/milliseconds);
@@ -3130,8 +3145,14 @@ void W3DView::moveAlongWaypointPath(Real milliseconds)
const Real deltaTime = m_mcwpInfo.ease(m_mcwpInfo.elapsedTimeMilliseconds/totalTime) -
m_mcwpInfo.ease((m_mcwpInfo.elapsedTimeMilliseconds - milliseconds)/totalTime);
m_mcwpInfo.curSegDistance += deltaTime*m_mcwpInfo.totalDistance;
- while (m_mcwpInfo.curSegDistance >= m_mcwpInfo.waySegLength[m_mcwpInfo.curSegment]) {
-
+ // TheSuperHacker @todo Investigate which one is really correct.
+ // The non Generals condition causes camera bug in Generals Shell Map.
+#if RTS_GENERALS
+ while (m_mcwpInfo.curSegDistance > m_mcwpInfo.waySegLength[m_mcwpInfo.curSegment])
+#else
+ while (m_mcwpInfo.curSegDistance >= m_mcwpInfo.waySegLength[m_mcwpInfo.curSegment])
+#endif
+ {
if ( m_doingMoveCameraOnWaypointPath )
{
//WWDEBUG_SAY(( "MBL TEST: Camera waypoint along path reached!" ));
diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt
index 01912ede6e..730e1ec6be 100644
--- a/Generals/Code/GameEngine/CMakeLists.txt
+++ b/Generals/Code/GameEngine/CMakeLists.txt
@@ -214,7 +214,7 @@ set(GAMEENGINE_SRC
Include/GameClient/TerrainRoads.h
Include/GameClient/TerrainVisual.h
# Include/GameClient/VideoPlayer.h
- Include/GameClient/View.h
+# Include/GameClient/View.h
Include/GameClient/Water.h
Include/GameClient/WindowLayout.h
# Include/GameClient/WindowVideoManager.h
@@ -776,7 +776,7 @@ set(GAMEENGINE_SRC
Source/GameClient/Terrain/TerrainRoads.cpp
Source/GameClient/Terrain/TerrainVisual.cpp
# Source/GameClient/VideoPlayer.cpp
- Source/GameClient/View.cpp
+# Source/GameClient/View.cpp
Source/GameClient/Water.cpp
Source/GameLogic/AI/AI.cpp
Source/GameLogic/AI/AIDock.cpp
diff --git a/Generals/Code/GameEngine/Include/Common/DrawModule.h b/Generals/Code/GameEngine/Include/Common/DrawModule.h
index b9e458a64a..e13310fa18 100644
--- a/Generals/Code/GameEngine/Include/Common/DrawModule.h
+++ b/Generals/Code/GameEngine/Include/Common/DrawModule.h
@@ -38,6 +38,7 @@
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Matrix3D;
class RenderCost;
+class OBBoxClass;
// TYPES //////////////////////////////////////////////////////////////////////////////////////////
@@ -154,6 +155,10 @@ class ObjectDrawInterface
// this method must ONLY be called from the client, NEVER From the logic, not even indirectly.
virtual Bool clientOnly_getRenderObjInfo(Coord3D* pos, Real* boundingSphereRadius, Matrix3D* transform) const = 0;
+
+ // (gth) C&C3 adding these accessors to render object properties
+ virtual Bool clientOnly_getRenderObjBoundBox(OBBoxClass * boundbox) const = 0;
+ virtual Bool clientOnly_getRenderObjBoneTransform(const AsciiString & boneName,Matrix3D * set_tm) const = 0;
/**
Find the bone(s) with the given name and return their positions and/or transforms in the given arrays.
We look for a bone named "boneNamePrefixQQ", where QQ is 01, 02, 03, etc, starting at the
diff --git a/Generals/Code/GameEngine/Include/GameClient/Display.h b/Generals/Code/GameEngine/Include/GameClient/Display.h
index 4d12e246e3..5823e8aef6 100644
--- a/Generals/Code/GameEngine/Include/GameClient/Display.h
+++ b/Generals/Code/GameEngine/Include/GameClient/Display.h
@@ -29,11 +29,9 @@
#pragma once
#include "Common/SubsystemInterface.h"
-#include "View.h"
#include "GameClient/Color.h"
#include "GameClient/GameFont.h"
-
-class View;
+#include "GameClient/View.h"
struct ShroudLevel
{
@@ -173,6 +171,7 @@ class Display : public SubsystemInterface
virtual void toggleLetterBox(void) = 0; ///< enabled letter-boxed display
virtual void enableLetterBox(Bool enable) = 0; ///< forces letter-boxed display on/off
virtual Bool isLetterBoxFading( void ) { return FALSE; } ///< returns true while letterbox fades in/out
+ virtual Bool isLetterBoxed( void ) { return FALSE; } //WST 10/2/2002. Added query interface
virtual void setCinematicText( AsciiString string ) { m_cinematicText = string; }
virtual void setCinematicFont( GameFont *font ) { m_cinematicFont = font; }
diff --git a/Generals/Code/GameEngine/Include/GameClient/View.h b/Generals/Code/GameEngine/Include/GameClient/View.h
deleted file mode 100644
index 9882babcc3..0000000000
--- a/Generals/Code/GameEngine/Include/GameClient/View.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// View.h /////////////////////////////////////////////////////////////////////////////////////////
-// A "view", or window, into the World
-// Author: Michael S. Booth, February 2001
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
-#include "Common/GameType.h"
-#include "Common/Snapshot.h"
-#include "Lib/BaseType.h"
-#include "WW3D2/coltype.h" ///< we don't generally do this, but we need the W3D collision types
-
-#define DEFAULT_VIEW_WIDTH 640
-#define DEFAULT_VIEW_HEIGHT 480
-#define DEFAULT_VIEW_ORIGIN_X 0
-#define DEFAULT_VIEW_ORIGIN_Y 0
-
-// FORWARD DECLARATIONS ///////////////////////////////////////////////////////////////////////////
-class Drawable;
-class ViewLocation;
-class Thing;
-class Waypoint;
-class LookAtTranslator;
-enum FilterTypes CPP_11(: Int);
-enum FilterModes CPP_11(: Int);
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-enum PickType CPP_11(: Int)
-{
- PICK_TYPE_TERRAIN = COLL_TYPE_0,
- PICK_TYPE_SELECTABLE = COLL_TYPE_1,
- PICK_TYPE_SHRUBBERY = COLL_TYPE_2,
- PICK_TYPE_MINES = COLL_TYPE_3, // mines aren't normally selectable, but workers/dozers need to
- PICK_TYPE_FORCEATTACKABLE = COLL_TYPE_4,
- PICK_TYPE_ALL_DRAWABLES = (PICK_TYPE_SELECTABLE | PICK_TYPE_SHRUBBERY | PICK_TYPE_MINES | PICK_TYPE_FORCEATTACKABLE)
-};
-
-// ------------------------------------------------------------------------------------------------
-/** The implementation of common view functionality. */
-// ------------------------------------------------------------------------------------------------
-class View : public Snapshot
-{
-
-public:
-
- enum
- {
- ZoomHeightPerSecond = 10,
- };
-
- /// Add an impulse force to shake the camera
- enum CameraShakeType
- {
- SHAKE_SUBTLE = 0,
- SHAKE_NORMAL,
- SHAKE_STRONG,
- SHAKE_SEVERE,
- SHAKE_CINE_EXTREME, //Added for cinematics ONLY
- SHAKE_CINE_INSANE, //Added for cinematics ONLY
- SHAKE_COUNT
- };
-
- // Return values for worldToScreenTriReturn
- enum WorldToScreenReturn CPP_11(: Int)
- {
- WTS_INSIDE_FRUSTUM = 0, // On the screen (inside frustum of camera)
- WTS_OUTSIDE_FRUSTUM, // Return is valid but off the screen (outside frustum of camera)
- WTS_INVALID, // No transform possible
- };
-
-public:
-
- View( void );
- virtual ~View( void );
-
- virtual void init( void );
- virtual void reset( void );
- virtual UnsignedInt getID( void ) { return m_id; }
-
- virtual void setZoomLimited( Bool limit ) { m_zoomLimited = limit; } ///< limit the zoom height
- virtual Bool isZoomLimited( void ) { return m_zoomLimited; } ///< get status of zoom limit
-
- /// pick drawable given the screen pixel coords. If force attack, picks bridges as well.
- virtual Drawable *pickDrawable( const ICoord2D *screen, Bool forceAttack, PickType pickType ) = 0;
-
- /// all drawables in the 2D screen region will call the 'callback'
- virtual Int iterateDrawablesInRegion( IRegion2D *screenRegion,
- Bool (*callback)( Drawable *draw, void *userData ),
- void *userData ) = 0;
-
- /** project the 4 corners of this view into the world and return each point as a parameter,
- the world points are at the requested Z */
- virtual void getScreenCornerWorldPointsAtZ( Coord3D *topLeft, Coord3D *topRight,
- Coord3D *bottomLeft, Coord3D *bottomRight,
- Real z );
-
- virtual void setWidth( Int width ) { m_width = width; }
- virtual Int getWidth( void ) { return m_width; }
- virtual void setHeight( Int height ) { m_height = height; }
- virtual Int getHeight( void ) { return m_height; }
- virtual void setOrigin( Int x, Int y) { m_originX=x; m_originY=y;} ///< Sets location of top-left view corner on display
- virtual void getOrigin( Int *x, Int *y) { *x=m_originX; *y=m_originY;} ///< Return location of top-left view corner on display
-
- virtual void lockViewUntilFrame(UnsignedInt frame); ///< Locks the current view until the given frame is reached.
- virtual void forceRedraw() = 0;
-
- 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
-
- virtual void moveCameraTo(const Coord3D *o, Int frames, Int shutter, Bool orient) { lookAt( o ); }
- virtual void moveCameraAlongWaypointPath(Waypoint *way, Int frames, Int shutter, Bool orient) { }
- virtual Bool isCameraMovementFinished( void ) { return TRUE; }
- virtual void cameraModFinalZoom(Real finalZoom){}; ///< Final zoom for current camera movement.
- virtual void cameraModRollingAverage(Int framesToAverage){}; ///< Number of frames to average movement for current camera movement.
- virtual void cameraModFinalTimeMultiplier(Int finalMultiplier){}; ///< Final time multiplier for current camera movement.
- virtual void cameraModFinalPitch(Real finalPitch){}; ///< Final pitch for current camera movement.
- virtual void cameraModFreezeTime(void){ } ///< Freezes time during the next camera movement.
- virtual void cameraModFreezeAngle(void){ } ///< Freezes time during the next camera movement.
- virtual void cameraModLookToward(Coord3D *pLoc){} ///< Sets a look at point during camera movement.
- virtual void cameraModFinalLookToward(Coord3D *pLoc){} ///< Sets a look at point during camera movement.
- virtual void cameraModFinalMoveTo(Coord3D *pLoc){ }; ///< Sets a final move to.
-
- virtual FilterModes getViewFilterMode(void) {return (FilterModes)0;} ///< Turns on viewport special effect (black & white mode)
- virtual FilterTypes getViewFilterType(void) {return (FilterTypes)0;} ///< Turns on viewport special effect (black & white mode)
- virtual Bool setViewFilterMode(FilterModes filterMode) { return FALSE; } ///< Turns on viewport special effect (black & white mode)
- virtual void setViewFilterPos(const Coord3D *pos) { }; ///< Passes a position to the special effect filter.
- virtual Bool setViewFilter( FilterTypes filter) { return FALSE;} ///< Turns on viewport special effect (black & white mode)
-
- virtual void setFadeParameters(Int fadeFrames, Int direction) { };
- virtual void set3DWireFrameMode(Bool enable) { };
-
- virtual void resetCamera(const Coord3D *location, Int frames) {}; ///< Move camera to location, and reset to default angle & zoom.
- virtual void rotateCamera(Real rotations, Int frames) {}; ///< Rotate camera about current viewpoint.
- virtual void rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds) {}; ///< Rotate camera to face an object, and hold on it
- virtual void rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds) {}; ///< Rotate camera to face a location.
- virtual Bool isTimeFrozen(void){ return false;} ///< Freezes time during the next camera movement.
- virtual Int getTimeMultiplier(void) {return 1;}; ///< Get the time multiplier.
- virtual void setTimeMultiplier(Int multiple) {}; ///< Set the time multiplier.
- virtual void setDefaultView(Real pitch, Real angle, Real maxHeight) {};
- virtual void zoomCamera( Real finalZoom, Int milliseconds ) {};
- virtual void pitchCamera( Real finalPitch, Int milliseconds ) {};
-
- virtual void setAngle( Real angle ); ///< Rotate the view around the up axis to the given angle
- virtual Real getAngle( void ) { return m_angle; }
- virtual void setPitch( Real angle ); ///< Rotate the view around the horizontal axis to the given angle
- virtual Real getPitch( void ) { return m_pitchAngle; } ///< Return current camera pitch
- virtual void setAngleAndPitchToDefault( void ); ///< Set the view angle back to default
- virtual void getPosition(Coord3D *pos) { *pos=m_pos;} ///< Returns position camera is looking at (z will be zero)
-
- virtual const Coord3D& get3DCameraPosition() const = 0; ///< Returns the actual camera position
-
- virtual Real getZoom() { return m_zoom; }
- virtual void setZoom(Real z) { m_zoom = z; }
- virtual Real getHeightAboveGround() { return m_heightAboveGround; }
- virtual void setHeightAboveGround(Real z);
- virtual void zoom( Real height ); ///< Zoom in/out, closer to the ground, limit to min, or farther away from the ground, limit to max
- virtual void setZoomToDefault( void ) { m_zoom = 1.0f; } ///< Set zoom to default value
- virtual void setOkToAdjustHeight( Bool val ) { m_okToAdjustHeight = val; } ///< Set this to adjust camera height
-
- // for debugging
- virtual Real getTerrainHeightUnderCamera() { return m_terrainHeightUnderCamera; }
- virtual void setTerrainHeightUnderCamera(Real z) { m_terrainHeightUnderCamera = z; }
- virtual Real getCurrentHeightAboveGround() { return m_currentHeightAboveGround; }
- virtual void setCurrentHeightAboveGround(Real z) { m_currentHeightAboveGround = z; }
-
- virtual void setFieldOfView( Real angle ) { m_FOV = angle; } ///< Set the horizontal field of view angle
- virtual Real getFieldOfView( void ) { return m_FOV; } ///< Get the horizontal field of view angle
-
- Bool worldToScreen( const Coord3D *w, ICoord2D *s ) { return worldToScreenTriReturn( w, s ) == WTS_INSIDE_FRUSTUM; } ///< Transform world coordinate "w" into screen coordinate "s"
- virtual WorldToScreenReturn worldToScreenTriReturn(const Coord3D *w, ICoord2D *s ) = 0; ///< Like worldToScreen(), but with a more informative return value
- virtual void screenToWorld( const ICoord2D *s, Coord3D *w ) = 0; ///< Transform screen coordinate "s" into world coordinate "w"
- virtual void screenToTerrain( const ICoord2D *screen, Coord3D *world ) = 0; ///< transform screen coord to a point on the 3D terrain
- virtual void screenToWorldAtZ( const ICoord2D *s, Coord3D *w, Real z ) = 0; ///< transform screen point to world point at the specified world Z value
-
- virtual void getLocation ( ViewLocation *location ); ///< write the view's current location in to the view location object
- virtual void setLocation ( const ViewLocation *location ); ///< set the view's current location from to the view location object
-
-
- virtual void drawView( void ) = 0; ///< Render the world visible in this view.
- virtual void updateView(void) = 0; ///.
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// View.cpp ///////////////////////////////////////////////////////////////////
-// A "view", or window, into the World
-// Author: Michael S. Booth, February 2001
-
-#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
-
-#include "Common/GameEngine.h"
-#include "Common/Xfer.h"
-#include "GameClient/View.h"
-#include "GameClient/Drawable.h"
-
-UnsignedInt View::m_idNext = 1;
-
-// the tactical view singleton
-View *TheTacticalView = NULL;
-
-
-View::View( void )
-{
- //Added By Sadullah Nader
- //Initialization(s) inserted
- m_viewLockedUntilFrame = 0u;
- m_currentHeightAboveGround = 0.0f;
- m_defaultAngle = 0.0f;
- m_defaultPitchAngle = 0.0f;
- m_heightAboveGround = 0.0f;
- m_lockDist = 0.0f;
- m_maxHeightAboveGround = 0.0f;
- m_minHeightAboveGround = 0.0f;
- m_next = NULL;
- m_okToAdjustHeight = TRUE;
- m_originX = 0;
- m_originY = 0;
- m_snapImmediate = FALSE;
- m_terrainHeightUnderCamera = 0.0f;
- m_zoom = 0.0f;
- //
- m_pos.x = 0;
- m_pos.y = 0;
- m_width = 0;
- m_height = 0;
- m_angle = 0.0f;
- m_pitchAngle = 0.0f;
- m_cameraLock = INVALID_ID;
- m_cameraLockDrawable = NULL;
- m_zoomLimited = TRUE;
-
- // create unique view ID
- m_id = m_idNext++;
-
- // default field of view
- m_FOV = 50.0f * PI/180.0f;
-
- m_mouseLocked = FALSE;
-
- m_guardBandBias.x = 0.0f;
- m_guardBandBias.y = 0.0f;
-}
-
-View::~View()
-{
-}
-
-void View::init( void )
-{
- m_width = DEFAULT_VIEW_WIDTH;
- m_height = DEFAULT_VIEW_HEIGHT;
- m_originX = DEFAULT_VIEW_ORIGIN_X;
- m_originY = DEFAULT_VIEW_ORIGIN_Y;
- m_pos.x = 0;
- m_pos.y = 0;
- m_angle = 0.0f;
- m_cameraLock = INVALID_ID;
- m_cameraLockDrawable = NULL;
- m_zoomLimited = TRUE;
-
- m_zoom = 1.0f;
- m_maxHeightAboveGround = TheGlobalData->m_maxCameraHeight;
- m_minHeightAboveGround = TheGlobalData->m_minCameraHeight;
- m_okToAdjustHeight = FALSE;
-
- m_defaultAngle = 0.0f;
- m_defaultPitchAngle = 0.0f;
-}
-
-void View::reset( void )
-{
- // Only fixing the reported bug. Who knows what side effects resetting the rest could have.
- m_zoomLimited = TRUE;
-
- m_viewLockedUntilFrame = 0u;
-}
-
-/**
- * Prepend this view to the given list, return the new list.
- */
-View *View::prependViewToList( View *list )
-{
- m_next = list;
- return this;
-}
-
-void View::zoom( Real height )
-{
- setHeightAboveGround(getHeightAboveGround() + height);
-}
-
-void View::lockViewUntilFrame(UnsignedInt frame)
-{
- m_viewLockedUntilFrame = frame;
-}
-
-/**
- * Center the view on the given coordinate.
- */
-void View::lookAt( const Coord3D *o )
-{
-
- /// @todo this needs to be changed to be 3D, this is still old 2D stuff
- Coord3D pos = *getPosition();
- pos.x = o->x - m_width * 0.5f;
- pos.y = o->y - m_height * 0.5f;
- setPosition(&pos);
-}
-
-/**
- * Shift the view by the given delta.
- */
-void View::scrollBy( Coord2D *delta )
-{
- // update view's world position
- m_pos.x += delta->x;
- m_pos.y += delta->y;
-}
-
-/**
- * Rotate the view around the up axis by the given angle.
- */
-void View::setAngle( Real angle )
-{
- m_angle = angle;
-}
-
-/**
- * Rotate the view around the horizontal (X) axis to the given angle.
- */
-void View::setPitch( Real angle )
-{
- constexpr Real limit = PI/5.0f;
- m_pitchAngle = clamp(-limit, angle, limit);
-}
-
-/**
- * Set the view angle back to default
- */
-void View::setAngleAndPitchToDefault( void )
-{
- m_angle = m_defaultAngle;
- m_pitchAngle = m_defaultPitchAngle;
-}
-
-void View::setHeightAboveGround(Real z)
-{
- // if our zoom is limited, we will stay within a predefined distance from the terrain
- if( m_zoomLimited )
- {
- m_heightAboveGround = clamp(m_minHeightAboveGround, z, m_maxHeightAboveGround);
- }
- else
- {
- m_heightAboveGround = z;
- }
-}
-
-/**
- * write the view's current location in to the view location object
- */
-void View::getLocation( ViewLocation *location )
-{
-
- const Coord3D *pos = getPosition();
- location->init( pos->x, pos->y, pos->z, getAngle(), getPitch(), getZoom() );
-
-}
-
-
-/**
- * set the view's current location from to the view location object
- */
-void View::setLocation( const ViewLocation *location )
-{
- if ( location->m_valid )
- {
- setPosition(&location->m_pos);
- setAngle(location->m_angle);
- setPitch(location->m_pitch);
- setZoom(location->m_zoom);
- forceRedraw();
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** project the 4 corners of this view into the world and return each point as a parameter,
- the world points are at the requested Z */
-//-------------------------------------------------------------------------------------------------
-void View::getScreenCornerWorldPointsAtZ( Coord3D *topLeft, Coord3D *topRight,
- Coord3D *bottomLeft, Coord3D *bottomRight,
- Real z )
-{
- ICoord2D screenTopLeft, screenTopRight, screenBottomLeft, screenBottomRight;
- ICoord2D origin;
- Int viewWidth = getWidth();
- Int viewHeight = getHeight();
-
- // sanity
- if( topLeft == NULL || topRight == NULL || bottomLeft == NULL || bottomRight == NULL )
- return;
-
- // setup the screen coords for the 4 corners of the viewable display
- getOrigin( &origin.x, &origin.y );
- screenTopLeft.x = origin.x; // upper left
- screenTopLeft.y = origin.y; // upper left
- screenTopRight.x = origin.x + viewWidth; // upper right
- screenTopRight.y = origin.y; // upper right
- screenBottomLeft.x = origin.x + viewWidth; // lower right
- screenBottomLeft.y = origin.y + viewHeight; // lower right
- screenBottomRight.x = origin.x; // lower left
- screenBottomRight.y = origin.y + viewHeight; // lower left
-
- // project
- screenToWorldAtZ( &screenTopLeft, topLeft, z );
- screenToWorldAtZ( &screenTopRight, topRight, z );
- screenToWorldAtZ( &screenBottomLeft, bottomLeft, z );
- screenToWorldAtZ( &screenBottomRight, bottomRight, z );
-
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Xfer method for a view */
-// ------------------------------------------------------------------------------------------------
-void View::xfer( Xfer *xfer )
-{
-
- // version
- XferVersion currentVersion = 1;
- XferVersion version = currentVersion;
- xfer->xferVersion( &version, currentVersion );
-
- // camera angle
- Real angle = getAngle();
- xfer->xferReal( &angle );
- setAngle( angle );
-
- // view position
- Coord3D viewPos;
- getPosition( &viewPos );
- xfer->xferReal( &viewPos.x );
- xfer->xferReal( &viewPos.y );
- xfer->xferReal( &viewPos.z );
- lookAt( &viewPos );
-
-}
diff --git a/Generals/Code/GameEngineDevice/CMakeLists.txt b/Generals/Code/GameEngineDevice/CMakeLists.txt
index 7d91eaf43e..de6e7bd69a 100644
--- a/Generals/Code/GameEngineDevice/CMakeLists.txt
+++ b/Generals/Code/GameEngineDevice/CMakeLists.txt
@@ -60,7 +60,7 @@ set(GAMEENGINEDEVICE_SRC
Include/W3DDevice/GameClient/W3DTerrainVisual.h
Include/W3DDevice/GameClient/W3DTreeBuffer.h
# Include/W3DDevice/GameClient/W3DVideoBuffer.h
- Include/W3DDevice/GameClient/W3DView.h
+# Include/W3DDevice/GameClient/W3DView.h
Include/W3DDevice/GameClient/W3DVolumetricShadow.h
Include/W3DDevice/GameClient/W3DWater.h
Include/W3DDevice/GameClient/W3DWaterTracks.h
@@ -158,7 +158,7 @@ set(GAMEENGINEDEVICE_SRC
Source/W3DDevice/GameClient/W3DTerrainVisual.cpp
Source/W3DDevice/GameClient/W3DTreeBuffer.cpp
# Source/W3DDevice/GameClient/W3DVideoBuffer.cpp
- Source/W3DDevice/GameClient/W3DView.cpp
+# Source/W3DDevice/GameClient/W3DView.cpp
Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp
Source/W3DDevice/GameClient/W3DWebBrowser.cpp
Source/W3DDevice/GameClient/Water/W3DWater.cpp
diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DModelDraw.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DModelDraw.h
index 2589bcb7c4..293ca4bc07 100644
--- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DModelDraw.h
+++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DModelDraw.h
@@ -363,6 +363,8 @@ class W3DModelDraw : public DrawModule, public ObjectDrawInterface
// this method must ONLY be called from the client, NEVER From the logic, not even indirectly.
virtual Bool clientOnly_getRenderObjInfo(Coord3D* pos, Real* boundingSphereRadius, Matrix3D* transform) const;
+ virtual Bool clientOnly_getRenderObjBoundBox(OBBoxClass * boundbox) const;
+ virtual Bool clientOnly_getRenderObjBoneTransform(const AsciiString & boneName,Matrix3D * set_tm) const;
virtual Int getPristineBonePositionsForConditionState(const ModelConditionFlags& condition, const char* boneNamePrefix, Int startIndex, Coord3D* positions, Matrix3D* transforms, Int maxBones) const;
virtual Int getCurrentBonePositions(const char* boneNamePrefix, Int startIndex, Coord3D* positions, Matrix3D* transforms, Int maxBones) const;
virtual Bool getCurrentWorldspaceClientBonePositions(const char* boneName, Matrix3D& transform) const;
diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h
index 018e27ef81..472d9d31bc 100644
--- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h
+++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h
@@ -127,6 +127,7 @@ class W3DDisplay : public Display
virtual void enableLetterBox(Bool enable); ///.
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: W3DView.h ////////////////////////////////////////////////////////////////////////////////
-//
-// W3D implementation of the game view window. View windows are literally
-// a window into the game world that have width, height, and camera
-// controls for what to look at
-//
-// Author: Colin Day, April 2001
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#pragma once
-
-// SYSTEM INCLUDES ////////////////////////////////////////////////////////////////////////////////
-
-// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
-#include "Common/STLTypedefs.h"
-#include "GameClient/View.h"
-#include "WW3D2/camera.h"
-
-// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
-class Drawable;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-enum {MAX_WAYPOINTS=25};
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-typedef struct
-{
- Int numWaypoints;
- Coord3D waypoints[MAX_WAYPOINTS+2]; // We pad first & last for interpolation.
- Real waySegLength[MAX_WAYPOINTS+2]; // Length of each segment;
- Real cameraAngle[MAX_WAYPOINTS+2]; // Camera Angle;
- Real cameraFXPitch[MAX_WAYPOINTS+2]; // Camera Pitch;
- Real cameraZoom[MAX_WAYPOINTS+2]; // Camera Zoom;
- Int timeMultiplier[MAX_WAYPOINTS+2]; // Time speedup factor.
- Real groundHeight[MAX_WAYPOINTS+1]; // Ground height.
- Real totalTimeMilliseconds; // Num of ms to do this movement.
- Real elapsedTimeMilliseconds; // Time since start.
- Real totalDistance; // Total length of paths.
- Real curSegDistance; // How far we are along the current seg.
- Int shutter;
- Int curSegment; // The current segment.
- Int curShutter; // The current shutter.
- Int rollingAverageFrames; // Number of frames to roll.
-} TMoveAlongWaypointPathInfo;
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-typedef struct
-{
- Int numFrames; ///< Number of frames to rotate.
- Int curFrame; ///< Current frame.
- Real angle;
- Real startZoom;
- Real endZoom;
- Real startPitch;
- Real endPitch;
- Int startTimeMultiplier;
- Int endTimeMultiplier;
- ObjectID targetObjectID; ///< Target if we are tracking an object instead of just rotating
- Coord3D targetObjectPos; ///< Target's position (so we can stay looking at that spot if he dies)
- Bool trackObject; ///< Are we tracking an object or just rotating?
- Int numHoldFrames; ///< Number of frames to hold the camera before finishing the movement
-} TRotateCameraInfo;
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-typedef struct
-{
- Int numFrames; ///< Number of frames to pitch.
- Int curFrame; ///< Current frame.
- Real angle;
- Real startPitch;
- Real endPitch;
- Int startTimeMultiplier;
- Int endTimeMultiplier;
-} TPitchCameraInfo;
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-typedef struct
-{
- Int numFrames; ///< Number of frames to zoom.
- Int curFrame; ///< Current frame.
- Real startZoom;
- Real endZoom;
- Int startTimeMultiplier;
- Int endTimeMultiplier;
-} TZoomCameraInfo;
-
-// ------------------------------------------------------------------------------------------------
-/** W3DView implementation of the game view class. This allows us to create
- * a "window" into the game world that can be sized and contains controls
- * for manipulating the camera */
-// ------------------------------------------------------------------------------------------------
-class W3DView : public View, public SubsystemInterface
-{
-
-public:
- W3DView();
- ~W3DView();
-
- virtual void init( void ); ///< init/re-init the W3DView
- virtual void reset( void );
- virtual void drawView( void ); ///< draw this view
- virtual void updateView(void); ///x; m_guardBandBias.y = gb->y; }
-
-
-private:
-
- CameraClass *m_3DCamera; ///< camera representation for 3D scene
- CameraClass *m_2DCamera; ///< camera for UI overlayed on top of 3D scene
- FilterModes m_viewFilterMode;
- FilterTypes m_viewFilter;
- Bool m_isWireFrameEnabled;
- Bool m_nextWireFrameEnabled; ///< used to delay wireframe changes by 1 frame (needed for transitions).
-
-
- Coord2D m_shakeOffset; ///< the offset to add to the camera position
- Real m_shakeAngleCos; ///< the cosine of the orientation of the oscillation
- Real m_shakeAngleSin; ///< the sine of the orientation of the oscillation
- Real m_shakeIntensity; ///< the intensity of the oscillation
-
-
- TRotateCameraInfo m_rcInfo;
- Bool m_doingRotateCamera; ///< True if we are doing a camera rotate.
-
- TPitchCameraInfo m_pcInfo;
- Bool m_doingPitchCamera;
- TZoomCameraInfo m_zcInfo;
- Bool m_doingZoomCamera;
-
- Bool m_doingScriptedCameraLock; ///< True if we are following a unit via script
-
- 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_freezeTimeForCameraMovement;
- Int m_timeMultiplier; ///< Time speedup multiplier.
-
- Bool m_cameraHasMovedSinceRequest; ///< If true, throw out all saved locations
- VecPosRequests m_locationRequests; ///< These are cached. New requests are added here
-
- Coord3D m_cameraOffset; ///< offset for camera from view center
- Coord3D m_previousLookAtPosition; ///< offset for camera from view center
- Coord2D m_scrollAmount; ///< scroll speed
- Real m_scrollAmountCutoff; ///< scroll speed at which we do not adjust height
-
- Real m_groundLevel; ///< height of ground.
-
- Region2D m_cameraConstraint; ///< m_pos should be constrained to be within this area
- Bool m_cameraConstraintValid; ///< if f, recalc cam constraints
-
- void setCameraTransform( void ); ///< set the transform matrix of m_3DCamera, based on m_pos & m_angle
- void buildCameraTransform( Matrix3D *transform ) ; ///< calculate (but do not set) the transform matrix of m_3DCamera, based on m_pos & m_angle
- void calcCameraConstraints() ; ///< recalc m_cameraConstraint
- void moveAlongWaypointPath(Real milliseconds); ///< Move camera along path.
- void getPickRay(const ICoord2D *screen, Vector3 *rayStart, Vector3 *rayEnd); ///Get_Obj_Space_Bounding_Box(aabox);
+
+ Matrix3D tm = m_renderObject->Get_Transform();
+
+ // build an OBB for this AAB,transform
+ OBBoxClass box0(aabox.Center,aabox.Extent);
+ OBBoxClass::Transform(tm,box0,boundbox);
+
+ return true;
+}
+
+
+//-------------------------------------------------------------------------------------------------
+// (gth) C&C3 Added this accessor for a bone transform in the render object
+// this method must ONLY be called from the client, NEVER From the logic, not even indirectly.
+Bool W3DModelDraw::clientOnly_getRenderObjBoneTransform(const AsciiString & boneName,Matrix3D * set_tm) const
+{
+ if (!m_renderObject) {
+ return false;
+ }
+
+ int idx = m_renderObject->Get_Bone_Index(boneName.str());
+ if (idx == 0) {
+ set_tm->Make_Identity();
+ return false;
+ } else {
+ *set_tm = m_renderObject->Get_Bone_Transform(idx);
+ return true;
+ }
+}
+
+
//-------------------------------------------------------------------------------------------------
Bool W3DModelDraw::getCurrentWorldspaceClientBonePositions(const char* boneName, Matrix3D& transform) const
{
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
index 90a1efd54c..9767f32c29 100644
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
+++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp
@@ -1940,6 +1940,12 @@ Bool W3DDisplay::isLetterBoxFading(void)
return FALSE;
}
+//WST 10/2/2002 added query function. JSC Integrated 5/20/03
+Bool W3DDisplay::isLetterBoxed(void)
+{
+ return (m_letterBoxEnabled);
+}
+
// W3DDisplay::createLightPulse ===============================================
/** Create a "light pulse" which is a dynamic light that grows, decays
* and vanishes over several frames */
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
deleted file mode 100644
index 703673a96f..0000000000
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp
+++ /dev/null
@@ -1,3141 +0,0 @@
-/*
-** Command & Conquer Generals(tm)
-** Copyright 2025 Electronic Arts Inc.
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation, either version 3 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program. If not, see .
-*/
-
-////////////////////////////////////////////////////////////////////////////////
-// //
-// (c) 2001-2003 Electronic Arts Inc. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-// FILE: W3DView.cpp //////////////////////////////////////////////////////////////////////////////
-//
-// W3D implementation of the game view class. This view allows us to have
-// a "window" into the game world that can change its width, height as
-// well as camera positioning controls
-//
-// Author: Colin Day, April 2001
-//
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-// SYSTEM INCLUDES ////////////////////////////////////////////////////////////////////////////////
-#include
-#include
-
-// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
-#include "Common/BuildAssistant.h"
-#include "Common/FramePacer.h"
-#include "Common/GameUtility.h"
-#include "Common/GlobalData.h"
-#include "Common/Module.h"
-#include "Common/RandomValue.h"
-#include "Common/ThingTemplate.h"
-#include "Common/ThingSort.h"
-#include "Common/PerfTimer.h"
-#include "Common/PlayerList.h"
-#include "Common/Player.h"
-
-#include "GameClient/Color.h"
-#include "GameClient/CommandXlat.h"
-#include "GameClient/Drawable.h"
-#include "GameClient/GameClient.h"
-#include "GameClient/GameWindowManager.h"
-#include "GameClient/Image.h"
-#include "GameClient/InGameUI.h"
-#include "GameClient/Line2D.h"
-#include "GameClient/SelectionInfo.h"
-#include "GameClient/Shell.h"
-#include "GameClient/TerrainVisual.h"
-#include "GameClient/Water.h"
-
-#include "GameLogic/AI.h" ///< For AI debug (yes, I'm cheating for now)
-#include "GameLogic/AIPathfind.h" ///< For AI debug (yes, I'm cheating for now)
-#include "GameLogic/ExperienceTracker.h"
-#include "GameLogic/GameLogic.h"
-#include "GameLogic/Module/AIUpdate.h"
-#include "GameLogic/Module/BodyModule.h"
-#include "GameLogic/Module/ContainModule.h"
-#include "GameLogic/Module/OpenContain.h"
-#include "GameLogic/Object.h"
-#include "GameLogic/ScriptEngine.h"
-#include "GameLogic/TerrainLogic.h" ///< @todo This should be TerrainVisual (client side)
-#include "Common/AudioEventInfo.h"
-
-#include "W3DDevice/Common/W3DConvert.h"
-#include "W3DDevice/GameClient/HeightMap.h"
-#include "W3DDevice/GameClient/W3DAssetManager.h"
-#include "W3DDevice/GameClient/W3DDisplay.h"
-#include "W3DDevice/GameClient/W3DScene.h"
-#include "W3DDevice/GameClient/W3DView.h"
-#include "d3dx8math.h"
-#include "W3DDevice/GameClient/W3DShaderManager.h"
-#include "W3DDevice/GameClient/Module/W3DModelDraw.h"
-#include "W3DDevice/GameClient/W3DCustomScene.h"
-
-#include "WW3D2/dx8renderer.h"
-#include "WW3D2/light.h"
-#include "WW3D2/camera.h"
-#include "WW3D2/coltype.h"
-#include "WW3D2/predlod.h"
-#include "WW3D2/ww3d.h"
-
-#include "WinMain.h" /** @todo Remove this, it's only here because we
- are using timeGetTime, but we can remove that
- when we have our own timer */
-
-
-
-// 30 fps
-Real TheW3DFrameLengthInMsec = MSEC_PER_LOGICFRAME_REAL; // default is 33msec/frame == 30fps. but we may change it depending on sys config.
-static const Int MAX_REQUEST_CACHE_SIZE = 40; // Any size larger than 10, or examine code below for changes. jkmcd.
-static const Real DRAWABLE_OVERSCAN = 75.0f; ///< 3D world coords of how much to overscan in the 3D screen region
-
-
-
-
-
-
-//=================================================================================================
-inline Real minf(Real a, Real b) { if (a < b) return a; else return b; }
-inline Real maxf(Real a, Real b) { if (a > b) return a; else return b; }
-
-//-------------------------------------------------------------------------------------------------
-// Normalizes angle to +- PI.
-//-------------------------------------------------------------------------------------------------
-static void normAngle(Real &angle)
-{
- angle = WWMath::Normalize_Angle(angle);
-}
-
-#define TERRAIN_SAMPLE_SIZE 40.0f
-static Real getHeightAroundPos(Real x, Real y)
-{
- // terrain height + desired height offset == cameraOffset * actual zoom
- Real terrainHeight = TheTerrainLogic->getGroundHeight(x, y);
-
- // find best approximation of max terrain height we can see
- Real terrainHeightMax = terrainHeight;
- terrainHeightMax = max(terrainHeightMax, TheTerrainLogic->getGroundHeight(x+TERRAIN_SAMPLE_SIZE, y-TERRAIN_SAMPLE_SIZE));
- terrainHeightMax = max(terrainHeightMax, TheTerrainLogic->getGroundHeight(x-TERRAIN_SAMPLE_SIZE, y-TERRAIN_SAMPLE_SIZE));
- terrainHeightMax = max(terrainHeightMax, TheTerrainLogic->getGroundHeight(x+TERRAIN_SAMPLE_SIZE, y+TERRAIN_SAMPLE_SIZE));
- terrainHeightMax = max(terrainHeightMax, TheTerrainLogic->getGroundHeight(x-TERRAIN_SAMPLE_SIZE, y+TERRAIN_SAMPLE_SIZE));
-
- return terrainHeightMax;
-}
-
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-W3DView::W3DView()
-{
-
- m_3DCamera = NULL;
- m_2DCamera = NULL;
- m_groundLevel = 10.0;
- m_cameraOffset.z = TheGlobalData->m_cameraHeight;
- m_cameraOffset.y = -(m_cameraOffset.z / tan(TheGlobalData->m_cameraPitch * (PI / 180.0)));
- m_cameraOffset.x = -(m_cameraOffset.y * tan(TheGlobalData->m_cameraYaw * (PI / 180.0)));
-
- m_viewFilterMode = FM_NULL_MODE;
- m_viewFilter = FT_NULL_FILTER;
- m_isWireFrameEnabled = m_nextWireFrameEnabled = FALSE;
- m_shakeOffset.x = 0.0f;
- m_shakeOffset.y = 0.0f;
- m_shakeIntensity = 0.0f;
- m_FXPitch = 1.0f;
- m_freezeTimeForCameraMovement = false;
- m_cameraHasMovedSinceRequest = true;
- m_locationRequests.clear();
- m_locationRequests.reserve(MAX_REQUEST_CACHE_SIZE + 10); // This prevents the vector from ever re-allocing
-
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-W3DView::~W3DView()
-{
-
- REF_PTR_RELEASE( m_2DCamera );
- REF_PTR_RELEASE( m_3DCamera );
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Sets the height of the viewport, while maintaining original camera perspective. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setHeight(Int height)
-{
- // extend View functionality
- View::setHeight(height);
-
- Vector2 vMin,vMax;
- m_3DCamera->Set_Aspect_Ratio((Real)getWidth()/(Real)height);
- m_3DCamera->Get_Viewport(vMin,vMax);
- vMax.Y=(Real)(m_originY+height)/(Real)TheDisplay->getHeight();
- m_3DCamera->Set_Viewport(vMin,vMax);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Sets the width of the viewport, while maintaining original camera perspective. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setWidth(Int width)
-{
- // extend View functionality
- View::setWidth(width);
-
- Vector2 vMin,vMax;
- m_3DCamera->Set_Aspect_Ratio((Real)width/(Real)getHeight());
- m_3DCamera->Get_Viewport(vMin,vMax);
- vMax.X=(Real)(m_originX+width)/(Real)TheDisplay->getWidth();
- m_3DCamera->Set_Viewport(vMin,vMax);
-
- //we want to maintain the same scale, so we'll need to adjust the fov.
- //default W3D fov for full-screen is 50 degrees.
- m_3DCamera->Set_View_Plane((Real)width/(Real)TheDisplay->getWidth()*DEG_TO_RADF(50.0f),-1);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Sets location of top-left view corner on display */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setOrigin( Int x, Int y)
-{
- // extend View functionality
- View::setOrigin(x,y);
-
- Vector2 vMin,vMax;
-
- m_3DCamera->Get_Viewport(vMin,vMax);
- vMin.X=(Real)x/(Real)TheDisplay->getWidth();
- vMin.Y=(Real)y/(Real)TheDisplay->getHeight();
- m_3DCamera->Set_Viewport(vMin,vMax);
-
- // bottom-right border was also moved my this call, so force an update of extents.
- setWidth(m_width);
- setHeight(m_height);
-}
-
-//-------------------------------------------------------------------------------------------------
-/** @todo This is inefficient. We should construct the matrix directly using vectors. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::buildCameraTransform( Matrix3D *transform )
-{
- Vector3 sourcePos, targetPos;
-
- Real groundLevel = m_groundLevel; // 93.0f;
-
- Real zoom = getZoom();
- Real angle = getAngle();
- Real pitch = getPitch();
- Coord3D pos = *getPosition();
-
- // add in the camera shake, if any
- pos.x += m_shakeOffset.x;
- pos.y += m_shakeOffset.y;
-
- if (m_cameraConstraintValid)
- {
- pos.x = maxf(m_cameraConstraint.lo.x, pos.x);
- pos.x = minf(m_cameraConstraint.hi.x, pos.x);
- pos.y = maxf(m_cameraConstraint.lo.y, pos.y);
- pos.y = minf(m_cameraConstraint.hi.y, pos.y);
- }
-
- // set position of camera itself
- sourcePos.X = m_cameraOffset.x*zoom;
- sourcePos.Y = m_cameraOffset.y*zoom;
- sourcePos.Z = m_cameraOffset.z*zoom;
-
-
-#ifdef NOT_IN_USE
- if (TheGlobalData->m_isOffsetCameraZ && TheTerrainLogic)
- {
- sourcePos.Z += TheTerrainLogic->getGroundHeight(pos.x, pos.y);
- if (m_prevSourcePosZ != SOURCEPOS_INVALID)
- {
- const Real MAX_SPZ_VARIATION = 0.05f;
- Real spzMin = m_prevSourcePosZ*(1.0-MAX_SPZ_VARIATION);
- Real spzMax Coord3D center;
- = m_prevSourcePosZ*(1.0+MAX_SPZ_VARIATION);
- if (sourcePos.Z < spzMin) sourcePos.Z = spzMin;
- if (sourcePos.Z > spzMax) sourcePos.Z = spzMax;
- }
- m_prevSourcePosZ = sourcePos.Z;
- }
-#endif
-
- // camera looking at origin
- targetPos.X = 0;
- targetPos.Y = 0;
- targetPos.Z = 0;
-
-
- Real factor = 1.0 - (groundLevel/sourcePos.Z );
-
- // construct a matrix to rotate around the up vector by the given angle
- Matrix3D angleTransform( Vector3( 0.0f, 0.0f, 1.0f ), angle );
-
- // construct a matrix to rotate around the horizontal vector by the given angle
- Matrix3D pitchTransform( Vector3( 1.0f, 0.0f, 0.0f ), pitch );
-
- // rotate camera position (pitch, then angle)
-#ifdef ALLOW_TEMPORARIES
- sourcePos = pitchTransform * sourcePos;
- sourcePos = angleTransform * sourcePos;
-#else
- pitchTransform.mulVector3(sourcePos);
- angleTransform.mulVector3(sourcePos);
-#endif
- sourcePos *= factor;
-
- // translate to current XY position
- sourcePos.X += pos.x;
- sourcePos.Y += pos.y;
- sourcePos.Z += groundLevel;
-
- targetPos.X += pos.x;
- targetPos.Y += pos.y;
- targetPos.Z += groundLevel;
-
- // do m_FXPitch adjustment.
- Real height = sourcePos.Z - targetPos.Z;
- height *= m_FXPitch;
- targetPos.Z = sourcePos.Z - height;
-
- // build new camera transform
- transform->Make_Identity();
- transform->Look_At( sourcePos, targetPos, 0 );
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::calcCameraConstraints()
-{
-// const Matrix3D& cameraTransform = m_3DCamera->Get_Transform();
-
-// DEBUG_LOG(("*** rebuilding cam constraints"));
-
- // ok, now check to ensure that we can't see outside the map region,
- // and twiddle the camera if needed
- if (TheTerrainLogic)
- {
- Region3D mapRegion;
- TheTerrainLogic->getExtent( &mapRegion );
-
- /*
- Note the following restrictions on camera constraints!
-
- -- they assume that all maps are height 'm_groundLevel' at the edges.
- (since you need to add some "buffer" around the edges of your map
- anyway, this shouldn't be an issue.)
-
- -- for angles/pitches other than zero, it may show boundaries.
- since we currently plan the game to be restricted to this,
- it shouldn't be an issue.
-
- */
- Real maxEdgeZ = m_groundLevel;
-// const Real BORDER_FUDGE = MAP_XY_FACTOR * 1.414f;
- Coord3D center, bottom;
- ICoord2D screen;
-
- //Pick at the center
- screen.x=0.5f*getWidth()+m_originX;
- screen.y=0.5f*getHeight()+m_originY;
-
- Vector3 rayStart,rayEnd;
-
- getPickRay(&screen,&rayStart,&rayEnd);
-
- center.x = Vector3::Find_X_At_Z(maxEdgeZ, rayStart, rayEnd);
- center.y = Vector3::Find_Y_At_Z(maxEdgeZ, rayStart, rayEnd);
- center.z = maxEdgeZ;
-
- screen.y = m_originY+ 0.95f*getHeight();
- getPickRay(&screen,&rayStart,&rayEnd);
- bottom.x = Vector3::Find_X_At_Z(maxEdgeZ, rayStart, rayEnd);
- bottom.y = Vector3::Find_Y_At_Z(maxEdgeZ, rayStart, rayEnd);
- bottom.z = maxEdgeZ;
- center.x -= bottom.x;
- center.y -= bottom.y;
-
- Real offset = center.length();
-
- if (TheGlobalData->m_debugAI) {
- offset = -1000; // push out the constraints so we can look at staging areas.
- }
-
- m_cameraConstraint.lo.x = mapRegion.lo.x + offset;
- m_cameraConstraint.hi.x = mapRegion.hi.x - offset;
- // this looks inverted, but is correct
- m_cameraConstraint.lo.y = mapRegion.lo.y + offset;
- m_cameraConstraint.hi.y = mapRegion.hi.y - offset;
- m_cameraConstraintValid = true;
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Returns a world-space ray originating at a given screen pixel position
- and ending at the far clip plane for current camera. Screen coordinates
- assumed in absolute values relative to full display resolution.*/
-//-------------------------------------------------------------------------------------------------
-void W3DView::getPickRay(const ICoord2D *screen, Vector3 *rayStart, Vector3 *rayEnd)
-{
- Real logX,logY;
-
- //W3D Screen coordinates are -1 to 1, so we need to do some conversion:
- PixelScreenToW3DLogicalScreen(screen->x - m_originX,screen->y - m_originY, &logX, &logY,getWidth(),getHeight());
-
- *rayStart = m_3DCamera->Get_Position(); //get camera location
- m_3DCamera->Un_Project(*rayEnd,Vector2(logX,logY)); //get world space point
- *rayEnd -= *rayStart; //vector camera to world space point
- rayEnd->Normalize(); //make unit vector
- *rayEnd *= m_3DCamera->Get_Depth(); //adjust length to reach far clip plane
- *rayEnd += *rayStart; //get point on far clip plane along ray from camera.
-}
-
-//-------------------------------------------------------------------------------------------------
-/** set the transform matrix of m_3DCamera, based on m_pos & m_angle */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setCameraTransform( void )
-{
- if (TheGlobalData->m_headless)
- return;
-
- if (m_viewLockedUntilFrame > TheGameClient->getFrame())
- return;
-
- m_cameraHasMovedSinceRequest = true;
- Matrix3D cameraTransform( 1 );
-
- Real nearZ, farZ;
- m_3DCamera->Get_Clip_Planes(nearZ, farZ);
- // Set the near to MAP_XY_FACTOR. Improves zbuffer resolution.
- nearZ = MAP_XY_FACTOR;
- farZ = 1200.0f;
-
- if ((TheGlobalData && TheGlobalData->m_drawEntireTerrain) || (m_FXPitch<0.95f || m_zoom>1.05))
- { //need to extend far clip plane so entire terrain can be visible
- farZ *= MAP_XY_FACTOR;
- }
-
- m_3DCamera->Set_Clip_Planes(nearZ, farZ);
-#if defined(RTS_DEBUG)
- if (TheGlobalData->m_useCameraConstraints)
-#endif
- {
- if (!m_cameraConstraintValid)
- {
- buildCameraTransform(&cameraTransform);
- m_3DCamera->Set_Transform( cameraTransform );
- calcCameraConstraints();
- }
- DEBUG_ASSERTLOG(m_cameraConstraintValid,("*** cam constraints are not valid!!!"));
-
- if (m_cameraConstraintValid)
- {
- Coord3D pos = *getPosition();
- pos.x = maxf(m_cameraConstraint.lo.x, pos.x);
- pos.x = minf(m_cameraConstraint.hi.x, pos.x);
- pos.y = maxf(m_cameraConstraint.lo.y, pos.y);
- pos.y = minf(m_cameraConstraint.hi.y, pos.y);
- setPosition(&pos);
- }
- }
-
-#if defined(RTS_DEBUG)
- m_3DCamera->Set_View_Plane( m_FOV, -1 );
-#endif
-
- // rebuild it (even if we just did it due to camera constraints)
- buildCameraTransform( &cameraTransform );
- m_3DCamera->Set_Transform( cameraTransform );
-
- if (TheTerrainRenderObject)
- {
- RefRenderObjListIterator *it = W3DDisplay::m_3DScene->createLightsIterator();
- TheTerrainRenderObject->updateCenter(m_3DCamera, it);
- if (it)
- {
- W3DDisplay::m_3DScene->destroyLightsIterator(it);
- it = NULL;
- }
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::init( void )
-{
- // extend View functionality
- View::init();
- setName("W3DView");
- // set default camera "lookat" point
- Coord3D pos;
- pos.x = 87.0f;
- pos.y = 77.0f;
- pos.z = 0;
-
- pos.x *= MAP_XY_FACTOR;
- pos.y *= MAP_XY_FACTOR;
-
- setPosition(&pos);
-
- // create our 3D camera
- m_3DCamera = NEW_REF( CameraClass, () );
-
-
- setCameraTransform();
-
- // create our 2D camera for the GUI overlay
- m_2DCamera = NEW_REF( CameraClass, () );
- m_2DCamera->Set_Position( Vector3( 0, 0, 1 ) );
- Vector2 min = Vector2( -1, -0.75f );
- Vector2 max = Vector2( +1, +0.75f );
- m_2DCamera->Set_View_Plane( min, max );
- m_2DCamera->Set_Clip_Planes( 0.995f, 2.0f );
-
- m_cameraConstraintValid = false;
-
- m_scrollAmountCutoff = TheGlobalData->m_scrollAmountCutoff;
-
-}
-
-//-------------------------------------------------------------------------------------------------
-const Coord3D& W3DView::get3DCameraPosition() const
-{
- Vector3 camera = m_3DCamera->Get_Position();
- static Coord3D pos;
- pos.set( camera.X, camera.Y, camera.Z );
- return pos;
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::reset( void )
-{
- View::reset();
-
- // Just in case...
- setTimeMultiplier(1); // Set time rate back to 1.
-
- 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);
-
- setViewFilter((FilterTypes)0);
-
- Coord2D gb = { 0,0 };
- setGuardBandBias( &gb );
-}
-
-//-------------------------------------------------------------------------------------------------
-/** draw worker for drawables in the view region */
-//-------------------------------------------------------------------------------------------------
-static void drawDrawable( Drawable *draw, void *userData )
-{
-
- draw->draw();
-
-}
-
-// ------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-static void drawTerrainNormal( Drawable *draw, void *userData )
-{
- UnsignedInt color = GameMakeColor( 255, 255, 0, 255 );
- if (TheTerrainLogic)
- {
- Coord3D pos = *draw->getPosition();
- Coord3D normal;
- pos.z = TheTerrainLogic->getGroundHeight(pos.x, pos.y, &normal);
- const Real NORMLEN = 20;
- normal.x = pos.x + normal.x * NORMLEN;
- normal.y = pos.y + normal.y * NORMLEN;
- normal.z = pos.z + normal.z * NORMLEN;
- ICoord2D start, end;
- TheTacticalView->worldToScreen(&pos, &start);
- TheTacticalView->worldToScreen(&normal, &end);
- TheDisplay->drawLine(start.x, start.y, end.x, end.y, 1.0f, color);
- }
-}
-
-#if defined(RTS_DEBUG)
-// ------------------------------------------------------------------------------------------------
-// Draw a crude circle. Appears on top of any world geometry
-// ------------------------------------------------------------------------------------------------
-void drawDebugCircle( const Coord3D & center, Real radius, Real width, Color color )
-{
- const Real inc = PI/4.0f;
- Real angle = 0.0f;
- Coord3D pnt, lastPnt;
- ICoord2D start, end;
- Bool endValid, startValid;
-
- lastPnt.x = center.x + radius * (Real)cos(angle);
- lastPnt.y = center.y + radius * (Real)sin(angle);
- lastPnt.z = center.z;
- endValid = ( TheTacticalView->worldToScreenTriReturn( &lastPnt, &end ) != View::WTS_INVALID );
-
- for( angle = inc; angle <= 2.0f * PI; angle += inc )
- {
- pnt.x = center.x + radius * (Real)cos(angle);
- pnt.y = center.y + radius * (Real)sin(angle);
- pnt.z = center.z;
- startValid = ( TheTacticalView->worldToScreenTriReturn( &pnt, &start ) != View::WTS_INVALID );
-
- if ( startValid && endValid )
- TheDisplay->drawLine( start.x, start.y, end.x, end.y, width, color );
-
- lastPnt = pnt;
- end = start;
- endValid = startValid;
- }
-}
-
-void drawDrawableExtents( Drawable *draw, void *userData ); // FORWARD DECLARATION
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-static void drawContainedDrawable( Object *obj, void *userData )
-{
- Drawable *draw = obj->getDrawable();
-
- if( draw )
- drawDrawableExtents( draw, userData );
-
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-static void drawDrawableExtents( Drawable *draw, void *userData )
-{
- UnsignedInt color = GameMakeColor( 0, 255, 0, 255 );
-
- switch( draw->getDrawableGeometryInfo().getGeomType() )
- {
-
- //---------------------------------------------------------------------------------------------
- case GEOMETRY_BOX:
- {
- Real angle = draw->getOrientation();
- Real c = (Real)cos(angle);
- Real s = (Real)sin(angle);
- Real exc = draw->getDrawableGeometryInfo().getMajorRadius()*c;
- Real eyc = draw->getDrawableGeometryInfo().getMinorRadius()*c;
- Real exs = draw->getDrawableGeometryInfo().getMajorRadius()*s;
- Real eys = draw->getDrawableGeometryInfo().getMinorRadius()*s;
- Coord3D pts[4];
- pts[0].x = draw->getPosition()->x - exc - eys;
- pts[0].y = draw->getPosition()->y + eyc - exs;
- pts[0].z = 0;
- pts[1].x = draw->getPosition()->x + exc - eys;
- pts[1].y = draw->getPosition()->y + eyc + exs;
- pts[1].z = 0;
- pts[2].x = draw->getPosition()->x + exc + eys;
- pts[2].y = draw->getPosition()->y - eyc + exs;
- pts[2].z = 0;
- pts[3].x = draw->getPosition()->x - exc + eys;
- pts[3].y = draw->getPosition()->y - eyc - exs;
- pts[3].z = 0;
- Real z = draw->getPosition()->z;
- for( int i = 0; i < 2; i++ )
- {
-
- for (int corner = 0; corner < 4; corner++)
- {
- ICoord2D start, end;
- pts[corner].z = z;
- pts[(corner+1)&3].z = z;
- TheTacticalView->worldToScreen(&pts[corner], &start);
- TheTacticalView->worldToScreen(&pts[(corner+1)&3], &end);
- TheDisplay->drawLine(start.x, start.y, end.x, end.y, 1.0f, color);
- }
-
- z += draw->getDrawableGeometryInfo().getMaxHeightAbovePosition();
-
- }
-
- break;
-
- }
-
- //---------------------------------------------------------------------------------------------
- case GEOMETRY_SPHERE: // not quite right, but close enough
- case GEOMETRY_CYLINDER:
- {
- Coord3D center = *draw->getPosition();
- const Real radius = draw->getDrawableGeometryInfo().getMajorRadius();
-
- // draw cylinder
- for( int i=0; i<2; i++ )
- {
- drawDebugCircle( center, radius, 1.0f, color );
-
- // next time 'round, draw the top of the cylinder
- center.z += draw->getDrawableGeometryInfo().getMaxHeightAbovePosition();
- }
-
- // draw centerline
- ICoord2D start, end;
- center = *draw->getPosition();
- TheTacticalView->worldToScreen( ¢er, &start );
- center.z += draw->getDrawableGeometryInfo().getMaxHeightAbovePosition();
- TheTacticalView->worldToScreen( ¢er, &end );
- TheDisplay->drawLine( start.x, start.y, end.x, end.y, 1.0f, color );
-
- break;
-
- }
-
- }
-
- // draw any extents for things that are contained by this
- Object *obj = draw->getObject();
- if( obj )
- {
- ContainModuleInterface *contain = obj->getContain();
-
- if( contain )
- contain->iterateContained( drawContainedDrawable, userData, FALSE );
-
- }
-
-}
-
-
-void drawAudioLocations( Drawable *draw, void *userData );
-// ------------------------------------------------------------------------------------------------
-// Helper for drawAudioLocations
-// ------------------------------------------------------------------------------------------------
-static void drawContainedAudioLocations( Object *obj, void *userData )
-{
- Drawable *draw = obj->getDrawable();
-
- if( draw )
- drawAudioLocations( draw, userData );
-
-}
-
-
-//-------------------------------------------------------------------------------------------------
-// Draw the location of audio objects in the world
-//-------------------------------------------------------------------------------------------------
-static void drawAudioLocations( Drawable *draw, void *userData )
-{
- // draw audio for things that are contained by this
- Object *obj = draw->getObject();
- if( obj )
- {
- ContainModuleInterface *contain = obj->getContain();
-
- if( contain )
- contain->iterateContained( drawContainedAudioLocations, userData, FALSE );
-
- }
-
- const ThingTemplate * thingTemplate = draw->getTemplate();
-
- if ( thingTemplate == NULL || thingTemplate->getEditorSorting() != ES_AUDIO )
- {
- return; // All done
- }
-
- // Copied in hideously inappropriate code copying ways from DrawObject.cpp
- // Should definately be a global, probably read in from an INI file
- static const Int poleHeight = 20;
- static const Int flagHeight = 10;
- static const Int flagWidth = 10;
- const Color color = GameMakeColor(0x25, 0x25, 0xEF, 0xFF);
-
- // Draw flag for audio-only objects:
- // *
- // * *
- // * *
- // * *
- // * *
- // * *
- // *
- // *
- // *
- // *
- // *
-
- Coord3D worldPoint;
- ICoord2D start, end;
-
- worldPoint = *draw->getPosition();
- TheTacticalView->worldToScreen( &worldPoint, &start );
- worldPoint.z += poleHeight;
- TheTacticalView->worldToScreen( &worldPoint, &end );
- TheDisplay->drawLine( start.x, start.y, end.x, end.y, 1.0f, color );
-
- worldPoint.z -= flagHeight / 2;
- worldPoint.x += flagWidth;
- TheTacticalView->worldToScreen( &worldPoint, &start );
- TheDisplay->drawLine( start.x, start.y, end.x, end.y, 1.0f, color );
-
- worldPoint.z -= flagHeight / 2;
- worldPoint.x -= flagWidth;
- TheTacticalView->worldToScreen( &worldPoint, &end );
- TheDisplay->drawLine( start.x, start.y, end.x, end.y, 1.0f, color );
-}
-
-//-------------------------------------------------------------------------------------------------
-// Draw the radii of sounds attached to any type of object.
-//-------------------------------------------------------------------------------------------------
-static void drawAudioRadii( const Drawable * drawable )
-{
-
- // Draw radii, if sound is playing
- const AudioEventRTS * ambientSound = drawable->getAmbientSound();
-
- if ( ambientSound && ambientSound->isCurrentlyPlaying() )
- {
- const AudioEventInfo * ambientInfo = ambientSound->getAudioEventInfo();
-
- if ( ambientInfo == NULL )
- {
- // I don't think that's right...
- OutputDebugString( ("Playing sound has NULL AudioEventInfo?\n" ) );
-
- if ( TheAudio != NULL )
- {
- ambientInfo = TheAudio->findAudioEventInfo( ambientSound->getEventName() );
- }
- }
-
- if ( ambientInfo != NULL )
- {
- // Colors match those used in WorldBuilder
- drawDebugCircle( *drawable->getPosition(), ambientInfo->m_minDistance, 1.0f, GameMakeColor(0x00, 0x00, 0xFF, 0xFF) );
- drawDebugCircle( *drawable->getPosition(), ambientInfo->m_maxDistance, 1.0f, GameMakeColor(0xFF, 0x00, 0xFF, 0xFF) );
- }
- }
-}
-
-#endif
-
-//-------------------------------------------------------------------------------------------------
-/** An opportunity to draw something after all drawables have been drawn once */
-//-------------------------------------------------------------------------------------------------
-static void drawablePostDraw( Drawable *draw, void *userData )
-{
- Real FXPitch = TheTacticalView->getFXPitch();
- if (draw->isDrawableEffectivelyHidden() || FXPitch < 0.0f)
- return;
-
- Object* obj = draw->getObject();
- const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
-#if ENABLE_CONFIGURABLE_SHROUD
- ObjectShroudStatus ss = (!obj || !TheGlobalData->m_shroudOn) ? OBJECTSHROUD_CLEAR : obj->getShroudedStatus(localPlayerIndex);
-#else
- ObjectShroudStatus ss = (!obj) ? OBJECTSHROUD_CLEAR : obj->getShroudedStatus(localPlayerIndex);
-#endif
- if (ss > OBJECTSHROUD_PARTIAL_CLEAR)
- return;
-
- // draw the any "icon" UI for a drawable (health bars, veterency, etc);
-
- //*****
- //@TODO: Create a way to reject this call easily -- like objects that have no compatible modules.
- //*****
- //if( draw->getStatusBits() )
- //{
- draw->drawIconUI();
- //}
-
-#if defined(RTS_DEBUG)
- // debug collision extents
- if( TheGlobalData->m_showCollisionExtents )
- drawDrawableExtents( draw, userData );
-
- if ( TheGlobalData->m_showAudioLocations )
- drawAudioLocations( draw, userData );
-#endif
-
- // debug terrain normals at object positions
- if( TheGlobalData->m_showTerrainNormals )
- drawTerrainNormal( draw, userData );
-
- TheGameClient->incrementRenderedObjectCount();
-
-}
-
-//-------------------------------------------------------------------------------------------------
-// Display AI debug visuals
-//-------------------------------------------------------------------------------------------------
-static void renderAIDebug( void )
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-Bool W3DView::updateCameraMovements()
-{
- Bool didUpdate = false;
-
- if (m_doingZoomCamera)
- {
- zoomCameraOneFrame();
- didUpdate = true;
- }
- if (m_doingPitchCamera)
- {
- pitchCameraOneFrame();
- didUpdate = true;
- }
- if (m_doingRotateCamera) {
- m_previousLookAtPosition = *getPosition();
- rotateCameraOneFrame();
- didUpdate = true;
- } else if (m_doingMoveCameraOnWaypointPath) {
- m_previousLookAtPosition = *getPosition();
- // TheSuperHackers @tweak The scripted camera movement is now decoupled from the render update.
- // The scripted camera will still move when the time is frozen, but not when the game is halted.
- moveAlongWaypointPath(TheFramePacer->getLogicTimeStepMilliseconds(FramePacer::IgnoreFrozenTime));
- didUpdate = true;
- }
- if (m_doingScriptedCameraLock)
- {
- didUpdate = true;
- }
- return didUpdate;
-}
-
-
-/** This function performs all actions which affect the camera transform or 3D objects
- rendered in this frame.
-
- MW: I moved this code out out W3DView::draw() so that we can get final camera and object
- positions before any rendering begins. This was necessary so that reflection textures
- (which update before the main rendering loop) could get a correct version of the scene.
- Without this change, the reflections were always 1 frame behind the non-reflected view.
-*/
-void W3DView::updateView(void)
-{
- UPDATE();
-}
-
-// TheSuperHackers @tweak xezon 12/08/2025 The camera shaker is no longer tied to the render
-// update. The shake does sharp shakes on every fixed time step, and is not intended to have
-// linear interpolation during the render update.
-void W3DView::stepView()
-{
- //
- // Process camera shake
- //
- if (m_shakeIntensity > 0.01f)
- {
- m_shakeOffset.x = m_shakeIntensity * m_shakeAngleCos;
- m_shakeOffset.y = m_shakeIntensity * m_shakeAngleSin;
-
- // fake a stiff spring/damper
- const Real dampingCoeff = 0.75f;
- m_shakeIntensity *= dampingCoeff;
-
- // spring is so "stiff", it pulls 180 degrees opposite each frame
- m_shakeAngleCos = -m_shakeAngleCos;
- m_shakeAngleSin = -m_shakeAngleSin;
- }
- else
- {
- m_shakeIntensity = 0.0f;
- m_shakeOffset.x = 0.0f;
- m_shakeOffset.y = 0.0f;
- }
-}
-
-//DECLARE_PERF_TIMER(W3DView_updateView)
-void W3DView::update(void)
-{
- //USE_PERF_TIMER(W3DView_updateView)
- Bool recalcCamera = false;
- Bool didScriptedMovement = false;
-#ifdef LOG_FRAME_TIMES
- __int64 curTime64,freq64;
- static __int64 prevTime64=0;
- QueryPerformanceFrequency((LARGE_INTEGER *)&freq64);
- QueryPerformanceCounter((LARGE_INTEGER *)&curTime64);
- freq64 /= 1000;
-
- Int elapsedTimeMs = (curTime64 - prevTime64)/freq64;
- prevTime64 = curTime64;
-
-#endif
-
-// Int elapsedTimeMs = TheW3DFrameLengthInMsec; // Assume a constant time flow. It just works out better. jba.
-
- if (TheTerrainRenderObject->doesNeedFullUpdate()) {
- RefRenderObjListIterator *it = W3DDisplay::m_3DScene->createLightsIterator();
- TheTerrainRenderObject->updateCenter(m_3DCamera, it);
- if (it)
- {
- W3DDisplay::m_3DScene->destroyLightsIterator(it);
- it = NULL;
- }
- }
-
- static Real followFactor = -1;
- ObjectID cameraLock = getCameraLock();
- if (cameraLock == INVALID_ID)
- {
- followFactor = -1;
- }
- if (cameraLock != INVALID_ID)
- {
- m_doingMoveCameraOnWaypointPath = false;
- Object* cameraLockObj = TheGameLogic->findObjectByID(cameraLock);
- Bool loseLock = false;
-
- // check if object has been destroyed or is dead -> lose lock
- if (cameraLockObj == NULL)
- {
- loseLock = true;
- }
-#if 0
- else
- {
- AIUpdateInterface *ai = cameraLockObj->getAIUpdateInterface();
- if (ai && ai->isDead())
- loseLock = true;
- }
-#endif
-
-
- if (loseLock)
- {
- setCameraLock(INVALID_ID);
- setCameraLockDrawable(NULL);
- followFactor = -1;
- }
- else
- {
- if (followFactor<0) {
- followFactor = 0.05f;
- } else {
- followFactor += 0.05f;
- if (followFactor>1.0f) followFactor = 1.0f;
- }
- if (getCameraLockDrawable() != NULL)
- {
- Drawable* cameraLockDrawable = (Drawable *)getCameraLockDrawable();
-
- if (!cameraLockDrawable)
- {
- setCameraLockDrawable(NULL);
- }
- else
- {
- Coord3D pos;
- Real boundingSphereRadius;
- Matrix3D transform;
- // this method must ONLY be called from the client, NEVER From the logic, not even indirectly.
- if (cameraLockDrawable->clientOnly_getFirstRenderObjInfo(&pos, &boundingSphereRadius, &transform))
- {
- Vector3 zaxis(0,0,1);
-
- Vector3 objPos;
- objPos.X = pos.x;
- objPos.Y = pos.y;
- objPos.Z = pos.z;
-
- //get position of top of object, assuming world z roughly along local z.
- objPos += boundingSphereRadius * 1.0f * zaxis;
- Vector3 objview = transform.Get_X_Vector(); //get view vector of object
- //move camera back behind object far enough not to intersect bounding sphere
- Vector3 camtran = objPos - objview * boundingSphereRadius*4.5f;
-
- Vector3 prevCamTran = m_3DCamera->Get_Position(); //get current camera position.
-
- Vector3 tranDiff = (camtran - prevCamTran); //vector old position to new position.
-
- camtran = prevCamTran + tranDiff * 0.1f; //slowly move camera to new position.
-
- Matrix3D camXForm;
- camXForm.Look_At(camtran,objPos,0);
- m_3DCamera->Set_Transform(camXForm);
-
- recalcCamera = false; //we already did it
- }
- }
- }
- else
- { Coord3D objpos = *cameraLockObj->getPosition();
- Coord3D curpos = *getPosition();
- // don't "snap" directly to the pos, but move there smoothly.
- Real snapThreshSqr = sqr(TheGlobalData->m_partitionCellSize);
- Real curDistSqr = sqr(curpos.x - objpos.x) + sqr(curpos.y - objpos.y);
- if ( m_snapImmediate)
- {
- // close enough.
- curpos.x = objpos.x;
- curpos.y = objpos.y;
- }
- else
- {
-// Real ratio = 1.0f - snapThreshSqr/curDistSqr;
- Real dx = objpos.x-curpos.x;
- Real dy = objpos.y-curpos.y;
- if (m_lockType == LOCK_TETHER)
- {
- //snapThreshSqr = sqr( m_lockDist * TheGlobalData->m_partitionCellSize );
- if (curDistSqr >= snapThreshSqr)
- {
- Real ratio = 1.0f - snapThreshSqr/curDistSqr;
-
- // move halfway there.
- curpos.x += dx*ratio*0.5f;
- curpos.y += dy*ratio*0.5f;
- }
- else
- {
- // we're inside our 'play' tolerance. Move slowly to the obj
- Real ratio = 0.01f * m_lockDist;
- Real dx = objpos.x-curpos.x;
- Real dy = objpos.y-curpos.y;
- curpos.x += dx*ratio;
- curpos.y += dy*ratio;
- }
- }
- else
- {
- curpos.x += dx*followFactor;
- curpos.y += dy*followFactor;
- }
- }
- if (!(TheScriptEngine->isTimeFrozenDebug() || TheScriptEngine->isTimeFrozenScript()) && !TheGameLogic->isGamePaused()) {
- m_previousLookAtPosition = *getPosition();
- }
- setPosition(&curpos);
-
- if (m_lockType == LOCK_FOLLOW)
- {
- // camera follow objects if they are flying
- if (cameraLockObj->isUsingAirborneLocomotor() && cameraLockObj->isAboveTerrainOrWater())
- {
- Matrix3D camXForm;
- Real oldZRot = m_angle;
- Real idealZRot = cameraLockObj->getOrientation() - M_PI_2;
- normAngle(oldZRot);
- normAngle(idealZRot);
- Real diff = idealZRot - oldZRot;
- normAngle(diff);
-
- if (m_snapImmediate)
- {
- m_angle = idealZRot;
- }
- else
- {
- m_angle += diff * 0.1f;
- }
- normAngle(m_angle);
- }
- }
- if (m_snapImmediate)
- m_snapImmediate = FALSE;
-
- m_groundLevel = objpos.z;
- didScriptedMovement = true;
- recalcCamera = true;
- }
- }
- }
-
- if (!(TheScriptEngine->isTimeFrozenDebug()/* || TheScriptEngine->isTimeFrozenScript()*/) && !TheGameLogic->isGamePaused()) {
- // If we aren't frozen for debug, allow the camera to follow scripted movements.
- if (updateCameraMovements()) {
- didScriptedMovement = true;
- recalcCamera = true;
- }
- } else {
- if (m_doingRotateCamera || m_doingMoveCameraOnWaypointPath || m_doingPitchCamera || m_doingZoomCamera || m_doingScriptedCameraLock) {
- didScriptedMovement = true; // don't mess up the scripted movement
- }
- }
- //
- // Process camera shake
- //
- if (m_shakeIntensity > 0.01f)
- {
- recalcCamera = true;
- }
-
- /*
- * In order to have the camera follow the terrain in a non-dizzying way, we will have a
- * "desired height" value that the user sets. While scrolling, the actual height (set by
- * zoom) will not get updated unless we are scrolling uphill and our view either goes
- * underground or higher than the max allowed height. When the camera is at rest (not
- * scrolling), the zoom will move toward matching the desired height.
- */
- // TheSuperHackers @tweak Can now also zoom when the game is paused.
- // TheSuperHackers @tweak The camera zoom speed is now decoupled from the render update.
- // TheSuperHackers @bugfix The camera terrain height adjustment now also works in replay playback.
-
- m_terrainHeightUnderCamera = getHeightAroundPos(m_pos.x, m_pos.y);
- m_currentHeightAboveGround = m_cameraOffset.z * m_zoom - m_terrainHeightUnderCamera;
-
- if (TheTerrainLogic && TheGlobalData && TheInGameUI && m_okToAdjustHeight)
- {
- Real desiredHeight = (m_terrainHeightUnderCamera + 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 (TheInGameUI->isScrolling())
- {
- // if scrolling, only adjust if we're too close or too far
- if (m_scrollAmount.length() < m_scrollAmountCutoff || (m_currentHeightAboveGround < m_minHeightAboveGround) || (TheGlobalData->m_enforceMaxCameraHeight && m_currentHeightAboveGround > m_maxHeightAboveGround))
- {
- const Real fpsRatio = TheFramePacer->getBaseOverUpdateFpsRatio();
- const Real zoomAdj = (desiredZoom - m_zoom) * TheGlobalData->m_cameraAdjustSpeed * fpsRatio;
- if (fabs(zoomAdj) >= 0.0001f) // only do positive
- {
- m_zoom += zoomAdj;
- recalcCamera = true;
- }
- }
- }
- else if (!didScriptedMovement)
- {
- // we're not scrolling; settle toward desired height above ground
- const Real fpsRatio = TheFramePacer->getBaseOverUpdateFpsRatio();
- const Real zoomAdj = (m_zoom - desiredZoom) * TheGlobalData->m_cameraAdjustSpeed * fpsRatio;
- if (fabs(zoomAdj) >= 0.0001f)
- {
- m_zoom -= zoomAdj;
- recalcCamera = true;
- }
- }
- }
- if (TheScriptEngine->isTimeFast()) {
- return; // don't draw - makes it faster :) jba.
- }
- if (recalcCamera)
- setCameraTransform();
-
- Region3D axisAlignedRegion;
- getAxisAlignedViewRegion(axisAlignedRegion);
-
- // render all of the visible Drawables
- /// @todo this needs to use a real region partition or something
- TheGameClient->iterateDrawablesInRegion( &axisAlignedRegion, drawDrawable, NULL );
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Find region which contains all drawables in 3D space. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::getAxisAlignedViewRegion(Region3D &axisAlignedRegion)
-{
- //
- // get the 4 points in 3D space of the 4 corners of the view, we will use a z = 0.0f
- // value so that we can get everything ... even stuff below the terrain
- //
- Coord3D box[ 4 ];
- getScreenCornerWorldPointsAtZ( &box[ 0 ], &box[ 1 ], &box[ 2 ], &box[ 3 ], 0.0f );
-
- //
- // take those 4 corners projected into the world and create an axis aligned bounding
- // box, we will use this box to iterate the drawables in 3D space
- //
- axisAlignedRegion.lo = box[ 0 ];
- axisAlignedRegion.hi = box[ 0 ];
- for( Int i = 0; i < 4; i++ )
- {
-
- if( box[ i ].x < axisAlignedRegion.lo.x )
- axisAlignedRegion.lo.x = box[ i ].x;
- if( box[ i ].y < axisAlignedRegion.lo.y )
- axisAlignedRegion.lo.y = box[ i ].y;
- if( box[ i ].x > axisAlignedRegion.hi.x )
- axisAlignedRegion.hi.x = box[ i ].x;
- if( box[ i ].y > axisAlignedRegion.hi.y )
- axisAlignedRegion.hi.y = box[ i ].y;
-
- }
-
- // low and high regions will be based of the extent of the map
- Region3D mapExtent;
- Real safeValue = 999999;
- TheTerrainLogic->getExtent( &mapExtent );
- axisAlignedRegion.lo.z = mapExtent.lo.z - safeValue;
- axisAlignedRegion.hi.z = mapExtent.hi.z + safeValue;
-
- // we want to overscan a little bit so that we get objects that are partially offscreen
- axisAlignedRegion.lo.x -= (DRAWABLE_OVERSCAN + m_guardBandBias.x);
- axisAlignedRegion.lo.y -= (DRAWABLE_OVERSCAN + m_guardBandBias.y + 60.0f );
- axisAlignedRegion.hi.x += (DRAWABLE_OVERSCAN + m_guardBandBias.x);
- axisAlignedRegion.hi.y += (DRAWABLE_OVERSCAN + m_guardBandBias.y);
-
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void W3DView::setFadeParameters(Int fadeFrames, Int direction)
-{
- ScreenBWFilter::setFadeParameters(fadeFrames, direction);
- ScreenCrossFadeFilter::setFadeParameters(fadeFrames,direction);
-}
-
-void W3DView::set3DWireFrameMode(Bool enable)
-{
- m_nextWireFrameEnabled = enable;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Sets the view filter mode. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setViewFilterPos(const Coord3D *pos)
-{
- ScreenMotionBlurFilter::setZoomToPos(pos);
-}
-//-------------------------------------------------------------------------------------------------
-/** Sets the view filter mode. */
-//-------------------------------------------------------------------------------------------------
-Bool W3DView::setViewFilterMode(FilterModes filterMode)
-{
- FilterModes oldMode = m_viewFilterMode; //save previous mode in case setup fails.
-
- m_viewFilterMode = filterMode;
- if (m_viewFilterMode != FM_NULL_MODE &&
- m_viewFilter != FT_NULL_FILTER) {
- if (!W3DShaderManager::filterSetup(m_viewFilter, m_viewFilterMode))
- { //setup failed so restore previous mode.
- m_viewFilterMode = oldMode;
- return FALSE;
- }
- }
- return TRUE;
-}
-//-------------------------------------------------------------------------------------------------
-/** Sets the view filter. */
-//-------------------------------------------------------------------------------------------------
-Bool W3DView::setViewFilter(FilterTypes filter)
-{
- FilterTypes oldFilter = m_viewFilter; //save previous filter in case setup fails.
-
- m_viewFilter = filter;
- if (m_viewFilterMode != FM_NULL_MODE &&
- m_viewFilter != FT_NULL_FILTER) {
- if (!W3DShaderManager::filterSetup(m_viewFilter, m_viewFilterMode))
- { //setup failed so restore previous mode.
- m_viewFilter = oldFilter;
- return FALSE;
- };
- }
- return TRUE;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Calculates how many pixels we scrolled since last frame for motion blur calculations. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::calcDeltaScroll(Coord2D &screenDelta)
-{
- screenDelta.x = 0;
- screenDelta.y = 0;
- Vector3 prevPos(m_previousLookAtPosition.x,m_previousLookAtPosition.y, m_groundLevel);
- Vector3 prevScreen;
- if (m_3DCamera->Project( prevScreen, prevPos ) != CameraClass::INSIDE_FRUSTUM)
- {
- return;
- }
- Vector3 pos(m_pos.x,m_pos.y, m_groundLevel);
- Vector3 screen;
- if (m_3DCamera->Project( screen, pos ) != CameraClass::INSIDE_FRUSTUM)
- {
- return;
- }
- screenDelta.x = screen.X-prevScreen.X;
- screenDelta.y = screen.Y-prevScreen.Y;
-}
-
-
-//-------------------------------------------------------------------------------------------------
-/** Draw member for the W3D window, this will literally draw the window
- * for this view */
-//-------------------------------------------------------------------------------------------------
-void W3DView::drawView( void )
-{
- DRAW();
-}
-
-//DECLARE_PERF_TIMER(W3DView_drawView)
-void W3DView::draw( void )
-{
- //USE_PERF_TIMER(W3DView_drawView)
- Bool skipRender = false;
- Bool doExtraRender = false;
- CustomScenePassModes customScenePassMode = SCENE_PASS_DEFAULT;
-
- if (m_viewFilterMode &&
- m_viewFilter > FT_NULL_FILTER &&
- m_viewFilter < FT_MAX)
- {
- // Most likely will redirect rendering to a texture.
- W3DShaderManager::filterPreRender(m_viewFilter, skipRender, customScenePassMode);
- if (!skipRender && getCameraLock())
- {
- Object* cameraLockObj = TheGameLogic->findObjectByID(getCameraLock());
- if (cameraLockObj)
- {
- Drawable *drawable = cameraLockObj->getDrawable();
- drawable->setDrawableHidden(true);
- }
- }
- }
-
- if (!skipRender)
- {
- // Render 3D scene from our camera
- W3DDisplay::m_3DScene->setCustomPassMode(customScenePassMode);
- if (m_isWireFrameEnabled)
- W3DDisplay::m_3DScene->Set_Extra_Pass_Polygon_Mode(SceneClass::EXTRA_PASS_CLEAR_LINE);
- W3DDisplay::m_3DScene->doRender( m_3DCamera );
- W3DDisplay::m_3DScene->Set_Extra_Pass_Polygon_Mode(SceneClass::EXTRA_PASS_DISABLE);
- m_isWireFrameEnabled = m_nextWireFrameEnabled;
- }
-
- if (m_viewFilterMode &&
- m_viewFilter > FT_NULL_FILTER &&
- m_viewFilter < FT_MAX)
- {
- Coord2D deltaScroll;
- calcDeltaScroll(deltaScroll);
- Bool continueTheEffect;
- continueTheEffect = W3DShaderManager::filterPostRender(m_viewFilter, m_viewFilterMode, deltaScroll,doExtraRender);
- if (!skipRender && getCameraLock())
- {
- Object* cameraLockObj = TheGameLogic->findObjectByID(getCameraLock());
- if (cameraLockObj)
- {
- Drawable *drawable = cameraLockObj->getDrawable();
- drawable->setDrawableHidden(false);
- RenderInfoClass rinfo(*m_3DCamera);
- // Apply the camera and viewport (including depth range)
- m_3DCamera->Apply();
- TheDX8MeshRenderer.Set_Camera(&rinfo.Camera);
- W3DDisplay::m_3DScene->renderSpecificDrawables(rinfo, 1, &drawable);
- WW3D::Flush(rinfo);
- }
- }
- if (!continueTheEffect)
- {
- // shut it down.
- m_viewFilter = FT_NULL_FILTER;
- m_viewFilterMode = FM_NULL_MODE;
- }
- }
-
- //Some effects require that we render a modified version of the scene into a texture but also require
- //an unaltered version in the framebuffer. So we re-render again into framebuffer after texture rendering
- //was turned off by filterPostRender().
- if (doExtraRender)
- {
- //Reset to normal scene rendering.
- //The pass that rendered into a texture may have left the z-buffer in a weird state
- //so clear it before rendering normal scene.
- ///@todo: Don't clear z-buffer unless shader uses z-bias or anything else that would cause <= z to fail on normal render.
- DX8Wrapper::Clear(false, true, Vector3(0.0f,0.0f,0.0f), TheWaterTransparency->m_minWaterOpacity); // Clear z but not color
- W3DDisplay::m_3DScene->setCustomPassMode(SCENE_PASS_DEFAULT);
- W3DDisplay::m_3DScene->doRender( m_3DCamera );
- Coord2D deltaScroll;
- W3DShaderManager::filterPostRender(m_viewFilter, m_viewFilterMode, deltaScroll, doExtraRender);
- }
-
- if( TheGlobalData->m_debugAI )
- {
- if (TheAI->pathfinder()->getDebugPath())
- {
- // setup screen clipping region
- IRegion2D clipRegion;
- clipRegion.lo.x = 0;
- clipRegion.lo.y = 0;
- clipRegion.hi.x = getWidth();
- clipRegion.hi.y = getHeight();
-
- UnsignedInt color = 0xFFFFFF00; //0xAARRGGBB
- ICoord2D start, end;
- PathNode *prevNode = TheAI->pathfinder()->getDebugPath()->getFirstNode();
-
- if (worldToScreen( prevNode->getPosition(), &start )) {
- TheDisplay->drawLine( start.x-3, start.y-3, start.x+3, start.y-3, 1.0f, color );
- TheDisplay->drawLine( start.x+3, start.y-3, start.x+3, start.y+3, 1.0f, color );
- TheDisplay->drawLine( start.x+3, start.y+3, start.x-3, start.y+3, 1.0f, color );
- TheDisplay->drawLine( start.x-3, start.y+3, start.x-3, start.y-3, 1.0f, color );
- }
- for( PathNode *node = prevNode->getNext(); node; node = node->getNext() )
- {
- Int k;
- Coord3D s, e;
- Coord3D delta;
- s = *node->getPosition();
- e = *prevNode->getPosition();
- delta.x = e.x-s.x;
- delta.y = e.y-s.y;
- delta.z = e.z-s.z;
- for (k = 0; k<10; k++) {
- Real factor1 = (k)/10.0;
- Real factor2 = (k+1)/10.0;
- s = *node->getPosition();
- e = *node->getPosition();
- s.x += delta.x*factor1;
- s.y += delta.y*factor1;
- s.z += delta.z*factor1;
- e.x += delta.x*factor2;
- e.y += delta.y*factor2;
- e.z += delta.z*factor2;
- Bool onScreen1 = worldToScreen( &e, &end );
- Bool onScreen2 = worldToScreen( &s, &start );
- if (!onScreen1 && !onScreen2) {
- continue; // neither point visible.
- }
- ICoord2D clipStart, clipEnd;
-
- if( ClipLine2D( &start, &end, &clipStart, &clipEnd, &clipRegion ) ) {
- TheDisplay->drawLine( clipStart.x, clipStart.y, clipEnd.x, clipEnd.y, 1.0f, color );
- }
- }
- prevNode = node;
- if (node->getNext()) {
- if (worldToScreen( node->getPosition(), &start )) {
- TheDisplay->drawLine( start.x-4, start.y, start.x+3, start.y, 1.0f, color );
- }
- }
- }
- if (prevNode && worldToScreen( prevNode->getPosition(), &start )) {
- TheDisplay->drawLine( start.x-4, start.y, start.x+3, start.y, 1.0f, color );
- TheDisplay->drawLine( start.x, start.y-4, start.x, start.y+3, 1.0f, color );
- }
- color = 0xFFFF0000; //0xAARRGGBB
- if (worldToScreen( TheAI->pathfinder()->getDebugPathPosition(), &start )) {
- TheDisplay->drawLine( start.x-3, start.y, start.x+3, start.y, 1.0f, color );
- TheDisplay->drawLine( start.x, start.y-3, start.x, start.y+3, 1.0f, color );
- }
- }
-
- }
-
-#if defined(RTS_DEBUG)
- if( TheGlobalData->m_debugCamera )
- {
- UnsignedInt c = 0xaaffffff;
- Coord3D worldPos = *getPosition();
- worldPos.z = TheTerrainLogic->getGroundHeight(worldPos.x, worldPos.y);
-
- Coord3D p1, p2;
- ICoord2D s1, s2;
- p1 = worldPos;
- p1.x += TERRAIN_SAMPLE_SIZE;
- p1.y += TERRAIN_SAMPLE_SIZE;
- p1.z = TheTerrainLogic->getGroundHeight(p1.x, p1.y);
- p2 = worldPos;
- p2.x += TERRAIN_SAMPLE_SIZE;
- p2.y -= TERRAIN_SAMPLE_SIZE;
- p2.z = TheTerrainLogic->getGroundHeight(p2.x, p2.y);
- worldToScreen( &p1, &s1 );
- worldToScreen( &p2, &s2 );
- TheDisplay->drawLine(s1.x, s1.y, s2.x, s2.y, 1.0f, c);
-
- p1 = worldPos;
- p1.x += TERRAIN_SAMPLE_SIZE;
- p1.y -= TERRAIN_SAMPLE_SIZE;
- p1.z = TheTerrainLogic->getGroundHeight(p1.x, p1.y);
- p2 = worldPos;
- p2.x -= TERRAIN_SAMPLE_SIZE;
- p2.y -= TERRAIN_SAMPLE_SIZE;
- p2.z = TheTerrainLogic->getGroundHeight(p2.x, p2.y);
- worldToScreen( &p1, &s1 );
- worldToScreen( &p2, &s2 );
- TheDisplay->drawLine(s1.x, s1.y, s2.x, s2.y, 1.0f, c);
-
- p1 = worldPos;
- p1.x -= TERRAIN_SAMPLE_SIZE;
- p1.y -= TERRAIN_SAMPLE_SIZE;
- p1.z = TheTerrainLogic->getGroundHeight(p1.x, p1.y);
- p2 = worldPos;
- p2.x -= TERRAIN_SAMPLE_SIZE;
- p2.y += TERRAIN_SAMPLE_SIZE;
- p2.z = TheTerrainLogic->getGroundHeight(p2.x, p2.y);
- worldToScreen( &p1, &s1 );
- worldToScreen( &p2, &s2 );
- TheDisplay->drawLine(s1.x, s1.y, s2.x, s2.y, 1.0f, c);
-
- p1 = worldPos;
- p1.x -= TERRAIN_SAMPLE_SIZE;
- p1.y += TERRAIN_SAMPLE_SIZE;
- p1.z = TheTerrainLogic->getGroundHeight(p1.x, p1.y);
- p2 = worldPos;
- p2.x += TERRAIN_SAMPLE_SIZE;
- p2.y += TERRAIN_SAMPLE_SIZE;
- p2.z = TheTerrainLogic->getGroundHeight(p2.x, p2.y);
- worldToScreen( &p1, &s1 );
- worldToScreen( &p2, &s2 );
- TheDisplay->drawLine(s1.x, s1.y, s2.x, s2.y, 1.0f, c);
-
- }
-
- if ( TheGlobalData->m_showAudioLocations )
- {
- // Draw audio radii for ALL drawables, not just those on screen
- const Drawable * drawable = TheGameClient->getDrawableList();
-
- while ( drawable != NULL )
- {
- drawAudioRadii( drawable );
- drawable = drawable->getNextDrawable();
- }
- }
-#endif // RTS_DEBUG
-
- Region3D axisAlignedRegion;
- getAxisAlignedViewRegion(axisAlignedRegion);
-
- //
- // there are several things we might want to do as a post pass on the objects after
- // they are all drawn
- /// @todo we might want to consider wiping this iterate out if there is nothing to post draw
- //
- TheGameClient->resetRenderedObjectCount();
- TheGameClient->iterateDrawablesInRegion( &axisAlignedRegion, drawablePostDraw, this );
-
- TheGameClient->flushTextBearingDrawables();
-
- // Render 2D scene
- W3DDisplay::m_2DScene->doRender( m_2DCamera );
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void W3DView::setCameraLock(ObjectID id)
-{
- // If we're disabling camera movements, don't lock onto the object.
- if (TheGlobalData->m_disableCameraMovement && id!=INVALID_ID) {
- return;
- }
- View::setCameraLock(id);
- m_doingScriptedCameraLock = FALSE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void W3DView::setSnapMode( CameraLockType lockType, Real lockDist )
-{
- View::setSnapMode(lockType, lockDist);
- m_doingScriptedCameraLock = TRUE;
-}
-
-//-------------------------------------------------------------------------------------------------
-// Scroll the view by the given delta in SCREEN COORDINATES, this interface
-// assumes we will be scrolling along the X,Y plane
-//
-// 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 )
-{
- // if we haven't moved, ignore
- if( delta && (delta->x != 0 || delta->y != 0) )
- {
- constexpr const Real SCROLL_RESOLUTION = 250.0f;
-
- Vector3 world, worldStart, worldEnd;
- Vector2 start, end;
-
- m_scrollAmount = *delta;
-
- start.X = getWidth();
- start.Y = getHeight();
-
- end.X = start.X + delta->x * SCROLL_RESOLUTION;
- end.Y = start.Y + delta->y * SCROLL_RESOLUTION;
-
- m_3DCamera->Device_To_View_Space( start, &worldStart );
- m_3DCamera->Device_To_View_Space( end, &worldEnd );
-
- const Real zRotation = m_3DCamera->Get_Transform().Get_Z_Rotation();
- worldStart.Rotate_Z(zRotation);
- worldEnd.Rotate_Z(zRotation);
-
- world.X = worldEnd.X - worldStart.X;
- world.Y = worldEnd.Y - worldStart.Y;
- world.Z = worldEnd.Z - worldStart.Z;
-
- // scroll by delta
- Coord3D pos = *getPosition();
- pos.x += world.X;
- pos.y += world.Y;
- //DEBUG_LOG(("Delta %.2f, %.2f", world.X, world.Z));
- // no change to z
- setPosition(&pos);
-
- //m_cameraConstraintValid = false; // pos change does NOT invalidate cam constraints
-
- m_doingRotateCamera = false;
- // set new camera position
- setCameraTransform();
-
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::forceRedraw()
-{
-
- // set the camera
- setCameraTransform();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Rotate the view around the up axis to the given angle. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setAngle( Real angle )
-{
- // Normalize to +-PI.
- normAngle(angle);
- // call our base class, we are adding functionality
- View::setAngle( angle );
-
-
- m_doingMoveCameraOnWaypointPath = false;
- m_doingRotateCamera = false;
- m_doingPitchCamera = false;
- m_doingZoomCamera = false;
- m_doingScriptedCameraLock = false;
- // set the camera
- setCameraTransform();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Rotate the view around the horizontal (X) axis to the given angle. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setPitch( Real angle )
-{
- // call our base class, we are extending functionality
- View::setPitch( angle );
-
-
- m_doingMoveCameraOnWaypointPath = false;
- m_doingRotateCamera = false;
- m_doingPitchCamera = false;
- m_doingZoomCamera = false;
- m_doingScriptedCameraLock = false;
- // set the camera
- setCameraTransform();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Set the view angle & pitch back to default */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setAngleAndPitchToDefault( void )
-{
- // call our base class, we are adding functionality
- View::setAngleAndPitchToDefault();
-
- m_FXPitch = 1.0;
-
- // set the camera
- setCameraTransform();
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::setDefaultView(Real pitch, Real angle, Real maxHeight)
-{
- // MDC - we no longer want to rotate maps (design made all of them right to begin with)
- // m_defaultAngle = angle * M_PI/180.0f;
- m_defaultPitchAngle = pitch;
- m_maxHeightAboveGround = TheGlobalData->m_maxCameraHeight*maxHeight;
- if (m_minHeightAboveGround > m_maxHeightAboveGround)
- m_maxHeightAboveGround = m_minHeightAboveGround;
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::setHeightAboveGround(Real z)
-{
- View::setHeightAboveGround(z);
-
- m_doingMoveCameraOnWaypointPath = false;
- m_doingRotateCamera = false;
- m_doingPitchCamera = false;
- m_doingZoomCamera = false;
- m_doingScriptedCameraLock = false;
- m_cameraConstraintValid = false; // recalc it.
- setCameraTransform();
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-// TheSuperHackers @bugfix xezon 18/09/2025 setZoom is no longer clamped by a min and max zoom.
-// Instead the min and max camera height will be clamped elsewhere. Clamping the zoom would cause
-// issues with camera playback in replay playback where changes in terrain elevation would not raise
-// the camera height.
-void W3DView::setZoom(Real z)
-{
- View::setZoom(z);
-
- m_doingMoveCameraOnWaypointPath = false;
- m_doingRotateCamera = false;
- m_doingPitchCamera = false;
- m_doingZoomCamera = false;
- m_doingScriptedCameraLock = false;
- m_cameraConstraintValid = false; // recalc it.
- setCameraTransform();
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::setZoomToDefault( void )
-{
- // default zoom has to be max, otherwise players will just zoom to max always
-
- // terrain height + desired height offset == cameraOffset * actual zoom
- // find best approximation of max terrain height we can see
- Real terrainHeightMax = getHeightAroundPos(m_pos.x, m_pos.y);
-
- Real desiredHeight = (terrainHeightMax + m_maxHeightAboveGround);
- Real desiredZoom = desiredHeight / m_cameraOffset.z;
-
- m_mcwpInfo.cameraZoom[2] = desiredZoom;//m_maxZoom;
- DEBUG_LOG(("W3DView::setZoomToDefault() Current zoom: %g Desired zoom: %g", m_zoom, desiredZoom));
-
- m_zoom = desiredZoom;
- m_heightAboveGround = m_maxHeightAboveGround;
-
- m_doingMoveCameraOnWaypointPath = false;
- m_doingRotateCamera = false;
- m_doingPitchCamera = false;
- m_doingZoomCamera = false;
- m_doingScriptedCameraLock = false;
- m_cameraConstraintValid = false; // recalc it.
- setCameraTransform();
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Set the horizontal field of view angle */
-//-------------------------------------------------------------------------------------------------
-void W3DView::setFieldOfView( Real angle )
-{
- View::setFieldOfView( angle );
-
-#if defined(RTS_DEBUG)
- // this is only for testing, and recalculating the
- // camera every frame is wasteful
- setCameraTransform();
-#endif
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Using the W3D camera translate the world coordinate to a screen coord.
- Screen coordinates returned in absolute values relative to full display resolution.
- Returns if the point is on screen, off screen, or not transformable */
-//-------------------------------------------------------------------------------------------------
-View::WorldToScreenReturn W3DView::worldToScreenTriReturn( const Coord3D *w, ICoord2D *s )
-{
- // sanity
- if( w == NULL || s == NULL )
- return WTS_INVALID;
-
- if( m_3DCamera )
- {
- Vector3 world;
- Vector3 screen;
-
- world.Set( w->x, w->y, w->z );
- enum CameraClass::ProjectionResType projection = m_3DCamera->Project( screen, world );
- if (projection != CameraClass::INSIDE_FRUSTUM && projection!=CameraClass::OUTSIDE_FRUSTUM)
- {
- // Can't get a valid number if it's beyond the clip planes. jba
- s->x = 0;
- s->y = 0;
- return WTS_INVALID;
- }
-
- //
- // note that the screen coord returned from the project W3D camera
- // gave us a screen coords that range from (-1,-1) bottom left to
- // (1,1) top right ... we are turning that into (0,0) upper left
- // coords now
- //
- W3DLogicalScreenToPixelScreen( screen.X, screen.Y,
- &s->x, &s->y,
- getWidth(), getHeight());
- s->x += m_originX; //convert viewport coordinates to full screen coordinates
- s->y += m_originY;
-
-// s->x = (getWidth() * (screen.X + 1.0f)) / 2.0f;
-// s->y = (getHeight() * (-screen.Y + 1.0f)) / 2.0f;
- if (projection != CameraClass::INSIDE_FRUSTUM)
- {
- return WTS_OUTSIDE_FRUSTUM;
- }
-
- return WTS_INSIDE_FRUSTUM;
-
- }
-
- return WTS_INVALID;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Using the W3D camera translate the screen coord to world coord */
-//-------------------------------------------------------------------------------------------------
-void W3DView::screenToWorld( const ICoord2D *s, Coord3D *w )
-{
-
- // sanity
- if( s == NULL || w == NULL )
- return;
-
- if( m_3DCamera )
- {
- DEBUG_CRASH(("implement me"));
- }
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** all the drawables in the view, that fall within the 2D screen region
- * will call the callback function. The number of drawables that passed
- * the test are returned.
- Screen coordinates assumed in absolute values relative to full display resolution. */
-//-------------------------------------------------------------------------------------------------
-Int W3DView::iterateDrawablesInRegion( IRegion2D *screenRegion,
- Bool (*callback)( Drawable *draw, void *userData ),
- void *userData )
-{
- Bool inside = FALSE;
- Int count = 0;
- Drawable *draw;
- Vector3 screen, world;
- Coord3D pos;
- Region2D normalizedRegion;
-
- /** @todo we need to have partitions of which drawables are in the
- view so we don't have to march through the whole list */
-
- //
- // to do this we are projecting the drawable centers onto the screen,
- // the W3D camera->project method is used to do this and that method
- // will return normalized screen coords from (-1,-1) bottom left to
- // (1,1) top right, normalize our screen region for comparison
- //
- /// @todo use fast int->real type casts here later
-
- Bool regionIsPoint = FALSE;
-
- if( screenRegion )
- {
- if (screenRegion->height() == 0 && screenRegion->width() == 0)
- {
- regionIsPoint = TRUE;
- }
-
- normalizedRegion.lo.x = ((Real)(screenRegion->lo.x - m_originX) / (Real)getWidth()) * 2.0f - 1.0f;
- normalizedRegion.lo.y = -(((Real)(screenRegion->hi.y - m_originY) / (Real)getHeight()) * 2.0f - 1.0f);
- normalizedRegion.hi.x = ((Real)(screenRegion->hi.x - m_originX) / (Real)getWidth()) * 2.0f - 1.0f;
- normalizedRegion.hi.y = -(((Real)(screenRegion->lo.y - m_originY) / (Real)getHeight()) * 2.0f - 1.0f);
-
- }
-
-
- Drawable *onlyDrawableToTest = NULL;
- if (regionIsPoint)
- {
- // Allow all drawables to be picked.
- onlyDrawableToTest = pickDrawable(&screenRegion->lo, TRUE, (PickType) getPickTypesForContext(TheInGameUI->isInForceAttackMode()));
- if (onlyDrawableToTest == NULL) {
- return 0;
- }
- }
-
- for( draw = TheGameClient->firstDrawable();
- draw;
- draw = draw->getNextDrawable() )
- {
- if (onlyDrawableToTest)
- {
- draw = onlyDrawableToTest;
- inside = TRUE;
- }
- else
- {
-
- // not inside
- inside = FALSE;
-
- // no screen region, means all drawbles
- if( screenRegion == NULL )
- inside = TRUE;
- else
- {
-
- // project the center of the drawable to the screen
- /// @todo use a real 3D position in the drawable
- pos = *draw->getPosition();
- world.X = pos.x;
- world.Y = pos.y;
- world.Z = pos.z;
-
- // project the world point to the screen
- if( m_3DCamera->Project( screen, world ) == CameraClass::INSIDE_FRUSTUM &&
- screen.X >= normalizedRegion.lo.x &&
- screen.X <= normalizedRegion.hi.x &&
- screen.Y >= normalizedRegion.lo.y &&
- screen.Y <= normalizedRegion.hi.y )
- {
-
- inside = TRUE;
-
- }
- }
-
- }
-
- // if inside do the callback and count up
- if( inside )
- {
-
- if( callback( draw, userData ) )
- ++count;
-
- }
-
- // If onlyDrawableToTest, then we should bail out now.
- if (onlyDrawableToTest != NULL)
- break;
-
- }
-
- return count;
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** cast a ray from the screen coords into the scene and return a drawable
- * there if present. Screen coordinates assumed in absolute values relative
- * to full display resolution. */
-//-------------------------------------------------------------------------------------------------
-Drawable *W3DView::pickDrawable( const ICoord2D *screen, Bool forceAttack, PickType pickType )
-{
- RenderObjClass *renderObj = NULL;
- Drawable *draw = NULL;
- DrawableInfo *drawInfo = NULL;
-
- // sanity
- if( screen == NULL )
- return NULL;
-
- // don't pick a drawable if there is a window under the cursor
- GameWindow *window = NULL;
- if (TheWindowManager)
- window = TheWindowManager->getWindowUnderCursor(screen->x, screen->y);
-
- while (window)
- {
- // check to see if it or any of its parents are opaque. If so, we can't select anything.
- if (!BitIsSet( window->winGetStatus(), WIN_STATUS_SEE_THRU ))
- return NULL;
-
- window = window->winGetParent();
- }
-
- Vector3 rayStart,rayEnd;
- getPickRay(screen,&rayStart,&rayEnd);
-
- LineSegClass lineseg;
- lineseg.Set(rayStart,rayEnd);
-
- CastResultStruct result;
-
- if (forceAttack)
- result.ComputeContactPoint = true;
-
- //Don't check against translucent or hidden objects
- RayCollisionTestClass raytest(lineseg,&result,COLL_TYPE_ALL,false,false);
-
- if( W3DDisplay::m_3DScene->castRay( raytest, false, (Int)pickType ) )
- renderObj = raytest.CollidedRenderObj;
-
- // for right now there is no drawable data in a render object which is // if we've found a render object, return our drawable associated with it,
-
- // the terrain, therefore the userdata is NULL
- /// @todo terrain and picking!
- if( renderObj )
- drawInfo = (DrawableInfo *)renderObj->Get_User_Data();
- if (drawInfo)
- draw=drawInfo->m_drawable;
-
- return draw;
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** convert a pixel (x,y) to a location in the world on the terrain.
- Screen coordinates assumed in absolute values relative to full display resolution. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::screenToTerrain( const ICoord2D *screen, Coord3D *world )
-{
- // sanity
- if( screen == NULL || world == NULL || TheTerrainRenderObject == NULL )
- return;
-
- if (m_cameraHasMovedSinceRequest) {
- m_locationRequests.clear();
- m_cameraHasMovedSinceRequest = false;
- }
-
- if (m_locationRequests.size() > MAX_REQUEST_CACHE_SIZE) {
- m_locationRequests.erase(m_locationRequests.begin(), m_locationRequests.begin() + 10);
- }
-
-
- // We insert them at the end for speed (no copies needed), but using the princ of locality, we should
- // start searching where we most recently inserted
- for (int i = m_locationRequests.size() - 1; i >= 0; --i) {
- if (m_locationRequests[i].first.x == screen->x && m_locationRequests[i].first.y == screen->y) {
- (*world) = m_locationRequests[i].second;
- return;
- }
- }
-
- Vector3 rayStart,rayEnd;
- LineSegClass lineseg;
- CastResultStruct result;
- Vector3 intersection(0,0,0);
-
- getPickRay(screen,&rayStart,&rayEnd);
-
- lineseg.Set(rayStart,rayEnd);
-
- RayCollisionTestClass raytest(lineseg,&result);
-
- if( TheTerrainRenderObject->Cast_Ray(raytest) )
- {
- // get the point of intersection according to W3D
- intersection = result.ContactPoint;
-
- }
-
- // Pick bridges.
- Vector3 bridgePt;
- Drawable *bridge = TheTerrainLogic->pickBridge(rayStart, rayEnd, &bridgePt);
- if (bridge && bridgePt.Z > intersection.Z) {
- intersection = bridgePt;
- }
-
- world->x = intersection.X;
- world->y = intersection.Y;
- world->z = intersection.Z;
-
- PosRequest req;
- req.first = (*screen);
- req.second = (*world);
- m_locationRequests.push_back(req); // Insert this request at the end, requires no extra copies
-
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-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);
-
- if (o->z > PATHFIND_CELL_SIZE_F+TheTerrainLogic->getGroundHeight(pos.x, pos.y)) {
- // Pos.z is not used, so if we want to look at something off the ground,
- // we have to look at the spot on the ground such that the object intersects
- // with the look at vector in the center of the screen. jba.
- Vector3 rayStart,rayEnd;
- LineSegClass lineseg;
- CastResultStruct result;
- Vector3 intersection(0,0,0);
-
- rayStart = m_3DCamera->Get_Position(); //get camera location
- m_3DCamera->Un_Project(rayEnd,Vector2(0.0f,0.0f)); //get world space point
- rayEnd -= rayStart; //vector camera to world space point
- rayEnd.Normalize(); //make unit vector
- rayEnd *= m_3DCamera->Get_Depth(); //adjust length to reach far clip plane
- rayStart.Set(pos.x, pos.y, pos.z);
- rayEnd += rayStart; //get point on far clip plane along ray from camera.
- lineseg.Set(rayStart,rayEnd);
-
- RayCollisionTestClass raytest(lineseg,&result);
-
- if( TheTerrainRenderObject->Cast_Ray(raytest) )
- {
- // get the point of intersection according to W3D
- pos.x = result.ContactPoint.X;
- pos.y = result.ContactPoint.Y;
-
- }
- }
- pos.z = 0;
- setPosition(&pos);
- m_doingRotateCamera = false;
- m_doingMoveCameraOnWaypointPath = false;
- m_doingScriptedCameraLock = false;
-
- setCameraTransform();
-
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::initHeightForMap( void )
-{
- m_groundLevel = TheTerrainLogic->getGroundHeight(m_pos.x, m_pos.y);
- const Real MAX_GROUND_LEVEL = 120.0; // jba - starting ground level can't exceed this height.
- if (m_groundLevel>MAX_GROUND_LEVEL) {
- m_groundLevel = MAX_GROUND_LEVEL;
- }
-
- m_cameraOffset.z = m_groundLevel+TheGlobalData->m_cameraHeight;
- m_cameraOffset.y = -(m_cameraOffset.z / tan(TheGlobalData->m_cameraPitch * (PI / 180.0)));
- m_cameraOffset.x = -(m_cameraOffset.y * tan(TheGlobalData->m_cameraYaw * (PI / 180.0)));
- m_cameraConstraintValid = false; // possible ground level change invalidates cam constraints
- setCameraTransform();
-
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Move camera to in an interesting fashion. Sets up parameters that get
- * evaluated in draw(). */
-//-------------------------------------------------------------------------------------------------
-void W3DView::moveCameraTo(const Coord3D *o, Int milliseconds, Int shutter, Bool orient)
-{
- m_mcwpInfo.waypoints[0] = *getPosition();
- m_mcwpInfo.cameraAngle[0] = getAngle();
- m_mcwpInfo.waySegLength[0] = 0;
-
- m_mcwpInfo.waypoints[1] = *getPosition();
- m_mcwpInfo.waySegLength[1] = 0;
-
- m_mcwpInfo.waypoints[2] = *o;
- m_mcwpInfo.waySegLength[2] = 0;
-
- m_mcwpInfo.numWaypoints = 2;
- if (milliseconds<1) milliseconds = 1;
- m_mcwpInfo.totalTimeMilliseconds = milliseconds;
- m_mcwpInfo.shutter = 1;
- m_mcwpInfo.curSegment = 1;
- m_mcwpInfo.curSegDistance = 0;
- m_mcwpInfo.totalDistance = 0;
-
- setupWaypointPath(orient);
- if (m_mcwpInfo.totalTimeMilliseconds==1) {
- // do it instantly.
- moveAlongWaypointPath(1);
- m_doingMoveCameraOnWaypointPath = true;
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Rotate the camera */
-//-------------------------------------------------------------------------------------------------
-void W3DView::rotateCamera(Real rotations, Int milliseconds)
-{
- m_rcInfo.numHoldFrames = 0;
- m_rcInfo.trackObject = FALSE;
-
- if (milliseconds<1) milliseconds = 1;
- m_rcInfo.numFrames = milliseconds/TheW3DFrameLengthInMsec;
- if (m_rcInfo.numFrames < 1) {
- m_rcInfo.numFrames = 1;
- }
- m_rcInfo.curFrame = 0;
- m_doingRotateCamera = true;
- m_rcInfo.angle = 2*PI*rotations/m_rcInfo.numFrames;
- m_rcInfo.startTimeMultiplier = m_timeMultiplier;
- m_rcInfo.endTimeMultiplier = m_timeMultiplier;
-
- m_doingMoveCameraOnWaypointPath = false;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Rotate the camera to follow a unit */
-//-------------------------------------------------------------------------------------------------
-void W3DView::rotateCameraTowardObject(ObjectID id, Int milliseconds, Int holdMilliseconds)
-{
- m_rcInfo.trackObject = TRUE;
- if (holdMilliseconds<1) holdMilliseconds = 0;
- m_rcInfo.numHoldFrames = holdMilliseconds/TheW3DFrameLengthInMsec;
- if (m_rcInfo.numHoldFrames < 1) {
- m_rcInfo.numHoldFrames = 0;
- }
-
- if (milliseconds<1) milliseconds = 1;
- m_rcInfo.numFrames = milliseconds/TheW3DFrameLengthInMsec;
- if (m_rcInfo.numFrames < 1) {
- m_rcInfo.numFrames = 1;
- }
- m_rcInfo.curFrame = 0;
- m_doingRotateCamera = true;
- m_rcInfo.angle = m_angle; // not used here
- m_rcInfo.targetObjectID = id;
- m_rcInfo.startTimeMultiplier = m_timeMultiplier;
- m_rcInfo.endTimeMultiplier = m_timeMultiplier;
-
- m_doingMoveCameraOnWaypointPath = false;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Rotate camera to face a location */
-//-------------------------------------------------------------------------------------------------
-void W3DView::rotateCameraTowardPosition(const Coord3D *pLoc, Int milliseconds)
-{
- m_rcInfo.numHoldFrames = 0;
- m_rcInfo.trackObject = FALSE;
-
-
- if (milliseconds<1) milliseconds = 1;
- m_rcInfo.numFrames = milliseconds/TheW3DFrameLengthInMsec;
- if (m_rcInfo.numFrames < 1) {
- m_rcInfo.numFrames = 1;
- }
- Coord3D curPos = *getPosition();
- Vector3 dir(pLoc->x-curPos.x, pLoc->y-curPos.y, 0);
- if (dir.Length()<0.1) return;
- dir.Normalize();
- Real angle = WWMath::Acos(dir.X);
- if (dir.Y<0) {
- angle = -angle;
- }
- // Default camera is rotated 90 degrees, so match.
- angle -= PI/2;
- normAngle(angle);
-
- m_rcInfo.curFrame = 0;
- m_doingRotateCamera = true;
- m_rcInfo.angle = angle/m_rcInfo.numFrames; // not used here
- m_rcInfo.targetObjectID = INVALID_ID;
- m_rcInfo.startTimeMultiplier = m_timeMultiplier;
- m_rcInfo.endTimeMultiplier = m_timeMultiplier;
-
- m_doingMoveCameraOnWaypointPath = false;
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::zoomCamera( Real finalZoom, Int milliseconds )
-{
- if (milliseconds<1) milliseconds = 1;
- m_zcInfo.numFrames = milliseconds/TheW3DFrameLengthInMsec;
- if (m_zcInfo.numFrames < 1) {
- m_zcInfo.numFrames = 1;
- }
- m_zcInfo.curFrame = 0;
- m_doingZoomCamera = TRUE;
- m_zcInfo.startZoom = m_zoom;
- m_zcInfo.endZoom = finalZoom;
-}
-
-//-------------------------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------------------------
-void W3DView::pitchCamera( Real finalPitch, Int milliseconds )
-{
- if (milliseconds<1) milliseconds = 1;
- m_pcInfo.numFrames = milliseconds/TheW3DFrameLengthInMsec;
- if (m_pcInfo.numFrames < 1) {
- m_pcInfo.numFrames = 1;
- }
- m_pcInfo.curFrame = 0;
- m_doingPitchCamera = TRUE;
- m_pcInfo.startPitch = m_FXPitch;
- m_pcInfo.endPitch = finalPitch;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Sets the final zoom for a camera movement. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::cameraModFinalZoom( Real finalZoom )
-{
-
- if (m_doingRotateCamera)
- {
- Real terrainHeightMax = getHeightAroundPos(m_pos.x, m_pos.y);
- Real maxHeight = (terrainHeightMax + m_maxHeightAboveGround);
- Real maxZoom = maxHeight / m_cameraOffset.z;
-
- zoomCamera( finalZoom*maxZoom, (m_rcInfo.numFrames + m_rcInfo.numHoldFrames - m_rcInfo.curFrame)*TheW3DFrameLengthInMsec );
- }
- if (m_doingMoveCameraOnWaypointPath)
- {
- Coord3D pos = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints];
- Real terrainHeightMax = getHeightAroundPos(pos.x, pos.y);
- Real maxHeight = (terrainHeightMax + m_maxHeightAboveGround);
- Real maxZoom = maxHeight / m_cameraOffset.z;
-
- zoomCamera( finalZoom*maxZoom, m_mcwpInfo.totalTimeMilliseconds - m_mcwpInfo.elapsedTimeMilliseconds );
- }
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Sets the final zoom for a camera movement. */
-//-------------------------------------------------------------------------------------------------
-void W3DView::cameraModFreezeAngle(void)
-{
- if (m_doingRotateCamera) {
- m_rcInfo.angle = 0; // Silly, but consistent.
- m_rcInfo.targetObjectID = INVALID_ID;
- }
- if (m_doingMoveCameraOnWaypointPath) {
- Int i;
-// Real curDistance = 0;
- for (i=0; ix-result.x, pLoc->y-result.y, 0);
- if (dir.Length()<0.1) continue;
- dir.Normalize();
- Real angle = WWMath::Acos(dir.X);
- if (dir.Y<0) {
- angle = -angle;
- }
- // Default camera is rotated 90 degrees, so match.
- angle -= PI/2;
- normAngle(angle);
- m_mcwpInfo.cameraAngle[i] = angle;
- }
- if (m_mcwpInfo.totalTimeMilliseconds==1) {
- // do it instantly.
- moveAlongWaypointPath(1);
- m_doingMoveCameraOnWaypointPath = true;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Sets the look toward point for the end of a camera movement. */
-// ------------------------------------------------------------------------------------------------
-void W3DView::cameraModFinalMoveTo(Coord3D *pLoc)
-{
- if (m_doingRotateCamera) {
- return; // Doesn't apply to rotate about a point.
- }
- if (m_doingMoveCameraOnWaypointPath) {
- Int i;
- Coord3D start, delta;
- start = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints];
- delta.x = pLoc->x - start.x;
- delta.y = pLoc->y - start.y;
- for (i=2; i<=m_mcwpInfo.numWaypoints; i++) {
- Coord3D result = m_mcwpInfo.waypoints[i];
- result.x += delta.x;
- result.y += delta.y;
- m_mcwpInfo.waypoints[i] = result;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Sets the look toward point for the end of a camera movement. */
-// ------------------------------------------------------------------------------------------------
-void W3DView::cameraModFinalLookToward(Coord3D *pLoc)
-{
- if (m_doingRotateCamera) {
- return; // Doesn't apply to rotate about a point.
- }
- if (m_doingMoveCameraOnWaypointPath) {
- Int i;
- Int min = m_mcwpInfo.numWaypoints-1;
- if (min<2) min=2;
-// Real curDistance = 0;
- for (i=min; i<=m_mcwpInfo.numWaypoints; i++) {
- Coord3D start, mid, end;
- Real factor = 0.5;
- start = m_mcwpInfo.waypoints[i-1];
- start.x += m_mcwpInfo.waypoints[i].x;
- start.y += m_mcwpInfo.waypoints[i].y;
- start.x /= 2;
- start.y /= 2;
- mid = m_mcwpInfo.waypoints[i];
- end = m_mcwpInfo.waypoints[i];
- end.x += m_mcwpInfo.waypoints[i+1].x;
- end.y += m_mcwpInfo.waypoints[i+1].y;
- end.x /= 2;
- end.y /= 2;
- Coord3D result = start;
- result.x += factor*(end.x-start.x);
- result.y += factor*(end.y-start.y);
- result.x += (1-factor)*factor*(mid.x-end.x + mid.x-start.x);
- result.y += (1-factor)*factor*(mid.y-end.y + mid.y-start.y);
- result.z = 0;
- Vector3 dir(pLoc->x-result.x, pLoc->y-result.y, 0);
- if (dir.Length()<0.1) continue;
- dir.Normalize();
- Real angle = WWMath::Acos(dir.X);
- if (dir.Y<0) {
- angle = -angle;
- }
- // Default camera is rotated 90 degrees, so match.
- angle -= PI/2;
- normAngle(angle);
- if (i==m_mcwpInfo.numWaypoints) {
- m_mcwpInfo.cameraAngle[i] = angle;
- } else {
- Real deltaAngle = angle - m_mcwpInfo.cameraAngle[i];
- normAngle(deltaAngle);
- angle = m_mcwpInfo.cameraAngle[i] + deltaAngle/2;
- normAngle(angle);
- m_mcwpInfo.cameraAngle[i] = angle;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Sets the final time multiplier for a camera movement. */
-// ------------------------------------------------------------------------------------------------
-void W3DView::cameraModFinalTimeMultiplier(Int finalMultiplier)
-{
- if (m_doingZoomCamera)
- m_zcInfo.endTimeMultiplier = finalMultiplier;
- if (m_doingPitchCamera)
- m_pcInfo.endTimeMultiplier = finalMultiplier;
- if (m_doingRotateCamera) {
- m_rcInfo.endTimeMultiplier = finalMultiplier;
- } else if (m_doingMoveCameraOnWaypointPath) {
- Int i;
- Real curDistance = 0;
- for (i=0; ix, location->y);
-
- Real desiredHeight = (terrainHeightMax + m_maxHeightAboveGround);
- Real desiredZoom = desiredHeight / m_cameraOffset.z;
-
- m_mcwpInfo.cameraZoom[2] = desiredZoom;//m_maxZoom;
-
- //Real terrainHeightMax = getHeightAroundPos(location->x, location->y);
- //Real desiredHeight = (terrainHeightMax + m_maxHeightAboveGround);
- //Real desiredZoom = desiredHeight / m_cameraOffset.z;
- zoomCamera( desiredZoom, milliseconds ); // this isn't right... or is it?
-
- pitchCamera( 1.0, milliseconds );
- DEBUG_LOG(("W3DView::resetCamera() Current zoom: %g Desired zoom: %g Current pitch: %g Desired pitch: %g",
- m_zoom, desiredZoom, m_pitchAngle, m_defaultPitchAngle));
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-Bool W3DView::isCameraMovementFinished(void)
-{
- if (m_viewFilter == FT_VIEW_MOTION_BLUR_FILTER) {
- // Several of the motion blur effects are similar to camera movements.
- if (m_viewFilterMode == FM_VIEW_MB_IN_AND_OUT_ALPHA ||
- m_viewFilterMode == FM_VIEW_MB_IN_AND_OUT_SATURATE ||
- m_viewFilterMode == FM_VIEW_MB_IN_ALPHA ||
- m_viewFilterMode == FM_VIEW_MB_OUT_ALPHA ||
- m_viewFilterMode == FM_VIEW_MB_IN_SATURATE ||
- m_viewFilterMode == FM_VIEW_MB_OUT_SATURATE ) {
- return true;
- }
- }
- return !m_doingMoveCameraOnWaypointPath && !m_doingRotateCamera && !m_doingPitchCamera && !m_doingZoomCamera;
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Move camera along a waypoint path in an interesting fashion. Sets up parameters that get
- * evaluated in draw(). */
- // ------------------------------------------------------------------------------------------------
-void W3DView::moveCameraAlongWaypointPath(Waypoint *pWay, Int milliseconds, Int shutter, Bool orient)
-{
- const Real MIN_DELTA = MAP_XY_FACTOR;
-
- m_mcwpInfo.waypoints[0] = *getPosition();
- m_mcwpInfo.cameraAngle[0] = getAngle();
- m_mcwpInfo.waySegLength[0] = 0;
- m_mcwpInfo.waypoints[1] = *getPosition();
- m_mcwpInfo.numWaypoints = 1;
- if (milliseconds<1) milliseconds = 1;
- m_mcwpInfo.totalTimeMilliseconds = milliseconds;
- m_mcwpInfo.shutter = shutter/TheW3DFrameLengthInMsec;
- if (m_mcwpInfo.shutter<1) m_mcwpInfo.shutter = 1;
-
- while (pWay && m_mcwpInfo.numWaypoints getLocation();
- if (pWay->getNumLinks()>0) {
- pWay = pWay->getLink(0);
- } else {
- pWay = NULL;
- }
- Vector3 dir(m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints].x-m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints-1].x, m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints].y-m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints-1].y, 0);
- if (dir.Length()1; i--) {
- m_mcwpInfo.cameraAngle[i] = (m_mcwpInfo.cameraAngle[i] + m_mcwpInfo.cameraAngle[i-1]) / 2;
- }
- m_mcwpInfo.waySegLength[m_mcwpInfo.numWaypoints+1] = m_mcwpInfo.waySegLength[m_mcwpInfo.numWaypoints+1];
- if (m_mcwpInfo.totalDistance<1.0) {
- m_mcwpInfo.waySegLength[m_mcwpInfo.numWaypoints-1] += 1.0-m_mcwpInfo.totalDistance;
- m_mcwpInfo.totalDistance = 1.0;
- }
- Real curDistance = 0;
- Coord3D finalPos = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints];
- Real newGround = TheTerrainLogic->getGroundHeight(finalPos.x, finalPos.y);
- for (i=0; i<=m_mcwpInfo.numWaypoints+1; i++) {
- Real factor2 = curDistance / m_mcwpInfo.totalDistance;
- Real factor1 = 1.0-factor2;
- m_mcwpInfo.cameraFXPitch[i] = m_FXPitch;
- m_mcwpInfo.cameraZoom[i] = m_zoom;
- m_mcwpInfo.timeMultiplier[i] = m_timeMultiplier;
- m_mcwpInfo.groundHeight[i] = m_groundLevel*factor1 + newGround*factor2;
- curDistance += m_mcwpInfo.waySegLength[i];
- //DEBUG_LOG(("New Index %d, angle %.2f", i, m_mcwpInfo.cameraAngle[i]*180/PI));
- }
-
- // Pad the end.
- m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints+1] = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints];
- Coord3D cur = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints];
- Coord3D prev = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints-1];
- m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints+1].x += cur.x-prev.x;
- m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints+1].y += cur.y-prev.y;
- m_mcwpInfo.cameraAngle[m_mcwpInfo.numWaypoints+1] = m_mcwpInfo.cameraAngle[m_mcwpInfo.numWaypoints];
- m_mcwpInfo.groundHeight[m_mcwpInfo.numWaypoints+1] = newGround;
-
-
- cur = m_mcwpInfo.waypoints[2];
- prev = m_mcwpInfo.waypoints[1];
- m_mcwpInfo.waypoints[0].x -= cur.x-prev.x;
- m_mcwpInfo.waypoints[0].y -= cur.y-prev.y;
-
- m_doingMoveCameraOnWaypointPath = m_mcwpInfo.numWaypoints>1;
- m_doingRotateCamera = false;
-
- m_mcwpInfo.elapsedTimeMilliseconds = 0;
- m_mcwpInfo.curShutter = m_mcwpInfo.shutter;
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-static Real makeQuadraticS(Real t)
-{
- // for t = linear 0-1, convert to quadratic s where 0==0, 0.5==0.5 && 1.0 == 1.0.
- Real tPrime = t;
- if (t<0.5) {
- tPrime = 0.5 * (2*t*2*t);
- } else {
- tPrime = (t-0.5)*2;
- tPrime = WWMath::Sqrt(tPrime);
- tPrime = 0.5 + 0.5*(tPrime);
- }
- return tPrime*0.5 + t*0.5;
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void W3DView::rotateCameraOneFrame(void)
-{
- m_rcInfo.curFrame++;
- if (TheGlobalData->m_disableCameraMovement) {
- if (m_rcInfo.curFrame >= m_rcInfo.numFrames + m_rcInfo.numHoldFrames) {
- m_doingRotateCamera = false;
- m_freezeTimeForCameraMovement = false;
- }
- return;
- }
-
- if (m_rcInfo.curFrame <= m_rcInfo.numFrames)
- {
- // not just holding; do the camera adjustment
- Real factor = ((Real)m_rcInfo.curFrame)/m_rcInfo.numFrames;
- if (m_rcInfo.trackObject)
- {
- const Object *obj = TheGameLogic->findObjectByID(m_rcInfo.targetObjectID);
- if (obj)
- {
- // object has not been destroyed
- m_rcInfo.targetObjectPos = *obj->getPosition();
- }
-
- Vector3 dir(m_rcInfo.targetObjectPos.x - m_pos.x, m_rcInfo.targetObjectPos.y - m_pos.y, 0);
- if (dir.Length()>=0.1)
- {
- dir.Normalize();
- Real angle = WWMath::Acos(dir.X);
- if (dir.Y<0) {
- angle = -angle;
- }
- // Default camera is rotated 90 degrees, so match.
- angle -= PI/2;
- normAngle(angle);
-
- factor = 1.0f / (m_rcInfo.numFrames - m_rcInfo.curFrame + 1);
- Real angleDiff = (angle - m_angle);
- normAngle(angleDiff);
- angleDiff *= factor;
-
- m_angle += angleDiff;
- }
- }
- else
- {
- m_angle += m_rcInfo.angle;
- }
- //m_zoom = m_rcInfo.startZoom + (m_rcInfo.endZoom-m_rcInfo.startZoom)*factor;
- //m_FXPitch = m_rcInfo.startPitch + (m_rcInfo.endPitch-m_rcInfo.startPitch)*factor;
- normAngle(m_angle);
- //DEBUG_LOG(("\tm_angle:%g", m_angle));
- m_timeMultiplier = m_rcInfo.startTimeMultiplier + REAL_TO_INT_FLOOR(0.5 + (m_rcInfo.endTimeMultiplier-m_rcInfo.startTimeMultiplier)*factor);
- }
- else if (m_rcInfo.curFrame <= m_rcInfo.numFrames + m_rcInfo.numHoldFrames && m_rcInfo.trackObject)
- {
- const Object *obj = TheGameLogic->findObjectByID(m_rcInfo.targetObjectID);
- if (obj)
- {
- // object has not been destroyed
- m_rcInfo.targetObjectPos = *obj->getPosition();
- }
-
- Vector3 dir(m_rcInfo.targetObjectPos.x - m_pos.x, m_rcInfo.targetObjectPos.y - m_pos.y, 0);
- if (dir.Length()>=0.1)
- {
- dir.Normalize();
- Real angle = WWMath::Acos(dir.X);
- if (dir.Y<0) {
- angle = -angle;
- }
- // Default camera is rotated 90 degrees, so match.
- angle -= PI/2;
- normAngle(angle);
- m_angle = angle;
- }
- }
-
-
- if (m_rcInfo.curFrame >= m_rcInfo.numFrames + m_rcInfo.numHoldFrames) {
- m_doingRotateCamera = false;
- m_freezeTimeForCameraMovement = false;
- //m_zoom = m_rcInfo.endZoom;
- //m_FXPitch = m_rcInfo.endPitch;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void W3DView::zoomCameraOneFrame(void)
-{
- m_zcInfo.curFrame++;
- if (TheGlobalData->m_disableCameraMovement) {
- if (m_zcInfo.curFrame >= m_zcInfo.numFrames) {
- m_doingZoomCamera = false;
- }
- return;
- }
- if (m_zcInfo.curFrame <= m_zcInfo.numFrames)
- {
- // not just holding; do the camera adjustment
- Real factor = ((Real)m_zcInfo.curFrame)/m_zcInfo.numFrames;
- m_zoom = m_zcInfo.startZoom + (m_zcInfo.endZoom-m_zcInfo.startZoom)*factor;
- }
-
- if (m_zcInfo.curFrame >= m_zcInfo.numFrames) {
- m_doingZoomCamera = false;
- m_zoom = m_zcInfo.endZoom;
- }
-
- //DEBUG_LOG(("W3DView::zoomCameraOneFrame() - m_zoom = %g", m_zoom));
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void W3DView::pitchCameraOneFrame(void)
-{
- m_pcInfo.curFrame++;
- if (TheGlobalData->m_disableCameraMovement) {
- if (m_pcInfo.curFrame >= m_pcInfo.numFrames) {
- m_doingPitchCamera = false;
- }
- return;
- }
- if (m_pcInfo.curFrame <= m_pcInfo.numFrames)
- {
- // not just holding; do the camera adjustment
- Real factor = ((Real)m_pcInfo.curFrame)/m_pcInfo.numFrames;
- m_FXPitch = m_pcInfo.startPitch + (m_pcInfo.endPitch-m_pcInfo.startPitch)*factor;
- }
-
- if (m_pcInfo.curFrame >= m_pcInfo.numFrames) {
- m_doingPitchCamera = false;
- m_FXPitch = m_pcInfo.endPitch;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// ------------------------------------------------------------------------------------------------
-void W3DView::moveAlongWaypointPath(Real milliseconds)
-{
- m_mcwpInfo.elapsedTimeMilliseconds += milliseconds;
- if (TheGlobalData->m_disableCameraMovement) {
- if (m_mcwpInfo.elapsedTimeMilliseconds>m_mcwpInfo.totalTimeMilliseconds) {
- m_doingMoveCameraOnWaypointPath = false;
- m_freezeTimeForCameraMovement = false;
- }
- return;
- }
- if (m_mcwpInfo.elapsedTimeMilliseconds>m_mcwpInfo.totalTimeMilliseconds) {
- m_doingMoveCameraOnWaypointPath = false;
- m_freezeTimeForCameraMovement = false;
- m_angle = m_mcwpInfo.cameraAngle[m_mcwpInfo.numWaypoints];
- //m_zoom = m_mcwpInfo.cameraZoom[m_mcwpInfo.numWaypoints];
- //m_FXPitch = m_mcwpInfo.cameraFXPitch[m_mcwpInfo.numWaypoints];
-
- m_groundLevel = m_mcwpInfo.groundHeight[m_mcwpInfo.numWaypoints];
- /////////////////////m_cameraOffset.z = m_groundLevel+TheGlobalData->m_cameraHeight;
- m_cameraOffset.y = -(m_cameraOffset.z / tan(TheGlobalData->m_cameraPitch * (PI / 180.0)));
- m_cameraOffset.x = -(m_cameraOffset.y * tan(TheGlobalData->m_cameraYaw * (PI / 180.0)));
-
- Coord3D pos = m_mcwpInfo.waypoints[m_mcwpInfo.numWaypoints];
- pos.z = 0;
- setPosition(&pos);
- // Note - assuming that the scripter knows what he is doing, we adjust the constraints so that
- // the scripted action can occur.
- m_cameraConstraint.lo.x = minf(m_cameraConstraint.lo.x, pos.x);
- m_cameraConstraint.hi.x = maxf(m_cameraConstraint.hi.x, pos.x);
- m_cameraConstraint.lo.y = minf(m_cameraConstraint.lo.y, pos.y);
- m_cameraConstraint.hi.y = maxf(m_cameraConstraint.hi.y, pos.y);
- return;
- }
- Int deltaTime = milliseconds;
-
- Real distance = m_mcwpInfo.totalDistance * deltaTime / m_mcwpInfo.totalTimeMilliseconds;
- m_mcwpInfo.curSegDistance += distance;
- while (m_mcwpInfo.curSegDistance > m_mcwpInfo.waySegLength[m_mcwpInfo.curSegment]) {
- m_mcwpInfo.curSegDistance -= m_mcwpInfo.waySegLength[m_mcwpInfo.curSegment];
- m_mcwpInfo.curSegment++;
- if (m_mcwpInfo.curSegment >= m_mcwpInfo.numWaypoints) {
- m_mcwpInfo.totalTimeMilliseconds = 0; // Will end following next frame.
- return;
- }
- }
- Real avgFactor = 1.0/m_mcwpInfo.rollingAverageFrames;
- m_mcwpInfo.curShutter--;
- if (m_mcwpInfo.curShutter>0) {
- return;
- }
- m_mcwpInfo.curShutter = m_mcwpInfo.shutter;
- Real factor = m_mcwpInfo.curSegDistance / m_mcwpInfo.waySegLength[m_mcwpInfo.curSegment];
- if (m_mcwpInfo.curSegment == m_mcwpInfo.numWaypoints-1) {
- avgFactor = avgFactor + (1.0-avgFactor)*factor;
- }
- Real angle = getAngle();
- Real factor1;
- Real factor2;
- factor1 = 1.0-factor;
- //factor1 = makeQuadraticS(factor1);
- factor2 = 1.0-factor1;
- Real angle1 = m_mcwpInfo.cameraAngle[m_mcwpInfo.curSegment];
- Real angle2 = m_mcwpInfo.cameraAngle[m_mcwpInfo.curSegment+1];
- if (angle2-angle1 > PI) angle1 += 2*PI;
- if (angle2-angle1 < -PI) angle1 -= 2*PI;
- angle = angle1 * (factor1) + angle2 * (factor2);
-
- normAngle(angle);
- Real deltaAngle = angle-m_angle;
- normAngle(deltaAngle);
- if (fabs(deltaAngle) > PI/10) {
- DEBUG_LOG(("Huh."));
- }
- m_angle += avgFactor*(deltaAngle);
- normAngle(m_angle);
-
- /*
- Real pitchFX = m_mcwpInfo.cameraFXPitch[m_mcwpInfo.curSegment]*factor1 +
- m_mcwpInfo.cameraFXPitch[m_mcwpInfo.curSegment+1]*factor2;
- m_FXPitch += avgFactor*(pitchFX-m_FXPitch);
-
- Real cameraZoom = m_mcwpInfo.cameraZoom[m_mcwpInfo.curSegment]*factor1 +
- m_mcwpInfo.cameraZoom[m_mcwpInfo.curSegment+1]*factor2;
- m_zoom += avgFactor*(cameraZoom-m_zoom);
- */
-
- Real timeMultiplier = m_mcwpInfo.timeMultiplier[m_mcwpInfo.curSegment]*factor1 +
- m_mcwpInfo.timeMultiplier[m_mcwpInfo.curSegment+1]*factor2;
- m_timeMultiplier = REAL_TO_INT_FLOOR(0.5 + timeMultiplier);
-
- m_groundLevel = m_mcwpInfo.groundHeight[m_mcwpInfo.curSegment]*factor1 +
- m_mcwpInfo.groundHeight[m_mcwpInfo.curSegment+1]*factor2;
- //////////////m_cameraOffset.z = m_groundLevel+TheGlobalData->m_cameraHeight;
- m_cameraOffset.y = -(m_cameraOffset.z / tan(TheGlobalData->m_cameraPitch * (PI / 180.0)));
- m_cameraOffset.x = -(m_cameraOffset.y * tan(TheGlobalData->m_cameraYaw * (PI / 180.0)));
-
- Coord3D start, mid, end;
- if (factor<0.5) {
- start = m_mcwpInfo.waypoints[m_mcwpInfo.curSegment-1];
- start.x += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment].x;
- start.y += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment].y;
- start.x /= 2;
- start.y /= 2;
- mid = m_mcwpInfo.waypoints[m_mcwpInfo.curSegment];
- end = m_mcwpInfo.waypoints[m_mcwpInfo.curSegment];
- end.x += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+1].x;
- end.y += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+1].y;
- end.x /= 2;
- end.y /= 2;
- factor += 0.5;
- } else {
- start = m_mcwpInfo.waypoints[m_mcwpInfo.curSegment];
- start.x += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+1].x;
- start.y += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+1].y;
- start.x /= 2;
- start.y /= 2;
- mid = m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+1];
- end = m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+1];
- end.x += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+2].x;
- end.y += m_mcwpInfo.waypoints[m_mcwpInfo.curSegment+2].y;
- end.x /= 2;
- end.y /= 2;
- factor -= 0.5;
- }
-
- Coord3D result = start;
- result.x += factor*(end.x-start.x);
- result.y += factor*(end.y-start.y);
- result.x += (1-factor)*factor*(mid.x-end.x + mid.x-start.x);
- result.y += (1-factor)*factor*(mid.y-end.y + mid.y-start.y);
- result.z = 0;
-/*
- static Real prevGround = 0;
- DEBUG_LOG(("Dx %.2f, dy %.2f, DeltaANgle = %.2f, %.2f DeltaGround %.2f", m_pos.x-result.x, m_pos.y-result.y, deltaAngle, m_groundLevel, m_groundLevel-prevGround));
- prevGround = m_groundLevel;
-*/
- setPosition(&result);
- // Note - assuming that the scripter knows what he is doing, we adjust the constraints so that
- // the scripted action can occur.
- m_cameraConstraint.lo.x = minf(m_cameraConstraint.lo.x, result.x);
- m_cameraConstraint.hi.x = maxf(m_cameraConstraint.hi.x, result.x);
- m_cameraConstraint.lo.y = minf(m_cameraConstraint.lo.y, result.y);
- m_cameraConstraint.hi.y = maxf(m_cameraConstraint.hi.y, result.y);
-
-}
-
-
-// ------------------------------------------------------------------------------------------------
-/** Add an impulse force to shake the camera.
- * The camera shake is a simple simulation of an oscillating spring/damper.
- * The idea is that some sort of shock has "pushed" the camera once, as an
- * impluse, after which the camera vibrates back to its rest position.
- * @todo This should be part of "View", not "W3DView". */
-// ------------------------------------------------------------------------------------------------
-void W3DView::shake( const Coord3D *epicenter, CameraShakeType shakeType )
-{
- Real angle = GameClientRandomValueReal( 0, 2*PI );
-
- m_shakeAngleCos = (Real)cos( angle );
- m_shakeAngleSin = (Real)sin( angle );
-
- Real intensity = 0.0f;
- switch( shakeType )
- {
- case SHAKE_SUBTLE:
- intensity = TheGlobalData->m_shakeSubtleIntensity;
- break;
-
- case SHAKE_NORMAL:
- intensity = TheGlobalData->m_shakeNormalIntensity;
- break;
-
- case SHAKE_STRONG:
- intensity = TheGlobalData->m_shakeStrongIntensity;
- break;
-
- case SHAKE_SEVERE:
- intensity = TheGlobalData->m_shakeSevereIntensity;
- break;
-
- case SHAKE_CINE_EXTREME:
- intensity = TheGlobalData->m_shakeCineExtremeIntensity;
- break;
-
- case SHAKE_CINE_INSANE:
- intensity = TheGlobalData->m_shakeCineInsaneIntensity;
- break;
- }
-
- // intensity falls off with distance
- const Coord3D *viewPos = getPosition();
- Coord3D d;
- d.x = epicenter->x - viewPos->x;
- d.y = epicenter->y - viewPos->y;
- /// @todo make this 3D once we have the real "lookat" spot
- //d.z = epicenter->z - viewPos->z;
-
- Real dist = (Real)sqrt( d.x*d.x + d.y*d.y );
-
- if (dist > TheGlobalData->m_maxShakeRange)
- return;
-
- intensity *= 1.0f - (dist/TheGlobalData->m_maxShakeRange);
-
- // add intensity and clamp
- m_shakeIntensity += intensity;
-
- //const Real maxIntensity = 10.0f;
- const Real maxIntensity = 3.0f;
- if (m_shakeIntensity > TheGlobalData->m_maxShakeIntensity)
- m_shakeIntensity = maxIntensity;
-}
-
-//-------------------------------------------------------------------------------------------------
-/** Transformt he screen pixel coord passed in, to a world coordinate at the specified
- * z value */
-//-------------------------------------------------------------------------------------------------
-void W3DView::screenToWorldAtZ( const ICoord2D *s, Coord3D *w, Real z )
-{
- Vector3 rayStart, rayEnd;
-
- getPickRay( s, &rayStart, &rayEnd );
- w->x = Vector3::Find_X_At_Z( z, rayStart, rayEnd );
- w->y = Vector3::Find_Y_At_Z( z, rayStart, rayEnd );
- w->z = z;
-
-}
-
diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt
index 0e11b9021a..b77b4292e5 100644
--- a/GeneralsMD/Code/GameEngine/CMakeLists.txt
+++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt
@@ -206,7 +206,7 @@ set(GAMEENGINE_SRC
Include/GameClient/Module/BeaconClientUpdate.h
Include/GameClient/Module/SwayClientUpdate.h
Include/GameClient/Mouse.h
- Include/GameClient/ParabolicEase.h
+# Include/GameClient/ParabolicEase.h
Include/GameClient/ParticleSys.h
Include/GameClient/PlaceEventTranslator.h
Include/GameClient/ProcessAnimateWindow.h
@@ -224,7 +224,7 @@ set(GAMEENGINE_SRC
Include/GameClient/TerrainRoads.h
Include/GameClient/TerrainVisual.h
# Include/GameClient/VideoPlayer.h
- Include/GameClient/View.h
+# Include/GameClient/View.h
Include/GameClient/Water.h
Include/GameClient/WindowLayout.h
# Include/GameClient/WindowVideoManager.h
@@ -807,7 +807,7 @@ set(GAMEENGINE_SRC
Source/GameClient/MessageStream/PlaceEventTranslator.cpp
Source/GameClient/MessageStream/SelectionXlat.cpp
Source/GameClient/MessageStream/WindowXlat.cpp
- Source/GameClient/ParabolicEase.cpp
+# Source/GameClient/ParabolicEase.cpp
Source/GameClient/RadiusDecal.cpp
Source/GameClient/SelectionInfo.cpp
Source/GameClient/Snow.cpp
@@ -824,7 +824,7 @@ set(GAMEENGINE_SRC
Source/GameClient/Terrain/TerrainVisual.cpp
# Source/GameClient/VideoPlayer.cpp
# Source/GameClient/VideoStream.cpp
- Source/GameClient/View.cpp
+# Source/GameClient/View.cpp
Source/GameClient/Water.cpp
Source/GameLogic/AI/AI.cpp
Source/GameLogic/AI/AIDock.cpp
diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h
index 3f3a783946..7a100795c1 100644
--- a/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h
+++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Display.h
@@ -29,11 +29,9 @@
#pragma once
#include "Common/SubsystemInterface.h"
-#include "View.h"
#include "GameClient/Color.h"
#include "GameClient/GameFont.h"
-
-class View;
+#include "GameClient/View.h"
struct ShroudLevel
{
diff --git a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt
index 40c75076c3..e1bb05cdb1 100644
--- a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt
+++ b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt
@@ -7,7 +7,7 @@ set(GAMEENGINEDEVICE_SRC
# Include/W3DDevice/Common/W3DRadar.h
Include/W3DDevice/Common/W3DThingFactory.h
Include/W3DDevice/GameClient/BaseHeightMap.h
- Include/W3DDevice/GameClient/camerashakesystem.h
+# Include/W3DDevice/GameClient/camerashakesystem.h
Include/W3DDevice/GameClient/FlatHeightMap.h
Include/W3DDevice/GameClient/HeightMap.h
Include/W3DDevice/GameClient/Module/W3DDebrisDraw.h
@@ -71,7 +71,7 @@ set(GAMEENGINEDEVICE_SRC
Include/W3DDevice/GameClient/W3DTerrainVisual.h
Include/W3DDevice/GameClient/W3DTreeBuffer.h
# Include/W3DDevice/GameClient/W3DVideoBuffer.h
- Include/W3DDevice/GameClient/W3DView.h
+# Include/W3DDevice/GameClient/W3DView.h
Include/W3DDevice/GameClient/W3DVolumetricShadow.h
Include/W3DDevice/GameClient/W3DWater.h
Include/W3DDevice/GameClient/W3DWaterTracks.h
@@ -98,7 +98,7 @@ set(GAMEENGINEDEVICE_SRC
Source/W3DDevice/Common/Thing/W3DThingFactory.cpp
Source/W3DDevice/Common/W3DConvert.cpp
Source/W3DDevice/GameClient/BaseHeightMap.cpp
- Source/W3DDevice/GameClient/camerashakesystem.cpp
+# Source/W3DDevice/GameClient/camerashakesystem.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DDebrisDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DDefaultDraw.cpp
Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp
@@ -173,7 +173,7 @@ set(GAMEENGINEDEVICE_SRC
Source/W3DDevice/GameClient/W3DTerrainVisual.cpp
Source/W3DDevice/GameClient/W3DTreeBuffer.cpp
# Source/W3DDevice/GameClient/W3DVideoBuffer.cpp
- Source/W3DDevice/GameClient/W3DView.cpp
+# Source/W3DDevice/GameClient/W3DView.cpp
Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp
Source/W3DDevice/GameClient/W3DWebBrowser.cpp
Source/W3DDevice/GameClient/Water/W3DWater.cpp
diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py
index c7e80a9325..6d401ef28f 100644
--- a/scripts/cpp/unify_move_files.py
+++ b/scripts/cpp/unify_move_files.py
@@ -180,6 +180,16 @@ def main():
#unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DShaderManager.h")
#unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DShaderManager.cpp")
+ #unify_move_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/ParabolicEase.h", Game.CORE, "GameEngine/Include/GameClient/ParabolicEase.h")
+ #unify_move_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/ParabolicEase.cpp", Game.CORE, "GameEngine/Source/GameClient/ParabolicEase.cpp")
+ #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/camerashakesystem.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/CameraShakeSystem.h")
+ #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/camerashakesystem.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/CameraShakeSystem.cpp")
+
+ #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/View.h", Game.CORE, "GameEngine/Include/GameClient/View.h")
+ #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/View.cpp", Game.CORE, "GameEngine/Source/GameClient/View.cpp")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DView.h")
+ #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp")
+
return