| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826 |
- /*
- ** 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 <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:: /VSS_Sync/ww3d2/camera.cpp $*
- * *
- * Author:: Greg_h *
- * *
- * $Modtime:: 8/29/01 7:29p $*
- * *
- * $Revision:: 22 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * CameraClass::CameraClass -- constructor *
- * CameraClass::CameraClass -- copy constructor *
- * CameraClass::operator == -- assignment operator *
- * CameraClass::~CameraClass -- destructor *
- * CameraClass::Clone -- virtual copy constructor *
- * CameraClass::Add -- add the camera to the world? *
- * CameraClass::Remove -- Remove the camera from the world? *
- * CameraClass::Get_Obj_Space_Bounding_Sphere -- returns the object space bounding sphere *
- * CameraClass::Get_Object_Space_Bounding_Box -- returns the object space bounding box *
- * CameraClass::Set_Transform -- set the transform of the camera *
- * CameraClass::Set_Position -- Set the position of the camera *
- * CameraClass::Set_Animation -- set the animation state of the camera *
- * CameraClass::Set_Animation -- Set the animation state of the camera *
- * CameraClass::Set_Animation -- set the animation state of the camera *
- * CameraClass::Set_Animation -- set the animation state of the camera *
- * CameraClass::Set_View_Plane -- control over the view plane *
- * CameraClass::Set_View_Plane -- set the viewplane using fov angles *
- * CameraClass::Set_Focal_Length -- set the view plane using focal length and aspect ratio *
- * CameraClass::Get_View_Plane -- get the corners of the current view plane *
- * CameraClass::Project -- project a point from ws to the view plane *
- * CameraClass::Project_Camera_Space_Point -- Project a point that is already in camera spac *
- * CameraClass::Un_Project -- "unproject" a point from the view plane to world space *
- * CameraClass::Transform_To_View_Space -- transforms the given world space point to camera *
- * CameraClass::Rotate_To_View_Space -- rotates the given world space vector to camera space *
- * CameraClass::Get_Near_Clip_Bounding_Box -- returns an obb that contains near clip plane *
- * CameraCLass::Update_Frustum -- updates the frustum parameters *
- * CameraClass::Cull_Box -- tests whether the given box can be culled *
- * CameraClass::Device_To_View_Space -- converts the given device coordinate to view space *
- * CameraClass::Device_To_World_Space -- converts given device coord to world space *
- * CameraClass::Camera_Push -- pushes the camera's parameters into the given GERD *
- * CameraClass::Camera_Pop -- pops the camera's parameters from the given GERD *
- * CameraClass::Set_Aspect_Ratio -- sets the aspect ratio of the camera *
- * CameraClass::Apply_D3D_State -- sets the D3D states controlled by the camera *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "camera.h"
- #include "ww3d.h"
- #include "matrix4.h"
- #include "dx8wrapper.h"
- /***********************************************************************************************
- * CameraClass::CameraClass -- constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- CameraClass::CameraClass(void) :
- Projection(PERSPECTIVE),
- Viewport(Vector2(0,0),Vector2(1,1)), // pixel viewport to render into
- AspectRatio(4.0f/3.0f),
- ZNear(1.0f), // near clip plane distance
- ZFar(1000.0f), // far clip plane distance
- ZBufferMin(0.0f), // smallest value we'll write into the z-buffer
- ZBufferMax(1.0f), // largest value we'll write into the z-buffer
- FrustumValid(false)
- {
- Set_Transform(Matrix3D(1));
- Set_View_Plane(DEG_TO_RADF(50.0f));
- }
- /***********************************************************************************************
- * CameraClass::CameraClass -- copy constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- * 4/13/2001 hy : added in copy code for new member functions *
- *=============================================================================================*/
- CameraClass::CameraClass(const CameraClass & src) :
- RenderObjClass(src),
- Projection(src.Projection),
- Viewport(src.Viewport),
- ViewPlane(src.ViewPlane),
- ZNear(src.ZNear),
- ZFar(src.ZFar),
- FrustumValid(src.FrustumValid),
- Frustum(src.Frustum),
- NearClipBBox(src.NearClipBBox),
- ProjectionTransform(src.ProjectionTransform),
- CameraInvTransform(src.CameraInvTransform),
- AspectRatio(src.AspectRatio),
- ZBufferMin(src.ZBufferMin),
- ZBufferMax(src.ZBufferMax)
- {
- // just being paraniod in case any parent class doesn't completely copy the entire state...
- FrustumValid = false;
- }
- /***********************************************************************************************
- * CameraClass::operator == -- assignment operator *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- CameraClass & CameraClass::operator = (const CameraClass & that)
- {
- if (this != &that) {
- RenderObjClass::operator = (that);
-
- Projection = that.Projection;
- Viewport = that.Viewport;
- ViewPlane = that.ViewPlane;
- ZNear = that.ZNear;
- ZFar = that.ZFar;
- FrustumValid = that.FrustumValid;
- Frustum = that.Frustum;
- NearClipBBox = that.NearClipBBox;
- ProjectionTransform = that.ProjectionTransform;
- CameraInvTransform = that.CameraInvTransform;
-
- // just being paraniod in case any parent class doesn't completely copy the entire state...
- FrustumValid = false;
- }
- return * this;
- }
- /***********************************************************************************************
- * CameraClass::~CameraClass -- destructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- CameraClass::~CameraClass(void)
- {
- }
- /***********************************************************************************************
- * CameraClass::Clone -- virtual copy constructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- RenderObjClass * CameraClass::Clone(void) const
- {
- return NEW_REF( CameraClass, (*this) );
- }
- /***********************************************************************************************
- * CameraClass::Get_Obj_Space_Bounding_Sphere -- returns the object space bounding sphere *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 9/29/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const
- {
- sphere.Center.Set(0,0,0);
- sphere.Radius = ZFar; // could optimize this but its not really used.
- }
- /***********************************************************************************************
- * CameraClass::Get_Object_Space_Bounding_Box -- returns the object space bounding box *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 9/29/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
- {
- box.Center.Set(0,0,0);
- box.Extent.Set(ZFar,ZFar,ZFar); // could optimize this but its not really used.
- }
- /***********************************************************************************************
- * CameraClass::Set_Transform -- set the transform of the camera *
- * *
- * This is over-ridden to invalidate the cached frustum parameters *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/29/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Set_Transform(const Matrix3D &m)
- {
- RenderObjClass::Set_Transform(m);
- FrustumValid = false;
- }
- /***********************************************************************************************
- * CameraClass::Set_Position -- Set the position of the camera *
- * *
- * This is overriden to invalidate the cached frustum parameters *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/29/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Set_Position(const Vector3 &v)
- {
- RenderObjClass::Set_Position(v);
- FrustumValid = false;
- }
- /***********************************************************************************************
- * CameraClass::Set_View_Plane -- control over the view plane *
- * *
- * INPUT: *
- * min - x,y of the upper left corner of the view rectangle (dist is assumed to be 1.0) *
- * max - x,y of the lower right corner of the view rectangle *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Set_View_Plane(const Vector2 & vmin,const Vector2 & vmax)
- {
- ViewPlane.Min = vmin;
- ViewPlane.Max = vmax;
- AspectRatio = (vmax.X - vmin.X) / (vmax.Y - vmin.Y);
- FrustumValid = false;
- }
- /***********************************************************************************************
- * CameraClass::Set_View_Plane -- set the viewplane using fov angles *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Set_View_Plane(float hfov,float vfov)
- {
- float width_half = tan(hfov/2.0);
- float height_half = 0.0f;
-
- if (vfov == -1) {
- height_half = (1.0f / AspectRatio) * width_half; // use the aspect ratio
- } else {
- height_half = tan(vfov/2.0);
- AspectRatio = width_half / height_half; // or, initialize the aspect ratio
- }
-
- ViewPlane.Min.Set(-width_half,-height_half);
- ViewPlane.Max.Set(width_half,height_half);
-
- FrustumValid = false;
- }
- /***********************************************************************************************
- * CameraClass::Set_Aspect_Ratio -- sets the aspect ratio of the camera *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/29/2001 gth : Created. *
- *=============================================================================================*/
- void CameraClass::Set_Aspect_Ratio(float width_to_height)
- {
- AspectRatio = width_to_height;
- ViewPlane.Min.Y = ViewPlane.Min.X / AspectRatio;
- ViewPlane.Max.Y = ViewPlane.Max.X / AspectRatio;
- FrustumValid = false;
- }
- /***********************************************************************************************
- * CameraClass::Get_View_Plane -- get the corners of the current view plane *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Get_View_Plane(Vector2 & set_min,Vector2 & set_max) const
- {
- set_min = ViewPlane.Min;
- set_max = ViewPlane.Max;
- }
- /***********************************************************************************************
- * CameraClass::Project -- project a point from ws to the view plane *
- * *
- * INPUT: *
- * dest - will be set to a point on the normalized view plane. x,y, and z range from -1 to 1 *
- * ws_point - input point in world space *
- * *
- * OUTPUT: *
- * ProjectionResType indicating whether the point was in the frustum *
- * *
- * WARNINGS: *
- * When the input is behind the near clip plane, 0,0,0 is returned. *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- CameraClass::ProjectionResType CameraClass::Project(Vector3 & dest,const Vector3 & ws_point) const
- {
- Update_Frustum();
- Vector3 cam_point;
- Matrix3D::Transform_Vector(CameraInvTransform,ws_point,&cam_point);
- if (cam_point.Z > -ZNear) {
- dest.Set(0,0,0);
- return OUTSIDE_NEAR_CLIP;
- }
- Vector4 view_point = ProjectionTransform * cam_point;
- float oow = 1.0f / view_point.W;
- dest.X = view_point.X * oow;
- dest.Y = view_point.Y * oow;
- dest.Z = view_point.Z * oow;
- if (dest.Z > 1.0f) {
- return OUTSIDE_FAR_CLIP;
- }
- if ((dest.X < -1.0f) || (dest.X > 1.0f) || (dest.Y < -1.0f) || (dest.Y > 1.0f)) {
- return OUTSIDE_FRUSTUM;
- }
- return INSIDE_FRUSTUM;
- }
- /***********************************************************************************************
- * CameraClass::Project_Camera_Space_Point -- Project a point that is already in camera space *
- * *
- * INPUT: *
- * dest - will be set to a point on the normalized view plane. x,y, and z range from -1 to 1 *
- * cam_point - input point in camera space *
- * *
- * OUTPUT: *
- * ProjectionResType indicating whether the point was in the frustum *
- * *
- * WARNINGS: *
- * When the input is behind the near clip plane, 0,0,0 is returned. *
- * *
- * HISTORY: *
- * 11/17/2000 gth : Created. *
- *=============================================================================================*/
- CameraClass::ProjectionResType
- CameraClass::Project_Camera_Space_Point(Vector3 & dest,const Vector3 & cam_point) const
- {
- Update_Frustum();
- if ( cam_point.Z > -ZNear + WWMATH_EPSILON) {
- dest.Set(0,0,0);
- return OUTSIDE_NEAR_CLIP;
- }
- Vector4 view_point = ProjectionTransform * cam_point;
- float oow = 1.0f / view_point.W;
- dest.X = view_point.X * oow;
- dest.Y = view_point.Y * oow;
- dest.Z = view_point.Z * oow;
- if (dest.Z > 1.0f) {
- return OUTSIDE_FAR_CLIP;
- }
- if ((dest.X < -1.0f) || (dest.X > 1.0f) || (dest.Y < -1.0f) || (dest.Y > 1.0f)) {
- return OUTSIDE_FRUSTUM;
- }
- return INSIDE_FRUSTUM;
- }
- /***********************************************************************************************
- * CameraClass::Un_Project -- "unproject" a point from the view plane to world space *
- * *
- * The given point is assumed to be on the view_plane at z=-1. The 3D world space point that *
- * this represents will be returned in dest. *
- * *
- * INPUT: *
- * dest - will be filled in with the 3D world space point that the given point represents *
- * view_point - point on the view_plane to be un-projected *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 3/21/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Un_Project(Vector3 & dest,const Vector2 & view_point) const
- {
- /*
- ** map view_point.X from -1..1 to ViewPlaneMin.X..ViewPlaneMax.X
- ** map view_point.Y from -1..1 to ViewPlaneMin.X..ViewPlaneMax.X
- */
- float vpdx = ViewPlane.Max.X - ViewPlane.Min.X;
- float vpdy = ViewPlane.Max.Y - ViewPlane.Min.Y;
-
- Vector3 point;
- point.X = ViewPlane.Min.X + vpdx * (view_point.X + 1.0f) * 0.5f;
- point.Y = ViewPlane.Min.Y + vpdy * (view_point.Y + 1.0f) * 0.5f;
- point.Z = -1.0f;
- Matrix3D::Transform_Vector(Transform,point,&dest);
- }
-
- /***********************************************************************************************
- * CameraClass::Transform_To_View_Space -- transforms the given world space point to camera sp *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/22/2001 gth : Created. *
- *=============================================================================================*/
- void CameraClass::Transform_To_View_Space(Vector3 & dest,const Vector3 & ws_point) const
- {
- Update_Frustum();
- Matrix3D::Transform_Vector(CameraInvTransform,ws_point,&dest);
- }
-
- /***********************************************************************************************
- * CameraClass::Rotate_To_View_Space -- rotates the given world space vector to camera space *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 2/22/2001 gth : Created. *
- *=============================================================================================*/
- void CameraClass::Rotate_To_View_Space(Vector3 & dest,const Vector3 & ws_vector) const
- {
- Update_Frustum();
- Matrix3D::Rotate_Vector(CameraInvTransform,ws_vector,&dest);
- }
- /***********************************************************************************************
- * CameraClass::Get_Near_Clip_Bounding_Box -- returns an obb that contains near clip plane *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 8/25/99 GTH : Created. *
- *=============================================================================================*/
- const OBBoxClass & CameraClass::Get_Near_Clip_Bounding_Box(void) const
- {
- Update_Frustum();
- return NearClipBBox;
- }
- /***********************************************************************************************
- * CameraClass::Cull_Box -- tests whether the given box can be culled *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/8/98 GTH : Created. *
- *=============================================================================================*/
- bool CameraClass::Cull_Box(const AABoxClass & box) const
- {
- const FrustumClass & frustum = Get_Frustum();
- return CollisionMath::Overlap_Test(frustum,box) == CollisionMath::OUTSIDE;
- }
- /***********************************************************************************************
- * CameraClass::Update_Frustum -- updates the frustum parameters *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 5/29/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Update_Frustum(void) const
- {
- if (FrustumValid) return;
- Vector2 vpmin,vpmax;
- float znear,zfar;
- float znear_dist,zfar_dist;
- Matrix3D cam_mat = Get_Transform();
- Get_View_Plane(vpmin, vpmax); // Normalized view plane at a depth of 1.0
- Get_Clip_Planes(znear_dist, zfar_dist);
- // Forward is negative Z in our viewspace coordinate system.
- znear = -znear_dist;
- zfar = -zfar_dist;
- // Update the frustum
- FrustumValid = true;
- Frustum.Init(cam_mat,vpmin,vpmax,znear,zfar);
- ViewSpaceFrustum.Init(Matrix3D(1),vpmin,vpmax,znear,zfar);
- // Update the OBB around the near clip rectangle
- #ifdef ALLOW_TEMPORARIES
- NearClipBBox.Center = cam_mat * Vector3(0,0,znear);
- #else
- cam_mat.mulVector3(Vector3(0,0,znear), NearClipBBox.Center);
- #endif
- NearClipBBox.Extent.X = (vpmax.X - vpmin.X) * (-znear) * 0.5f; // (near_clip_x / |znear|) == (vpmin.X / 1.0f)...
- NearClipBBox.Extent.Y = (vpmax.Y - vpmin.Y) * (-znear) * 0.5f;
- NearClipBBox.Extent.Z = 0.01f;
- NearClipBBox.Basis.Set(cam_mat);
- // Update the inverse camera matrix
- Transform.Get_Inverse(CameraInvTransform);
- // Update the projection matrix
- if (Projection == PERSPECTIVE) {
- ProjectionTransform.Init_Perspective( vpmin.X*znear_dist, vpmax.X*znear_dist,
- vpmin.Y*znear_dist, vpmax.Y*znear_dist,
- znear_dist, zfar_dist );
- } else {
-
- ProjectionTransform.Init_Ortho( vpmin.X,vpmax.X,vpmin.Y,vpmax.Y,znear_dist,zfar_dist);
- }
- }
- /***********************************************************************************************
- * CameraClass::Device_To_View_Space -- converts the given device coordinate to view space *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/8/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Device_To_View_Space(const Vector2 & device_coord,Vector3 * set_view)
- {
- int res_width;
- int res_height;
- int res_bits;
- bool windowed;
- WW3D::Get_Render_Target_Resolution(res_width,res_height,res_bits,windowed);
- // convert the device coordinates into normalized device coordinates:
- Vector2 ndev;
- ndev.X = device_coord.X / (float)res_width;
- ndev.Y = device_coord.Y / (float)res_height;
- // view space rectangle which corresponds to the viewport
- Vector2 vs_min;
- Vector2 vs_max;
- Get_View_Plane(vs_min,vs_max);
-
- // mapping from the viewport coordinates to view space coordinates
- set_view->X = vs_min.X + (ndev.X - Viewport.Min.X) * (vs_max.X - vs_min.X) / (Viewport.Width());
- set_view->Y = vs_max.Y - (ndev.Y - Viewport.Min.Y) * (vs_max.Y - vs_min.Y) / (Viewport.Height());
- set_view->Z = -1.0f;
- }
- /***********************************************************************************************
- * CameraClass::Device_To_World_Space -- converts given device coord to world space *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 12/8/98 GTH : Created. *
- *=============================================================================================*/
- void CameraClass::Device_To_World_Space(const Vector2 & device_coord,Vector3 * world_coord)
- {
- Vector3 vs;
- Device_To_View_Space(device_coord,&vs);
- Matrix3D::Transform_Vector(Transform,vs,world_coord);
- }
- /***********************************************************************************************
- * CameraClass::Apply -- sets the D3D states controlled by the camera *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/29/2001 gth : Created. *
- *=============================================================================================*/
- void CameraClass::Apply(void)
- {
- Update_Frustum();
- int width,height,bits;
- bool windowed;
- WW3D::Get_Render_Target_Resolution(width,height,bits,windowed);
-
- D3DVIEWPORT8 vp;
- vp.X = (DWORD)(Viewport.Min.X * (float)width);
- vp.Y = (DWORD)(Viewport.Min.Y * (float)height);
- vp.Width = (DWORD)((Viewport.Max.X - Viewport.Min.X) * (float)width);
- vp.Height = (DWORD)((Viewport.Max.Y - Viewport.Min.Y) * (float)height);
- vp.MinZ = ZBufferMin;
- vp.MaxZ = ZBufferMax;
- DX8Wrapper::Set_Viewport(&vp);
- Matrix4 d3dprojection;
- Get_D3D_Projection_Matrix(&d3dprojection);
- DX8Wrapper::Set_Transform(D3DTS_PROJECTION,d3dprojection);
- DX8Wrapper::Set_Transform(D3DTS_VIEW,CameraInvTransform);
- }
- void CameraClass::Set_Clip_Planes(float znear,float zfar)
- {
- FrustumValid = false;
- ZNear = znear;
- ZFar = zfar;
- }
- void CameraClass::Get_Clip_Planes(float & znear,float & zfar) const
- {
- znear = ZNear;
- zfar = ZFar;
- }
- float CameraClass::Get_Horizontal_FOV(void) const
- {
- float width = ViewPlane.Max.X - ViewPlane.Min.X;
- return 2*WWMath::Atan2(width,2.0);
- }
- float CameraClass::Get_Vertical_FOV(void) const
- {
- float height = ViewPlane.Max.Y - ViewPlane.Min.Y;
- return 2*WWMath::Atan2(height,2.0);
- }
- float CameraClass::Get_Aspect_Ratio(void) const
- {
- return AspectRatio;
- }
- void CameraClass::Get_Projection_Matrix(Matrix4 * set_tm)
- {
- WWASSERT(set_tm != NULL);
-
- Update_Frustum();
- *set_tm = ProjectionTransform;
- }
- void CameraClass::Get_D3D_Projection_Matrix(Matrix4 * set_tm)
- {
- WWASSERT(set_tm != NULL);
- Update_Frustum();
- *set_tm = ProjectionTransform;
- /*
- ** We need to flip the handed-ness of the projection matrix and
- ** move the z-range to 0<z<1 rather than -1<z<1
- */
- float oozdiff = 1.0 / (ZFar - ZNear);
- if (Projection == PERSPECTIVE) {
- (*set_tm)[2][2] = -(ZFar) * oozdiff;
- (*set_tm)[2][3] = -(ZFar*ZNear) * oozdiff;
- } else {
- (*set_tm)[2][2] = -oozdiff;
- (*set_tm)[2][3] = -ZNear * oozdiff;
- }
- }
- void CameraClass::Get_View_Matrix(Matrix3D * set_tm)
- {
- WWASSERT(set_tm != NULL);
- Update_Frustum();
- *set_tm = CameraInvTransform;
- }
- const Matrix4 & CameraClass::Get_Projection_Matrix(void)
- {
- Update_Frustum();
- return ProjectionTransform;
- }
- const Matrix3D & CameraClass::Get_View_Matrix(void)
- {
- Update_Frustum();
- return CameraInvTransform;
- }
- void CameraClass::Convert_Old(Vector3 &pos)
- {
- pos.X=(pos.X+1)/2;
- pos.Y=(pos.Y+1)/2;
- }
- float CameraClass::Compute_Projected_Sphere_Radius(float dist,float radius)
- {
- Vector4 result = ProjectionTransform * Vector4(radius,0.0f,dist,1.0f);
- return result.X / result.W;
- }
|