This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Tools/W3DView/CameraSettingsDialog.cpp

402 lines
11 KiB
C++

/*
** 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 <http://www.gnu.org/licenses/>.
*/
// 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);
}