| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- /*
- ** Command & Conquer Generals Zero Hour(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 <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : WW3D *
- * *
- * $Archive:: /Commando/Code/ww3d2/camera.h $*
- * *
- * Org Author:: Greg_h *
- * *
- * $Author:: Kenny Mitchell *
- * *
- * $Modtime:: 06/26/02 4:04p $*
- * *
- * $Revision:: 14 $*
- * *
- * 06/26/02 KM Matrix name change to avoid MAX conflicts *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * CameraClass::Get_Frustum -- returns the frustum of the camera *
- * CameraClass::Get_Frustum_Planes -- returns pointer to the array of frustum planes *
- * CameraClass::Get_Frustum_Corners -- returns pointer to the array of frustum corners *
- * CameraClass::Get_View_Space_Frustum -- returns the view-space frustum for this camera *
- * CameraClass::Get_View_Space_Frustum_Planes -- returns the view space clip planes for this *
- * CameraClass::Get_View_Space_Frustum_Corners -- returns the corners of the view space frus *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #ifndef CAMERA_H
- #define CAMERA_H
- #include "always.h"
- #include "rendobj.h"
- #include "plane.h"
- #include "frustum.h"
- #include "obbox.h"
- #include "vector2.h"
- #include "matrix4.h"
- #include "colmath.h"
- class RenderInfoClass;
- /**
- ** ViewportClass
- ** This class is used to define a "normalized" screen space rectangle for the
- ** camera to render into. A viewport which filled the entire screen would be
- ** (0,0) - (1,1) with 0,0 being the upper left and 1,1 being the lower right.
- */
- class ViewportClass
- {
- public:
- ViewportClass(void) : Min(0,0), Max(1,1) { }
- ViewportClass(const Vector2 & min,const Vector2 & max) : Min(min), Max(max) { }
- ViewportClass(const ViewportClass & vp) : Min(vp.Min), Max(vp.Max) { }
-
- float Width(void) const { return Max.X - Min.X; }
- float Height(void) const { return Max.Y - Min.Y; }
- Vector2 Min;
- Vector2 Max;
- };
- /**
- ** CameraClass
- ** This object controls how vertices are transformed from world-space to view
- ** space, the parameters of the perspective projection, and the viewport
- ** on screen that the result is mapped into.
- **
- ** Cameras are not "rendered" and do not need to be "added" to a scene. A
- ** CameraClass is passed into the WW3D::Render(...) function. The reason
- ** they are render objects is so that they can be inserted onto the bone of
- ** some animation and move with the animation...
- **
- ** For all of the projection functions (Matrix4x4, ProjectorClass (used by
- ** decals and texture projections), and CameraClass) I followed the OpenGL
- ** convention of passing positive distances for your clip planes even though
- ** in a right-handed coordinate system your z values are negative after
- ** transformation to camera space. So Set_Clip_Planes expects positive distances
- ** to your near and far clip planes.
- **
- ** (gth) We should probably separate CameraClass from RenderObjClass... In the
- ** case where a camera is using a transform from an animation; the programmer
- ** is usually requesting the transform and plugging it into the camera anyway.
- */
- class CameraClass : public RenderObjClass
- {
- public:
- enum ProjectionType
- {
- PERSPECTIVE = 0,
- ORTHO
- };
- enum ProjectionResType
- {
- INSIDE_FRUSTUM,
- OUTSIDE_FRUSTUM,
- OUTSIDE_NEAR_CLIP,
- OUTSIDE_FAR_CLIP,
- };
- CameraClass(void);
- CameraClass(const CameraClass & src);
- CameraClass & operator = (const CameraClass &);
- virtual ~CameraClass(void);
- virtual RenderObjClass * Clone(void) const;
- virtual int Class_ID(void) const { return CLASSID_CAMERA; }
-
- /////////////////////////////////////////////////////////////////////////////
- // Render Object Interface - Rendering, cameras don't "render"
- /////////////////////////////////////////////////////////////////////////////
- virtual void Render(RenderInfoClass & rinfo) { }
-
- /////////////////////////////////////////////////////////////////////////////
- // Render Object Interface - "Scene Graph"
- // Cameras cache their frustum description, this is invalidated whenever
- // the transform/position is changed
- /////////////////////////////////////////////////////////////////////////////
- virtual void Set_Transform(const Matrix3D &m);
- virtual void Set_Position(const Vector3 &v);
- /////////////////////////////////////////////////////////////////////////////
- // Render Object Interface - Bounding Volumes
- /////////////////////////////////////////////////////////////////////////////
- virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
- virtual void Get_Obj_Space_Bounding_Box(AABoxClass & box) const;
- ///////////////////////////////////////////////////////////////////////////
- // Camera parameter control
- ///////////////////////////////////////////////////////////////////////////
- // Depth of the scene.
- float Get_Depth(void) const;
- // Setting the projection type
- void Set_Projection_Type(ProjectionType ptype);
- ProjectionType Get_Projection_Type(void);
-
- // Setting the clipping ranges in world space distances
- void Set_Clip_Planes(float znear,float zfar);
- void Get_Clip_Planes(float & znear,float & zfar) const;
- // Setting the zbuffer range used during rendering. (Added to allow subdividing the z-buffer. -MW).
- void Set_Zbuffer_Range(float znear,float zfar) {ZBufferMin = znear;ZBufferMax=zfar;}
- void Get_Zbuffer_Range(float & znear,float & zfar) const {znear=ZBufferMin;zfar=ZBufferMax;}
- // Methods for setting the View Plane.
- // NOTE: View plane is always at a distance of 1.0 from the eye.
- void Set_View_Plane(const Vector2 & min,const Vector2 & max);
- void Set_View_Plane(float hfov,float vfov = -1);
- void Set_Aspect_Ratio(float width_to_height);
- // Methods for querying the View Plane settings.
- void Get_View_Plane(Vector2 & set_min,Vector2 & set_max) const;
- float Get_Horizontal_FOV(void) const;
- float Get_Vertical_FOV(void) const;
- float Get_Aspect_Ratio(void) const;
- // Access to the projection matrices for this camera
- void Get_Projection_Matrix(Matrix4x4 * set_tm);
- void Get_D3D_Projection_Matrix(Matrix4x4 * set_tm);
- void Get_View_Matrix(Matrix3D * set_tm);
- const Matrix4x4 & Get_Projection_Matrix(void);
- const Matrix3D & Get_View_Matrix(void);
- // Projecting and Un-Projecting a point
- ProjectionResType Project(Vector3 & dest,const Vector3 & ws_point) const;
- ProjectionResType Project_Camera_Space_Point(Vector3 & dest,const Vector3 & cam_point) const;
- void Un_Project(Vector3 & dest,const Vector2 & view_point) const;
- void Transform_To_View_Space(Vector3 & dest,const Vector3 & ws_point) const;
- void Rotate_To_View_Space(Vector3 & dest,const Vector3 & ws_vector) const;
- // Viewport control
- void Set_Viewport(const Vector2 & min,const Vector2 & max);
- void Get_Viewport(Vector2 & set_min,Vector2 & set_max) const;
- const ViewportClass & Get_Viewport(void) const;
-
- void Set_Depth_Range(float zstart = 0.0f,float zend = 1.0f);
- void Get_Depth_Range(float * set_zstart,float * set_zend) const;
- // Culling for various bounding volumes. These functions will return true if the
- // given primitive is culled (i.e. it is *outside* the view frustum)
- bool Cull_Sphere(const SphereClass & sphere) const;
- bool Cull_Sphere_On_Frustum_Sides(const SphereClass & sphere) const;
- bool Cull_Box(const AABoxClass & box) const;
- // Various properties of the camera's frustum: These funcitons return a
- // pointer to the internal storage of the descriptions. there will be
- // 6 frustum planes, 8 corner points, see the implementations of these
- // functions for definitions on which points/planes are associated with
- // each index. Better yet, just use the Frustum object.
- const FrustumClass & Get_Frustum(void) const;
- const PlaneClass * Get_Frustum_Planes(void) const;
- const Vector3 * Get_Frustum_Corners(void) const;
- const FrustumClass & Get_View_Space_Frustum(void) const;
- const PlaneClass * Get_View_Space_Frustum_Planes(void) const;
- const Vector3 * Get_View_Space_Frustum_Corners(void) const;
- const OBBoxClass & Get_Near_Clip_Bounding_Box(void) const;
-
- // Methods for transforming/projecting points between various coordinate systems
- // associated with this camera.
- // "Device Space" - pixel coordinate
- // "View Space" - 3D space where the view point is at 0,0,0 and the view plane is at z=-1.0
- // "World Space" - 3D world coordinate system.
- void Device_To_View_Space(const Vector2 & device_coord,Vector3 * view_coord);
- void Device_To_World_Space(const Vector2 & device_coord,Vector3 * world_coord);
- float Compute_Projected_Sphere_Radius(float dist,float radius);
- // apply this camera's settings into d3d.
- void Apply(void);
- // utility class to convert to old space of 0..1
- static void Convert_Old(Vector3 &pos);
- protected:
-
- void Update_Frustum(void) const;
- ProjectionType Projection; // projection type, orthographic or perspective
- ViewportClass Viewport; // pixel viewport to render into
- ViewportClass ViewPlane; // corners of a slice through the frustum at z=-1.0
- float AspectRatio; // aspect ratio of the camera, width / height
- float ZNear; // near clip plane distance
- float ZFar; // far clip plane distance
- float ZBufferMin; // smallest value we'll write into the z-buffer (usually 0.0)
- float ZBufferMax; // largest value we'll write into the z-buffer (usually 1.0)
- mutable bool FrustumValid;
- mutable FrustumClass Frustum; // world-space frustum and clip planes
- mutable FrustumClass ViewSpaceFrustum; // view-space frustum and clip planes
- mutable OBBoxClass NearClipBBox; // obbox which bounds the near clip plane
- mutable Matrix4x4 ProjectionTransform;
- mutable Matrix3D CameraInvTransform;
- };
- inline float CameraClass::Get_Depth(void) const
- {
- return ZFar;
- }
- inline void CameraClass::Set_Projection_Type(ProjectionType ptype)
- {
- FrustumValid = false;
- Projection = ptype;
- }
- inline CameraClass::ProjectionType CameraClass::Get_Projection_Type(void)
- {
- return Projection;
- }
- inline void CameraClass::Set_Viewport(const Vector2 & min,const Vector2 & max)
- {
- Viewport.Min = min; Viewport.Max = max;
- FrustumValid = false;
- }
- inline void CameraClass::Get_Viewport(Vector2 & set_min,Vector2 & set_max) const
- {
- set_min = Viewport.Min;
- set_max = Viewport.Max;
- }
- inline void CameraClass::Set_Depth_Range(float zmin,float zmax)
- {
- ZBufferMin = zmin;
- ZBufferMax = zmax;
- }
- inline void CameraClass::Get_Depth_Range(float * set_zmin,float * set_zmax) const
- {
- if (set_zmin != NULL) {
- *set_zmin = ZBufferMin;
- }
- if (set_zmax != NULL) {
- *set_zmax = ZBufferMax;
- }
- }
- inline const ViewportClass & CameraClass::Get_Viewport(void) const
- {
- return Viewport;
- }
- inline bool CameraClass::Cull_Sphere(const SphereClass & sphere) const
- {
- const FrustumClass & frustum = Get_Frustum();
- return CollisionMath::Overlap_Test(frustum,sphere) == CollisionMath::OUTSIDE;
- }
- inline bool CameraClass::Cull_Sphere_On_Frustum_Sides(const SphereClass & sphere) const
- {
- const FrustumClass & frustum = Get_Frustum();
- const PlaneClass * planes = frustum.Planes;
- bool is_visible = true;
- for (int i = 1; i < 5; i++) {
- is_visible = is_visible && (CollisionMath::Overlap_Test(planes[i],sphere) & (CollisionMath::INSIDE|CollisionMath::BOTH));
- }
- return !is_visible;
- }
- /***********************************************************************************************
- * CameraClass::Get_Frustum -- returns the frustum of the camera *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/24/99 GTH : Created. *
- *=============================================================================================*/
- inline const FrustumClass &
- CameraClass::Get_Frustum(void) const
- {
- Update_Frustum();
- return Frustum;
- }
- /***********************************************************************************************
- * CameraClass::Get_Frustum_Planes -- returns pointer to the array of frustum planes *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/29/98 GTH : Created. *
- *=============================================================================================*/
- inline const PlaneClass *
- CameraClass::Get_Frustum_Planes(void) const
- {
- const FrustumClass & frustum = Get_Frustum();
- return frustum.Planes;
- }
- /***********************************************************************************************
- * CameraClass::Get_Frustum_Corners -- returns pointer to the array of frustum corners *
- * *
- * The camera frustum corner FrustumCorners are defined in the following order *
- * The first four points lie on the near clipping plane: *
- * upper left 0, upper right 1, lower left 2, lower right 3. *
- * The last four points lie on the far clipping plane, numbered analogous fashion. *
- * upper left 4, upper right 5, lower left 6, lower right 7. *
- * (remember: the camera space has x going to the right, y up and z backwards). *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/29/98 GTH : Created. *
- *=============================================================================================*/
- inline const Vector3 *
- CameraClass::Get_Frustum_Corners(void) const
- {
- const FrustumClass & frustum = Get_Frustum();
- return frustum.Corners;
- }
- /***********************************************************************************************
- * CameraClass::Get_View_Space_Frustum -- returns the view-space frustum for this camera *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/16/2001 gth : Created. *
- *=============================================================================================*/
- inline const FrustumClass & CameraClass::Get_View_Space_Frustum(void) const
- {
- Update_Frustum();
- return ViewSpaceFrustum;
- }
- /***********************************************************************************************
- * CameraClass::Get_View_Space_Frustum_Planes -- returns the view space clip planes for this c *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/16/2001 gth : Created. *
- *=============================================================================================*/
- inline const PlaneClass * CameraClass::Get_View_Space_Frustum_Planes(void) const
- {
- const FrustumClass & frustum = Get_View_Space_Frustum();
- return frustum.Planes;
- }
- /***********************************************************************************************
- * CameraClass::Get_View_Space_Frustum_Corners -- returns the corners of the view space frustu *
- * *
- * The camera frustum corner FrustumCorners are defined in the following order *
- * The first four points lie on the near clipping plane: *
- * upper left 0, upper right 1, lower left 2, lower right 3. *
- * The last four points lie on the far clipping plane, numbered analogous fashion. *
- * upper left 4, upper right 5, lower left 6, lower right 7. *
- * (remember: camera space has x going to the right, y up and z backwards). *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/16/2001 gth : Created. *
- *=============================================================================================*/
- inline const Vector3 * CameraClass::Get_View_Space_Frustum_Corners(void) const
- {
- const FrustumClass & frustum = Get_View_Space_Frustum();
- return frustum.Corners;
- }
- #endif
|