EmitterPropertySheet.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  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. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : W3DView *
  23. * *
  24. * $Archive:: /VSS_Sync/W3DView/EmitterPropertySheet.cpp $Modtime:: $*
  25. * *
  26. * $Revision:: 12 $*
  27. * *
  28. *---------------------------------------------------------------------------------------------*
  29. * Functions: *
  30. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  31. #include "StdAfx.H"
  32. #include "W3DView.H"
  33. #include "EmitterPropertySheet.H"
  34. #include "Part_Emt.H"
  35. #include "Part_Ldr.H"
  36. #include "AssetMgr.H"
  37. #include "W3DViewDoc.H"
  38. #include "Utils.H"
  39. #include "DataTreeView.H"
  40. #include "AssetInfo.H"
  41. #include "texture.h"
  42. #include "EmitterInstanceList.H"
  43. #ifdef _DEBUG
  44. #define new DEBUG_NEW
  45. #undef THIS_FILE
  46. static char THIS_FILE[] = __FILE__;
  47. #endif
  48. /////////////////////////////////////////////////////////////////////////////
  49. // EmitterPropertySheetClass
  50. IMPLEMENT_DYNAMIC(EmitterPropertySheetClass, CPropertySheet)
  51. /////////////////////////////////////////////////////////////
  52. //
  53. // EmitterPropertySheetClass
  54. //
  55. EmitterPropertySheetClass::EmitterPropertySheetClass
  56. (
  57. EmitterInstanceListClass *emitter_list,
  58. UINT nIDCaption,
  59. CWnd *pParentWnd
  60. )
  61. : m_pEmitterList (NULL),
  62. CPropertySheet (nIDCaption, pParentWnd, 0)
  63. {
  64. m_pEmitterList = emitter_list;
  65. Initialize ();
  66. return ;
  67. }
  68. /////////////////////////////////////////////////////////////
  69. //
  70. // EmitterPropertySheetClass
  71. //
  72. EmitterPropertySheetClass::EmitterPropertySheetClass
  73. (
  74. EmitterInstanceListClass *emitter_list,
  75. LPCTSTR pszCaption,
  76. CWnd *pParentWnd
  77. )
  78. : m_pEmitterList (NULL),
  79. CPropertySheet (pszCaption, pParentWnd, 0)
  80. {
  81. m_pEmitterList = emitter_list;
  82. Initialize ();
  83. return ;
  84. }
  85. /////////////////////////////////////////////////////////////
  86. //
  87. // EmitterPropertySheetClass
  88. //
  89. EmitterPropertySheetClass::~EmitterPropertySheetClass (void)
  90. {
  91. SAFE_DELETE (m_pEmitterList);
  92. return ;
  93. }
  94. BEGIN_MESSAGE_MAP(EmitterPropertySheetClass, CPropertySheet)
  95. //{{AFX_MSG_MAP(EmitterPropertySheetClass)
  96. // NOTE - the ClassWizard will add and remove mapping macros here.
  97. //}}AFX_MSG_MAP
  98. END_MESSAGE_MAP()
  99. /////////////////////////////////////////////////////////////////////////////
  100. // EmitterPropertySheetClass message handlers
  101. /////////////////////////////////////////////////////////////
  102. //
  103. // EmitterPropertySheetClass
  104. //
  105. LRESULT
  106. EmitterPropertySheetClass::WindowProc
  107. (
  108. UINT message,
  109. WPARAM wParam,
  110. LPARAM lParam
  111. )
  112. {
  113. switch (message)
  114. {
  115. // Is a control sending us an oldstyle notification?
  116. case WM_COMMAND:
  117. {
  118. // What control sent the notification?
  119. switch (LOWORD (wParam))
  120. {
  121. case IDCANCEL:
  122. {
  123. ::GetCurrentDocument ()->Reload_Displayed_Object ();
  124. }
  125. break;
  126. case IDOK:
  127. {
  128. // If the apply button isn't enabled, then don't do the apply operation.
  129. if (::IsWindowEnabled (::GetDlgItem (m_hWnd, ID_APPLY_NOW)) == FALSE) {
  130. break;
  131. }
  132. }
  133. case ID_APPLY_NOW:
  134. {
  135. // Did the user click the button?
  136. if (HIWORD (wParam) == BN_CLICKED) {
  137. LRESULT lresult = CPropertySheet::WindowProc (message, wParam, lParam);
  138. // If all the pages contain valid data, then update the emitter
  139. if (m_GeneralPage.Is_Data_Valid () &&
  140. m_ParticlePage.Is_Data_Valid () &&
  141. m_PhysicsPage.Is_Data_Valid () &&
  142. m_ColorPage.Is_Data_Valid () &&
  143. m_UserPage.Is_Data_Valid () &&
  144. m_SizePage.Is_Data_Valid () &&
  145. m_LinePage.Is_Data_Valid () &&
  146. m_RotationPage.Is_Data_Valid () &&
  147. m_FramePage.Is_Data_Valid () &&
  148. m_LineGroupPage.Is_Data_Valid () )
  149. {
  150. // Update the current emitter to match the data
  151. Update_Emitter ();
  152. }
  153. return lresult;
  154. }
  155. }
  156. break;
  157. }
  158. break;
  159. }
  160. break;
  161. }
  162. // Allow the base class to process this message
  163. return CPropertySheet::WindowProc (message, wParam, lParam);
  164. }
  165. /////////////////////////////////////////////////////////////
  166. //
  167. // Add_Emitter_To_Viewer
  168. //
  169. void
  170. EmitterPropertySheetClass::Add_Emitter_To_Viewer (void)
  171. {
  172. CW3DViewDoc *pdoc = ::GetCurrentDocument ();
  173. if ((pdoc != NULL) && (m_pEmitterList != NULL)) {
  174. //
  175. // Create a new prototype for this emitter and add it to the asset manager
  176. //
  177. ParticleEmitterDefClass *pdefinition = new ParticleEmitterDefClass (*m_pEmitterList);
  178. ParticleEmitterPrototypeClass *pprototype = new ParticleEmitterPrototypeClass (pdefinition);
  179. //
  180. // Update the asset manager with the new prototype
  181. //
  182. if (m_LastSavedName.GetLength () > 0) {
  183. WW3DAssetManager::Get_Instance()->Remove_Prototype (m_LastSavedName);
  184. }
  185. WW3DAssetManager::Get_Instance()->Add_Prototype (pprototype);
  186. //
  187. // Add this emitter to the data tree
  188. //
  189. CDataTreeView *pdata_tree = pdoc->GetDataTreeView ();
  190. pdata_tree->Refresh_Asset (m_pEmitterList->Get_Name (), m_LastSavedName, TypeEmitter);
  191. /*if (m_LastSavedName.GetLength () > 0) {
  192. pdata_tree->Refresh_Asset (m_pEmitterList->Get_Name (), m_LastSavedName, TypeEmitter);
  193. } else {
  194. pdata_tree->Add_Asset_To_Tree (m_pEmitterList->Get_Name (), TypeEmitter, true);
  195. }*/
  196. //
  197. // Display the emitter
  198. //
  199. pdoc->Reload_Displayed_Object ();
  200. m_LastSavedName = m_pEmitterList->Get_Name ();
  201. //
  202. // Regenerate the emitter pointer list
  203. //
  204. m_pEmitterList->Free_List ();
  205. pdoc->Build_Emitter_List (m_pEmitterList, m_pEmitterList->Get_Name ());
  206. }
  207. return ;
  208. }
  209. /////////////////////////////////////////////////////////////
  210. //
  211. // Update_Emitter
  212. //
  213. void
  214. EmitterPropertySheetClass::Update_Emitter (void)
  215. {
  216. //
  217. // Update those pages that are dependant on the particle's
  218. // lifetime.
  219. //
  220. float lifetime = m_GeneralPage.Get_Lifetime ();
  221. m_ColorPage.On_Lifetime_Changed (lifetime);
  222. m_SizePage.On_Lifetime_Changed (lifetime);
  223. m_RotationPage.On_Lifetime_Changed (lifetime);
  224. m_FramePage.On_Lifetime_Changed (lifetime);
  225. m_LineGroupPage.On_Lifetime_Changed (lifetime);
  226. Add_Emitter_To_Viewer ();
  227. //
  228. // Create a new emitter
  229. //
  230. /*ParticleEmitterClass *pemitter = Create_Emitter ();
  231. Add_Emitter_To_Viewer (pemitter);
  232. //
  233. // Use this emitter as the edited emitter from here on out
  234. //
  235. MEMBER_RELEASE (m_pEmitter);
  236. m_pEmitter = pemitter;*/
  237. // Pass the emitter along to the pages
  238. /*m_GeneralPage.Set_Emitter (m_pEmitterList);
  239. m_ParticlePage.Set_Emitter (m_pEmitterList);
  240. m_PhysicsPage.Set_Emitter (m_pEmitterList);
  241. m_ColorPage.Set_Emitter (m_pEmitterList);
  242. m_UserPage.Set_Emitter (m_pEmitterList);
  243. m_SizePage.Set_Emitter (m_pEmitterList);*/
  244. return ;
  245. }
  246. /////////////////////////////////////////////////////////////
  247. //
  248. // Initialize
  249. //
  250. void
  251. EmitterPropertySheetClass::Initialize (void)
  252. {
  253. if (m_pEmitterList == NULL) {
  254. Create_New_Emitter ();
  255. } else {
  256. m_LastSavedName = m_pEmitterList->Get_Name ();
  257. }
  258. // Pass the emitter along to the pages
  259. m_GeneralPage.Set_Emitter (m_pEmitterList);
  260. m_ParticlePage.Set_Emitter (m_pEmitterList);
  261. m_PhysicsPage.Set_Emitter (m_pEmitterList);
  262. m_ColorPage.Set_Emitter (m_pEmitterList);
  263. m_UserPage.Set_Emitter (m_pEmitterList);
  264. m_SizePage.Set_Emitter (m_pEmitterList);
  265. m_LinePage.Set_Emitter (m_pEmitterList);
  266. m_RotationPage.Set_Emitter (m_pEmitterList);
  267. m_FramePage.Set_Emitter (m_pEmitterList);
  268. m_LineGroupPage.Set_Emitter (m_pEmitterList);
  269. // Initialize the user page with data from the prototype
  270. /*if (m_pEmitter != NULL) {
  271. ParticleEmitterPrototypeClass *proto = NULL;
  272. proto = (ParticleEmitterPrototypeClass *)WW3DAssetManager::Get_Instance ()->Find_Prototype (m_pEmitter->Get_Name ());
  273. if (proto != NULL) {
  274. ParticleEmitterDefClass *definition = proto->Get_Definition ();
  275. m_UserPage.Set_Type (definition->Get_User_Type ());
  276. m_UserPage.Set_String (definition->Get_User_String ());
  277. }
  278. }*/
  279. // Add the pages to the sheet
  280. AddPage (&m_GeneralPage);
  281. AddPage (&m_ParticlePage);
  282. AddPage (&m_PhysicsPage);
  283. AddPage (&m_ColorPage);
  284. AddPage (&m_SizePage);
  285. AddPage (&m_UserPage);
  286. AddPage (&m_LinePage);
  287. AddPage (&m_RotationPage);
  288. AddPage (&m_FramePage);
  289. AddPage (&m_LineGroupPage);
  290. m_GeneralPage.Set_Parent(this);
  291. return ;
  292. }
  293. /////////////////////////////////////////////////////////////
  294. //
  295. // Create_Emitter
  296. //
  297. /*ParticleEmitterClass *
  298. EmitterPropertySheetClass::Create_Emitter (void)
  299. {
  300. //
  301. // Read the particle settings
  302. //
  303. float rate = m_ParticlePage.Get_Rate ();
  304. int burst = m_ParticlePage.Get_Burst_Size ();
  305. float max_particles = m_ParticlePage.Get_Max_Particles ();
  306. //
  307. // Read the physics settings
  308. //
  309. Vector3 velocity = m_PhysicsPage.Get_Velocity ();
  310. Vector3 acceleration = m_PhysicsPage.Get_Acceleration ();
  311. float out_factor = m_PhysicsPage.Get_Out_Factor ();
  312. float inherit_factor = m_PhysicsPage.Get_Inheritance_Factor ();
  313. //
  314. // Read the general settings
  315. //
  316. CString name = m_GeneralPage.Get_Name ();
  317. CString texture_name = m_GeneralPage.Get_Texture_Filename ();
  318. float lifetime = m_GeneralPage.Get_Lifetime ();
  319. ShaderClass shader = m_GeneralPage.Get_Shader ();
  320. //
  321. // Read the keyframe settings
  322. //
  323. ParticlePropertyStruct<Vector3> colors;
  324. ParticlePropertyStruct<float> opacity;
  325. ParticlePropertyStruct<float> size;
  326. m_ColorPage.Get_Color_Keyframes (colors);
  327. m_ColorPage.Get_Opacity_Keyframes (opacity);
  328. m_SizePage.Get_Size_Keyframes (size);
  329. //
  330. // Read the randomizers
  331. //
  332. Vector3Randomizer *creation_vol = m_ParticlePage.Get_Creation_Volume ();
  333. Vector3Randomizer *vel_random = m_PhysicsPage.Get_Velocity_Random ();
  334. //
  335. // Load the texture
  336. //
  337. TextureClass *ptexture = NULL;
  338. if (texture_name.GetLength () > 0) {
  339. ptexture = WW3DAssetManager::Get_Instance()->Get_Texture (texture_name);
  340. }
  341. //
  342. // Create the new particle emitter
  343. //
  344. ParticleEmitterClass *pemitter = new ParticleEmitterClass (rate,
  345. burst,
  346. creation_vol,
  347. velocity,
  348. vel_random,
  349. out_factor,
  350. inherit_factor,
  351. colors,
  352. opacity,
  353. size,
  354. acceleration,
  355. lifetime,
  356. ptexture,
  357. shader,
  358. max_particles);
  359. //
  360. // Pass the name onto the emitter
  361. //
  362. pemitter->Set_Name (name);
  363. // Return the emitter
  364. return pemitter;
  365. }*/
  366. /////////////////////////////////////////////////////////////
  367. //
  368. // Create_New_Emitter
  369. //
  370. void
  371. EmitterPropertySheetClass::Create_New_Emitter (void)
  372. {
  373. ParticlePropertyStruct<Vector3> color;
  374. color.Start = Vector3 (1, 1, 1);
  375. color.Rand.Set (0,0,0);
  376. color.NumKeyFrames = 0;
  377. color.KeyTimes = NULL;
  378. color.Values = NULL;
  379. ParticlePropertyStruct<float> opacity;
  380. opacity.Start = 1.0F;
  381. opacity.Rand = 0.0F;
  382. opacity.NumKeyFrames = 0;
  383. opacity.KeyTimes = NULL;
  384. opacity.Values = NULL;
  385. ParticlePropertyStruct<float> size;
  386. size.Start = 0.1F;
  387. size.Rand = 0.0F;
  388. size.NumKeyFrames = 0;
  389. size.KeyTimes = NULL;
  390. size.Values = NULL;
  391. ParticlePropertyStruct<float> rotation;
  392. rotation.Start = 0.0f;
  393. rotation.Rand = 0.0f;
  394. rotation.NumKeyFrames = 0;
  395. rotation.KeyTimes = NULL;
  396. rotation.Values = NULL;
  397. ParticlePropertyStruct<float> frames;
  398. frames.Start = 0.0f;
  399. frames.Rand = 0.0f;
  400. frames.NumKeyFrames = 0;
  401. frames.KeyTimes = NULL;
  402. frames.Values = NULL;
  403. ParticlePropertyStruct<float> blurtimes;
  404. blurtimes.Start = 0.0f;
  405. blurtimes.Rand = 0.0f;
  406. blurtimes.NumKeyFrames = 0;
  407. blurtimes.KeyTimes = NULL;
  408. blurtimes.Values = NULL;
  409. //
  410. // Create the new emitter
  411. //
  412. ParticleEmitterClass *emitter = NULL;
  413. emitter = new ParticleEmitterClass (10,
  414. 1,
  415. new Vector3SolidBoxRandomizer(Vector3(0.1F, 0.1F, 0.1F)),
  416. Vector3 (0, 0, 1),
  417. new Vector3SolidBoxRandomizer(Vector3(0, 0, 0.1F)),
  418. 0,
  419. 0,
  420. color,
  421. opacity,
  422. size,
  423. rotation,
  424. 0.0f,
  425. frames,
  426. blurtimes,
  427. Vector3 (0, 0, 0),
  428. 1.0F,
  429. NULL,
  430. ShaderClass::_PresetAdditiveSpriteShader,
  431. 0);
  432. //
  433. // Create the new emitter list
  434. //
  435. m_pEmitterList = new EmitterInstanceListClass;
  436. m_pEmitterList->Add_Emitter (emitter);
  437. //
  438. // Display the new emitter
  439. //
  440. ::GetCurrentDocument ()->Display_Emitter (emitter);
  441. MEMBER_RELEASE (emitter);
  442. /*SAFE_DELETE_ARRAY (color.Values);
  443. SAFE_DELETE_ARRAY (color.KeyTimes);
  444. SAFE_DELETE_ARRAY (opacity.Values);
  445. SAFE_DELETE_ARRAY (opacity.KeyTimes);
  446. SAFE_DELETE_ARRAY (size.Values);
  447. SAFE_DELETE_ARRAY (size.KeyTimes);*/
  448. return ;
  449. }
  450. void
  451. EmitterPropertySheetClass::Notify_Render_Mode_Changed(int new_mode)
  452. {
  453. bool enable_line_page = (new_mode == W3D_EMITTER_RENDER_MODE_LINE);
  454. ::Enable_Dialog_Controls(m_LinePage,enable_line_page);
  455. }