DummyObjectNode.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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 : LevelEdit *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/LevelEdit/DummyObjectNode.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 12/01/00 2:25p $*
  29. * *
  30. * $Revision:: 11 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "stdafx.h"
  36. #include "phys.h"
  37. #include "rendobj.h"
  38. #include "dummyobjectnode.h"
  39. #include "dummyobjectdefinition.h"
  40. #include "sceneeditor.h"
  41. #include "filemgr.h"
  42. #include "_assetmgr.h"
  43. #include "editorassetmgr.h"
  44. #include "w3d_file.h"
  45. #include "cameramgr.h"
  46. #include "collisiongroups.h"
  47. #include "persistfactory.h"
  48. #include "editorchunkids.h"
  49. #include "preset.h"
  50. #include "presetmgr.h"
  51. #include "nodemgr.h"
  52. #include "part_emt.h"
  53. #include "modelutils.h"
  54. //////////////////////////////////////////////////////////////////////////////
  55. // Local prototypes
  56. //////////////////////////////////////////////////////////////////////////////
  57. void Remove_Particle_Buffers (RenderObjClass *render_obj);
  58. //////////////////////////////////////////////////////////////////////////////
  59. // Persist factory
  60. //////////////////////////////////////////////////////////////////////////////
  61. SimplePersistFactoryClass<DummyObjectNodeClass, CHUNKID_DUMMY_OBJECT> _DummyNodePersistFactory;
  62. //////////////////////////////////////////////////////////////////////////////
  63. //
  64. // DummyObjectNodeClass
  65. //
  66. //////////////////////////////////////////////////////////////////////////////
  67. DummyObjectNodeClass::DummyObjectNodeClass (PresetClass *preset)
  68. : m_DisplayObj (NULL),
  69. m_RealObj (NULL),
  70. NodeClass (preset)
  71. {
  72. return ;
  73. }
  74. //////////////////////////////////////////////////////////////////////////////
  75. //
  76. // DummyObjectNodeClass
  77. //
  78. //////////////////////////////////////////////////////////////////////////////
  79. DummyObjectNodeClass::DummyObjectNodeClass (const DummyObjectNodeClass &src)
  80. : m_DisplayObj (NULL),
  81. m_RealObj (NULL),
  82. NodeClass (NULL)
  83. {
  84. *this = src;
  85. return ;
  86. }
  87. //////////////////////////////////////////////////////////////////////////////
  88. //
  89. // ~DummyObjectNodeClass
  90. //
  91. //////////////////////////////////////////////////////////////////////////////
  92. DummyObjectNodeClass::~DummyObjectNodeClass (void)
  93. {
  94. Remove_From_Scene ();
  95. MEMBER_RELEASE (m_DisplayObj);
  96. MEMBER_RELEASE (m_RealObj);
  97. return ;
  98. }
  99. //////////////////////////////////////////////////////////////////////////////
  100. //
  101. // Initialize
  102. //
  103. // Note: This may be called more than once. It is used as an 'initialize'
  104. // and a 're-initialize'.
  105. //
  106. //////////////////////////////////////////////////////////////////////////////
  107. void
  108. DummyObjectNodeClass::Initialize (void)
  109. {
  110. //
  111. // Build the phys obj that is used as the position locator in the world.
  112. // This is usefull for things like emitters which do not have anything
  113. // to 'grab'...
  114. //
  115. if (m_DisplayObj == NULL) {
  116. m_DisplayObj = new DecorationPhysClass;
  117. m_DisplayObj->Set_Model_By_Name ("DUMMY");
  118. m_DisplayObj->Set_Collision_Group (EDITOR_COLLISION_GROUP);
  119. m_DisplayObj->Peek_Model ()->Set_User_Data ((PVOID)&m_HitTestInfo, FALSE);
  120. ::Set_Model_Collision_Type (m_DisplayObj->Peek_Model (), COLLISION_TYPE_0);
  121. }
  122. DummyObjectDefinitionClass *definition = static_cast<DummyObjectDefinitionClass *> (m_Preset->Get_Definition ());
  123. if (definition != NULL) {
  124. MEMBER_RELEASE (m_RealObj);
  125. //
  126. // Make sure we have all the assets loaded into memory that this object needs.
  127. //
  128. m_Preset->Load_All_Assets ();
  129. //
  130. // Create the real physics object that will get exported to the game
  131. //
  132. m_RealObj = new DecorationPhysClass;
  133. CString render_obj_name = ::Asset_Name_From_Filename (definition->Get_Model_Name ());
  134. RenderObjClass *render_obj = ::Create_Render_Obj (render_obj_name);
  135. if (render_obj != NULL) {
  136. //
  137. // Start the emitter if necessary
  138. //
  139. if (render_obj->Class_ID () == RenderObjClass::CLASSID_PARTICLEEMITTER) {
  140. ((ParticleEmitterClass *)render_obj)->Start ();
  141. render_obj->Set_User_Data (m_RealObj);
  142. }
  143. m_RealObj->Set_Model (render_obj);
  144. MEMBER_RELEASE (render_obj);
  145. }
  146. //
  147. // Update the transforms of both objects
  148. //
  149. Set_Transform (m_Transform);
  150. }
  151. return ;
  152. }
  153. ////////////////////////////////////////////////////////////////
  154. //
  155. // Get_Factory
  156. //
  157. ////////////////////////////////////////////////////////////////
  158. const PersistFactoryClass &
  159. DummyObjectNodeClass::Get_Factory (void) const
  160. {
  161. return _DummyNodePersistFactory;
  162. }
  163. /////////////////////////////////////////////////////////////////
  164. //
  165. // operator=
  166. //
  167. /////////////////////////////////////////////////////////////////
  168. const DummyObjectNodeClass &
  169. DummyObjectNodeClass::operator= (const DummyObjectNodeClass &src)
  170. {
  171. NodeClass::operator= (src);
  172. return *this;
  173. }
  174. //////////////////////////////////////////////////////////////////////
  175. //
  176. // Pre_Export
  177. //
  178. //////////////////////////////////////////////////////////////////////
  179. void
  180. DummyObjectNodeClass::Pre_Export (void)
  181. {
  182. //
  183. // Remove ourselves from the 'system' so we don't get accidentally
  184. // saved during the export.
  185. //
  186. Add_Ref ();
  187. if (m_DisplayObj != NULL && m_IsInScene) {
  188. ::Get_Scene_Editor ()->Remove_Object (m_DisplayObj);
  189. }
  190. return ;
  191. }
  192. //////////////////////////////////////////////////////////////////////
  193. //
  194. // Post_Export
  195. //
  196. //////////////////////////////////////////////////////////////////////
  197. void
  198. DummyObjectNodeClass::Post_Export (void)
  199. {
  200. //
  201. // Put ourselves back into the system
  202. //
  203. if (m_DisplayObj != NULL && m_IsInScene) {
  204. ::Get_Scene_Editor ()->Add_Dynamic_Object (m_DisplayObj);
  205. }
  206. Release_Ref ();
  207. return ;
  208. }
  209. //////////////////////////////////////////////////////////////////////
  210. //
  211. // Add_To_Scene
  212. //
  213. //////////////////////////////////////////////////////////////////////
  214. void
  215. DummyObjectNodeClass::Add_To_Scene (void)
  216. {
  217. if (m_RealObj == NULL) {
  218. Initialize ();
  219. }
  220. if (m_RealObj != NULL && m_RealObj->Peek_Model ()->Peek_Scene () == NULL) {
  221. ::Get_Scene_Editor ()->Add_Dynamic_Object (m_RealObj);
  222. ::Get_Scene_Editor ()->Add_To_Dirty_Cull_List (m_RealObj);
  223. }
  224. NodeClass::Add_To_Scene ();
  225. return ;
  226. }
  227. //////////////////////////////////////////////////////////////////////
  228. //
  229. // Remove_From_Scene
  230. //
  231. //////////////////////////////////////////////////////////////////////
  232. void
  233. DummyObjectNodeClass::Remove_From_Scene (void)
  234. {
  235. if (m_RealObj != NULL && m_RealObj->Peek_Model ()->Peek_Scene () != NULL) {
  236. //
  237. // If this is a particle emitter, then be sure to remove the buffer as well
  238. //
  239. RenderObjClass *render_obj = m_RealObj->Peek_Model ();
  240. Remove_Particle_Buffers (render_obj);
  241. ::Get_Scene_Editor ()->Remove_From_Dirty_Cull_List (m_RealObj);
  242. ::Get_Scene_Editor ()->Remove_Object (m_RealObj);
  243. MEMBER_RELEASE (m_RealObj);
  244. }
  245. NodeClass::Remove_From_Scene ();
  246. return ;
  247. }
  248. //////////////////////////////////////////////////////////////////////
  249. //
  250. // Handle_Emitter_Transform
  251. //
  252. //////////////////////////////////////////////////////////////////////
  253. void
  254. DummyObjectNodeClass::Handle_Emitter_Transform (void)
  255. {
  256. if (m_RealObj != NULL && m_RealObj->Peek_Model () != NULL) {
  257. //
  258. // If this is a particle emitter, then be sure to move the buffer as well
  259. //
  260. RenderObjClass *render_obj = m_RealObj->Peek_Model ();
  261. if (render_obj->Class_ID () == RenderObjClass::CLASSID_PARTICLEEMITTER) {
  262. ParticleBufferClass *buffer = ((ParticleEmitterClass *)render_obj)->Peek_Buffer ();
  263. if (buffer != NULL) {
  264. buffer->Set_Transform (m_Transform);
  265. }
  266. }
  267. }
  268. return ;
  269. }
  270. ///////////////////////////////////////////////////////////////
  271. //
  272. // Remove_Particle_Buffers
  273. //
  274. ///////////////////////////////////////////////////////////////
  275. void
  276. Remove_Particle_Buffers (RenderObjClass *render_obj)
  277. {
  278. //
  279. // Recursively walk through the objects in the scene
  280. //
  281. for (int index = 0; index < render_obj->Get_Num_Sub_Objects (); index ++) {
  282. RenderObjClass *sub_obj = render_obj->Get_Sub_Object (index);
  283. if (sub_obj != NULL) {
  284. Remove_Particle_Buffers (sub_obj);
  285. }
  286. MEMBER_RELEASE (sub_obj);
  287. }
  288. //
  289. // Is this the emitter we are requesting?
  290. //
  291. if ((render_obj != NULL) &&
  292. (render_obj->Class_ID () == RenderObjClass::CLASSID_PARTICLEEMITTER))
  293. {
  294. ParticleBufferClass *buffer = ((ParticleEmitterClass *)render_obj)->Peek_Buffer ();
  295. if (buffer != NULL && buffer->Peek_Scene () != NULL) {
  296. ::Get_Scene_Editor ()->Remove_Render_Object (buffer);
  297. }
  298. }
  299. return ;
  300. }