/* ** Command & Conquer Renegade(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 . */ // CameraSettingsDialog.cpp : implementation file // #include "stdafx.h" #include "w3dview.h" #include "w3dviewdoc.h" #include "graphicview.h" #include "CameraSettingsDialog.h" #include "utils.h" #include "camera.h" #include "viewerscene.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // // CameraSettingsDialogClass // ///////////////////////////////////////////////////////////////////////////// CameraSettingsDialogClass::CameraSettingsDialogClass(CWnd* pParent /*=NULL*/) : CDialog(CameraSettingsDialogClass::IDD, pParent) { //{{AFX_DATA_INIT(CameraSettingsDialogClass) //}}AFX_DATA_INIT return ; } ///////////////////////////////////////////////////////////////////////////// // // DoDataExchange // ///////////////////////////////////////////////////////////////////////////// void CameraSettingsDialogClass::DoDataExchange (CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CameraSettingsDialogClass) DDX_Control(pDX, IDC_LENS_SPIN, m_LensSpin); DDX_Control(pDX, IDC_FAR_CLIP_SPIN, m_FarClipSpin); DDX_Control(pDX, IDC_VFOV_SPIN, m_VFOVSpin); DDX_Control(pDX, IDC_NEAR_CLIP_SPIN, m_NearClipSpin); DDX_Control(pDX, IDC_HFOV_SPIN, m_HFOVSpin); //}}AFX_DATA_MAP return ; } BEGIN_MESSAGE_MAP(CameraSettingsDialogClass, CDialog) //{{AFX_MSG_MAP(CameraSettingsDialogClass) ON_BN_CLICKED(IDC_FOV_CHECK, OnFovCheck) ON_BN_CLICKED(IDC_CLIP_PLANE_CHECK, OnClipPlaneCheck) ON_BN_CLICKED(IDC_RESET, OnReset) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // // OnInitDialog // ///////////////////////////////////////////////////////////////////////////// BOOL CameraSettingsDialogClass::OnInitDialog (void) { CDialog::OnInitDialog (); CW3DViewDoc *doc = ::GetCurrentDocument (); CGraphicView *graphic_view = doc->GetGraphicView (); CameraClass *camera = graphic_view->GetCamera (); // // Enable/disable the group boxes // SendDlgItemMessage (IDC_FOV_CHECK, BM_SETCHECK, (WPARAM)doc->Is_FOV_Manual ()); SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_SETCHECK, (WPARAM)doc->Are_Clip_Planes_Manual ()); float znear = 0; float zfar = 0; camera->Get_Clip_Planes (znear, zfar); ::Initialize_Spinner (m_NearClipSpin, znear, 0.0F, 999999.0F); ::Initialize_Spinner (m_FarClipSpin, zfar, 1.0F, 999999.0F); // // Setup the FOV controls // int hfov_deg = (int)RAD_TO_DEG (camera->Get_Horizontal_FOV ()); int vfov_deg = (int)RAD_TO_DEG (camera->Get_Vertical_FOV ()); ::Initialize_Spinner (m_HFOVSpin, hfov_deg, 0.0F, 180.0F); ::Initialize_Spinner (m_VFOVSpin, vfov_deg, 0.0F, 180.0F); // // Setup the camera lens controls // float hfov = camera->Get_Horizontal_FOV (); const float constant = (18.0F / 1000.0F); float lens = (constant / (::tan (hfov / 2))) * 1000.0F; ::Initialize_Spinner (m_LensSpin, lens, 1.0F, 200.0F); OnFovCheck (); OnClipPlaneCheck (); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // // OnOK // ///////////////////////////////////////////////////////////////////////////// void CameraSettingsDialogClass::OnOK (void) { CW3DViewDoc *doc = ::GetCurrentDocument (); CGraphicView *graphic_view = doc->GetGraphicView (); CameraClass *camera = graphic_view->GetCamera (); bool manual_fov = (SendDlgItemMessage (IDC_FOV_CHECK, BM_GETCHECK) == 1); bool manual_planes = (SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_GETCHECK) == 1); doc->Set_Manual_FOV (manual_fov); doc->Set_Manul_Clip_Planes (manual_planes); if (manual_fov == false) { graphic_view->Reset_FOV (); } else { // // Update the camera's FOV // float hfov_deg = ::GetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT); float vfov_deg = ::GetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT); camera->Set_View_Plane (DEG_TO_RAD (hfov_deg), DEG_TO_RAD (vfov_deg)); } // // Update the camera's clip planes // float znear = ::GetDlgItemFloat (m_hWnd, IDC_NEAR_CLIP_EDIT); float zfar = ::GetDlgItemFloat (m_hWnd, IDC_FAR_CLIP_EDIT); camera->Set_Clip_Planes (znear, zfar); doc->Save_Camera_Settings (); // // Update the fog settings. The fog near clip plane should always be equal // to the camera near clip plane, but the fog far clip plane is scene // dependant. We will be sure to modify only the near clip plane here. // float fog_near, fog_far; doc->GetScene()->Get_Fog_Range(&fog_near, &fog_far); doc->GetScene()->Set_Fog_Range(znear, fog_far); doc->GetScene()->Recalculate_Fog_Planes(); // // Refresh the camera settings // RenderObjClass *render_obj = doc->GetDisplayedObject (); if (render_obj != NULL) { graphic_view->Reset_Camera_To_Display_Object (*render_obj); } CDialog::OnOK (); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnFovCheck // ///////////////////////////////////////////////////////////////////////////// void CameraSettingsDialogClass::OnFovCheck (void) { bool manual_fov = (SendDlgItemMessage (IDC_FOV_CHECK, BM_GETCHECK) == 1); ::EnableWindow (m_VFOVSpin, manual_fov); ::EnableWindow (m_HFOVSpin, manual_fov); ::EnableWindow (m_LensSpin, manual_fov); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_VFOV_EDIT), manual_fov); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_HFOV_EDIT), manual_fov); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_LENS_EDIT), manual_fov); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnClipPlaneCheck // ///////////////////////////////////////////////////////////////////////////// void CameraSettingsDialogClass::OnClipPlaneCheck (void) { bool manual_planes = (SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_GETCHECK) == 1); ::EnableWindow (m_NearClipSpin, manual_planes); ::EnableWindow (m_FarClipSpin, manual_planes); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_NEAR_CLIP_EDIT), manual_planes); ::EnableWindow (::GetDlgItem (m_hWnd, IDC_FAR_CLIP_EDIT), manual_planes); return ; } ///////////////////////////////////////////////////////////////////////////// // // OnReset // ///////////////////////////////////////////////////////////////////////////// void CameraSettingsDialogClass::OnReset (void) { CW3DViewDoc *doc = ::GetCurrentDocument (); CGraphicView *graphic_view = doc->GetGraphicView (); CameraClass *camera = graphic_view->GetCamera (); doc->Set_Manual_FOV (false); doc->Set_Manul_Clip_Planes (false); graphic_view->Reset_FOV (); RenderObjClass *render_obj = doc->GetDisplayedObject (); if (render_obj != NULL) { graphic_view->Reset_Camera_To_Display_Object (*render_obj); } // // Update the clip plane controls // float znear = 0; float zfar = 0; camera->Get_Clip_Planes (znear, zfar); ::SetDlgItemFloat (m_hWnd, IDC_NEAR_CLIP_EDIT, znear); ::SetDlgItemFloat (m_hWnd, IDC_FAR_CLIP_EDIT, zfar); // // Update the FOV controls // int hfov_deg = (int)RAD_TO_DEG (camera->Get_Horizontal_FOV ()); int vfov_deg = (int)RAD_TO_DEG (camera->Get_Vertical_FOV ()); ::SetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT, hfov_deg); ::SetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT, vfov_deg); // // Setup the camera lens controls // float vfov = camera->Get_Vertical_FOV (); float lens = ((::atan ((18.0F / 1000.0F)) / vfov) * 2.0F) * 1000.0F; ::SetDlgItemFloat (m_hWnd, IDC_LENS_EDIT, lens); return ; } //////////////////////////////////////////////////////////////////// // // OnNotify // //////////////////////////////////////////////////////////////////// BOOL CameraSettingsDialogClass::OnNotify ( WPARAM wParam, LPARAM lParam, LRESULT *pResult ) { // // Update the spinner control if necessary // NMHDR *header = (NMHDR *)lParam; if ((header != NULL) && (header->code == UDN_DELTAPOS)) { LPNMUPDOWN updown_info = (LPNMUPDOWN)lParam; ::Update_Spinner_Buddy (header->hwndFrom, updown_info->iDelta); // // Update the FOV settings (they are dependent on each other) // if (updown_info->hdr.idFrom == IDC_LENS_SPIN) { Update_FOV (); } else if (updown_info->hdr.idFrom == IDC_HFOV_SPIN) { Update_Camera_Lens (); } } // Allow the base class to process this message return CDialog::OnNotify (wParam, lParam, pResult); } //////////////////////////////////////////////////////////////////// // // Update_Camera_Lens // //////////////////////////////////////////////////////////////////// void CameraSettingsDialogClass::Update_Camera_Lens (void) { // // Get the current vertical FOV settings // float hfov = ::GetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT); // // Convert the vertical FOV to a camera lens setting // if (hfov > 0) { const float constant = (18.0F / 1000.0F); float lens = (constant / (::tan (DEG_TO_RAD (hfov) / 2))) * 1000.0F; ::SetDlgItemFloat (m_hWnd, IDC_LENS_EDIT, lens); } return ; } //////////////////////////////////////////////////////////////////// // // Update_FOV // //////////////////////////////////////////////////////////////////// void CameraSettingsDialogClass::Update_FOV (void) { // // Get the current camera lens setting // float lens = (::GetDlgItemFloat (m_hWnd, IDC_LENS_EDIT) / 1000.0F); // // Convert the camera lens to a FOV // if (lens > 0) { const float constant = (18.0F / 1000.0F); float hfov = (::atan (constant / lens) * 2.0F); float vfov = (3 * hfov / 4); // // Pass the new FOV settings onto the dialog // ::SetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT, RAD_TO_DEG (hfov)); ::SetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT, RAD_TO_DEG (vfov)); } return ; } //////////////////////////////////////////////////////////////////// // // Update_FOV // //////////////////////////////////////////////////////////////////// BOOL CameraSettingsDialogClass::OnCommand ( WPARAM wParam, LPARAM lParam ) { static bool updating = false; if (updating == false) { // // Update the FOV settings if necessary // if ( LOWORD (wParam) == IDC_HFOV_EDIT && HIWORD (wParam) == EN_UPDATE) { updating = true; Update_Camera_Lens (); updating = false; } else if ( LOWORD (wParam) == IDC_LENS_EDIT && HIWORD (wParam) == EN_UPDATE) { updating = true; Update_FOV (); updating = false; } } return CDialog::OnCommand(wParam, lParam); }