dynamicanimphys.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  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 : WWPhys *
  23. * *
  24. * $Archive:: /Commando/Code/wwphys/dynamicanimphys.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Greg_h $*
  29. * *
  30. * $Modtime:: 11/01/01 2:41p $*
  31. * *
  32. * $Revision:: 12 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #include "dynamicanimphys.h"
  38. #include "wwphysids.h"
  39. #include "persistfactory.h"
  40. #include "simpledefinitionfactory.h"
  41. #include "wwhack.h"
  42. #include "wwprofile.h"
  43. #include "matinfo.h"
  44. DECLARE_FORCE_LINK(dynamicanimphys);
  45. /***********************************************************************************************
  46. DynamicAnimPhysClass Implementation
  47. ***********************************************************************************************/
  48. /*
  49. ** Declare a PersistFactory for DynamicAnimPhysClass. This enables the class to save and load.
  50. */
  51. SimplePersistFactoryClass<DynamicAnimPhysClass,PHYSICS_CHUNKID_DYNAMICANIMPHYS> _DynamicAnimPhysFactory;
  52. /*
  53. ** Chunk ID's used by DynamicAnimPhysClass
  54. */
  55. enum
  56. {
  57. DYNAMICANIMPHYS_CHUNK_DECOPHYS = 526000339,
  58. DYNAMICANIMPHYS_CHUNK_VARIABLES,
  59. DYNAMICANIMPHYS_CHUNK_ANIMMANAGER,
  60. };
  61. DynamicAnimPhysClass::DynamicAnimPhysClass(void) :
  62. AnimManager(*this),
  63. ShadowManager(*this)
  64. {
  65. }
  66. DynamicAnimPhysClass::~DynamicAnimPhysClass(void)
  67. {
  68. }
  69. void DynamicAnimPhysClass::Init(const DynamicAnimPhysDefClass & def)
  70. {
  71. DecorationPhysClass::Init(def);
  72. AnimManager.Init(def.AnimManagerDef);
  73. }
  74. void DynamicAnimPhysClass::Set_Model(RenderObjClass * model)
  75. {
  76. DecorationPhysClass::Set_Model(model);
  77. Update_Cached_Model_Parameters();
  78. /*
  79. ** Nuke strike uses a linear offset mapper to fade out, have to reset it so I'm
  80. ** just resetting any mappers in any model used by a DynamicAnimPhys... hacky, oh well.
  81. */
  82. if (Model != NULL) {
  83. Reset_Mappers(Model);
  84. }
  85. }
  86. void DynamicAnimPhysClass::Update_Cached_Model_Parameters(void)
  87. {
  88. /*
  89. ** Set up our animation manager
  90. */
  91. AnimManager.Update_Cached_Model_Parameters();
  92. /*
  93. ** Set up our shadow manager
  94. */
  95. const DynamicAnimPhysDefClass * def = Get_DynamicAnimPhysDef();
  96. Enable_Shadow_Generation(def->CastsShadows);
  97. ShadowManager.Set_Shadow_Planes(def->ShadowNearZ,def->ShadowFarZ);
  98. }
  99. void DynamicAnimPhysClass::Reset_Mappers(RenderObjClass * model)
  100. {
  101. if (model != NULL) {
  102. MaterialInfoClass * matinfo = model->Get_Material_Info();
  103. if (matinfo != NULL) {
  104. matinfo->Reset_Texture_Mappers();
  105. }
  106. REF_PTR_RELEASE(matinfo);
  107. for (int i=0; i<model->Get_Num_Sub_Objects(); i++) {
  108. RenderObjClass * sub_obj = model->Get_Sub_Object(i);
  109. Reset_Mappers(sub_obj);
  110. REF_PTR_RELEASE(sub_obj);
  111. }
  112. }
  113. }
  114. void DynamicAnimPhysClass::Timestep(float dt)
  115. {
  116. WWPROFILE("DynAnimPhys::Timestep");
  117. /*
  118. ** Let the animation manager handle progressing the animation, checking
  119. ** for collisions, and managing any "riders"
  120. */
  121. bool anim_changed = AnimManager.Timestep(dt);
  122. if (anim_changed) {
  123. Update_Visibility_Status();
  124. Update_Cull_Box();
  125. }
  126. }
  127. void DynamicAnimPhysClass::Post_Timestep_Process(void)
  128. {
  129. ShadowManager.Update_Shadow();
  130. }
  131. const PersistFactoryClass & DynamicAnimPhysClass::Get_Factory(void) const
  132. {
  133. return _DynamicAnimPhysFactory;
  134. }
  135. bool DynamicAnimPhysClass::Save(ChunkSaveClass &csave)
  136. {
  137. csave.Begin_Chunk(DYNAMICANIMPHYS_CHUNK_DECOPHYS);
  138. DecorationPhysClass::Save(csave);
  139. csave.End_Chunk();
  140. csave.Begin_Chunk(DYNAMICANIMPHYS_CHUNK_ANIMMANAGER);
  141. AnimManager.Save(csave);
  142. csave.End_Chunk();
  143. return true;
  144. }
  145. bool DynamicAnimPhysClass::Load(ChunkLoadClass &cload)
  146. {
  147. /*
  148. ** Read in the chunks from the file
  149. */
  150. while (cload.Open_Chunk()) {
  151. switch(cload.Cur_Chunk_ID())
  152. {
  153. case DYNAMICANIMPHYS_CHUNK_DECOPHYS:
  154. DecorationPhysClass::Load(cload);
  155. break;
  156. case DYNAMICANIMPHYS_CHUNK_ANIMMANAGER:
  157. AnimManager.Load(cload);
  158. break;
  159. default:
  160. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  161. break;
  162. }
  163. cload.Close_Chunk();
  164. }
  165. SaveLoadSystemClass::Register_Post_Load_Callback(this);
  166. return true;
  167. }
  168. void DynamicAnimPhysClass::On_Post_Load(void)
  169. {
  170. DecorationPhysClass::On_Post_Load();
  171. /*
  172. ** Always re-initialize any variables which depend on the model
  173. */
  174. Update_Cached_Model_Parameters();
  175. }
  176. /***********************************************************************************************
  177. DynamicAnimPhysDefClass Implementation
  178. ***********************************************************************************************/
  179. /*
  180. ** Persist factory for StaticAnimPhysDefClass's. This makes them able to save and load.
  181. */
  182. SimplePersistFactoryClass<DynamicAnimPhysDefClass,PHYSICS_CHUNKID_DYNAMICANIMPHYSDEF> _DynamicAnimPhysDefFactory;
  183. /*
  184. ** Definition factory for StaticAnimPhysDefClass. This makes it show up in the editor
  185. */
  186. DECLARE_DEFINITION_FACTORY(DynamicAnimPhysDefClass, CLASSID_DYNAMICANIMPHYSDEF, "DynamicAnimPhys") _DynamicAnimPhysDefDefFactory;
  187. /*
  188. ** Chunk ID's used by StaticAnimPhysDefClass
  189. */
  190. enum
  191. {
  192. DYNAMICANIMPHYSDEF_CHUNK_DECOPHYSDEF = 052600316, // (parent class)
  193. DYNAMICANIMPHYSDEF_CHUNK_ANIMMANAGERDEF,
  194. DYNAMICANIMPHYSDEF_CHUNK_VARIABLES,
  195. DYNAMICANIMPHYSDEF_VARIABLE_CASTSSHADOWS = 0x01,
  196. DYNAMICANIMPHYSDEF_VARIABLE_SHADOWNEARZ,
  197. DYNAMICANIMPHYSDEF_VARIABLE_SHADOWFARZ,
  198. };
  199. DynamicAnimPhysDefClass::DynamicAnimPhysDefClass(void) :
  200. CastsShadows(false),
  201. ShadowNearZ(-1.0f),
  202. ShadowFarZ(-1.0f)
  203. {
  204. // Make the animation manager variables editable
  205. ANIMCOLLISIONMANAGERDEF_EDITABLE_PARAMS( DynamicAnimPhysDefClass , AnimManagerDef );
  206. PARAM_SEPARATOR(DynamicAnimPhysDefClass, "Shadow Settings");
  207. EDITABLE_PARAM(DynamicAnimPhysDefClass,ParameterClass::TYPE_BOOL, CastsShadows);
  208. FLOAT_UNITS_PARAM(DynamicAnimPhysDefClass,ShadowNearZ, -1.0f,1000.0f, "meters (-1 for default)")
  209. FLOAT_UNITS_PARAM(DynamicAnimPhysDefClass,ShadowFarZ, -1.0f,1000.0f, "meters (-1 for default)")
  210. }
  211. uint32 DynamicAnimPhysDefClass::Get_Class_ID (void) const
  212. {
  213. return CLASSID_DYNAMICANIMPHYSDEF;
  214. }
  215. PersistClass * DynamicAnimPhysDefClass::Create(void) const
  216. {
  217. DynamicAnimPhysClass * obj = NEW_REF(DynamicAnimPhysClass,());
  218. obj->Init(*this);
  219. return obj;
  220. }
  221. const PersistFactoryClass & DynamicAnimPhysDefClass::Get_Factory (void) const
  222. {
  223. return _DynamicAnimPhysDefFactory;
  224. }
  225. const char * DynamicAnimPhysDefClass::Get_Type_Name(void)
  226. {
  227. return "DynamicAnimPhysDef";
  228. }
  229. bool DynamicAnimPhysDefClass::Is_Type(const char * type_name)
  230. {
  231. if (stricmp(type_name,DynamicAnimPhysDefClass::Get_Type_Name()) == 0) {
  232. return true;
  233. } else {
  234. return DecorationPhysDefClass::Is_Type(type_name);
  235. }
  236. }
  237. bool DynamicAnimPhysDefClass::Save(ChunkSaveClass &csave)
  238. {
  239. csave.Begin_Chunk(DYNAMICANIMPHYSDEF_CHUNK_DECOPHYSDEF);
  240. DecorationPhysDefClass::Save(csave);
  241. csave.End_Chunk();
  242. csave.Begin_Chunk(DYNAMICANIMPHYSDEF_CHUNK_ANIMMANAGERDEF);
  243. AnimManagerDef.Save(csave);
  244. csave.End_Chunk();
  245. csave.Begin_Chunk(DYNAMICANIMPHYSDEF_CHUNK_VARIABLES);
  246. WRITE_MICRO_CHUNK(csave,DYNAMICANIMPHYSDEF_VARIABLE_CASTSSHADOWS,CastsShadows);
  247. WRITE_MICRO_CHUNK(csave,DYNAMICANIMPHYSDEF_VARIABLE_SHADOWNEARZ,ShadowNearZ);
  248. WRITE_MICRO_CHUNK(csave,DYNAMICANIMPHYSDEF_VARIABLE_SHADOWFARZ,ShadowFarZ);
  249. csave.End_Chunk();
  250. return true;
  251. }
  252. bool DynamicAnimPhysDefClass::Load(ChunkLoadClass &cload)
  253. {
  254. while (cload.Open_Chunk()) {
  255. switch(cload.Cur_Chunk_ID()) {
  256. case DYNAMICANIMPHYSDEF_CHUNK_DECOPHYSDEF:
  257. DecorationPhysDefClass::Load(cload);
  258. break;
  259. case DYNAMICANIMPHYSDEF_CHUNK_ANIMMANAGERDEF:
  260. AnimManagerDef.Load(cload);
  261. break;
  262. case DYNAMICANIMPHYSDEF_CHUNK_VARIABLES:
  263. while (cload.Open_Micro_Chunk()) {
  264. switch(cload.Cur_Micro_Chunk_ID()) {
  265. READ_MICRO_CHUNK(cload,DYNAMICANIMPHYSDEF_VARIABLE_CASTSSHADOWS,CastsShadows);
  266. READ_MICRO_CHUNK(cload,DYNAMICANIMPHYSDEF_VARIABLE_SHADOWNEARZ,ShadowNearZ);
  267. READ_MICRO_CHUNK(cload,DYNAMICANIMPHYSDEF_VARIABLE_SHADOWFARZ,ShadowFarZ);
  268. }
  269. cload.Close_Micro_Chunk();
  270. }
  271. break;
  272. default:
  273. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  274. break;
  275. }
  276. cload.Close_Chunk();
  277. }
  278. return true;
  279. }