CameraSettingsDialog.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // CameraSettingsDialog.cpp : implementation file
  19. //
  20. #include "stdafx.h"
  21. #include "w3dview.h"
  22. #include "w3dviewdoc.h"
  23. #include "graphicview.h"
  24. #include "CameraSettingsDialog.h"
  25. #include "utils.h"
  26. #include "camera.h"
  27. #include "viewerscene.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. /////////////////////////////////////////////////////////////////////////////
  34. //
  35. // CameraSettingsDialogClass
  36. //
  37. /////////////////////////////////////////////////////////////////////////////
  38. CameraSettingsDialogClass::CameraSettingsDialogClass(CWnd* pParent /*=NULL*/)
  39. : CDialog(CameraSettingsDialogClass::IDD, pParent)
  40. {
  41. //{{AFX_DATA_INIT(CameraSettingsDialogClass)
  42. //}}AFX_DATA_INIT
  43. return ;
  44. }
  45. /////////////////////////////////////////////////////////////////////////////
  46. //
  47. // DoDataExchange
  48. //
  49. /////////////////////////////////////////////////////////////////////////////
  50. void
  51. CameraSettingsDialogClass::DoDataExchange (CDataExchange* pDX)
  52. {
  53. CDialog::DoDataExchange(pDX);
  54. //{{AFX_DATA_MAP(CameraSettingsDialogClass)
  55. DDX_Control(pDX, IDC_LENS_SPIN, m_LensSpin);
  56. DDX_Control(pDX, IDC_FAR_CLIP_SPIN, m_FarClipSpin);
  57. DDX_Control(pDX, IDC_VFOV_SPIN, m_VFOVSpin);
  58. DDX_Control(pDX, IDC_NEAR_CLIP_SPIN, m_NearClipSpin);
  59. DDX_Control(pDX, IDC_HFOV_SPIN, m_HFOVSpin);
  60. //}}AFX_DATA_MAP
  61. return ;
  62. }
  63. BEGIN_MESSAGE_MAP(CameraSettingsDialogClass, CDialog)
  64. //{{AFX_MSG_MAP(CameraSettingsDialogClass)
  65. ON_BN_CLICKED(IDC_FOV_CHECK, OnFovCheck)
  66. ON_BN_CLICKED(IDC_CLIP_PLANE_CHECK, OnClipPlaneCheck)
  67. ON_BN_CLICKED(IDC_RESET, OnReset)
  68. //}}AFX_MSG_MAP
  69. END_MESSAGE_MAP()
  70. /////////////////////////////////////////////////////////////////////////////
  71. //
  72. // OnInitDialog
  73. //
  74. /////////////////////////////////////////////////////////////////////////////
  75. BOOL
  76. CameraSettingsDialogClass::OnInitDialog (void)
  77. {
  78. CDialog::OnInitDialog ();
  79. CW3DViewDoc *doc = ::GetCurrentDocument ();
  80. CGraphicView *graphic_view = doc->GetGraphicView ();
  81. CameraClass *camera = graphic_view->GetCamera ();
  82. //
  83. // Enable/disable the group boxes
  84. //
  85. SendDlgItemMessage (IDC_FOV_CHECK, BM_SETCHECK, (WPARAM)doc->Is_FOV_Manual ());
  86. SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_SETCHECK, (WPARAM)doc->Are_Clip_Planes_Manual ());
  87. float znear = 0;
  88. float zfar = 0;
  89. camera->Get_Clip_Planes (znear, zfar);
  90. ::Initialize_Spinner (m_NearClipSpin, znear, 0.0F, 999999.0F);
  91. ::Initialize_Spinner (m_FarClipSpin, zfar, 1.0F, 999999.0F);
  92. //
  93. // Setup the FOV controls
  94. //
  95. int hfov_deg = (int)RAD_TO_DEG (camera->Get_Horizontal_FOV ());
  96. int vfov_deg = (int)RAD_TO_DEG (camera->Get_Vertical_FOV ());
  97. ::Initialize_Spinner (m_HFOVSpin, hfov_deg, 0.0F, 180.0F);
  98. ::Initialize_Spinner (m_VFOVSpin, vfov_deg, 0.0F, 180.0F);
  99. //
  100. // Setup the camera lens controls
  101. //
  102. float hfov = camera->Get_Horizontal_FOV ();
  103. const float constant = (18.0F / 1000.0F);
  104. float lens = (constant / (::tan (hfov / 2))) * 1000.0F;
  105. ::Initialize_Spinner (m_LensSpin, lens, 1.0F, 200.0F);
  106. OnFovCheck ();
  107. OnClipPlaneCheck ();
  108. return TRUE;
  109. }
  110. /////////////////////////////////////////////////////////////////////////////
  111. //
  112. // OnOK
  113. //
  114. /////////////////////////////////////////////////////////////////////////////
  115. void
  116. CameraSettingsDialogClass::OnOK (void)
  117. {
  118. CW3DViewDoc *doc = ::GetCurrentDocument ();
  119. CGraphicView *graphic_view = doc->GetGraphicView ();
  120. CameraClass *camera = graphic_view->GetCamera ();
  121. bool manual_fov = (SendDlgItemMessage (IDC_FOV_CHECK, BM_GETCHECK) == 1);
  122. bool manual_planes = (SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_GETCHECK) == 1);
  123. doc->Set_Manual_FOV (manual_fov);
  124. doc->Set_Manul_Clip_Planes (manual_planes);
  125. if (manual_fov == false) {
  126. graphic_view->Reset_FOV ();
  127. } else {
  128. //
  129. // Update the camera's FOV
  130. //
  131. float hfov_deg = ::GetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT);
  132. float vfov_deg = ::GetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT);
  133. camera->Set_View_Plane (DEG_TO_RAD (hfov_deg), DEG_TO_RAD (vfov_deg));
  134. }
  135. //
  136. // Update the camera's clip planes
  137. //
  138. float znear = ::GetDlgItemFloat (m_hWnd, IDC_NEAR_CLIP_EDIT);
  139. float zfar = ::GetDlgItemFloat (m_hWnd, IDC_FAR_CLIP_EDIT);
  140. camera->Set_Clip_Planes (znear, zfar);
  141. doc->Save_Camera_Settings ();
  142. //
  143. // Update the fog settings. The fog near clip plane should always be equal
  144. // to the camera near clip plane, but the fog far clip plane is scene
  145. // dependant. We will be sure to modify only the near clip plane here.
  146. //
  147. float fog_near, fog_far;
  148. doc->GetScene()->Get_Fog_Range(&fog_near, &fog_far);
  149. doc->GetScene()->Set_Fog_Range(znear, fog_far);
  150. doc->GetScene()->Recalculate_Fog_Planes();
  151. //
  152. // Refresh the camera settings
  153. //
  154. RenderObjClass *render_obj = doc->GetDisplayedObject ();
  155. if (render_obj != NULL) {
  156. graphic_view->Reset_Camera_To_Display_Object (*render_obj);
  157. }
  158. CDialog::OnOK ();
  159. return ;
  160. }
  161. /////////////////////////////////////////////////////////////////////////////
  162. //
  163. // OnFovCheck
  164. //
  165. /////////////////////////////////////////////////////////////////////////////
  166. void
  167. CameraSettingsDialogClass::OnFovCheck (void)
  168. {
  169. bool manual_fov = (SendDlgItemMessage (IDC_FOV_CHECK, BM_GETCHECK) == 1);
  170. ::EnableWindow (m_VFOVSpin, manual_fov);
  171. ::EnableWindow (m_HFOVSpin, manual_fov);
  172. ::EnableWindow (m_LensSpin, manual_fov);
  173. ::EnableWindow (::GetDlgItem (m_hWnd, IDC_VFOV_EDIT), manual_fov);
  174. ::EnableWindow (::GetDlgItem (m_hWnd, IDC_HFOV_EDIT), manual_fov);
  175. ::EnableWindow (::GetDlgItem (m_hWnd, IDC_LENS_EDIT), manual_fov);
  176. return ;
  177. }
  178. /////////////////////////////////////////////////////////////////////////////
  179. //
  180. // OnClipPlaneCheck
  181. //
  182. /////////////////////////////////////////////////////////////////////////////
  183. void
  184. CameraSettingsDialogClass::OnClipPlaneCheck (void)
  185. {
  186. bool manual_planes = (SendDlgItemMessage (IDC_CLIP_PLANE_CHECK, BM_GETCHECK) == 1);
  187. ::EnableWindow (m_NearClipSpin, manual_planes);
  188. ::EnableWindow (m_FarClipSpin, manual_planes);
  189. ::EnableWindow (::GetDlgItem (m_hWnd, IDC_NEAR_CLIP_EDIT), manual_planes);
  190. ::EnableWindow (::GetDlgItem (m_hWnd, IDC_FAR_CLIP_EDIT), manual_planes);
  191. return ;
  192. }
  193. /////////////////////////////////////////////////////////////////////////////
  194. //
  195. // OnReset
  196. //
  197. /////////////////////////////////////////////////////////////////////////////
  198. void
  199. CameraSettingsDialogClass::OnReset (void)
  200. {
  201. CW3DViewDoc *doc = ::GetCurrentDocument ();
  202. CGraphicView *graphic_view = doc->GetGraphicView ();
  203. CameraClass *camera = graphic_view->GetCamera ();
  204. doc->Set_Manual_FOV (false);
  205. doc->Set_Manul_Clip_Planes (false);
  206. graphic_view->Reset_FOV ();
  207. RenderObjClass *render_obj = doc->GetDisplayedObject ();
  208. if (render_obj != NULL) {
  209. graphic_view->Reset_Camera_To_Display_Object (*render_obj);
  210. }
  211. //
  212. // Update the clip plane controls
  213. //
  214. float znear = 0;
  215. float zfar = 0;
  216. camera->Get_Clip_Planes (znear, zfar);
  217. ::SetDlgItemFloat (m_hWnd, IDC_NEAR_CLIP_EDIT, znear);
  218. ::SetDlgItemFloat (m_hWnd, IDC_FAR_CLIP_EDIT, zfar);
  219. //
  220. // Update the FOV controls
  221. //
  222. int hfov_deg = (int)RAD_TO_DEG (camera->Get_Horizontal_FOV ());
  223. int vfov_deg = (int)RAD_TO_DEG (camera->Get_Vertical_FOV ());
  224. ::SetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT, hfov_deg);
  225. ::SetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT, vfov_deg);
  226. //
  227. // Setup the camera lens controls
  228. //
  229. float vfov = camera->Get_Vertical_FOV ();
  230. float lens = ((::atan ((18.0F / 1000.0F)) / vfov) * 2.0F) * 1000.0F;
  231. ::SetDlgItemFloat (m_hWnd, IDC_LENS_EDIT, lens);
  232. return ;
  233. }
  234. ////////////////////////////////////////////////////////////////////
  235. //
  236. // OnNotify
  237. //
  238. ////////////////////////////////////////////////////////////////////
  239. BOOL
  240. CameraSettingsDialogClass::OnNotify
  241. (
  242. WPARAM wParam,
  243. LPARAM lParam,
  244. LRESULT *pResult
  245. )
  246. {
  247. //
  248. // Update the spinner control if necessary
  249. //
  250. NMHDR *header = (NMHDR *)lParam;
  251. if ((header != NULL) && (header->code == UDN_DELTAPOS)) {
  252. LPNMUPDOWN updown_info = (LPNMUPDOWN)lParam;
  253. ::Update_Spinner_Buddy (header->hwndFrom, updown_info->iDelta);
  254. //
  255. // Update the FOV settings (they are dependent on each other)
  256. //
  257. if (updown_info->hdr.idFrom == IDC_LENS_SPIN) {
  258. Update_FOV ();
  259. } else if (updown_info->hdr.idFrom == IDC_HFOV_SPIN) {
  260. Update_Camera_Lens ();
  261. }
  262. }
  263. // Allow the base class to process this message
  264. return CDialog::OnNotify (wParam, lParam, pResult);
  265. }
  266. ////////////////////////////////////////////////////////////////////
  267. //
  268. // Update_Camera_Lens
  269. //
  270. ////////////////////////////////////////////////////////////////////
  271. void
  272. CameraSettingsDialogClass::Update_Camera_Lens (void)
  273. {
  274. //
  275. // Get the current vertical FOV settings
  276. //
  277. float hfov = ::GetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT);
  278. //
  279. // Convert the vertical FOV to a camera lens setting
  280. //
  281. if (hfov > 0) {
  282. const float constant = (18.0F / 1000.0F);
  283. float lens = (constant / (::tan (DEG_TO_RAD (hfov) / 2))) * 1000.0F;
  284. ::SetDlgItemFloat (m_hWnd, IDC_LENS_EDIT, lens);
  285. }
  286. return ;
  287. }
  288. ////////////////////////////////////////////////////////////////////
  289. //
  290. // Update_FOV
  291. //
  292. ////////////////////////////////////////////////////////////////////
  293. void
  294. CameraSettingsDialogClass::Update_FOV (void)
  295. {
  296. //
  297. // Get the current camera lens setting
  298. //
  299. float lens = (::GetDlgItemFloat (m_hWnd, IDC_LENS_EDIT) / 1000.0F);
  300. //
  301. // Convert the camera lens to a FOV
  302. //
  303. if (lens > 0) {
  304. const float constant = (18.0F / 1000.0F);
  305. float hfov = (::atan (constant / lens) * 2.0F);
  306. float vfov = (3 * hfov / 4);
  307. //
  308. // Pass the new FOV settings onto the dialog
  309. //
  310. ::SetDlgItemFloat (m_hWnd, IDC_HFOV_EDIT, RAD_TO_DEG (hfov));
  311. ::SetDlgItemFloat (m_hWnd, IDC_VFOV_EDIT, RAD_TO_DEG (vfov));
  312. }
  313. return ;
  314. }
  315. ////////////////////////////////////////////////////////////////////
  316. //
  317. // Update_FOV
  318. //
  319. ////////////////////////////////////////////////////////////////////
  320. BOOL
  321. CameraSettingsDialogClass::OnCommand
  322. (
  323. WPARAM wParam,
  324. LPARAM lParam
  325. )
  326. {
  327. static bool updating = false;
  328. if (updating == false) {
  329. //
  330. // Update the FOV settings if necessary
  331. //
  332. if ( LOWORD (wParam) == IDC_HFOV_EDIT &&
  333. HIWORD (wParam) == EN_UPDATE)
  334. {
  335. updating = true;
  336. Update_Camera_Lens ();
  337. updating = false;
  338. } else if ( LOWORD (wParam) == IDC_LENS_EDIT &&
  339. HIWORD (wParam) == EN_UPDATE)
  340. {
  341. updating = true;
  342. Update_FOV ();
  343. updating = false;
  344. }
  345. }
  346. return CDialog::OnCommand(wParam, lParam);
  347. }